hotwire_combobox 0.1.41 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -0
- data/app/assets/javascripts/controllers/hw_combobox_controller.js +1 -1
- data/app/assets/javascripts/hotwire_combobox.esm.js +161 -85
- data/app/assets/javascripts/hotwire_combobox.umd.js +161 -85
- data/app/assets/javascripts/hw_combobox/models/combobox/async_loading.js +4 -0
- data/app/assets/javascripts/hw_combobox/models/combobox/autocomplete.js +8 -6
- data/app/assets/javascripts/hw_combobox/models/combobox/events.js +17 -7
- data/app/assets/javascripts/hw_combobox/models/combobox/filtering.js +19 -22
- data/app/assets/javascripts/hw_combobox/models/combobox/options.js +12 -4
- data/app/assets/javascripts/hw_combobox/models/combobox/selection.js +95 -44
- data/app/assets/javascripts/hw_combobox/models/combobox/toggle.js +13 -0
- data/app/assets/javascripts/hw_combobox/models/combobox/validity.js +1 -1
- data/app/presenters/hotwire_combobox/component.rb +2 -2
- data/lib/hotwire_combobox/engine.rb +2 -2
- data/lib/hotwire_combobox/helper.rb +26 -16
- data/lib/hotwire_combobox/version.rb +1 -1
- metadata +2 -2
@@ -41,6 +41,10 @@
|
|
41
41
|
get _isAsync() {
|
42
42
|
return this.hasAsyncSrcValue
|
43
43
|
}
|
44
|
+
|
45
|
+
get _isSync() {
|
46
|
+
return !this._isAsync
|
47
|
+
}
|
44
48
|
};
|
45
49
|
|
46
50
|
function Concerns(Base, ...mixins) {
|
@@ -132,16 +136,18 @@
|
|
132
136
|
}
|
133
137
|
}
|
134
138
|
|
135
|
-
|
136
|
-
|
139
|
+
_replaceFullQueryWithAutocompletedValue(option) {
|
140
|
+
const autocompletedValue = option.getAttribute(this.autocompletableAttributeValue);
|
141
|
+
|
142
|
+
this._fullQuery = autocompletedValue;
|
143
|
+
this._actingCombobox.setSelectionRange(autocompletedValue.length, autocompletedValue.length);
|
144
|
+
}
|
137
145
|
|
146
|
+
_autocompleteMissingPortion(option) {
|
138
147
|
const typedValue = this._typedQuery;
|
139
148
|
const autocompletedValue = option.getAttribute(this.autocompletableAttributeValue);
|
140
149
|
|
141
|
-
if (
|
142
|
-
this._fullQuery = autocompletedValue;
|
143
|
-
this._actingCombobox.setSelectionRange(autocompletedValue.length, autocompletedValue.length);
|
144
|
-
} else if (startsWith(autocompletedValue, typedValue)) {
|
150
|
+
if (this._autocompletesInline && startsWith(autocompletedValue, typedValue)) {
|
145
151
|
this._fullQuery = autocompletedValue;
|
146
152
|
this._actingCombobox.setSelectionRange(typedValue.length, autocompletedValue.length);
|
147
153
|
}
|
@@ -240,17 +246,27 @@
|
|
240
246
|
};
|
241
247
|
|
242
248
|
Combobox.Events = Base => class extends Base {
|
243
|
-
_dispatchSelectionEvent({
|
244
|
-
|
245
|
-
|
249
|
+
_dispatchSelectionEvent({ isNewAndAllowed, previousValue }) {
|
250
|
+
if (previousValue !== this._value) {
|
251
|
+
dispatch("hw-combobox:selection", {
|
252
|
+
target: this.element,
|
253
|
+
detail: { ...this._eventableDetails, isNewAndAllowed, previousValue }
|
254
|
+
});
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
_dispatchClosedEvent() {
|
259
|
+
dispatch("hw-combobox:closed", { target: this.element, detail: this._eventableDetails });
|
260
|
+
}
|
261
|
+
|
262
|
+
get _eventableDetails() {
|
263
|
+
return {
|
264
|
+
value: this._value,
|
246
265
|
display: this._fullQuery,
|
247
266
|
query: this._typedQuery,
|
248
267
|
fieldName: this.hiddenFieldTarget.name,
|
249
|
-
isValid: this._valueIsValid
|
250
|
-
|
251
|
-
};
|
252
|
-
|
253
|
-
dispatch("hw-combobox:selection", { target: this.element, detail });
|
268
|
+
isValid: this._valueIsValid
|
269
|
+
}
|
254
270
|
}
|
255
271
|
};
|
256
272
|
|
@@ -532,20 +548,28 @@
|
|
532
548
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
533
549
|
|
534
550
|
Combobox.Filtering = Base => class extends Base {
|
535
|
-
|
551
|
+
filterAndSelect(event) {
|
552
|
+
this._filter(event);
|
553
|
+
|
554
|
+
if (this._isSync) {
|
555
|
+
this._selectBasedOnQuery(event);
|
556
|
+
}
|
557
|
+
}
|
558
|
+
|
559
|
+
_initializeFiltering() {
|
560
|
+
this._debouncedFilterAsync = debounce(this._debouncedFilterAsync.bind(this));
|
561
|
+
}
|
562
|
+
|
563
|
+
_filter(event) {
|
536
564
|
if (this._isAsync) {
|
537
565
|
this._debouncedFilterAsync(event);
|
538
566
|
} else {
|
539
|
-
this._filterSync(
|
567
|
+
this._filterSync();
|
540
568
|
}
|
541
569
|
|
542
570
|
this._actingCombobox.toggleAttribute("data-queried", this._isQueried);
|
543
571
|
}
|
544
572
|
|
545
|
-
_initializeFiltering() {
|
546
|
-
this._debouncedFilterAsync = debounce(this._debouncedFilterAsync.bind(this));
|
547
|
-
}
|
548
|
-
|
549
573
|
_debouncedFilterAsync(event) {
|
550
574
|
this._filterAsync(event);
|
551
575
|
}
|
@@ -560,27 +584,14 @@
|
|
560
584
|
await get(this.asyncSrcValue, { responseKind: "turbo-stream", query });
|
561
585
|
}
|
562
586
|
|
563
|
-
_filterSync(
|
587
|
+
_filterSync() {
|
564
588
|
this.open();
|
565
589
|
this._allOptionElements.forEach(applyFilter(this._fullQuery, { matching: this.filterableAttributeValue }));
|
566
|
-
this._commitFilter(event);
|
567
|
-
}
|
568
|
-
|
569
|
-
_commitFilter(event) {
|
570
|
-
if (this._shouldTreatAsNewOptionForFiltering(!isDeleteEvent(event))) {
|
571
|
-
this._selectNew();
|
572
|
-
} else if (isDeleteEvent(event)) {
|
573
|
-
this._deselect();
|
574
|
-
} else if (event.inputType === "hw:lockInSelection") {
|
575
|
-
this._select(this._ensurableOption);
|
576
|
-
} else if (this._isOpen) {
|
577
|
-
this._select(this._visibleOptionElements[0]);
|
578
|
-
}
|
579
590
|
}
|
580
591
|
|
581
592
|
_clearQuery() {
|
582
593
|
this._fullQuery = "";
|
583
|
-
this.
|
594
|
+
this.filterAndSelect({ inputType: "deleteContentBackward" });
|
584
595
|
}
|
585
596
|
|
586
597
|
get _isQueried() {
|
@@ -674,9 +685,17 @@
|
|
674
685
|
};
|
675
686
|
|
676
687
|
Combobox.Options = Base => class extends Base {
|
677
|
-
|
678
|
-
this._deselect();
|
679
|
-
|
688
|
+
_resetOptionsSilently() {
|
689
|
+
this._resetOptions(this._deselect.bind(this));
|
690
|
+
}
|
691
|
+
|
692
|
+
_resetOptionsAndNotify() {
|
693
|
+
this._resetOptions(this._deselectAndNotify.bind(this));
|
694
|
+
}
|
695
|
+
|
696
|
+
_resetOptions(deselectionStrategy) {
|
697
|
+
this._setName(this.originalNameValue);
|
698
|
+
deselectionStrategy();
|
680
699
|
}
|
681
700
|
|
682
701
|
get _allowNew() {
|
@@ -704,7 +723,7 @@
|
|
704
723
|
}
|
705
724
|
|
706
725
|
get _isUnjustifiablyBlank() {
|
707
|
-
const valueIsMissing = !this.
|
726
|
+
const valueIsMissing = !this._value;
|
708
727
|
const noBlankOptionSelected = !this._selectedOptionElement;
|
709
728
|
|
710
729
|
return valueIsMissing && noBlankOptionSelected
|
@@ -713,8 +732,7 @@
|
|
713
732
|
|
714
733
|
Combobox.Selection = Base => class extends Base {
|
715
734
|
selectOptionOnClick(event) {
|
716
|
-
this.
|
717
|
-
this._select(event.currentTarget, { forceAutocomplete: true });
|
735
|
+
this._forceSelectionAndFilter(event.currentTarget, event);
|
718
736
|
this.close();
|
719
737
|
}
|
720
738
|
|
@@ -724,91 +742,136 @@
|
|
724
742
|
}
|
725
743
|
}
|
726
744
|
|
727
|
-
|
728
|
-
this.
|
729
|
-
|
730
|
-
if (
|
731
|
-
this.
|
732
|
-
|
733
|
-
this.
|
734
|
-
} else {
|
745
|
+
_selectBasedOnQuery(event) {
|
746
|
+
if (this._shouldTreatAsNewOptionForFiltering(!isDeleteEvent(event))) {
|
747
|
+
this._selectNew();
|
748
|
+
} else if (isDeleteEvent(event)) {
|
749
|
+
this._deselect();
|
750
|
+
} else if (event.inputType === "hw:lockInSelection" && this._ensurableOption) {
|
751
|
+
this._selectAndAutocompleteMissingPortion(this._ensurableOption);
|
752
|
+
} else if (this._isOpen && this._visibleOptionElements[0]) {
|
753
|
+
this._selectAndAutocompleteMissingPortion(this._visibleOptionElements[0]);
|
754
|
+
} else if (this._isOpen) {
|
755
|
+
this._resetOptionsAndNotify();
|
735
756
|
this._markInvalid();
|
736
|
-
}
|
757
|
+
} else ;
|
737
758
|
}
|
738
759
|
|
739
|
-
|
740
|
-
|
760
|
+
_select(option, autocompleteStrategy) {
|
761
|
+
const previousValue = this._value;
|
741
762
|
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
}
|
763
|
+
this._resetOptionsSilently();
|
764
|
+
|
765
|
+
autocompleteStrategy(option);
|
746
766
|
|
747
|
-
this.
|
767
|
+
this._setValue(option.dataset.value);
|
768
|
+
this._markSelected(option);
|
769
|
+
this._markValid();
|
770
|
+
this._dispatchSelectionEvent({ isNewAndAllowed: false, previousValue: previousValue });
|
771
|
+
|
772
|
+
option.scrollIntoView({ block: "nearest" });
|
748
773
|
}
|
749
774
|
|
750
|
-
|
751
|
-
|
752
|
-
option.classList.toggle(this.selectedClass, selected);
|
753
|
-
}
|
775
|
+
_selectNew() {
|
776
|
+
const previousValue = this._value;
|
754
777
|
|
755
|
-
|
756
|
-
this.
|
778
|
+
this._resetOptionsSilently();
|
779
|
+
this._setValue(this._fullQuery);
|
780
|
+
this._setName(this.nameWhenNewValue);
|
781
|
+
this._markValid();
|
782
|
+
this._dispatchSelectionEvent({ isNewAndAllowed: true, previousValue: previousValue });
|
757
783
|
}
|
758
784
|
|
759
785
|
_deselect() {
|
760
|
-
const
|
786
|
+
const previousValue = this._value;
|
761
787
|
|
762
|
-
if (
|
788
|
+
if (this._selectedOptionElement) {
|
789
|
+
this._markNotSelected(this._selectedOptionElement);
|
790
|
+
}
|
763
791
|
|
764
|
-
this.
|
792
|
+
this._setValue(null);
|
765
793
|
this._setActiveDescendant("");
|
766
794
|
|
767
|
-
|
795
|
+
return previousValue
|
768
796
|
}
|
769
797
|
|
770
|
-
|
771
|
-
this.
|
772
|
-
this.
|
773
|
-
|
774
|
-
this._markValid();
|
798
|
+
_deselectAndNotify() {
|
799
|
+
const previousValue = this._deselect();
|
800
|
+
this._dispatchSelectionEvent({ isNewAndAllowed: false, previousValue: previousValue });
|
801
|
+
}
|
775
802
|
|
776
|
-
|
803
|
+
_forceSelectionAndFilter(option, event) {
|
804
|
+
this._forceSelectionWithoutFiltering(option);
|
805
|
+
this._filter(event);
|
806
|
+
}
|
807
|
+
|
808
|
+
_forceSelectionWithoutFiltering(option) {
|
809
|
+
this._selectAndReplaceFullQuery(option);
|
777
810
|
}
|
778
811
|
|
779
812
|
_selectIndex(index) {
|
780
813
|
const option = wrapAroundAccess(this._visibleOptionElements, index);
|
781
|
-
this.
|
814
|
+
this._forceSelectionWithoutFiltering(option);
|
782
815
|
}
|
783
816
|
|
784
817
|
_preselectOption() {
|
785
818
|
if (this._hasValueButNoSelection && this._allOptions.length < 100) {
|
786
819
|
const option = this._allOptions.find(option => {
|
787
|
-
return option.dataset.value === this.
|
820
|
+
return option.dataset.value === this._value
|
788
821
|
});
|
789
822
|
|
790
|
-
if (option) this._markSelected(option
|
823
|
+
if (option) this._markSelected(option);
|
791
824
|
}
|
792
825
|
}
|
793
826
|
|
827
|
+
_selectAndReplaceFullQuery(option) {
|
828
|
+
this._select(option, this._replaceFullQueryWithAutocompletedValue.bind(this));
|
829
|
+
}
|
830
|
+
|
831
|
+
_selectAndAutocompleteMissingPortion(option) {
|
832
|
+
this._select(option, this._autocompleteMissingPortion.bind(this));
|
833
|
+
}
|
834
|
+
|
794
835
|
_lockInSelection() {
|
795
836
|
if (this._shouldLockInSelection) {
|
796
|
-
this.
|
797
|
-
this.filter({ inputType: "hw:lockInSelection" });
|
837
|
+
this._forceSelectionAndFilter(this._ensurableOption, { inputType: "hw:lockInSelection" });
|
798
838
|
}
|
839
|
+
}
|
799
840
|
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
841
|
+
_markSelected(option) {
|
842
|
+
if (this.hasSelectedClass) option.classList.add(this.selectedClass);
|
843
|
+
option.setAttribute("aria-selected", true);
|
844
|
+
this._setActiveDescendant(option.id);
|
845
|
+
}
|
846
|
+
|
847
|
+
_markNotSelected(option) {
|
848
|
+
if (this.hasSelectedClass) option.classList.remove(this.selectedClass);
|
849
|
+
option.removeAttribute("aria-selected");
|
850
|
+
this._removeActiveDescendant();
|
804
851
|
}
|
805
852
|
|
806
853
|
_setActiveDescendant(id) {
|
807
854
|
this._forAllComboboxes(el => el.setAttribute("aria-activedescendant", id));
|
808
855
|
}
|
809
856
|
|
857
|
+
_removeActiveDescendant() {
|
858
|
+
this._setActiveDescendant("");
|
859
|
+
}
|
860
|
+
|
861
|
+
_setValue(value) {
|
862
|
+
this.hiddenFieldTarget.value = value;
|
863
|
+
}
|
864
|
+
|
865
|
+
_setName(value) {
|
866
|
+
this.hiddenFieldTarget.name = value;
|
867
|
+
}
|
868
|
+
|
869
|
+
get _value() {
|
870
|
+
return this.hiddenFieldTarget.value
|
871
|
+
}
|
872
|
+
|
810
873
|
get _hasValueButNoSelection() {
|
811
|
-
return this.
|
874
|
+
return this._value && !this._selectedOptionElement
|
812
875
|
}
|
813
876
|
|
814
877
|
get _shouldLockInSelection() {
|
@@ -1102,7 +1165,11 @@
|
|
1102
1165
|
close() {
|
1103
1166
|
if (this._isOpen) {
|
1104
1167
|
this._lockInSelection();
|
1168
|
+
this._clearInvalidQuery();
|
1169
|
+
|
1105
1170
|
this.expandedValue = false;
|
1171
|
+
|
1172
|
+
this._dispatchClosedEvent();
|
1106
1173
|
}
|
1107
1174
|
}
|
1108
1175
|
|
@@ -1171,6 +1238,8 @@
|
|
1171
1238
|
this._actingCombobox.setAttribute("aria-expanded", true); // needs to happen after setting acting combobox
|
1172
1239
|
}
|
1173
1240
|
|
1241
|
+
// +._collapse()+ differs from `.close()` in that it might be called by stimulus on connect because
|
1242
|
+
// it interprets a change in `expandedValue` — whereas `.close()` is only called internally by us.
|
1174
1243
|
_collapse() {
|
1175
1244
|
this._actingCombobox.setAttribute("aria-expanded", false); // needs to happen before resetting acting combobox
|
1176
1245
|
|
@@ -1211,6 +1280,13 @@
|
|
1211
1280
|
enableBodyScroll(this.dialogListboxTarget);
|
1212
1281
|
}
|
1213
1282
|
|
1283
|
+
_clearInvalidQuery() {
|
1284
|
+
if (this._isUnjustifiablyBlank) {
|
1285
|
+
this._deselect();
|
1286
|
+
this._clearQuery();
|
1287
|
+
}
|
1288
|
+
}
|
1289
|
+
|
1214
1290
|
get _isOpen() {
|
1215
1291
|
return this.expandedValue
|
1216
1292
|
}
|
@@ -1254,7 +1330,7 @@
|
|
1254
1330
|
// +_valueIsInvalid+ only checks if `comboboxTarget` (and not `_actingCombobox`) is required
|
1255
1331
|
// because the `required` attribute is only forwarded to the `comboboxTarget` element
|
1256
1332
|
get _valueIsInvalid() {
|
1257
|
-
const isRequiredAndEmpty = this.comboboxTarget.required && !this.
|
1333
|
+
const isRequiredAndEmpty = this.comboboxTarget.required && !this._value;
|
1258
1334
|
return isRequiredAndEmpty
|
1259
1335
|
}
|
1260
1336
|
};
|
@@ -1337,7 +1413,7 @@
|
|
1337
1413
|
|
1338
1414
|
if (inputType && inputType !== "hw:lockInSelection") {
|
1339
1415
|
if (delay) await sleep(delay);
|
1340
|
-
this.
|
1416
|
+
this._selectBasedOnQuery({ inputType });
|
1341
1417
|
} else {
|
1342
1418
|
this._preselectOption();
|
1343
1419
|
}
|
@@ -8,16 +8,18 @@ Combobox.Autocomplete = Base => class extends Base {
|
|
8
8
|
}
|
9
9
|
}
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
_replaceFullQueryWithAutocompletedValue(option) {
|
12
|
+
const autocompletedValue = option.getAttribute(this.autocompletableAttributeValue)
|
13
|
+
|
14
|
+
this._fullQuery = autocompletedValue
|
15
|
+
this._actingCombobox.setSelectionRange(autocompletedValue.length, autocompletedValue.length)
|
16
|
+
}
|
13
17
|
|
18
|
+
_autocompleteMissingPortion(option) {
|
14
19
|
const typedValue = this._typedQuery
|
15
20
|
const autocompletedValue = option.getAttribute(this.autocompletableAttributeValue)
|
16
21
|
|
17
|
-
if (
|
18
|
-
this._fullQuery = autocompletedValue
|
19
|
-
this._actingCombobox.setSelectionRange(autocompletedValue.length, autocompletedValue.length)
|
20
|
-
} else if (startsWith(autocompletedValue, typedValue)) {
|
22
|
+
if (this._autocompletesInline && startsWith(autocompletedValue, typedValue)) {
|
21
23
|
this._fullQuery = autocompletedValue
|
22
24
|
this._actingCombobox.setSelectionRange(typedValue.length, autocompletedValue.length)
|
23
25
|
}
|
@@ -2,16 +2,26 @@ import Combobox from "hw_combobox/models/combobox/base"
|
|
2
2
|
import { dispatch } from "hw_combobox/helpers"
|
3
3
|
|
4
4
|
Combobox.Events = Base => class extends Base {
|
5
|
-
_dispatchSelectionEvent({
|
6
|
-
|
7
|
-
|
5
|
+
_dispatchSelectionEvent({ isNewAndAllowed, previousValue }) {
|
6
|
+
if (previousValue !== this._value) {
|
7
|
+
dispatch("hw-combobox:selection", {
|
8
|
+
target: this.element,
|
9
|
+
detail: { ...this._eventableDetails, isNewAndAllowed, previousValue }
|
10
|
+
})
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
_dispatchClosedEvent() {
|
15
|
+
dispatch("hw-combobox:closed", { target: this.element, detail: this._eventableDetails })
|
16
|
+
}
|
17
|
+
|
18
|
+
get _eventableDetails() {
|
19
|
+
return {
|
20
|
+
value: this._value,
|
8
21
|
display: this._fullQuery,
|
9
22
|
query: this._typedQuery,
|
10
23
|
fieldName: this.hiddenFieldTarget.name,
|
11
|
-
isValid: this._valueIsValid
|
12
|
-
isNew: isNew
|
24
|
+
isValid: this._valueIsValid
|
13
25
|
}
|
14
|
-
|
15
|
-
dispatch("hw-combobox:selection", { target: this.element, detail })
|
16
26
|
}
|
17
27
|
}
|
@@ -1,23 +1,33 @@
|
|
1
1
|
|
2
2
|
import Combobox from "hw_combobox/models/combobox/base"
|
3
|
-
import { applyFilter, debounce,
|
3
|
+
import { applyFilter, debounce, unselectedPortion } from "hw_combobox/helpers"
|
4
4
|
import { get } from "hw_combobox/vendor/requestjs"
|
5
5
|
|
6
6
|
Combobox.Filtering = Base => class extends Base {
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
filterAndSelect(event) {
|
8
|
+
this._filter(event)
|
9
|
+
|
10
|
+
if (this._isSync) {
|
11
|
+
this._selectBasedOnQuery(event)
|
10
12
|
} else {
|
11
|
-
|
13
|
+
// noop, async selection is handled by stimulus callbacks
|
12
14
|
}
|
13
|
-
|
14
|
-
this._actingCombobox.toggleAttribute("data-queried", this._isQueried)
|
15
15
|
}
|
16
16
|
|
17
17
|
_initializeFiltering() {
|
18
18
|
this._debouncedFilterAsync = debounce(this._debouncedFilterAsync.bind(this))
|
19
19
|
}
|
20
20
|
|
21
|
+
_filter(event) {
|
22
|
+
if (this._isAsync) {
|
23
|
+
this._debouncedFilterAsync(event)
|
24
|
+
} else {
|
25
|
+
this._filterSync()
|
26
|
+
}
|
27
|
+
|
28
|
+
this._actingCombobox.toggleAttribute("data-queried", this._isQueried)
|
29
|
+
}
|
30
|
+
|
21
31
|
_debouncedFilterAsync(event) {
|
22
32
|
this._filterAsync(event)
|
23
33
|
}
|
@@ -32,27 +42,14 @@ Combobox.Filtering = Base => class extends Base {
|
|
32
42
|
await get(this.asyncSrcValue, { responseKind: "turbo-stream", query })
|
33
43
|
}
|
34
44
|
|
35
|
-
_filterSync(
|
45
|
+
_filterSync() {
|
36
46
|
this.open()
|
37
47
|
this._allOptionElements.forEach(applyFilter(this._fullQuery, { matching: this.filterableAttributeValue }))
|
38
|
-
this._commitFilter(event)
|
39
|
-
}
|
40
|
-
|
41
|
-
_commitFilter(event) {
|
42
|
-
if (this._shouldTreatAsNewOptionForFiltering(!isDeleteEvent(event))) {
|
43
|
-
this._selectNew()
|
44
|
-
} else if (isDeleteEvent(event)) {
|
45
|
-
this._deselect()
|
46
|
-
} else if (event.inputType === "hw:lockInSelection") {
|
47
|
-
this._select(this._ensurableOption)
|
48
|
-
} else if (this._isOpen) {
|
49
|
-
this._select(this._visibleOptionElements[0])
|
50
|
-
}
|
51
48
|
}
|
52
49
|
|
53
50
|
_clearQuery() {
|
54
51
|
this._fullQuery = ""
|
55
|
-
this.
|
52
|
+
this.filterAndSelect({ inputType: "deleteContentBackward" })
|
56
53
|
}
|
57
54
|
|
58
55
|
get _isQueried() {
|
@@ -2,9 +2,17 @@ import Combobox from "hw_combobox/models/combobox/base"
|
|
2
2
|
import { visible } from "hw_combobox/helpers"
|
3
3
|
|
4
4
|
Combobox.Options = Base => class extends Base {
|
5
|
-
|
6
|
-
this._deselect()
|
7
|
-
|
5
|
+
_resetOptionsSilently() {
|
6
|
+
this._resetOptions(this._deselect.bind(this))
|
7
|
+
}
|
8
|
+
|
9
|
+
_resetOptionsAndNotify() {
|
10
|
+
this._resetOptions(this._deselectAndNotify.bind(this))
|
11
|
+
}
|
12
|
+
|
13
|
+
_resetOptions(deselectionStrategy) {
|
14
|
+
this._setName(this.originalNameValue)
|
15
|
+
deselectionStrategy()
|
8
16
|
}
|
9
17
|
|
10
18
|
get _allowNew() {
|
@@ -32,7 +40,7 @@ Combobox.Options = Base => class extends Base {
|
|
32
40
|
}
|
33
41
|
|
34
42
|
get _isUnjustifiablyBlank() {
|
35
|
-
const valueIsMissing = !this.
|
43
|
+
const valueIsMissing = !this._value
|
36
44
|
const noBlankOptionSelected = !this._selectedOptionElement
|
37
45
|
|
38
46
|
return valueIsMissing && noBlankOptionSelected
|