Multiselect2 初始搜索被禁用
Multiselect2 initial search is disabled
当 select2 和 ajax/initSelection 用于 select 源时,过滤器选项被禁用并且 select2-search__field 不在 html 在初始负载上。
由于此 select 或没有 minimumInputLength,因此会显示选项,一旦 selected,此搜索字段就会创建并可以使用。如果定义了 minimumInputLength 则 select2 基本上不可用。
这是使用敲除,所以我包含了绑定处理程序。
HTML:
...
<select class="form-control"
data-bind="selectedOptions: matchList,
select2: {
initSelection: $parents[1].initSupplier,
ajax: $parents[1].ajaxSuppliers,
escapeMarkup: function (markup) { return markup },
multiple: true,
maximumSelectionSize: 5,
placeholder: 'Select Supplier...',
width: '100%',
allowClear: true
}"></select>
...
视图模型:
self.initSupplier = function (element, callback) {
var options = $(element).children();
if (options.length > 0) {
var suppliers = [];
var ajax = options.map(function (opt) {
if (options[opt]) {
return $.ajax('api/supplier/' + options[opt].value).done(function (data) {
try {
suppliers.push({ id: data.identifierGuid, text: data.name });
} catch (err) {
if (system.debug()) {
console.error(err);
}
}
});
}
});
$.when.apply($, ajax).then(function () {
if (suppliers.length > 0) {
callback(suppliers);
}
});
}
};
self.supplierPageSize = ko.observable(25);
self.ajaxSuppliers = {
delay: 450,
url: 'api/suppliers',
type: 'GET',
dataType: 'json',
data: function (params) {
return {
skip: self.supplierPageSize() * ((params.page || 1) - 1),
take: self.supplierPageSize(),
code: isNaN(params.term) ? null : params.term,
name: isNaN(params.term) ? params.term : null,
showAll: true
};
},
processResults: function (data, params) {
if (data && data.list) {
data.list = data.list.map(function (supplier) {
return { id: supplier.identifierGuid || null, text: supplier.name || '' };
});
} else {
data = { list: [] };
}
return {
results: data.list,
pagination: {
more: (params.page * self.supplierPageSize()) < data.totalCount
}
};
}
}
绑定处理程序:
ko.bindingHandlers.select2 = {
init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
var allBindings = allBindingsAccessor();
var select2 = ko.unwrap(allBindings.select2);
if (select2.data) {
select2.data = ko.unwrap(select2.data);
}
if ("selectedOptions" in allBindings && !("options" in allBindings)) {//initalising select2 with selections correctly
var values = ko.unwrap(allBindings.selectedOptions);
if (values && values.length > 0) {
select2.data = values.map(function (opt) { return { id: opt, text: opt }; });
}
}
if (!select2.width) {
select2.width = '100%';
}
select2.formatInputTooShort = select2.formatInputTooShort || function (value, min) {
return "Please enter " + (min - value.length) + " or more characters";
};
$(el).select2(select2);
if (select2.selecting) {
$(el).on('select2:selecting', select2.selecting);
}
if (select2.removing) {
$(el).on('select2:unselecting', select2.removing);
}
ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
$(el).select2('destroy');
});
$(el).trigger('change');
},
update: function (el, valueAccessor, allBindingsAccessor, viewModel) {
var allBindings = allBindingsAccessor();
var select2 = ko.unwrap(allBindings.select2);
if ("value" in allBindings) {
var value = ko.unwrap(allBindings.value);
if (ko.unwrap(select2.multiple) && value.constructor !== Array) {
value = String(value).split(',');
}
$(el).select2('val', value);
$(el).val(value).trigger('change');
} else if ("selectedOptions" in allBindings) {
var converted = [];
var textAccessor = function (value) { return value; };
if ("optionsText" in allBindings) {
textAccessor = function (value) {
var valueAccessor = function (item) {
return item;
};
if ("optionsValue" in allBindings) {
valueAccessor = function (item) {
return item[allBindings.optionsValue];
};
}
var items = $.grep(allBindings.options(), function (e) {
return valueAccessor(e) == value;
});
if (items.length == 0 || items.length > 1) {
return "UNKNOWN";
}
return items[0][allBindings.optionsText];
}
}
$.each(allBindings.selectedOptions(), function (key, value) {
converted.push({ id: value, text: textAccessor(value) });
});
$(el).select2("data", converted);
$(el).trigger('change');
}
}
};
解决此问题的方法。这仅适用于您需要它在加载时为空的情况。
定义 id 和文本为 ""
的数据
<select class="form-control" multiple
data-bind="selectedOptions: matchList,
select2: {
data: [{id: '', text: ''}],
initSelection: $parents[1].initPriceGroup,
ajax: $parents[1].ajaxPriceGroups,
escapeMarkup: function (markup) { return markup },
multiple: true,
maximumSelectionSize: 5,
placeholder: 'Select Price Group...',
width: '100%',
allowClear: true
}"></select>
然后初始化程序需要忽略无效的 ID 和 return 空列表回调。
这将强制 select2 认为它已被取消选择并添加搜索输入,而无需用户看到并必须自己执行。
self.initPriceGroup = function (element, callback) {
var options = $(element).children();
if (options.length > 0) {
var groups = [];
var ajax = options.map(function (opt) {
if (options[opt] && options[opt].value) {
return $.ajax('api/priceGroup/' + options[opt].value).done(function (data) {
try {
groups.push({ id: data.priceGroupGuid, text: data.name });
} catch (err) {
if (system.debug()) {
console.error(err);
}
}
});
}
});
$.when.apply($, ajax).then(function () {
if (groups.length > 0) {
callback(groups);
} else {
callback([]);
}
});
}
};
当 select2 和 ajax/initSelection 用于 select 源时,过滤器选项被禁用并且 select2-search__field 不在 html 在初始负载上。
由于此 select 或没有 minimumInputLength,因此会显示选项,一旦 selected,此搜索字段就会创建并可以使用。如果定义了 minimumInputLength 则 select2 基本上不可用。
这是使用敲除,所以我包含了绑定处理程序。
HTML:
...
<select class="form-control"
data-bind="selectedOptions: matchList,
select2: {
initSelection: $parents[1].initSupplier,
ajax: $parents[1].ajaxSuppliers,
escapeMarkup: function (markup) { return markup },
multiple: true,
maximumSelectionSize: 5,
placeholder: 'Select Supplier...',
width: '100%',
allowClear: true
}"></select>
...
视图模型:
self.initSupplier = function (element, callback) {
var options = $(element).children();
if (options.length > 0) {
var suppliers = [];
var ajax = options.map(function (opt) {
if (options[opt]) {
return $.ajax('api/supplier/' + options[opt].value).done(function (data) {
try {
suppliers.push({ id: data.identifierGuid, text: data.name });
} catch (err) {
if (system.debug()) {
console.error(err);
}
}
});
}
});
$.when.apply($, ajax).then(function () {
if (suppliers.length > 0) {
callback(suppliers);
}
});
}
};
self.supplierPageSize = ko.observable(25);
self.ajaxSuppliers = {
delay: 450,
url: 'api/suppliers',
type: 'GET',
dataType: 'json',
data: function (params) {
return {
skip: self.supplierPageSize() * ((params.page || 1) - 1),
take: self.supplierPageSize(),
code: isNaN(params.term) ? null : params.term,
name: isNaN(params.term) ? params.term : null,
showAll: true
};
},
processResults: function (data, params) {
if (data && data.list) {
data.list = data.list.map(function (supplier) {
return { id: supplier.identifierGuid || null, text: supplier.name || '' };
});
} else {
data = { list: [] };
}
return {
results: data.list,
pagination: {
more: (params.page * self.supplierPageSize()) < data.totalCount
}
};
}
}
绑定处理程序:
ko.bindingHandlers.select2 = {
init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
var allBindings = allBindingsAccessor();
var select2 = ko.unwrap(allBindings.select2);
if (select2.data) {
select2.data = ko.unwrap(select2.data);
}
if ("selectedOptions" in allBindings && !("options" in allBindings)) {//initalising select2 with selections correctly
var values = ko.unwrap(allBindings.selectedOptions);
if (values && values.length > 0) {
select2.data = values.map(function (opt) { return { id: opt, text: opt }; });
}
}
if (!select2.width) {
select2.width = '100%';
}
select2.formatInputTooShort = select2.formatInputTooShort || function (value, min) {
return "Please enter " + (min - value.length) + " or more characters";
};
$(el).select2(select2);
if (select2.selecting) {
$(el).on('select2:selecting', select2.selecting);
}
if (select2.removing) {
$(el).on('select2:unselecting', select2.removing);
}
ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
$(el).select2('destroy');
});
$(el).trigger('change');
},
update: function (el, valueAccessor, allBindingsAccessor, viewModel) {
var allBindings = allBindingsAccessor();
var select2 = ko.unwrap(allBindings.select2);
if ("value" in allBindings) {
var value = ko.unwrap(allBindings.value);
if (ko.unwrap(select2.multiple) && value.constructor !== Array) {
value = String(value).split(',');
}
$(el).select2('val', value);
$(el).val(value).trigger('change');
} else if ("selectedOptions" in allBindings) {
var converted = [];
var textAccessor = function (value) { return value; };
if ("optionsText" in allBindings) {
textAccessor = function (value) {
var valueAccessor = function (item) {
return item;
};
if ("optionsValue" in allBindings) {
valueAccessor = function (item) {
return item[allBindings.optionsValue];
};
}
var items = $.grep(allBindings.options(), function (e) {
return valueAccessor(e) == value;
});
if (items.length == 0 || items.length > 1) {
return "UNKNOWN";
}
return items[0][allBindings.optionsText];
}
}
$.each(allBindings.selectedOptions(), function (key, value) {
converted.push({ id: value, text: textAccessor(value) });
});
$(el).select2("data", converted);
$(el).trigger('change');
}
}
};
解决此问题的方法。这仅适用于您需要它在加载时为空的情况。 定义 id 和文本为 ""
的数据<select class="form-control" multiple
data-bind="selectedOptions: matchList,
select2: {
data: [{id: '', text: ''}],
initSelection: $parents[1].initPriceGroup,
ajax: $parents[1].ajaxPriceGroups,
escapeMarkup: function (markup) { return markup },
multiple: true,
maximumSelectionSize: 5,
placeholder: 'Select Price Group...',
width: '100%',
allowClear: true
}"></select>
然后初始化程序需要忽略无效的 ID 和 return 空列表回调。
这将强制 select2 认为它已被取消选择并添加搜索输入,而无需用户看到并必须自己执行。
self.initPriceGroup = function (element, callback) {
var options = $(element).children();
if (options.length > 0) {
var groups = [];
var ajax = options.map(function (opt) {
if (options[opt] && options[opt].value) {
return $.ajax('api/priceGroup/' + options[opt].value).done(function (data) {
try {
groups.push({ id: data.priceGroupGuid, text: data.name });
} catch (err) {
if (system.debug()) {
console.error(err);
}
}
});
}
});
$.when.apply($, ajax).then(function () {
if (groups.length > 0) {
callback(groups);
} else {
callback([]);
}
});
}
};