|
174 | 174 | <div class="dropdown v-select" :class="dropdownClasses">
|
175 | 175 | <div ref="toggle" @mousedown.prevent="toggleDropdown" class="dropdown-toggle clearfix" type="button">
|
176 | 176 |
|
177 |
| - <span class="selected-tag" v-for="option in valueAsArray" v-bind:key="index"> |
| 177 | + <span class="selected-tag" v-for="option in valueAsArray" v-bind:key="option.index"> |
178 | 178 | {{ getOptionLabel(option) }}
|
179 | 179 | <button v-if="multiple" @click="select(option)" type="button" class="close">
|
180 | 180 | <span aria-hidden="true">×</span>
|
|
199 | 199 | :style="{ width: isValueEmpty ? '100%' : 'auto' }"
|
200 | 200 | >
|
201 | 201 |
|
202 |
| - <i ref="open-indicator" role="presentation" class="open-indicator"></i> |
| 202 | + <i ref="openIndicator" role="presentation" class="open-indicator"></i> |
203 | 203 |
|
204 | 204 | <slot name="spinner">
|
205 |
| - <div class="spinner" v-show="loading">Loading...</div> |
| 205 | + <div class="spinner" v-show="showLoading">Loading...</div> |
206 | 206 | </slot>
|
207 | 207 | </div>
|
208 | 208 |
|
209 |
| - <ul ref="dropdown-menu" v-show="open" :transition="transition" class="dropdown-menu" :style="{ 'max-height': maxHeight }"> |
| 209 | + <ul ref="dropdownMenu" v-show="open" :transition="transition" class="dropdown-menu" :style="{ 'max-height': maxHeight }"> |
210 | 210 | <li v-for="(option, index) in filteredOptions" v-bind:key="index" :class="{ active: isOptionSelected(option), highlight: index === typeAheadPointer }" @mouseover="typeAheadPointer = index">
|
211 | 211 | <a @mousedown.prevent="select(option)">
|
212 | 212 | {{ getOptionLabel(option) }}
|
|
236 | 236 | props: {
|
237 | 237 | /**
|
238 | 238 | * Contains the currently selected value. Very similar to a
|
239 |
| - * `value` attribute on an <input>. In most cases, you'll want |
240 |
| - * to set this as a two-way binding, using :value.sync. However, |
241 |
| - * this will not work with Vuex, in which case you'll need to use |
242 |
| - * the onChange callback property. |
| 239 | + * `value` attribute on an <input>. You can listen for changes |
| 240 | + * using 'change' event using v-on |
243 | 241 | * @type {Object||String||null}
|
244 | 242 | */
|
245 | 243 | value: {
|
|
352 | 350 | * @default {null}
|
353 | 351 | */
|
354 | 352 | onChange: Function,
|
| 353 | + |
355 | 354 |
|
356 | 355 | /**
|
357 | 356 | * Enable/disable creating options from searchInput.
|
|
379 | 378 | createOption: {
|
380 | 379 | type: Function,
|
381 | 380 | default: function (newOption) {
|
382 |
| - if (typeof this.options[0] === 'object') { |
| 381 | + if (typeof this.currentOptions[0] === 'object') { |
383 | 382 | return {[this.label]: newOption}
|
384 | 383 | }
|
385 | 384 | return newOption
|
|
399 | 398 | data() {
|
400 | 399 | return {
|
401 | 400 | search: '',
|
402 |
| - open: false |
| 401 | + open: false, |
| 402 | + currentSelection: null, |
| 403 | + currentOptions: [], |
| 404 | + showLoading: false |
403 | 405 | }
|
404 | 406 | },
|
405 | 407 |
|
406 | 408 | watch: {
|
407 | 409 | value(val, old) {
|
| 410 | + this.currentSelection = val |
| 411 | + }, |
| 412 | + currentSelection(val, old) { |
408 | 413 | if (this.multiple) {
|
409 | 414 | this.onChange ? this.onChange(val) : null
|
| 415 | + this.$emit('change', val) |
410 | 416 | } else {
|
411 |
| - this.onChange && val !== old ? this.onChange(val) : null |
| 417 | + if(val !== old) { |
| 418 | + this.onChange? this.onChange(val) : null |
| 419 | + this.$emit('change', val) |
| 420 | + } |
412 | 421 | }
|
413 | 422 | },
|
414 |
| - options() { |
| 423 | + options(val) { |
| 424 | + this.currentOptions = val |
| 425 | + }, |
| 426 | + currentOptions() { |
415 | 427 | if (!this.taggable && this.resetOnOptionsChange) {
|
416 |
| - this.$set('value', this.multiple ? [] : null) |
| 428 | + this.currentSelection = this.multiple ? [] : null |
417 | 429 | }
|
418 | 430 | },
|
419 |
| - multiple(val) { |
420 |
| - this.$set('value', val ? [] : null) |
421 |
| - } |
| 431 | + multiple(val) { |
| 432 | + this.currentSelection = val ? [] : null |
| 433 | + } |
422 | 434 | },
|
423 | 435 |
|
424 | 436 | methods: {
|
|
436 | 448 | option = this.createOption(option)
|
437 | 449 |
|
438 | 450 | if (this.pushTags) {
|
439 |
| - this.options.push(option) |
| 451 | + console.log("adding " + option +" to "+ this.currentOptions) |
| 452 | + this.currentOptions.push(option) |
440 | 453 | }
|
441 | 454 | }
|
442 | 455 |
|
443 | 456 | if (this.multiple) {
|
444 |
| - if (!this.value) { |
445 |
| - this.$set('value', [option]) |
| 457 | + if (!this.currentSelection) { |
| 458 | + this.currentSelection = [option] |
446 | 459 | } else {
|
447 |
| - this.value.push(option) |
| 460 | + this.currentSelection.push(option) |
448 | 461 | }
|
449 | 462 | } else {
|
450 |
| - this.value = option |
| 463 | + this.currentSelection = option |
451 | 464 | }
|
452 | 465 | }
|
453 | 466 |
|
|
462 | 475 | deselect(option) {
|
463 | 476 | if (this.multiple) {
|
464 | 477 | let ref = -1
|
465 |
| - this.value.forEach((val) => { |
| 478 | + this.currentSelection.forEach((val) => { |
466 | 479 | if (val === option || typeof val === 'object' && val[this.label] === option[this.label]) {
|
467 | 480 | ref = val
|
468 | 481 | }
|
469 | 482 | })
|
470 |
| - var index = this.value.indexOf(ref) |
471 |
| - this.value.splice(index, 1) |
| 483 | + var index = this.currentSelection.indexOf(ref) |
| 484 | + this.currentSelection.splice(index, 1) |
472 | 485 | } else {
|
473 |
| - this.value = null |
| 486 | + this.currentSelection = null |
474 | 487 | }
|
475 | 488 | },
|
476 | 489 |
|
|
512 | 525 | * @return {Boolean} True when selected || False otherwise
|
513 | 526 | */
|
514 | 527 | isOptionSelected(option) {
|
515 |
| - if (this.multiple && this.value) { |
| 528 | + if (this.multiple && this.currentSelection) { |
516 | 529 | let selected = false
|
517 |
| - this.value.forEach(opt => { |
| 530 | + this.currentSelection.forEach(opt => { |
518 | 531 | if (typeof opt === 'object' && opt[this.label] === option[this.label]) {
|
519 | 532 | selected = true
|
520 | 533 | } else if (opt === option) {
|
|
524 | 537 | return selected
|
525 | 538 | }
|
526 | 539 |
|
527 |
| - return this.value === option |
| 540 | + return this.currentSelection === option |
528 | 541 | },
|
529 | 542 |
|
530 | 543 | /**
|
|
546 | 559 | * @return {this.value}
|
547 | 560 | */
|
548 | 561 | maybeDeleteValue() {
|
549 |
| - if (!this.$refs.search.value.length && this.value) { |
550 |
| - return this.multiple ? this.value.pop() : this.$set('value', null) |
| 562 | + if (!this.$refs.search.value.length && this.currentSelection) { |
| 563 | + return this.multiple ? this.currentSelection.pop() : this.currentSelection = null |
551 | 564 | }
|
552 | 565 | },
|
553 | 566 |
|
554 | 567 | /**
|
555 | 568 | * Determine if an option exists
|
556 |
| - * within this.options array. |
| 569 | + * within this.currentOptions array. |
557 | 570 | *
|
558 | 571 | * @param {Object || String} option
|
559 | 572 | * @return {boolean}
|
560 | 573 | */
|
561 | 574 | optionExists(option) {
|
562 | 575 | let exists = false
|
563 | 576 |
|
564 |
| - this.options.forEach(opt => { |
| 577 | + this.currentOptions.forEach(opt => { |
565 | 578 | if (typeof opt === 'object' && opt[this.label] === option) {
|
566 | 579 | exists = true
|
567 | 580 | } else if (opt === option) {
|
|
583 | 596 | return {
|
584 | 597 | open: this.open,
|
585 | 598 | searchable: this.searchable,
|
586 |
| - loading: this.loading |
| 599 | + loading: this.showLoading |
587 | 600 | }
|
588 | 601 | },
|
589 | 602 |
|
|
607 | 620 | * @return {array}
|
608 | 621 | */
|
609 | 622 | filteredOptions() {
|
610 |
| - let options = this.$options.filters.filterBy?this.$options.filters.filterBy(this.options, this.search):this.options |
| 623 | + let options = this.$options.filters.filterBy?this.$options.filters.filterBy(this.currentOptions, this.search):this.currentOptions |
611 | 624 | if (this.taggable && this.search.length && !this.optionExists(this.search)) {
|
612 | 625 | options.unshift(this.search)
|
613 | 626 | }
|
|
619 | 632 | * @return {Boolean}
|
620 | 633 | */
|
621 | 634 | isValueEmpty() {
|
622 |
| - if (this.value) { |
623 |
| - if (typeof this.value === 'object') { |
624 |
| - return !Object.keys(this.value).length |
| 635 | + if (this.currentSelection) { |
| 636 | + if (typeof this.currentSelection === 'object') { |
| 637 | + return !Object.keys(this.currentSelection).length |
625 | 638 | }
|
626 |
| - return !this.value.length |
| 639 | + return !this.currentSelection.length |
627 | 640 | }
|
628 | 641 |
|
629 | 642 | return true;
|
|
635 | 648 | */
|
636 | 649 | valueAsArray() {
|
637 | 650 | if (this.multiple) {
|
638 |
| - return this.value |
639 |
| - } else if (this.value) { |
640 |
| - return [this.value] |
| 651 | + return this.currentSelection |
| 652 | + } else if (this.currentSelection) { |
| 653 | + return [this.currentSelection] |
641 | 654 | }
|
642 | 655 |
|
643 | 656 | return []
|
644 | 657 | }
|
| 658 | + }, |
| 659 | + created: function() { |
| 660 | + this.currentSelection = this.value |
| 661 | + this.currentOptions = this.options.slice(0) |
| 662 | + this.showLoading = this.loading |
645 | 663 | }
|
646 | 664 |
|
647 | 665 | }
|
|
0 commit comments