Skip to content

Instantly share code, notes, and snippets.

@Elyorbe
Created January 31, 2023 02:19
Show Gist options
  • Save Elyorbe/1b5816aa182246475a530066c10662e9 to your computer and use it in GitHub Desktop.
Save Elyorbe/1b5816aa182246475a530066c10662e9 to your computer and use it in GitHub Desktop.
<template>
<div class="columns">
<div class=" field column is-3">
<label class="label">대 카테고리<span v-if="isRequired">*</span></label>
<multiselect v-model="firstLevelCategory" track-by="id" label="name" placeholder="대 가테고리 검색"
:options="firstLevelCategories" :show-labels="false" :searchable="true" :allow-empty="false">
<span slot="noResult">검색 결과가 없습니다</span>
<span class="multiselect__tag-custom-icon mdi mdi-chevron-down" slot="caret"></span>
</multiselect>
<div v-if="isRequired && $v.firstLevelCategory.$invalid" class="help is-danger">대 카테고리를 선택해주세요</div>
</div>
<div class="field column is-3">
<label class="label">중 카테고리<span v-if="isRequired">*</span></label>
<multiselect v-model="secondLevelCategory" track-by="id" label="name" placeholder="중 가테고리 검색"
:options="secondLevelCategories" :show-labels="false" :searchable="true" :allow-empty="false">
<span slot="noResult">검색 결과가 없습니다</span>
<span class="multiselect__tag-custom-icon mdi mdi-chevron-down" slot="caret"></span>
</multiselect>
<div v-if="isRequired && $v.secondLevelCategory.$invalid" class="help is-danger">중 카테고리를 선택해주세요</div>
</div>
<div class="field column is-3">
<label class="label">소 카테고리<span v-if="isRequired">*</span></label>
<multiselect v-model="thirdLevelCategory" track-by="id" label="name" placeholder="소 가테고리 검색"
:options="thirdLevelCategories" :show-labels="false" :searchable="true" :allow-empty="false">
<span slot="noResult">검색 결과가 없습니다</span>
<span class="multiselect__tag-custom-icon mdi mdi-chevron-down" slot="caret"></span>
</multiselect>
<div v-if="isRequired && $v.thirdLevelCategory.$invalid" class="help is-danger">소 카테고리를 선택해주세요</div>
</div>
<div class="field column is-3">
<label class="label">세 카테고리<span v-if="isRequired">*</span></label>
<multiselect v-model="fourthLevelCategory" track-by="id" label="name" placeholder="세 가테고리 검색"
:options="fourthLevelCategories" :show-labels="false" :searchable="true" :allow-empty="false">
<span slot="noResult">검색 결과가 없습니다</span>
<span class="multiselect__tag-custom-icon mdi mdi-chevron-down" slot="caret"></span>
</multiselect>
<div v-if="isRequired && $v.fourthLevelCategory.$invalid" class="help is-danger">세 카테고리를 선택해주세요</div>
</div>
<Snackbar ref="snackbar"/>
</div>
</template>
<script>
import {required} from "vuelidate/lib/validators";
import { fetchCategories} from "@/modules/standard-product/api/standard-product";
import Snackbar from "@/common/Snackbar";
const defaultSelect = { id: -99, name: '선택' };
const mustBeSelected = (value) => (value !== defaultSelect)
export default {
name: "CategorySelect",
components: { Snackbar },
props: {
isRequired: {
type: Boolean,
default: () => true
}
},
data() {
return {
category: {
firstId: defaultSelect.id,
secondId: defaultSelect.id,
thirdId: defaultSelect.id,
fourthId: defaultSelect.id,
isValid: false,
},
firstLevelCategory: defaultSelect,
secondLevelCategory: defaultSelect,
thirdLevelCategory: defaultSelect,
fourthLevelCategory: defaultSelect,
firstLevelCategories: [defaultSelect],
secondLevelCategories: [defaultSelect],
thirdLevelCategories: [defaultSelect],
fourthLevelCategories: [defaultSelect],
}
},
validations: {
firstLevelCategory: { required, mustBeSelected },
secondLevelCategory: { required, mustBeSelected },
thirdLevelCategory: { required, mustBeSelected },
fourthLevelCategory: { required, mustBeSelected },
},
mounted: function () {
this.populate();
},
methods: {
populate: async function () {
const categories = await fetchCategories().catch(error => {
console.error("Category fetch error: ", error);
this.$refs.snackbar.show("Failed to fetch categories", "is-danger")
})
this.firstLevelCategories = this.firstLevelCategories.concat(categories);
},
emitChanges: function () {
this.$v.$touch();
this.category.isValid = !this.$v.$invalid;
this.$emit('select', this.category);
},
setSelectedOptions: function(firstId, secondId, thirdId, fourthId) {
if(this.firstLevelCategories && firstId) {
this.firstLevelCategory = this.firstLevelCategories.find((c) => c.id === firstId);
}
setImmediate(() => {
if(this.secondLevelCategories && secondId) {
this.secondLevelCategory = this.secondLevelCategories.find((c) => c.id === secondId);
}
})
setImmediate(() => {
if(this.thirdLevelCategories && thirdId) {
this.thirdLevelCategory = this.thirdLevelCategories.find((c) => c.id === thirdId);
}
})
setImmediate(() => {
if(this.fourthLevelCategories && fourthId) {
this.fourthLevelCategory = this.fourthLevelCategories.find((c) => c.id === fourthId);
}
})
}
},
watch: {
firstLevelCategory(newValue) {
this.category.firstId = newValue.id;
this.secondLevelCategory = defaultSelect;
if (newValue === defaultSelect) return;
this.secondLevelCategories = [defaultSelect].concat(newValue.subCategories);
this.emitChanges();
},
secondLevelCategory(newValue) {
this.category.secondId = newValue.id;
this.thirdLevelCategory = defaultSelect;
if (newValue === defaultSelect) return;
this.thirdLevelCategories = [defaultSelect].concat(newValue.subCategories);
this.emitChanges();
},
thirdLevelCategory(newValue) {
this.category.thirdId = newValue.id;
this.fourthLevelCategory = defaultSelect;
if (newValue === defaultSelect) return;
this.fourthLevelCategories = [defaultSelect].concat(newValue.subCategories);
this.emitChanges();
},
fourthLevelCategory(newValue) {
this.category.fourthId = newValue.id;
this.emitChanges();
},
immediate: true
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment