2
0
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:
Faris Ansari 2019-11-19 23:24:56 +05:30
parent 4154cc5edc
commit 84f5476909
4 changed files with 90 additions and 30 deletions

View File

@ -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);

View File

@ -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: {

View File

@ -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;

View File

@ -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>