fix: created EditableInput for tab & section label
This commit is contained in:
parent
074176cfba
commit
2dc9bbd2a5
4 changed files with 96 additions and 80 deletions
83
frappe/public/js/form_builder/components/EditableInput.vue
Normal file
83
frappe/public/js/form_builder/components/EditableInput.vue
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<script setup>
|
||||
import { ref, nextTick, computed, onMounted } from "vue";
|
||||
import { useStore } from "../store";
|
||||
let store = useStore();
|
||||
|
||||
let props = defineProps({
|
||||
text: {
|
||||
type: String
|
||||
},
|
||||
placeholder: {
|
||||
default: __("No Label")
|
||||
}
|
||||
});
|
||||
|
||||
let editing = ref(false);
|
||||
let input_text = ref(null);
|
||||
let hidden_text = ref(null);
|
||||
let hidden_placeholder = ref(null);
|
||||
|
||||
let hidden_span_width = computed(() => {
|
||||
if (hidden_text.value && props.text) {
|
||||
return hidden_text.value.offsetWidth + 15 + "px";
|
||||
} else if (!props.text) {
|
||||
return hidden_placeholder.value.offsetWidth + 15 + "px";
|
||||
}
|
||||
return "40px";
|
||||
});
|
||||
|
||||
function focus_on_label() {
|
||||
if (!store.read_only) {
|
||||
editing.value = true;
|
||||
nextTick(() => input_text.value.focus());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div @dblclick="focus_on_label">
|
||||
<input
|
||||
v-if="editing"
|
||||
class="input-text"
|
||||
ref="input_text"
|
||||
:disabled="store.read_only"
|
||||
type="text"
|
||||
:placeholder="placeholder"
|
||||
v-model="text"
|
||||
:style="{ width: hidden_span_width }"
|
||||
@input="event => $emit('update:modelValue', event.target.value)"
|
||||
@keydown.enter="editing = false"
|
||||
@blur="editing = false"
|
||||
@click.stop
|
||||
/>
|
||||
<span v-else-if="text">{{ text }}</span>
|
||||
<i v-else class="text-muted">
|
||||
{{ __("No Label") }}
|
||||
</i>
|
||||
<span class="hidden-span" ref="hidden_text">{{ text }}</span>
|
||||
<span class="hidden-span" ref="hidden_placeholder">{{ placeholder }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.input-text {
|
||||
border: none;
|
||||
min-width: 50px;
|
||||
margin-left: -2px;
|
||||
|
||||
&:focus {
|
||||
outline: 1px solid var(--primary);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden-span {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
<script setup>
|
||||
import draggable from "vuedraggable";
|
||||
import Column from "./Column.vue";
|
||||
import { ref, nextTick } from "vue";
|
||||
import EditableInput from "./EditableInput.vue";
|
||||
import { ref } from "vue";
|
||||
import { useStore } from "../store";
|
||||
import { section_boilerplate } from "../utils";
|
||||
|
||||
|
|
@ -9,8 +10,6 @@ let props = defineProps(["tab", "section"]);
|
|||
let store = useStore();
|
||||
|
||||
let hovered = ref(false);
|
||||
let label_input = ref(null);
|
||||
let editing = ref(false);
|
||||
let collapsed = ref(false);
|
||||
|
||||
function add_section_above() {
|
||||
|
|
@ -57,13 +56,6 @@ function select_section() {
|
|||
}
|
||||
store.selected_field = props.section.df;
|
||||
}
|
||||
|
||||
function focus_on_label() {
|
||||
if (!store.read_only) {
|
||||
editing.value = true;
|
||||
nextTick(() => label_input.value.focus());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -87,21 +79,12 @@ function focus_on_label() {
|
|||
:hidden="!section.df.label && store.read_only"
|
||||
:style="{ paddingBottom: !collapsed ? '0.75rem' : '' }"
|
||||
>
|
||||
<div class="section-label" @dblclick="focus_on_label">
|
||||
<input
|
||||
v-if="editing"
|
||||
ref="label_input"
|
||||
class="input-section-label"
|
||||
:disabled="store.read_only"
|
||||
type="text"
|
||||
<div class="section-label">
|
||||
<EditableInput
|
||||
:text="section.df.label"
|
||||
:placeholder="__('Section Title')"
|
||||
v-model="section.df.label"
|
||||
@keydown.enter="editing = false"
|
||||
@blur="editing = false"
|
||||
@click.stop
|
||||
/>
|
||||
<span v-else-if="section.df.label">{{ section.df.label }}</span>
|
||||
<i class="text-muted" v-else> {{ __("No Label") }} </i>
|
||||
<div
|
||||
v-if="section.df.collapsible"
|
||||
class="collapse-indicator"
|
||||
|
|
@ -194,22 +177,7 @@ function focus_on_label() {
|
|||
.section-label {
|
||||
display: flex;
|
||||
|
||||
.input-section-label {
|
||||
border: none;
|
||||
margin-left: -2px;
|
||||
|
||||
&:focus {
|
||||
outline: 1px solid var(--primary);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
:deep(span) {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<script setup>
|
||||
import Section from "./Section.vue";
|
||||
import EditableInput from "./EditableInput.vue";
|
||||
import draggable from "vuedraggable";
|
||||
import { useStore } from "../store";
|
||||
import { section_boilerplate } from "../utils";
|
||||
|
|
@ -102,14 +103,6 @@ function remove_tab() {
|
|||
store.active_tab = tabs[prev_tab_index].df.name;
|
||||
store.selected_field = null;
|
||||
}
|
||||
|
||||
function focus_on_label(tab, event) {
|
||||
if (!store.read_only) {
|
||||
tab.editing = true;
|
||||
let $tab = event.target.closest(".tab.active");
|
||||
nextTick(() => $($tab).find("input").focus());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -134,21 +127,12 @@ function focus_on_label(tab, event) {
|
|||
@dragstart="dragged = true"
|
||||
@dragend="dragged = false"
|
||||
@dragover="drag_over(element)"
|
||||
@dblclick="(event) => focus_on_label(element, event)"
|
||||
>
|
||||
<input
|
||||
v-if="element.editing"
|
||||
class="input-tab-label"
|
||||
:disabled="store.read_only"
|
||||
type="text"
|
||||
<EditableInput
|
||||
:text="element.df.label"
|
||||
:placeholder="__('Tab Label')"
|
||||
v-model="element.df.label"
|
||||
@keydown.enter="element.editing = false"
|
||||
@blur="element.editing = false"
|
||||
@click.stop
|
||||
/>
|
||||
<span v-else-if="element.df.label">{{ element.df.label }}</span>
|
||||
<i class="text-muted" v-else> {{ __("No Label") }} </i>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
|
|
@ -204,10 +188,7 @@ function focus_on_label(tab, event) {
|
|||
<div class="empty-tab" :hidden="store.read_only">
|
||||
<div>{{ __("Drag & Drop a section here") }}</div>
|
||||
<div>{{ __("OR") }}</div>
|
||||
<button
|
||||
class="btn btn-default btn-sm"
|
||||
@click="add_new_section()"
|
||||
>
|
||||
<button class="btn btn-default btn-sm" @click="add_new_section()">
|
||||
{{ __("Add a new section") }}
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -272,21 +253,6 @@ function focus_on_label(tab, event) {
|
|||
min-width: max-content;
|
||||
cursor: pointer;
|
||||
|
||||
.input-tab-label {
|
||||
border: none;
|
||||
|
||||
&:focus {
|
||||
outline: 1px solid var(--primary);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
.tab-name {
|
||||
outline: none;
|
||||
border: none;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-bottom: 1px solid var(--gray-300);
|
||||
}
|
||||
|
|
@ -322,7 +288,7 @@ function focus_on_label(tab, event) {
|
|||
height: 7rem;
|
||||
margin: 1rem;
|
||||
|
||||
&+ .empty-tab {
|
||||
& + .empty-tab {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
|
@ -338,7 +304,7 @@ function focus_on_label(tab, event) {
|
|||
}
|
||||
}
|
||||
|
||||
&+ .empty-tab {
|
||||
& + .empty-tab {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,8 +86,7 @@ class FormBuilder {
|
|||
if (
|
||||
this.store.doc &&
|
||||
(this.store.doc.custom || this.store.doc.issingle,
|
||||
in_list(frappe.model.core_doctypes_list, this.doctype) ||
|
||||
!in_list(frappe.boot.active_domains, this.store.doc.restrict_to_domain))
|
||||
in_list(frappe.model.core_doctypes_list, this.doctype))
|
||||
) {
|
||||
this.customize_form_btn.hide();
|
||||
this.go_to_customize_form_btn.hide();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue