Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit ced4a1e

Browse files
authored
fix(filters): add more variable checking in multiple-select external lib (#710)
- in some rare occasion we had "cannot read 'prop' of undefined" happening. This PR adds more checks to make sure we aren't trying to read a method of an undefined element
1 parent 19af974 commit ced4a1e

File tree

1 file changed

+66
-46
lines changed

1 file changed

+66
-46
lines changed

src/assets/lib/multiple-select/multiple-select.js

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,12 @@
441441
if ($items.length === that.$selectItems.length) {
442442
that[checked ? 'checkAll' : 'uncheckAll']();
443443
} else { // when the filter option is true
444-
that.$selectGroups.prop('checked', checked);
445-
$items.prop('checked', checked);
444+
if (that.$selectGroups) {
445+
that.$selectGroups.prop('checked', checked);
446+
}
447+
if ($items) {
448+
$items.prop('checked', checked);
449+
}
446450
that.options[checked ? 'onCheckAll' : 'onUncheckAll']();
447451
that.update();
448452
}
@@ -452,8 +456,9 @@
452456
$items = that.$selectItems.filter(':visible'),
453457
$children = $items.filter(sprintf('[data-group="%s"]', group)),
454458
checked = $children.length !== $children.filter(':checked').length;
455-
456-
$children.prop('checked', checked);
459+
if ($children) {
460+
$children.prop('checked', checked);
461+
}
457462
that.updateSelectAll();
458463
that.update();
459464
that.options.onOptgroupClick({
@@ -495,6 +500,7 @@
495500
return;
496501
}
497502
this.options.isOpen = true;
503+
this.$parent.addClass('ms-parent-open');
498504
this.$choice.find('>div').addClass('open');
499505
this.$drop[this.animateMethod('show')]();
500506

@@ -573,6 +579,7 @@
573579

574580
close: function () {
575581
this.options.isOpen = false;
582+
this.$parent.removeClass('ms-parent-open');
576583
this.$choice.find('>div').removeClass('open');
577584
this.$drop[this.animateMethod('hide')]();
578585
if (this.options.container) {
@@ -762,8 +769,10 @@
762769
}
763770

764771
if (this.options.addTitle) {
765-
var selectType = (this.options.useSelectOptionLabel || this.options.useSelectOptionLabelToHtml) ? 'label' : 'text'
766-
$span.prop('title', this.getSelects(selectType));
772+
var selectType = (this.options.useSelectOptionLabel || this.options.useSelectOptionLabelToHtml) ? 'label' : 'text';
773+
if ($span) {
774+
$span.prop('title', this.getSelects(selectType));
775+
}
767776
}
768777

769778
// set selects to select
@@ -787,10 +796,12 @@
787796
if (!isInit) {
788797
$items = $items.filter(':visible');
789798
}
790-
this.$selectAll.prop('checked', $items.length &&
791-
$items.length === $items.filter(':checked').length);
792-
if (!isInit && this.$selectAll.prop('checked')) {
793-
this.options.onCheckAll();
799+
if (this.$selectAll) {
800+
this.$selectAll.prop('checked', $items.length &&
801+
$items.length === $items.filter(':checked').length);
802+
if (!isInit && this.$selectAll.prop('checked')) {
803+
this.options.onCheckAll();
804+
}
794805
}
795806
},
796807

@@ -832,7 +843,7 @@
832843
values.push($(this).val());
833844
});
834845

835-
if (type === 'text' && this.$selectGroups.length) {
846+
if (type === 'text' && this.$selectGroups && this.$selectGroups.length) {
836847
texts = [];
837848
this.$selectGroups.each(function () {
838849
var html = [],
@@ -841,13 +852,13 @@
841852
$children = that.$drop.find(sprintf('[%s][data-group="%s"]', that.selectItemName, group)),
842853
$selected = $children.filter(':checked');
843854

844-
if (!$selected.length) {
855+
if (!$selected || !$selected.length) {
845856
return;
846857
}
847858

848859
html.push('[');
849860
html.push(text);
850-
if ($children.length > $selected.length) {
861+
if (($children && $children.length) > ($selected && $selected.length)) {
851862
var list = [];
852863
$selected.each(function () {
853864
list.push($(this).parent().text());
@@ -857,7 +868,7 @@
857868
html.push(']');
858869
texts.push(html.join(''));
859870
});
860-
} else if (type === 'label' && this.$selectGroups.length) {
871+
} else if (type === 'label' && this.$selectGroups && this.$selectGroups.length) {
861872
labels = [];
862873
this.$selectGroups.each(function () {
863874
var html = [],
@@ -866,13 +877,13 @@
866877
$children = that.$drop.find(sprintf('[%s][data-group="%s"]', that.selectItemName, group)),
867878
$selected = $children.filter(':checked');
868879

869-
if (!$selected.length) {
880+
if (!$selected || !$selected.length) {
870881
return;
871882
}
872883

873884
html.push('[');
874885
html.push(label);
875-
if ($children.length > $selected.length) {
886+
if (($children && $children.length) > ($selected && $selected.length)) {
876887
var list = [];
877888
$selected.each(function () {
878889
list.push($(this).attr('label') || '');
@@ -921,22 +932,31 @@
921932

922933
setSelects: function (values) {
923934
var that = this;
924-
this.$selectItems.prop('checked', false);
925-
this.$disableItems.prop('checked', false);
926-
$.each(values, function (i, value) {
927-
that.$selectItems.filter(sprintf('[value="%s"]', value)).prop('checked', true);
928-
that.$disableItems.filter(sprintf('[value="%s"]', value)).prop('checked', true);
929-
});
930-
this.$selectAll.prop('checked', this.$selectItems.length ===
931-
this.$selectItems.filter(':checked').length + this.$disableItems.filter(':checked').length);
932-
933-
$.each(that.$selectGroups, function (i, val) {
934-
var group = $(val).parent().attr('data-group'),
935-
$children = that.$selectItems.filter('[data-group="' + group + '"]');
936-
$(val).prop('checked', $children.length &&
937-
$children.length === $children.filter(':checked').length);
938-
});
935+
if (this.$selectItems && this.$disableItems) {
936+
this.$selectItems.prop('checked', false);
937+
this.$disableItems.prop('checked', false);
938+
$.each(values, function (i, value) {
939+
var selectedItemElm = that.$selectItems.filter(sprintf('[value="%s"]', value));
940+
var disabledItemElm = that.$disableItems.filter(sprintf('[value="%s"]', value));
941+
if (selectedItemElm) {
942+
selectedItemElm.prop('checked', true);
943+
}
944+
if (disabledItemElm) {
945+
disabledItemElm.prop('checked', true);
946+
}
947+
});
948+
if (this.$selectItems && this.$selectAll) {
949+
this.$selectAll.prop('checked', this.$selectItems.length ===
950+
this.$selectItems.filter(':checked').length + this.$disableItems.filter(':checked').length);
951+
}
939952

953+
$.each(that.$selectGroups, function (i, val) {
954+
var group = $(val).parent().attr('data-group'),
955+
$children = that.$selectItems.filter('[data-group="' + group + '"]');
956+
$(val).prop('checked', $children.length &&
957+
$children.length === $children.filter(':checked').length);
958+
});
959+
}
940960
this.update(false);
941961
},
942962

@@ -962,28 +982,28 @@
962982
},
963983

964984
checkAll: function () {
965-
this.$selectItems.prop('checked', true);
966-
this.$selectGroups.prop('checked', true);
967-
this.$selectAll.prop('checked', true);
985+
this.$selectItems && this.$selectItems.prop('checked', true);
986+
this.$selectGroups && this.$selectGroups.prop('checked', true);
987+
this.$selectAll && this.$selectAll.prop('checked', true);
968988
this.update();
969989
this.options.onCheckAll();
970990
},
971991

972992
uncheckAll: function () {
973-
this.$selectItems.prop('checked', false);
974-
this.$selectGroups.prop('checked', false);
975-
this.$selectAll.prop('checked', false);
993+
this.$selectItems && this.$selectItems.prop('checked', false);
994+
this.$selectGroups && this.$selectGroups.prop('checked', false);
995+
this.$selectAll && this.$selectAll.prop('checked', false);
976996
this.update();
977997
this.options.onUncheckAll();
978998
},
979999

9801000
focus: function () {
981-
this.$choice.focus();
1001+
this.$choice && this.$choice.focus();
9821002
this.options.onFocus();
9831003
},
9841004

9851005
blur: function () {
986-
this.$choice.blur();
1006+
this.$choice && this.$choice.blur();
9871007
this.options.onBlur();
9881008
},
9891009

@@ -996,17 +1016,17 @@
9961016
text = $.trim(this.$searchInput.val()).toLowerCase();
9971017

9981018
if (text.length === 0) {
999-
this.$selectAll.parent().show();
1000-
this.$selectItems.parent().show();
1001-
this.$disableItems.parent().show();
1002-
this.$selectGroups.parent().show();
1019+
this.$selectAll && this.$selectAll.parent().show();
1020+
this.$selectItems && this.$selectItems.parent().show();
1021+
this.$disableItems && this.$disableItems.parent().show();
1022+
this.$selectGroups && this.$selectGroups.parent().show();
10031023
this.$noResults.hide();
10041024
} else {
10051025
this.$selectItems.each(function () {
10061026
var $parent = $(this).parent();
10071027
$parent[removeDiacritics($parent.text().toLowerCase()).indexOf(removeDiacritics(text)) < 0 ? 'hide' : 'show']();
10081028
});
1009-
this.$disableItems.parent().hide();
1029+
this.$disableItems && this.$disableItems.parent().hide();
10101030
this.$selectGroups.each(function () {
10111031
var $parent = $(this).parent();
10121032
var group = $parent.attr('data-group'),
@@ -1015,11 +1035,11 @@
10151035
});
10161036

10171037
//Check if no matches found
1018-
if (this.$selectItems.parent().filter(':visible').length) {
1038+
if (this.$selectItems && this.$selectItems.parent().filter(':visible').length) {
10191039
this.$selectAll.parent().show();
10201040
this.$noResults.hide();
10211041
} else {
1022-
this.$selectAll.parent().hide();
1042+
this.$selectAll && this.$selectAll.parent().hide();
10231043
this.$noResults.show();
10241044
}
10251045
}

0 commit comments

Comments
 (0)