mirror of
https://github.com/frappe/books.git
synced 2024-11-10 07:40:55 +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>
|
||||
<Dropdown :items="suggestions">
|
||||
<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
|
||||
ref="input"
|
||||
:class="inputClasses"
|
||||
type="text"
|
||||
:value="linkValue"
|
||||
:placeholder="inputPlaceholder"
|
||||
:readonly="df.readOnly"
|
||||
:readonly="isReadOnly"
|
||||
@focus="e => onFocus(e, toggleDropdown)"
|
||||
@blur="e => onBlur(e.target.value)"
|
||||
@input="onInput"
|
||||
@keydown.up="highlightItemUp"
|
||||
@keydown.down="highlightItemDown"
|
||||
@ -67,24 +76,28 @@ export default {
|
||||
},
|
||||
async getSuggestions(keyword = '') {
|
||||
keyword = keyword.toLowerCase();
|
||||
let list = this.df.getList();
|
||||
return list
|
||||
.map(d => {
|
||||
if (typeof d === 'string') {
|
||||
return {
|
||||
label: d,
|
||||
value: d
|
||||
};
|
||||
}
|
||||
return d;
|
||||
})
|
||||
.filter(d => {
|
||||
let key = keyword.toLowerCase();
|
||||
return (
|
||||
d.label.toLowerCase().includes(keyword) ||
|
||||
d.value.toLowerCase().includes(keyword)
|
||||
);
|
||||
});
|
||||
let list = this.df.getList ? this.df.getList() : this.df.options || [];
|
||||
let items = list.map(d => {
|
||||
if (typeof d === 'string') {
|
||||
return {
|
||||
label: d,
|
||||
value: d
|
||||
};
|
||||
}
|
||||
return d;
|
||||
});
|
||||
|
||||
if (!keyword) {
|
||||
return items;
|
||||
}
|
||||
|
||||
return items.filter(d => {
|
||||
let key = keyword.toLowerCase();
|
||||
return (
|
||||
d.label.toLowerCase().includes(key) ||
|
||||
d.value.toLowerCase().includes(key)
|
||||
);
|
||||
});
|
||||
},
|
||||
setSuggestion(suggestion) {
|
||||
this.linkValue = suggestion.value;
|
||||
@ -95,6 +108,12 @@ export default {
|
||||
this.toggleDropdown = toggleDropdown;
|
||||
this.toggleDropdown(true);
|
||||
this.updateSuggestions();
|
||||
this.$emit('focus', e);
|
||||
},
|
||||
onBlur(value) {
|
||||
if (value === '' || value == null) {
|
||||
this.triggerChange('');
|
||||
}
|
||||
},
|
||||
onInput(e) {
|
||||
this.toggleDropdown(true);
|
||||
|
@ -1,13 +1,18 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="text-gray-600 text-sm mb-1" v-if="showLabel">
|
||||
{{ df.label }}
|
||||
</div>
|
||||
<input
|
||||
ref="input"
|
||||
:class="inputClasses"
|
||||
:type="inputType"
|
||||
:value="value"
|
||||
:placeholder="inputPlaceholder"
|
||||
:readonly="df.readOnly"
|
||||
:readonly="isReadOnly"
|
||||
@blur="e => triggerChange(e.target.value)"
|
||||
@focus="e => $emit('focus', e)"
|
||||
@input="e => $emit('input', e)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -15,8 +20,26 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'Base',
|
||||
props: ['df', 'value', 'inputClass', 'placeholder', 'size'],
|
||||
inject: ['doctype', 'name'],
|
||||
props: [
|
||||
'df',
|
||||
'value',
|
||||
'inputClass',
|
||||
'placeholder',
|
||||
'size',
|
||||
'showLabel',
|
||||
'readOnly'
|
||||
],
|
||||
inject: {
|
||||
doctype: {
|
||||
default: null
|
||||
},
|
||||
name: {
|
||||
default: null
|
||||
},
|
||||
doc: {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
inputType() {
|
||||
return 'text';
|
||||
@ -32,7 +55,10 @@ export default {
|
||||
];
|
||||
},
|
||||
inputPlaceholder() {
|
||||
return this.placeholder || this.df.placeholder
|
||||
return this.placeholder || this.df.placeholder;
|
||||
},
|
||||
isReadOnly() {
|
||||
return this.readOnly || this.df.readOnly;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -8,7 +8,7 @@ export default {
|
||||
extends: AutoComplete,
|
||||
methods: {
|
||||
async getSuggestions(keyword = '') {
|
||||
let doctype = this.df.target;
|
||||
let doctype = this.getTarget();
|
||||
let meta = frappe.getMeta(doctype);
|
||||
let filters = await this.getFilters(keyword);
|
||||
if (keyword && !filters.keywords) {
|
||||
@ -45,10 +45,15 @@ export default {
|
||||
});
|
||||
},
|
||||
async getFilters(keyword) {
|
||||
let doc = await frappe.getDoc(this.doctype, this.name);
|
||||
return this.df.getFilters
|
||||
? (await this.df.getFilters(keyword, doc)) || {}
|
||||
: {};
|
||||
if (this.doc) {
|
||||
return this.df.getFilters
|
||||
? (await this.df.getFilters(keyword, this.doc)) || {}
|
||||
: {};
|
||||
}
|
||||
return {};
|
||||
},
|
||||
getTarget() {
|
||||
return this.df.target;
|
||||
},
|
||||
async openNewDoc() {
|
||||
let doctype = this.df.target;
|
||||
|
@ -1,12 +1,21 @@
|
||||
<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">
|
||||
<select
|
||||
class="appearance-none bg-transparent focus:outline-none w-full"
|
||||
:class="isReadOnly && 'pointer-events-none'"
|
||||
: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>
|
||||
</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">
|
||||
<path
|
||||
d="M1 2.636L2.636 1l1.637 1.636M1 7.364L2.636 9l1.637-1.636"
|
||||
@ -18,6 +27,7 @@
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
Loading…
Reference in New Issue
Block a user