Files
2024-09-01 18:54:23 +05:00

157 lines
3.7 KiB
Vue

<template>
<DefaultField
:field="currentField"
:errors="errors"
:show-help-text="showHelpText"
:full-width-content="fullWidthContent"
>
<template #field>
<!-- Select Input Field -->
<MultiSelectControl
:id="currentField.uniqueKey"
:dusk="field.attribute"
v-model:selected="value"
@change="handleChange"
class="w-full"
:class="errorClasses"
:options="currentField.options"
:disabled="currentlyIsReadonly"
>
<option
v-if="shouldShowPlaceholder"
value=""
:selected="!hasValue"
:disabled="!currentField.nullable"
>
{{ placeholder }}
</option>
</MultiSelectControl>
</template>
</DefaultField>
</template>
<script>
import filter from 'lodash/filter'
import map from 'lodash/map'
import merge from 'lodash/merge'
import { DependentFormField, HandlesValidationErrors } from '@/mixins'
import filled from '@/util/filled'
export default {
mixins: [HandlesValidationErrors, DependentFormField],
data: () => ({
search: '',
}),
methods: {
/*
* Set the initial value for the field
*/
setInitialValue() {
let values = !(
this.currentField.value === undefined ||
this.currentField.value === null ||
this.currentField.value === ''
)
? merge(this.currentField.value || [], this.value)
: this.value
let selectedOptions = filter(
this.currentField.options ?? [],
o => values.includes(o.value) || values.includes(o.value.toString())
)
this.value = map(selectedOptions, o => o.value)
},
/**
* Return the field default value.
*/
fieldDefaultValue() {
return []
},
/**
* Provide a function that fills a passed FormData object with the
* field's internal value attribute. Here we are forcing there to be a
* value sent to the server instead of the default behavior of
* `this.value || ''` to avoid loose-comparison issues if the keys
* are truthy or falsey
*/
fill(formData) {
this.fillIfVisible(
formData,
this.fieldAttribute,
JSON.stringify(this.value)
)
},
/**
* Set the search string to be used to filter the select field.
*/
performSearch(event) {
this.search = event
},
/**
* Handle the selection change event.
*/
handleChange(values) {
let selectedOptions = filter(
this.currentField.options ?? [],
o => values.includes(o.value) || values.includes(o.value.toString())
)
this.value = map(selectedOptions, o => o.value)
if (this.field) {
this.emitFieldValueChange(this.fieldAttribute, this.value)
}
},
onSyncedField() {
this.setInitialValue()
},
},
computed: {
/**
* Return the field options filtered by the search string.
*/
filteredOptions() {
let options = this.currentField.options || []
return options.filter(option => {
return (
option.label
.toString()
.toLowerCase()
.indexOf(this.search.toLowerCase()) > -1
)
})
},
/**
* Return the placeholder text for the field.
*/
placeholder() {
return this.currentField.placeholder || this.__('Choose an option')
},
/**
* Return value has been setted.
*/
hasValue() {
return Boolean(
!(this.value === undefined || this.value === null || this.value === '')
)
},
shouldShowPlaceholder() {
return filled(this.currentField.placeholder) || this.currentField.nullable
},
},
}
</script>