mirror of
https://github.com/frappe/books.git
synced 2025-02-02 20:18:26 +00:00
fix: Controls
- Show labels in controls - Placeholder in Select - Emit input and focus events
This commit is contained in:
parent
4154cc5edc
commit
84f5476909
@ -1,16 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dropdown :items="suggestions">
|
<Dropdown :items="suggestions">
|
||||||
<template
|
<template
|
||||||
v-slot="{ toggleDropdown, highlightItemUp, highlightItemDown, selectHighlightedItem }"
|
v-slot="{
|
||||||
|
toggleDropdown,
|
||||||
|
highlightItemUp,
|
||||||
|
highlightItemDown,
|
||||||
|
selectHighlightedItem
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
|
<div class="text-gray-600 text-sm mb-1" v-if="showLabel">
|
||||||
|
{{ df.label }}
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
ref="input"
|
ref="input"
|
||||||
:class="inputClasses"
|
:class="inputClasses"
|
||||||
type="text"
|
type="text"
|
||||||
:value="linkValue"
|
:value="linkValue"
|
||||||
:placeholder="inputPlaceholder"
|
:placeholder="inputPlaceholder"
|
||||||
:readonly="df.readOnly"
|
:readonly="isReadOnly"
|
||||||
@focus="e => onFocus(e, toggleDropdown)"
|
@focus="e => onFocus(e, toggleDropdown)"
|
||||||
|
@blur="e => onBlur(e.target.value)"
|
||||||
@input="onInput"
|
@input="onInput"
|
||||||
@keydown.up="highlightItemUp"
|
@keydown.up="highlightItemUp"
|
||||||
@keydown.down="highlightItemDown"
|
@keydown.down="highlightItemDown"
|
||||||
@ -67,24 +76,28 @@ export default {
|
|||||||
},
|
},
|
||||||
async getSuggestions(keyword = '') {
|
async getSuggestions(keyword = '') {
|
||||||
keyword = keyword.toLowerCase();
|
keyword = keyword.toLowerCase();
|
||||||
let list = this.df.getList();
|
let list = this.df.getList ? this.df.getList() : this.df.options || [];
|
||||||
return list
|
let items = list.map(d => {
|
||||||
.map(d => {
|
if (typeof d === 'string') {
|
||||||
if (typeof d === 'string') {
|
return {
|
||||||
return {
|
label: d,
|
||||||
label: d,
|
value: d
|
||||||
value: d
|
};
|
||||||
};
|
}
|
||||||
}
|
return d;
|
||||||
return d;
|
});
|
||||||
})
|
|
||||||
.filter(d => {
|
if (!keyword) {
|
||||||
let key = keyword.toLowerCase();
|
return items;
|
||||||
return (
|
}
|
||||||
d.label.toLowerCase().includes(keyword) ||
|
|
||||||
d.value.toLowerCase().includes(keyword)
|
return items.filter(d => {
|
||||||
);
|
let key = keyword.toLowerCase();
|
||||||
});
|
return (
|
||||||
|
d.label.toLowerCase().includes(key) ||
|
||||||
|
d.value.toLowerCase().includes(key)
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
setSuggestion(suggestion) {
|
setSuggestion(suggestion) {
|
||||||
this.linkValue = suggestion.value;
|
this.linkValue = suggestion.value;
|
||||||
@ -95,6 +108,12 @@ export default {
|
|||||||
this.toggleDropdown = toggleDropdown;
|
this.toggleDropdown = toggleDropdown;
|
||||||
this.toggleDropdown(true);
|
this.toggleDropdown(true);
|
||||||
this.updateSuggestions();
|
this.updateSuggestions();
|
||||||
|
this.$emit('focus', e);
|
||||||
|
},
|
||||||
|
onBlur(value) {
|
||||||
|
if (value === '' || value == null) {
|
||||||
|
this.triggerChange('');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onInput(e) {
|
onInput(e) {
|
||||||
this.toggleDropdown(true);
|
this.toggleDropdown(true);
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<div class="text-gray-600 text-sm mb-1" v-if="showLabel">
|
||||||
|
{{ df.label }}
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
ref="input"
|
ref="input"
|
||||||
:class="inputClasses"
|
:class="inputClasses"
|
||||||
:type="inputType"
|
:type="inputType"
|
||||||
:value="value"
|
:value="value"
|
||||||
:placeholder="inputPlaceholder"
|
:placeholder="inputPlaceholder"
|
||||||
:readonly="df.readOnly"
|
:readonly="isReadOnly"
|
||||||
@blur="e => triggerChange(e.target.value)"
|
@blur="e => triggerChange(e.target.value)"
|
||||||
|
@focus="e => $emit('focus', e)"
|
||||||
|
@input="e => $emit('input', e)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -15,8 +20,26 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'Base',
|
name: 'Base',
|
||||||
props: ['df', 'value', 'inputClass', 'placeholder', 'size'],
|
props: [
|
||||||
inject: ['doctype', 'name'],
|
'df',
|
||||||
|
'value',
|
||||||
|
'inputClass',
|
||||||
|
'placeholder',
|
||||||
|
'size',
|
||||||
|
'showLabel',
|
||||||
|
'readOnly'
|
||||||
|
],
|
||||||
|
inject: {
|
||||||
|
doctype: {
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
doc: {
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
inputType() {
|
inputType() {
|
||||||
return 'text';
|
return 'text';
|
||||||
@ -32,7 +55,10 @@ export default {
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
inputPlaceholder() {
|
inputPlaceholder() {
|
||||||
return this.placeholder || this.df.placeholder
|
return this.placeholder || this.df.placeholder;
|
||||||
|
},
|
||||||
|
isReadOnly() {
|
||||||
|
return this.readOnly || this.df.readOnly;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -8,7 +8,7 @@ export default {
|
|||||||
extends: AutoComplete,
|
extends: AutoComplete,
|
||||||
methods: {
|
methods: {
|
||||||
async getSuggestions(keyword = '') {
|
async getSuggestions(keyword = '') {
|
||||||
let doctype = this.df.target;
|
let doctype = this.getTarget();
|
||||||
let meta = frappe.getMeta(doctype);
|
let meta = frappe.getMeta(doctype);
|
||||||
let filters = await this.getFilters(keyword);
|
let filters = await this.getFilters(keyword);
|
||||||
if (keyword && !filters.keywords) {
|
if (keyword && !filters.keywords) {
|
||||||
@ -45,10 +45,15 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
async getFilters(keyword) {
|
async getFilters(keyword) {
|
||||||
let doc = await frappe.getDoc(this.doctype, this.name);
|
if (this.doc) {
|
||||||
return this.df.getFilters
|
return this.df.getFilters
|
||||||
? (await this.df.getFilters(keyword, doc)) || {}
|
? (await this.df.getFilters(keyword, this.doc)) || {}
|
||||||
: {};
|
: {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
getTarget() {
|
||||||
|
return this.df.target;
|
||||||
},
|
},
|
||||||
async openNewDoc() {
|
async openNewDoc() {
|
||||||
let doctype = this.df.target;
|
let doctype = this.df.target;
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="text-gray-600 text-sm mb-1" v-if="showLabel">
|
||||||
|
{{ df.label }}
|
||||||
|
</div>
|
||||||
<div class="relative flex items-center justify-end bg-white focus-within:bg-gray-200" :class="inputClasses">
|
<div class="relative flex items-center justify-end bg-white focus-within:bg-gray-200" :class="inputClasses">
|
||||||
<select
|
<select
|
||||||
class="appearance-none bg-transparent focus:outline-none w-full"
|
class="appearance-none bg-transparent focus:outline-none w-full"
|
||||||
|
:class="isReadOnly && 'pointer-events-none'"
|
||||||
:value="value"
|
:value="value"
|
||||||
@blur="e => triggerChange(e.target.value)"
|
@change="e => triggerChange(e.target.value)"
|
||||||
|
@focus="e => $emit('focus', e)"
|
||||||
>
|
>
|
||||||
<option v-for="option in options" :value="option.value">{{ option.label }}</option>
|
<option v-for="option in options" :value="option.value">{{ option.label }}</option>
|
||||||
</select>
|
</select>
|
||||||
|
<div class="absolute left-0 pl-2 text-gray-600 pointer-events-none" v-if="!value">
|
||||||
|
{{ inputPlaceholder }}
|
||||||
|
</div>
|
||||||
<svg class="w-3 h-3 absolute" viewBox="0 0 5 10" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-3 h-3 absolute" viewBox="0 0 5 10" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
d="M1 2.636L2.636 1l1.637 1.636M1 7.364L2.636 9l1.637-1.636"
|
d="M1 2.636L2.636 1l1.637 1.636M1 7.364L2.636 9l1.637-1.636"
|
||||||
@ -18,6 +27,7 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user