2
0
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:
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>
<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);

View File

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

View File

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

View File

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