Skip to content

Instantly share code, notes, and snippets.

@tsulatsitamim
Last active June 18, 2022 05:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsulatsitamim/a073d159bd715d13a5b18497e22a02af to your computer and use it in GitHub Desktop.
Save tsulatsitamim/a073d159bd715d13a5b18497e22a02af to your computer and use it in GitHub Desktop.
Vue Bootstrap Wrapper for Select2
<template>
<ValidationProvider
ref="validator"
v-slot="{ errors }"
:name="errorLabel || label"
:rules="rules"
>
<b-form-group
:label="label"
:label-for="uid"
:invalid-feedback="errors[0]"
:state="!errors.length"
>
<select
:id="uid"
ref="formSelect"
class="form-control select2"
:value="value"
></select>
</b-form-group>
</ValidationProvider>
</template>
<script lang="ts">
import { Vue, Prop, Component, Watch } from 'vue-property-decorator'
import 'select2'
import { ValidationProvider, extend, localize } from 'vee-validate'
import { required, email } from 'vee-validate/dist/rules'
import id from '../../../node_modules/vee-validate/dist/locale/id.json'
localize('id', id)
extend('required', required)
extend('email', email)
@Component({ components: { ValidationProvider } })
export default class FormSelect extends Vue {
@Prop() value!: string | number
@Prop() preselect!: null | { id: string; name: string }
@Prop() label!: string
@Prop() name!: string
@Prop() url!: string
@Prop() items!: any[] | null
@Prop({ default: 'Please select' }) placeholder!: string
@Prop({ default: true }) inModal!: boolean
@Prop({ default: '' }) errorLabel!: string
@Prop() rules!: string
@Prop({
default: x => ({
id: x.id,
text: x.name,
}),
type: Function,
})
mapper!: () => { id: string; name: string }
$refs!: {
validator: any
formSelect: any
}
mounted() {
if (this.inModal) {
return this.$root.$on('bv::modal::shown', (e, modalId) => {
this.initSelect(modalId)
})
}
this.initSelect()
}
destroyed() {
$(this.$refs.formSelect)
.off()
.select2('destroy')
}
@Watch('items')
initSelect(modalId: null | string = null) {
const vm = this
if ($(this.$refs.formSelect).hasClass('select2-hidden-accessible')) {
$(this.$refs.formSelect)
.empty()
.off()
.select2('destroy')
}
$(this.$refs.formSelect)
.select2({
dropdownParent: modalId
? $(`#${modalId}___BV_modal_content_`)
: $(document.body),
placeholder: this.placeholder,
minimumResultsForSearch: 0,
allowClear: true,
ajax: this.url
? {
url: this.url,
delay: 250,
processResults(data, params) {
params.page = params.page || 1
return {
results: data.data.map(vm.mapper),
pagination: {
more: data.meta.page <= data.meta.total % data.meta.perpage,
},
}
},
data: function(params) {
return {
search: params.term,
pagination: { page: params.page || 1 },
}
},
}
: null,
data: this.items && !this.url ? this.items : null,
})
.on('select2:select', () => {
const [selected] = $(this.$refs.formSelect).select2('data')
this.$emit('input', selected.id, {
id: Number(selected.id),
name: selected.text,
})
})
.on('select2:clear', () => {
this.$emit('input', null, null)
})
this.updateValue()
}
@Watch('value')
updateValue() {
if (this.preselect) {
$(this.$refs.formSelect).append(
new Option(this.preselect.name, this.preselect.id, false, false)
)
}
$(this.$refs.formSelect).val(this.value)
$(this.$refs.formSelect).trigger('change')
}
@Watch('value')
validate() {
console.log(this.value)
if (this.$refs.validator) {
this.$refs.validator.validate(this.value)
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment