Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <template lang='pug'>
- div.input-select(:class="{ quiet: quiet }")
- div.dummy(v-show="loading")
- select(:multiple="multiple" size=1 ref="original")
- template(v-for="optionOrGroup in options")
- template(v-if="!!optionOrGroup.options")
- optgroup(:label="optionOrGroup.label")
- option(
- v-for="option in optionOrGroup.options"
- :value="String(option.value)"
- ) {{ option.label }}
- template(v-else)
- option(
- :value="String(optionOrGroup.value)"
- ) {{ optionOrGroup.label }}
- </template>
- <script>
- import $ from "jquery"
- export default {
- props: {
- value: {
- type: [Array, String, Number],
- default: null
- },
- options: {
- type: Array,
- default: () => []
- },
- placeholder: {
- type: String,
- default: ' '
- },
- multiple: {
- type: Boolean,
- default: false
- },
- search: {
- type: Boolean,
- default: false
- },
- selectAll: {
- type: Boolean,
- default: false
- },
- displayCount: {
- type: Number,
- default: 4
- },
- quiet: {
- type: Boolean,
- default: false
- },
- readonly: {
- type: Boolean,
- default: false
- }
- },
- data () {
- return {
- loading: true
- }
- },
- computed: {
- optionsFlatten() {
- if (!this.options[0].options) return this.options
- return Array.prototype.concat.apply([], this.options.map(optGroup => optGroup.options))
- }
- },
- watch: {
- value() {
- this.reload(this.value)
- },
- options() {
- this.$nextTick(() => {
- this.$refs.original.sumo.reload()
- this.reload(this.value)
- })
- }
- },
- mounted() {
- // init
- $(this.$refs.original).SumoSelect({
- search: this.search,
- selectAll: this.selectAll,
- locale: ['OK', 'Cancel', this.$t("select_all")],
- searchText: '',
- noMatch: '...',
- placeholder: this.placeholder || this.$t("select"),
- captionFormatAllSelected: this.$t("all_selected"),
- captionFormat: this.$t("many_selected"),
- csvDispCount: this.displayCount
- })
- // event handler
- $(this.$refs.original).on('sumo:closing', (e) => {
- const valRaw = $(e.target).val()
- let val
- if (this.multiple) {
- val = valRaw.map(v => this.optionsFlatten.find(opt => String(opt.value) === v).value)
- } else {
- val = this.optionsFlatten.find(opt => String(opt.value) === valRaw).value
- }
- this.$emit('input', val)
- if (!_.isEqual(val, this.value)) this.$emit('change', val)
- // set placeholder
- if (!this.multiple) {
- if ([null, ""].includes(val)) {
- $(this.$el).find(".CaptionCont > span").addClass("unselected")
- $(this.$el).find(".CaptionCont > span.unselected").text(this.placeholder)
- } else {
- $(this.$el).find(".CaptionCont > span").removeClass("unselected")
- }
- }
- })
- // set initial value
- this.reload(this.value)
- this.loading = false
- },
- beforeDestroy() {
- this.$refs.original.sumo.unload()
- },
- methods: {
- reload(val) {
- // set selected item
- this.optionsFlatten.forEach(opt => this.$refs.original.sumo.unSelectItem(String(opt.value)))
- if (this.multiple && val) {
- val.forEach(v => this.$refs.original.sumo.selectItem(String(v)))
- } else {
- this.$refs.original.sumo.selectItem(String(val))
- }
- // set placeholder
- if (!this.multiple) {
- if ([null, ""].includes(val)) {
- $(this.$el).find(".CaptionCont > span").addClass("unselected")
- $(this.$el).find(".CaptionCont > span.unselected").text(this.placeholder)
- } else {
- $(this.$el).find(".CaptionCont > span").removeClass("unselected")
- }
- }
- // set icon
- $('.SumoSelect > .CaptionCont > label > i').addClass("fas fa-caret-down")
- // set disabled
- if (this.readonly) this.$refs.original.sumo.disable()
- }
- }
- }
- </script>
- <style lang='scss' scoped>
- @import "~/assets/stylesheets/variables.scss";
- .input-select {
- width: 100%;
- display: flex;
- }
- select {
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- display: none;
- }
- .dummy {
- box-sizing: border-box;
- flex-grow: 1;
- border: 1px solid $border-base;
- color: $bg-base;
- height: calc(1em + 11px);
- }
- </style>
- <style lang='scss'>
- @import "~/assets/stylesheets/variables.scss";
- @import "sumoselect/sumoselect.css";
- .SumoSelect {
- flex-grow: 1;
- max-width: 100%;
- }
- .SumoSelect .SelectBox {
- padding: 4px 2px;
- }
- .SumoSelect.disabled {
- cursor: default;
- opacity: 1;
- }
- .SumoSelect.disabled > .CaptionCont {
- background-color: $bg-disable;
- }
- .SumoSelect.open > .optWrapper {
- top: initial;
- border-radius: 0;
- border: 1px solid $border-base;
- }
- .SumoSelect.open .search-txt {
- border-radius: 0;
- padding: 4px 2px;
- }
- .SumoSelect > .CaptionCont {
- border-radius: 0;
- border: 1px solid $border-base;
- min-height: initial;
- box-sizing: border-box;
- width: 100%;
- }
- .SumoSelect > .CaptionCont > span {
- }
- .quiet .SumoSelect > .CaptionCont {
- border-color: transparent;
- }
- .quiet .SumoSelect > .CaptionCont > span {
- padding-right: 0;
- }
- .SumoSelect > .CaptionCont > span.unselected {
- color: $fg-quiet;
- }
- .SumoSelect > .CaptionCont > span.placeholder {
- font-style: initial;
- color: $fg-quiet;
- }
- .SumoSelect > .CaptionCont > label > i {
- background-image: none;
- font-size: 1.45em;
- text-align: right;
- color: $fg-quiet;
- }
- .quiet .SumoSelect > .CaptionCont > label > i {
- display: none;
- }
- .SumoSelect:focus > .CaptionCont, .SumoSelect:hover > .CaptionCont, .SumoSelect.open > .CaptionCont {
- box-shadow: 0 0 2px $border-focus;
- border-color: $border-focus;
- }
- .SumoSelect > .optWrapper > .options {
- max-height: 50vh;
- }
- .SumoSelect > .optWrapper.multiple > .options li.opt.selected span i, .SumoSelect .select-all.selected > span i, .SumoSelect .select-all.partial > span i {
- background-color: $bg-selection;
- }
- .SumoSelect .select-all {
- border-radius: 0;
- padding-top: 3px;
- > label {
- margin-top: 3px;
- display: inline-block;
- }
- }
- </style>
- <i18n>
- ja:
- select: 選択
- select_all: 全選択/解除
- all_selected: 全て
- many_selected: "{0}件を選択中"
- filter: "..."
- </i18n>
Add Comment
Please, Sign In to add comment