@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,494 lines (1,493 loc) • 85.3 kB
JavaScript
const require_dropdowns_loader = require('./dropdowns-loader-Ct0fKyLR.js');
//#region ../src/kendo.list.js
const __meta__ = {
id: "list",
name: "List",
category: "framework",
depends: [
"data",
"popup",
"label",
"icons",
"actionsheet"
],
hidden: true
};
(function($, undefined) {
var kendo = window.kendo, ui = kendo.ui, outerHeight = kendo._outerHeight, percentageUnitsRegex = /^\d+(\.\d+)?%$/i, Widget = ui.Widget, keys = kendo.keys, support = kendo.support, htmlEncode = kendo.htmlEncode, activeElement = kendo._activeElement, outerWidth = kendo._outerWidth, ObservableArray = kendo.data.ObservableArray, ID = "id", CHANGE = "change", FOCUSED = "k-focus", HOVER = "k-hover", KSELECTED = "k-selected", LIST = "k-list", TABLE = "k-table", DATA_TABLE = "k-data-table", LIST_UL = "k-list-ul", TABLE_LIST = "k-table-list", FIXED_GROUP_HEADER = ".k-list-group-sticky-header", FIXED_GROUP_TABLE_HEADER = ".k-table-group-sticky-header", GROUP_LABEL = ".k-list-item-group-label", ITEMSELECTOR = ".k-list-item", ITEMSELECTORTABLE = ".k-table-row", OPEN = "open", CLOSE = "close", CASCADE = "cascade", SELECT = "select", CLICK = "click", MOUSELEAVE = "mouseleave", MOUSEENTER = "mouseenter", ACTIVATE = "activate", DEACTIVATE = "deactivate", DATA_BINDING = "dataBinding", DATA_BOUND = "dataBound", SELECTED_ITEM_CHANGE = "selectedItemChange", SELECTED = "selected", REQUESTSTART = "requestStart", REQUESTEND = "requestEnd", BLUR = "blur", FOCUS = "focus", FOCUSOUT = "focusout", extend = $.extend, isArray = Array.isArray, browser = support.browser, HIDDENCLASS = "k-hidden", WIDTH = "width", TEXT = "text", VALUE = "value", isIE = browser.msie, quotRegExp = /"/g, alternativeNames = {
"ComboBox": ["DropDownList", "MultiColumnComboBox"],
"DropDownList": ["ComboBox", "MultiColumnComboBox"],
"MultiColumnComboBox": ["ComboBox", "DropDownList"]
}, UL_EL = "<ul unselectable=\"on\"/>", LIST_EL = "<div class='k-list'/>", NO_DATA_EL = "<div class=\"k-no-data\"></div>", LIST_FOOTER_EL = "<div class=\"k-list-footer\"></div>", TABLE_FOOTER_EL = "<div class=\"k-table-footer\">" + "<span class=\"k-table-td\"></span>" + "</div>", MOUSEDOWN = "mousedown", ACTION = "action", LIST_SUFFIX = "-list", LISTBOX_SUFFIX = "_listbox", ARIA_LABELLEDBY = "aria-labelledby", ARIA_LABEL = "aria-label", ARIA_ACTIVEDESCENDANT = "aria-activedescendant", ARIA_AUTOCOMPLETE = "aria-autocomplete", ARIA_CONTROLS = "aria-controls", ARIA_LIVE = "aria-live", ARIA_EXPANDED = "aria-expanded", ARIA_HIDDEN = "aria-hidden", ARIA_MULTISELECTABLE = "aria-multiselectable", ARIA_SELECTED = "aria-selected", GROUP_ROW_SEL = ".k-table-group-row", ACTIONSHEET_TITLEBAR = ".k-actionsheet-titlebar";
var List = kendo.ui.DataBoundWidget.extend({
init: function(element, options) {
var that = this, id;
Widget.fn.init.call(that, element, options);
element = that.element;
options = that.options;
that._isSelect = element.is(SELECT);
if (that._isSelect && that.element[0].length) {
if (!options.dataSource) {
options.dataTextField = options.dataTextField || TEXT;
options.dataValueField = options.dataValueField || VALUE;
}
}
if (options.adaptiveMode === "auto") {
that.largeMQL = kendo.mediaQuery("large");
that.mediumMQL = kendo.mediaQuery("medium");
that.smallMQL = kendo.mediaQuery("small");
}
that._bindLoader();
that._listSize = kendo.cssProperties.getValidClass({
widget: "List",
propName: "size",
value: options.size
});
that._filterHeader();
that.list = $(LIST_EL).addClass(that._listSize);
id = element.attr(ID);
if (!id) {
id = kendo.guid();
}
that.list.attr(ID, id + LIST_SUFFIX);
if (options.columns && options.columns.length) {
that.list.removeClass(LIST).addClass(DATA_TABLE);
that.list.removeClass(that._listSize);
that._columnsHeader();
}
that._header();
that._noData();
that._footer();
that._accessors();
that._initValue();
},
options: {
valuePrimitive: false,
footerTemplate: "",
headerTemplate: "",
noDataTemplate: true,
size: undefined,
messages: {
"noData": "No data found.",
"clear": "clear",
"filterInputPlaceholder": "Filter"
},
adaptiveMode: "none"
},
_getUlElement: function() {
const that = this;
const ul = that.list.find(`.${LIST_UL}, .${TABLE_LIST}`).first();
return ul;
},
_isTableVariant: function() {
return this.options.columns && this.options.columns.length;
},
_getFixedGroupHeaderSelector: function() {
return this._isTableVariant() ? FIXED_GROUP_TABLE_HEADER : FIXED_GROUP_HEADER;
},
setOptions: function(options) {
Widget.fn.setOptions.call(this, options);
if (options && options.enable !== undefined) {
options.enabled = options.enable;
}
if (options.columns && options.columns.length) {
this._columnsHeader();
}
this._header();
this._noData();
this._footer();
this._renderFooter();
this._renderNoData();
if (options.label && this._inputLabel) {
this.label.setOptions(options.label);
} else if (options.label === false) {
this.label._unwrapFloating();
this._inputLabel.remove();
delete this._inputLabel;
} else if (options.label) {
this._label();
}
},
_bindLoader: function() {
const that = this;
that._initLoader = require_dropdowns_loader.initLoader.bind(that);
that._initLoader();
},
focus: function() {
this._focused.trigger(FOCUS);
},
readonly: function(readonly) {
this._editable({
readonly: readonly === undefined ? true : readonly,
disable: false
});
if (this.label && this.label.floatingLabel) {
this.label.floatingLabel.readonly(readonly === undefined ? true : readonly);
}
},
enable: function(enable) {
this._editable({
readonly: false,
disable: !(enable = enable === undefined ? true : enable)
});
if (this.label && this.label.floatingLabel) {
this.label.floatingLabel.enable(enable = enable === undefined ? true : enable);
}
},
_label: function() {
var that = this;
var options = that.options;
var labelOptions = $.isPlainObject(options.label) ? options.label : { content: options.label };
that.label = new kendo.ui.Label(null, $.extend({}, labelOptions, {
widget: that,
floatCheck: that._floatCheck.bind(that)
}));
that._inputLabel = that.label.element;
that._refreshFloatingLabel();
},
_floatCheck: function() {
if (this.listView) {
var hasValue = this.value() || (this.text ? this.text() : false);
return !hasValue && !this.popup.visible();
}
return true;
},
_refreshFloatingLabel: function() {
var that = this;
if (that.label && that.label.floatingLabel) {
that.label.floatingLabel.refresh();
}
},
_header: function() {
var list = this;
var header = $(list.header);
var template = list.options.headerTemplate;
kendo.destroy(header);
header.remove();
if (!template) {
list.header = null;
return;
}
var headerTemplate = typeof template !== "function" ? kendo.template(template) : template;
header = $(headerTemplate({}));
list.header = header[0] ? header : null;
if (list.list.parent.length > 0) {
list.list.before(header);
}
},
_filterHeader: function() {
this.filterTemplate = "<div class=\"k-list-filter\">" + "<span class=\"k-searchbox k-input\" type=\"text\" autocomplete=\"off\">" + kendo.ui.icon({
icon: "search",
iconClass: "k-input-icon"
}) + "</span>" + "</div>";
this.actionSheetFilterTemplate = `<div class="k-actionsheet-titlebar-group k-actionsheet-filter">${this.filterTemplate}</div>`;
if (this._isFilterEnabled()) {
this.filterInput = $("<input class=\"k-input-inner\" type=\"text\" />").attr({
placeholder: this.element.attr("placeholder") || this.options.messages.filterInputPlaceholder,
title: this.options.filterTitle || this.element.attr("title"),
role: "searchbox",
"aria-label": this.options.filterTitle,
"aria-haspopup": "listbox",
"aria-autocomplete": "list"
});
}
},
_columnsHeader: function() {
var list = this;
var $header;
var columnsHeader = $(list.columnsHeader);
kendo.destroy(columnsHeader);
columnsHeader.remove();
var header = "<div class='k-table-header'><div class='k-table-header-wrap'><table class='k-table' role='presentation'>";
var colGroup = "<colgroup>";
var row = "<tr class='k-table-row'>";
for (var idx = 0; idx < this.options.columns.length; idx++) {
var currentColumn = this.options.columns[idx];
var title = currentColumn.title || currentColumn.field || "";
var titleFunc = () => title;
var template = currentColumn.headerTemplate || titleFunc;
var columnsHeaderTemplate = typeof template !== "function" ? kendo.template(template) : template;
var currentWidth = currentColumn.width;
var currentWidthInt = parseInt(currentWidth, 10);
var widthStyle = "";
if (currentWidth && !isNaN(currentWidthInt)) {
widthStyle += `${kendo.attr("style-width")}="${currentWidthInt}${percentageUnitsRegex.test(currentWidth) ? "%" : "px"}"`;
}
colGroup += "<col " + widthStyle + "/>";
row += "<th class='k-table-th'>";
row += columnsHeaderTemplate(currentColumn);
row += "</th>";
}
colGroup += "</colgroup>";
row += "</tr>";
header += colGroup;
header += "<thead class='k-table-thead'>";
header += row;
header += "</thead></table></div></div>";
$header = $(header);
kendo.applyStylesFromKendoAttributes($header, ["width"]);
list.columnsHeader = columnsHeader = $header;
list.list.prepend(columnsHeader);
},
_noData: function() {
var list = this;
var noData = $(list.noData);
var template = list.options.noDataTemplate === true ? () => htmlEncode(list.options.messages.noData) : list.options.noDataTemplate;
kendo.destroy(noData);
noData.remove();
if (!template) {
list.noData = null;
return;
}
list.noData = $(NO_DATA_EL).attr(ARIA_LIVE, "polite").hide().appendTo(list.list);
list.noDataTemplate = typeof template !== "function" ? kendo.template(template) : template;
},
_footer: function() {
var list = this;
var footer = $(list.footer);
var template = list.options.footerTemplate;
var footerEl = this.options.columns && this.options.columns.length ? TABLE_FOOTER_EL : LIST_FOOTER_EL;
kendo.destroy(footer);
footer.remove();
if (!template) {
list.footer = null;
return;
}
list.footer = $(footerEl).appendTo(list.list);
list.footerTemplate = typeof template !== "function" ? kendo.template(template) : template;
},
_listOptions: function(options) {
var that = this;
var currentOptions = that.options;
var virtual = currentOptions.virtual;
var changeEventOption = { change: that._listChange.bind(that) };
var listBoundHandler = that._listBound.bind(that);
var focusedElm = that._focused;
var inputId = that.element.attr("id");
var labelElm = $("label[for=\"" + that.element.attr("id") + "\"]");
var labelledBy = focusedElm.attr(ARIA_LABELLEDBY);
if (!labelledBy && labelElm.length) {
labelledBy = labelElm.attr("id") || that._generateLabelId(labelElm, inputId || kendo.guid());
}
virtual = typeof virtual === "object" ? virtual : {};
options = $.extend({
autoBind: false,
selectable: true,
dataSource: that.dataSource,
click: that._click.bind(that),
activate: that._activateItem.bind(that),
columns: currentOptions.columns,
deactivate: that._deactivateItem.bind(that),
dataBinding: function() {
that.trigger(DATA_BINDING);
},
dataBound: listBoundHandler,
height: currentOptions.height,
dataValueField: currentOptions.dataValueField,
dataTextField: currentOptions.dataTextField,
groupTemplate: currentOptions.groupTemplate,
fixedGroupTemplate: currentOptions.fixedGroupTemplate,
fixedGroupHeader: currentOptions.fixedGroupHeader,
template: currentOptions.template,
ariaLabel: focusedElm.attr(ARIA_LABEL),
ariaLabelledBy: labelledBy,
ariaLive: !that._isFilterEnabled() ? "off" : "polite",
listSize: that._listSize
}, options, virtual, changeEventOption);
if (!options.template) {
options.template = (data) => htmlEncode(kendo.getter(options.dataTextField)(data));
}
return options;
},
_initList: function(opts) {
const that = this;
const skipValueUpdate = opts && opts.skipValueUpdate;
let listId = that.list.attr(ID);
let id = listId ? listId.replace(LIST_SUFFIX, "") : kendo.guid();
const listOptions = that._listOptions({
selectedItemChange: that._listChange && that._listChange.bind(that),
id: id + LISTBOX_SUFFIX
});
if (!that.options.virtual) {
that.listView = new kendo.ui.StaticList(that.list, listOptions);
} else {
that.listView = new kendo.ui.VirtualList(that.list, Object.assign(listOptions, { height: that._hasActionSheet() ? 362 : that.options.height }));
that.list.addClass("k-virtual-list");
}
that.listView.bind("listBound", that._listBound.bind(that));
if (!skipValueUpdate) {
that._setListValue();
}
},
_setListValue: function(value) {
value = value || this.options.value;
if (value !== undefined) {
this.listView.value(value).done(this._updateSelectionState.bind(this));
}
},
_updateSelectionState: $.noop,
_listMousedown: function(e) {
if (!this.filterInput || this.filterInput[0] !== e.target) {
e.preventDefault();
}
},
_isFilterEnabled: function() {
var filter = this.options.filter;
return filter && filter !== "none";
},
_hideClear: function() {
var list = this;
if (list._clear) {
list._clear.addClass(HIDDENCLASS);
}
},
_showClear: function() {
if (this._clear) {
this._clear.removeClass(HIDDENCLASS);
}
},
_clearValue: function() {
this._clearText();
this._accessor("");
this.listView.value([]);
if (this._isSelect) {
this._customOption = undefined;
}
if (this._isFilterEnabled() && !this.options.enforceMinLength) {
this._filter({
word: "",
open: false
});
if (this.options.highlightFirst) {
this.listView.focus(0);
}
}
this._change();
},
_clearText: function() {
this.text("");
},
_clearFilter: function() {
if (!this.options.virtual) {
this.listView.bound(false);
}
this._filterSource();
},
_filterSource: function(filter, force) {
var that = this;
var options = that.options;
var isMultiColumnFiltering = options.filterFields && filter && filter.logic && filter.filters && filter.filters.length;
var dataSource = that.dataSource;
var expression = extend({}, dataSource.filter() || {});
var resetPageSettings = filter || expression.filters && expression.filters.length && !filter;
var removed = removeFiltersForField(expression, options.dataTextField);
this._clearFilterExpressions(expression);
if ((filter || removed) && that.trigger("filtering", { filter })) {
return $.Deferred().reject().promise();
}
var newExpression = {
filters: [],
logic: "and"
};
if (isMultiColumnFiltering) {
newExpression.filters.push(filter);
} else {
this._pushFilterExpression(newExpression, filter);
}
if (isValidFilterExpr(expression)) {
if (newExpression.logic === expression.logic) {
newExpression.filters = newExpression.filters.concat(expression.filters);
} else {
newExpression.filters.push(expression);
}
}
if (that._cascading) {
this.listView.setDSFilter(newExpression);
}
var dataSourceState = extend({}, {
page: resetPageSettings ? 1 : dataSource.page(),
pageSize: resetPageSettings ? dataSource.options.pageSize : dataSource.pageSize(),
sort: dataSource.sort(),
filter: dataSource.filter(),
group: dataSource.group(),
aggregate: dataSource.aggregate()
}, { filter: newExpression });
return dataSource[force ? "read" : "query"](dataSource._mergeState(dataSourceState));
},
_pushFilterExpression: function(newExpression, filter) {
if (isValidFilterExpr(filter) && filter.value !== "") {
newExpression.filters.push(filter);
}
},
_clearFilterExpressions: function(expression) {
if (!expression.filters) {
return;
}
var filtersToRemove;
for (var i = 0; i < expression.filters.length; i++) {
if ("fromFilter" in expression.filters[i]) {
filtersToRemove = i;
}
}
if (!isNaN(filtersToRemove)) {
expression.filters.splice(filtersToRemove, 1);
}
},
_renderNoData: function() {
var list = this;
var noData = list.noData;
if (!noData) {
return;
}
noData.html(list.noDataTemplate({ instance: list }));
},
_toggleNoData: function(show) {
$(this.noData).toggle(show);
},
_toggleHeader: function(show) {
var groupHeader = this.listView.content.prev(this._getFixedGroupHeaderSelector());
if (this.options.fixedGroupHeader === false) {
show = false;
}
groupHeader.toggle(show);
},
_renderFooter: function() {
var list = this, footer = list.footer ? this.options.columns && this.options.columns.length ? list.footer.children().first() : list.footer : null;
if (!footer) {
return;
}
footer.html(list.footerTemplate({ instance: list }));
},
_allowOpening: function() {
return this.options.noDataTemplate || this.dataSource.flatView().length;
},
_initValue: function() {
var that = this, value = that.options.value;
if (value !== null) {
that.element.val(value);
} else {
value = that._accessor();
that.options.value = value;
}
that._old = value;
},
_ignoreCase: function() {
var that = this, model = that.dataSource.reader.model, field;
if (model && model.fields) {
field = model.fields[that.options.dataTextField];
if (field && field.type && field.type !== "string") {
that.options.ignoreCase = false;
}
}
},
_focus: function(candidate) {
return this.listView.focus(candidate);
},
_filter: function(options) {
var that = this;
var widgetOptions = that.options;
var word = options.word;
var filterFields = widgetOptions.filterFields;
var field = widgetOptions.dataTextField;
var expression;
if (filterFields && filterFields.length) {
expression = {
logic: "or",
filters: [],
fromFilter: true
};
for (var i = 0; i < filterFields.length; i++) {
this._pushFilterExpression(expression, that._buildExpression(word, filterFields[i]));
}
} else {
expression = that._buildExpression(word, field);
}
that._open = options.open;
that._filterSource(expression);
},
_buildExpression: function(value, field) {
var that = this;
var widgetOptions = that.options;
var ignoreCase = widgetOptions.ignoreCase;
var accentFoldingFiltering = that.dataSource.options.accentFoldingFiltering;
return {
value: ignoreCase ? accentFoldingFiltering ? value.toLocaleLowerCase(accentFoldingFiltering) : value.toLowerCase() : value,
field,
operator: widgetOptions.filter,
ignoreCase
};
},
_clearButton: function() {
var list = this;
var clearTitle = list.options.messages.clear;
if (!list._clear) {
list._clear = $(`<span unselectable="on" class="k-clear-value" title="${clearTitle}">${kendo.ui.icon("x")}</span>`).attr({
"role": "button",
"tabIndex": -1
});
}
if (!list.options.clearButton) {
list._clear.remove();
}
this._hideClear();
},
search: function(word) {
var options = this.options;
word = typeof word === "string" ? word : this._inputValue();
clearTimeout(this._typingTimeout);
if (!options.enforceMinLength && !word.length || word.length >= options.minLength) {
this._state = "filter";
if (this.listView) {
this.listView._emptySearch = !kendo.trim(word).length;
}
if (!this._isFilterEnabled()) {
this._searchByWord(word);
} else {
this._filter({
word,
open: true
});
}
}
},
current: function(candidate) {
return this._focus(candidate);
},
items: function() {
const ulElement = this._getUlElement();
if (!ulElement.length) {
return $();
}
return ulElement.children();
},
destroy: function() {
var that = this;
var ns = that.ns;
Widget.fn.destroy.call(that);
that._unbindDataSource();
if (that.largeMQL || that.mediumMQL || that.smallMQL) {
that.largeMQL.destroy();
that.mediumMQL.destroy();
that.smallMQL.destroy();
}
that.listView.destroy();
that.list.off(ns);
that.popup.destroy();
if (that._form) {
that._form.off("reset", that._resetHandler);
}
if (that.label) {
that.label.destroy();
}
},
dataItem: function(index) {
var that = this;
if (index === undefined) {
return that.listView.selectedDataItems()[0];
}
if (typeof index !== "number") {
if (that.options.virtual) {
return that.dataSource.getByUid($(index).data("uid"));
}
index = $(that.items()).index(index);
}
return that.dataSource.flatView()[index];
},
_activateItem: function() {
var current = this.listView.focus();
if (current && this.popup.visible()) {
this._focused.add(this.filterInput).attr(ARIA_ACTIVEDESCENDANT, current.attr("id"));
}
},
_deactivateItem: function() {
this._focused.add(this.filterInput).removeAttr(ARIA_ACTIVEDESCENDANT);
},
_accessors: function() {
var that = this;
var element = that.element;
var options = that.options;
var getter = kendo.getter;
var textField = element.attr(kendo.attr("text-field"));
var valueField = element.attr(kendo.attr("value-field"));
if (!options.dataTextField && textField) {
options.dataTextField = textField;
}
if (!options.dataValueField && valueField) {
options.dataValueField = valueField;
}
that._text = getter(options.dataTextField);
that._value = getter(options.dataValueField);
},
_aria: function(id) {
var that = this, options = that.options, element = that._focused, autocomplete;
if (options.suggest !== undefined) {
if (options.filter === "none") {
if (options.suggest === true) {
autocomplete = "inline";
} else {
autocomplete = "none";
}
} else {
if (options.suggest === true) {
autocomplete = "both";
} else {
autocomplete = "list";
}
}
element.attr(ARIA_AUTOCOMPLETE, autocomplete);
}
const ul = that.list.find(`.${LIST_UL}, .${TABLE_LIST}`).first();
const allUls = that.list.find(`.${LIST_UL}, .${TABLE_LIST}`);
const ariaLiveValue = !that._isFilterEnabled() ? "off" : "polite";
if (ul.length) {
id = id ? id + " " + ul[0].id : ul[0].id;
element.attr({ "aria-controls": id });
if (that.filterInput && that.filterInput.length > 0) {
that.filterInput.attr(ARIA_CONTROLS, id);
}
allUls.attr(ARIA_LIVE, ariaLiveValue);
} else if (options.virtual && that.listView && that.listView.options && typeof that.listView.options.id === "string") {
var listViewId = that.listView.options.id;
id = id ? id + " " + listViewId : listViewId;
element.attr({ "aria-controls": id });
if (that.filterInput && that.filterInput.length > 0) {
that.filterInput.attr(ARIA_CONTROLS, id);
}
}
that._ariaLabel(that._focused);
},
_blur: function() {
var that = this;
that._change();
that.close();
that._userTriggered = false;
},
_isValueChanged: function(value) {
return value !== unifyType(this._old, typeof value);
},
_change: function() {
var that = this;
var index = that.selectedIndex;
var optionValue = that.options.value;
var value = that.value();
var trigger;
if (that._isSelect && !that.listView.bound() && optionValue) {
value = optionValue;
}
if (that._isValueChanged(value)) {
trigger = true;
} else if (that._valueBeforeCascade !== undefined && that._isValueChanged(that._valueBeforeCascade) && that._userTriggered) {
trigger = true;
} else if (index !== undefined && index !== that._oldIndex && !that.listView.isFiltered() && !that.options.virtual) {
trigger = true;
}
if (trigger) {
if (that._old === null || that._old === "" || value === "") {
that._valueBeforeCascade = that._old = value;
} else {
if (that.dataItem()) {
that._valueBeforeCascade = that._old = that.options.dataValueField ? that.dataItem()[that.options.dataValueField] : that.dataItem();
} else {
that._valueBeforeCascade = that._old = null;
}
}
that._oldIndex = index;
if (!that._typing) {
that.element.trigger(CHANGE);
}
that.trigger(CHANGE);
}
that.typing = false;
},
_data: function() {
return this.dataSource.view();
},
_enable: function() {
var that = this, options = that.options, disabled = that.element.is("[disabled]");
if (options.enable !== undefined) {
options.enabled = options.enable;
}
if (!options.enabled || disabled) {
that.enable(false);
} else {
that.readonly(kendo.isPresent(options.readonly) ? options.readonly : that.element.is("[readonly]"));
}
},
_dataValue: function(dataItem) {
var value = this._value(dataItem);
if (value === undefined) {
value = this._text(dataItem);
}
return value;
},
_offsetHeight: function() {
var offsetHeight = 0;
var siblings = this.listView.content.parent().prevAll(":visible");
siblings.each(function() {
var element = $(this);
offsetHeight += outerHeight(element, true);
});
return offsetHeight;
},
_height: function(length) {
var that = this;
var list = that.list;
var height = that.options.height;
var visible = that.popup.visible();
var isMccb = this.options.columns && this.options.columns.length;
var offsetTop, popups;
if (length || that.options.noDataTemplate) {
popups = list.parent().add(list.closest(".k-animation-container").add(list.closest(".k-child-animation-container"))).show();
if (!list.parent().is(":visible")) {
popups.hide();
return;
}
height = that.listView.content[0].scrollHeight > height ? height : "auto";
popups.height(height);
if (height !== "auto") {
offsetTop = that._offsetHeight();
height = height - offsetTop;
if (isMccb) {
height = height - (outerHeight($(that.footer)) || 0) - (outerHeight($(that.columnsHeader)) || 0);
}
}
if (isMccb) {
that.listView.content.outerHeight(height);
} else {
that.listView.content.parent().outerHeight(height);
}
if (!visible) {
list.parent().hide();
}
}
return height;
},
_openHandler: function(e) {
var current;
this._adjustListWidth();
if (this.trigger(OPEN)) {
e.preventDefault();
} else {
this._focused.attr(ARIA_EXPANDED, true);
const ulElements = this.list.find(`.${LIST_UL}, .${TABLE_LIST}`);
ulElements.attr(ARIA_HIDDEN, false);
current = this.listView.focus();
if (current) {
this._focused.add(this.filterInput).attr(ARIA_ACTIVEDESCENDANT, current.attr("id"));
}
}
},
_adjustListWidth: function() {
var that = this, list = that.list.parent(), width = list[0].style.width, wrapper = that.wrapper, computedStyle, computedWidth;
if (!list.data(WIDTH) && width || that._hasActionSheet()) {
return;
}
computedStyle = window.getComputedStyle ? window.getComputedStyle(wrapper[0], null) : 0;
computedWidth = parseFloat(computedStyle && computedStyle.width) || outerWidth(wrapper);
if (computedStyle && browser.msie) {
computedWidth += parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight) + parseFloat(computedStyle.borderLeftWidth) + parseFloat(computedStyle.borderRightWidth);
}
if (list.css("box-sizing") !== "border-box") {
width = computedWidth - (outerWidth(list) - list.width());
} else {
width = computedWidth;
}
list.css({
fontFamily: wrapper.css("font-family"),
width: that.options.autoWidth ? "auto" : width,
minWidth: width,
whiteSpace: that.options.autoWidth ? "nowrap" : "normal"
}).data(WIDTH, width);
return true;
},
_closeHandler: function(e) {
if (e.closeButton) {
this._onCloseButtonPressed();
}
if (this.trigger(CLOSE)) {
e.preventDefault();
} else {
this._focused.attr(ARIA_EXPANDED, false);
const ulElements = this.list.find(`.${LIST_UL}, .${TABLE_LIST}`);
ulElements.attr(ARIA_HIDDEN, true);
this._focused.add(this.filterInput).removeAttr(ARIA_ACTIVEDESCENDANT);
}
},
_focusItem: function() {
var listView = this.listView;
var noFocusedItem = !listView.focus();
var index = last(listView.select());
if (index === undefined && this.options.highlightFirst && noFocusedItem) {
index = 0;
}
if (index !== undefined) {
listView.focus(index);
} else if (noFocusedItem) {
listView.scrollToIndex(0);
}
},
_calculateGroupPadding: function(height) {
var groupHeader = this.listView.content.prev(this._getFixedGroupHeaderSelector());
var padding = 0;
var direction = "right";
var li;
if (groupHeader[0] && groupHeader[0].style.display !== "none") {
var ulElements = this.list.find(`.${LIST_UL}, .${TABLE_LIST}`);
if (ulElements.length > 1) {
ulElements.each(function() {
var firstChild = $(this).children(ITEMSELECTOR).first();
if (firstChild.length) {
li = firstChild;
return false;
}
});
} else {
li = this._getUlElement().children(ITEMSELECTOR).first();
}
if (!li || !li.length) {
return;
}
if (height !== "auto") {
padding = kendo.support.scrollbar();
}
if (this.element.parents(".k-rtl").length) {
direction = "left";
}
padding += parseFloat(li.css("border-" + direction + "-width"), 10) + parseFloat(li.children(GROUP_LABEL).css("padding-" + direction), 10);
groupHeader.css("padding-" + direction, padding);
}
},
_calculatePopupHeight: function(force) {
var height = this._height(this.dataSource.flatView().length || force);
this._calculateGroupPadding(height);
this._calculateColumnsHeaderPadding(height);
},
_calculateColumnsHeaderPadding: function(height) {
if (this.options.columns && this.options.columns.length) {
var list = this;
var isRtl = support.isRtl(list.wrapper);
var scrollbar = kendo.support.scrollbar();
list.columnsHeader.css(isRtl ? "padding-left" : "padding-right", height !== "auto" ? scrollbar : 0);
}
},
_refreshScroll: function() {
var listView = this.listView;
var enableYScroll = listView.element.height() > listView.content.height();
if (this.options.autoWidth) {
listView.content.css({
overflowX: "hidden",
overflowY: enableYScroll ? "scroll" : "auto"
});
}
},
_hasActionSheet: function() {
return this.options.adaptiveMode === "auto" && (this.mediumMQL.mediaQueryList.matches || this.smallMQL.mediaQueryList.matches);
},
_resizePopup: function(force) {
if (this.options.virtual || this._hasActionSheet()) {
return;
}
if (!this.popup.element.is(":visible")) {
this.popup.one("open", (function(force) {
return (function(e) {
if (!e.isDefaultPrevented()) {
this._calculatePopupHeight(force);
}
}).bind(this);
}).call(this, force));
this.popup.one(ACTIVATE, this._refreshScroll.bind(this));
} else {
this._calculatePopupHeight(force);
}
},
_popup: function() {
var list = this;
list.list.wrap("<div>");
if (list.options.adaptiveMode === "auto") {
list.largeMQL.onEnter(list._createPopup.bind(list));
list.mediumMQL.onEnter(list._createActionSheet.bind(list));
list.smallMQL.onEnter(() => {
if (!list.popup || !list.popup.fullscreen) {
list._createActionSheet();
}
list.popup.fullscreen(true);
});
} else {
list._createPopup();
}
},
_addFilterHeader: function() {
var list = this;
if (list._isFilterEnabled()) {
list._filterHeader();
if (list.options.adaptiveMode === "auto" && (list.mediumMQL.mediaQueryList.matches || list.smallMQL.mediaQueryList.matches)) {
list.popup.element.find(ACTIONSHEET_TITLEBAR).append($(list.actionSheetFilterTemplate)).find(".k-searchbox").append(list.filterInput);
list._enable();
} else if (list.options.popupFilter) {
list.list.parent().prepend($(list.filterTemplate)).find(".k-searchbox").append(list.filterInput);
}
list._enable();
}
},
_createPopup: function() {
var list = this;
if (list._unboundClick) {
if (list.input) {
list.input.off(CLICK);
} else if (list.element) {
list.element.off(CLICK);
}
list._unboundClick = false;
}
if (list.popup) {
list._cachedFilterValue = list.filterInput ? list.filterInput.val() : null;
list.popup.destroy();
if (list.popup.wrapper) {
list.popup.wrapper.remove();
}
list._removeFilterHeader();
list._removeStaticHeader();
}
list.popup = new ui.Popup(list.list.parent().addClass("k-list-container"), extend({}, list.options.popup, {
anchor: list.wrapper,
open: list._openHandler.bind(list),
close: list._closeHandler.bind(list),
animation: list.options.animation,
isRtl: support.isRtl(list.wrapper),
autosize: list.options.autoWidth,
autowidth: list.options.autoWidth,
activate: () => {
this._refreshFloatingLabel();
},
deactivate: () => {
this._refreshFloatingLabel();
}
}));
list._postCreatePopup();
},
_onActionSheetCreate: $.noop,
_onCloseButtonPressed: $.noop,
_createActionSheet: function() {
var list = this;
if (list.popup) {
list._cachedFilterValue = list.filterInput ? list.filterInput.val() : null;
list.popup.destroy();
if (list.popup.wrapper) {
list.popup.wrapper.remove();
}
list._removeFilterHeader();
list._removeStaticHeader();
list.list.add(list.list.parent()).css({
width: "",
height: "",
minWidth: ""
});
}
list.popup = new ui.ActionSheet(list.list.parent(), {
headerTemplate: (options) => `<div class="k-text-center k-actionsheet-titlebar" >` + "<div class=\"k-actionsheet-titlebar-group k-hbox\">" + `<div class="k-actionsheet-title">` + (list.options.adaptiveTitle || list.options.label ? `<div class="k-text-center">${list.options.adaptiveTitle || list.options.label}</div>` : "") + (list.options.adaptiveSubtitle ? `<div class="k-actionsheet-subtitle k-text-center">${list.options.adaptiveSubtitle || ""}</div>` : "") + "</div>" + (options.closeButton ? "<div class=\"k-actionsheet-actions\">" + kendo.html.renderButton(`<button tabindex="-1" ${kendo.attr("ref-actionsheet-close-button")}></button>`, {
icon: "check",
fillMode: "flat",
size: "large",
themeColor: "primary"
}) + "</div>" : "") + "</div>" + "</div>",
open: list._openHandler.bind(list),
close: list._closeHandler.bind(list),
focusOnActivate: false,
adaptive: true,
appendTo: list.options.popup && list.options.popup.appendTo || document.body,
closeButton: true,
fullscreen: list.smallMQL.mediaQueryList.matches,
activate: () => {
this._refreshFloatingLabel();
},
deactivate: () => {
this._refreshFloatingLabel();
},
popup: extend({}, list.options.popup, { autosize: list.options.autoWidth })
});
list._postCreatePopup();
list._onActionSheetCreate();
},
_removeFilterHeader: function() {
if (this.filterInput) {
this.filterInput.off(this.ns).closest(".k-list-filter").remove();
this.filterInput = null;
}
},
_removeStaticHeader: function() {
this.listView.header.remove();
},
_postCreatePopup: function() {
var list = this;
var listViewValue;
list._addFilterHeader();
if (list.filterInput && list._cachedFilterValue) {
list.filterInput.val(list._cachedFilterValue);
}
list.popup.element.prepend(list.header).on(MOUSEDOWN + this.ns, this._listMousedown.bind(this));
if (list.listView) {
listViewValue = list.listView.value();
if (list.listView._clean) {
list.listView._clean();
}
if (list.tagList && list.options.virtual) {
list.tagList.empty();
}
list.listView.destroy();
if (list.listView.content) {
this._getUlElement().unwrap();
}
list._initList({ skipValueUpdate: true });
list.listView.value(listViewValue);
}
},
_toggleHover: function(e) {
$(e.currentTarget).toggleClass(HOVER, e.type === MOUSEENTER);
},
_toggle: function(open, preventFocus) {
var that = this;
var touchEnabled = support.mobileOS && (support.touch || support.MSPointers || support.pointers);
open = open !== undefined ? open : !that.popup.visible();
if (!preventFocus && !touchEnabled && that._focused[0] !== activeElement()) {
that._prevent = true;
that._focused.trigger(FOCUS);
that._prevent = false;
}
that[open ? OPEN : CLOSE]();
},
_triggerCascade: function() {
var that = this;
if (!that._cascadeTriggered || that.value() !== unifyType(that._cascadedValue, typeof that.value())) {
that._cascadedValue = that.value();
that._cascadeTriggered = true;
that.trigger(CASCADE, { userTriggered: that._userTriggered });
}
},
_triggerChange: function() {
if (this._valueBeforeCascade !== this.value()) {
this.trigger(CHANGE);
}
},
_unbindDataSource: function() {
var that = this;
that.dataSource.unbind(REQUESTSTART, that._requestStartHandler).unbind(REQUESTEND, that._requestEndHandler).unbind("error", that._errorHandler);
},
requireValueMapper: function(options, value) {
var hasValue = (options.value instanceof Array ? options.value.length : options.value) || (value instanceof Array ? value.length : value);
if (hasValue && options.virtual && typeof options.virtual.valueMapper !== "function") {
throw new Error("ValueMapper is not provided while the value is being set. See http://docs.telerik.com/kendo-ui/controls/editors/combobox/virtualization#the-valuemapper-function");
}
}
});
Object.defineProperty(List.prototype, "ul", {
get: function() {
return this._getUlElement();
},
configurable: true
});
function unifyType(value, type) {
if (value !== undefined && value !== "" && value !== null) {
if (type === "boolean") {
if (typeof value !== "boolean") {
value = value.toString().toLowerCase() === "true";
}
value = Boolean(value);
} else if (type === "number") {
value = Number(value);
} else if (type === "string") {
value = value.toString();
}
}
return value;
}
extend(List, {
inArray: function(node, parentNode) {
var idx, length, siblings = parentNode.children;
if (!node || node.parentNode !== parentNode) {
return -1;
}
for (idx = 0, length = siblings.length; idx < length; idx++) {
if (node === siblings[idx]) {
return idx;
}
}
return -1;
},
unifyType
});
kendo.ui.List = List;
ui.Select = List.extend({
init: function(element, options) {
List.fn.init.call(this, element, options);
this._initial = this.element.val();
},
setDataSource: function(dataSource) {
var that = this;
var parent;
that.options.dataSource = dataSource;
that._dataSource();
if (that.listView.bound()) {
that._initialIndex = null;
that.listView._current = null;
}
that.listView.setDataSource(that.dataSource);
if (that.options.autoBind) {
that.dataSource.fetch();
}
parent = that._parentWidget();
if (parent) {
that._cascadeSelect(parent);
}
},
close: function() {
this.popup.close();
},
select: function(candidate) {
var that = this;
if (candidate === undefined) {
return that.selectedIndex;
} else {
return that._select(candidate).done(function() {
that._cascadeValue = that._old = that._accessor();
that._oldIndex = that.selectedIndex;
that._refreshFloatingLabel();
});
}
},
_accessor: function(value, idx) {
return this[this._isSelect ? "_accessorSelect" : "_accessorInput"](value, idx);
},
_accessorInput: function(value) {
var element = this.element[0];
if (value === undefined) {
return element.value;
} else {
if (value === null) {
value = "";
}
element.value = value;
}
},
_accessorSelect: function(value, idx) {
var element = this.element[0];
var hasValue;
if (value === undefined) {
return getSelectedOption(element).value || "";
}
getSelectedOption(element).selected = false;
if (idx === undefined) {
idx = -1;
}
hasValue = value !== null && value !== "";
if (hasValue && idx == -1) {
this._custom(value);
} else {
if (value) {
element.value = value;
} else {
element.selectedIndex = idx;
}
}
},
_syncValueAndText: function() {
return true;
},
_custom: function(value) {
var that = this;
var element = that.element;
var custom = that._customOption;
if (!custom) {
custom = $("<option/>");
that._customOption = custom;
element.append(custom);
}
custom.text(value);
custom[0].selected = true;
},
_dataSource: function() {
var that = this, element = that.element, options = that.options, dataSource = options.dataSource || {}, idx;
dataSource = Array.isArray(dataSource) ? { data: dataSource } : dataSource;
if (that._isSelect) {
idx = element[0].selectedIndex;
if (idx > -1) {
options.index = idx;
}
dataSource.select = element;
dataSource.fields = [{ field: options.dataTextField }, { field: options.dataValueField }];
}
if (that.dataSource) {
that._unbindDataSource();
} else {
that._requestStartHandler = that._showBusy;
that._requestEndHandler = that._hideBusy;
that._errorHandler = function() {
that._hideBusy();
};
}
that.dataSource = kendo.data.DataSource.create(dataSource).bind(REQUESTSTART, that._requestStartHandler).bind(REQUESTEND, that._requestEndHandler).bind("error", that._errorHandler);
},
_firstItem: function() {
this.listView.focusFirst();
},
_lastItem: function() {
this.listView.focusLast();
},
_nextItem: function() {
return this.listView.focusNext();
},
_prevItem: function() {
return this.listView.focusPrev();
},
_getNormalizedDataItem: function(candidate) {
var that = this, listView = that.listView, isIndex = typeof candidate === "number", hasOptionLabel = that.optionLabel && that.optionLabel.length, index;
if (isIndex) {
index = hasOptionLabel ? --candidate : candidate;
} else {
index = listView.getElementIndex(candidate);
}
return listView.dataItemByIndex(index);
},
_getNormalizedSelectCandidate: function(candidate) {
var that = this, hasOptionLabel = that.optionLabel && that.optionLabel.length, isIndex = typeof candidate === "number", normalizedCandidate = candidate;
if (hasOptionLabel && isIndex) {
normalizedCandidate++;
}
return normalizedCandidate;
},
_move: function(e) {
var that = this;
var listView = that.listView;
var key = e.keyCode;
var down = key === keys.DOWN;
var isVirtual = that.options.virtual;
var dataItem;
var pressed;
var current;
var moveIndex;
var selectCandidate;
if (key === keys.UP || down) {
if (e.altKey) {
that.toggle(down);
} else {
const ul = that.list.find(`.${LIST_UL}, .${TABLE_LIST}`);
if (!listView.bound() && (!ul.length || !ul[0].firstChild)) {
if (!that._fetch) {
that.dataSource.one(CHANGE, function() {
that._fetch = false;
that._move(e);
});
that._fetch = true;
that._filterSource();
}
e.preventDefault();
return true;
}
current = that._focus();
if (!that._fetch && (!current || current.hasClass(KSELECTED))) {
if (down) {
moveIndex = that._nextItem();
if (isVirtual && moveIndex <= 0 || !that._focus() && !moveIndex) {
that._lastItem();
}
} else {
moveIndex = that._prevItem();
if (isVirtual && moveIndex >= listView.dataSource.total() - 1 || !that._focus() && !moveIndex) {
that._firstItem();
}
}
}
selectCandidate = that._getNormalizedSelectCandidate(that._get(that._focus()) || moveIndex || 0);
that._select(selectCandidate, true).done(function() {
var done = function() {
if (!that.popup.visible()) {
that._blur();
}
if (that._cascadedValue === null) {
that._cascadedValue = that.value();
} else {
that._cascadedValue = that.dataItem() ? that.dataItem()[that.options.dataValueField] || that.dataItem() : null;
}
};
if (that.trigger(SELECT, {
dataItem: that._getNormalizedDataItem(selectCandidate),
item: that._focus()
})) {
that._select(current).done(done);
} else {
done();
}
});
}
e.preventDefault();
pressed = true;
} else if (key === keys.ENTER || key === keys.TAB) {
if (that.popup.visible()) {
e.preventDefault();
}
current = that._focus();
dataItem = that.dataItem();
if (!that.popup.visible() && (!dataItem || that.text() !== that._text(dataItem))) {
current = null;
}
var activeFilter = that.filterInput && that.filterInput[0] === activeElement();
var selection;
if (current) {
dataItem = listView.dataItemByIndex(listView.getElementIndex(current));
var shouldTrigger = true;
if (dataItem) {
shouldTrigger = that._value(dataItem) !== List.unifyType(that.value(), typeof that._value(dataItem));
}
if (shouldTrigger && that.trigger(SELECT, {
dataItem,
item: current
})) {
return;
}
selection = that._select(current);
} else if (that.input) {
if (that._syncValueAndText() || that._isSelect) {
that._accessor(that.input.val());
}
that.listView.value(that.input.val());
}
if (that._focusElement) {
that._focusElement(that.wrapper);
}
if (activeFilter && key === keys.TAB) {
that.wrapper.focusout();
} else {
if (selection && typeof selection.done === "function") {
selection.done(function() {
that._blur();
});
} else {
that._blur();
}
}
that.close();
pressed = true;
} else if (key === keys.ESC) {
if (that.popup.visible()) {
e.preventDefault();
e.stopPropagation();
}
that.close();
pressed = true;
} else if (that.popup.visible() && (key === keys.PAGEDOWN || key === keys.PAGEUP)) {
e.preventDefault();
var direction = key === keys.PAGEDOWN ? 1 : -1;
listView.scrollWith(direction * listView.screenHeight());
pressed = true;
}
return pressed;
},
_fetchData: function() {
var that = this;
var hasItems = !!that.dataSource.view().length;
if (that._request || that.options.cascadeFrom) {
return;
}
if (!that.listView.bound() && !that._fetch && !hasItems) {
that._fetch = true;
that.dataSource.fetch().done(function() {
that._fetch = false;
});
}
},
_options: function(data, optionLabel, value) {
var that = this, element = that.element, htmlElement = element[0], length = data.length, options = "", option, dataItem, dataText, dataValue, idx = 0;
if (optionLabel) {
options = optionLabel;
}
for (; idx < length; idx++) {
option = "<option";
dataItem = data[idx];
dataText = that._text(dataItem);
dataValue = that._value(dataItem);
if (dataValue !== undefined) {
dataValue += "";
if (dataValue.indexOf("\"") !== -1) {
dataValue = dataValue.replace(quotRegExp, """);
}
option += " value=\"" + dataValue + "\"";
}
option += ">";
if (dataText !== undefined) {
option += htmlEncode(dataText);
}
option += "</option>";
options += option;
}
element.html(options);
if (value !== undefined) {
htmlElement.value = value;
if (htmlElement.value && !value) {
htmlElement.selectedIndex = -1;
}
}
if (htmlElement.selectedIndex !== -1) {
option = getSelectedOption(htmlElement);
if (option) {
option.setAttribute(SELECTED, SELECTED);
}
}
},
_reset: function() {
var that = this, element = that.element, formId = element.attr("form"), form = formId ? $("#" + formId) : element.closest("form");
if (form[0]) {
that._resetHandler = function() {
setTimeout(function() {
if (that.options._removeDataItems) {
that.listView._dataItems = [];
}
that.value(that._initial);
if (that.options._shouldRefresh) {
that.text(that._initial);
that.refresh();
}
});
};
that._form = form.on("reset", that._resetHandler);
}
},
_parentWidget: function() {
var name = this.options.name;
if (!this.options.cascadeFrom) {
return;
}
var parentElement = $("#" + this.options.cascadeFrom);
var parent = parentElement.data("kendo" + name);
if (!parent) {
for (var i = 0; i < alternativeNames[name].length; i += 1) {
parent = parentElement.data("kendo" + alternativeNames[name][i]);
if (!!parent) {
break;
}
}
}
return parent;
},
_cascade: function() {
var that = this;
var options = that.options;
var cascade = options.cascadeFrom;
var parent;
if (cascade) {
parent = that._parentWidget();
if (!parent) {
return;
}
that._cascadeHandlerProxy = that._cascadeHandler.bind(that);
that._cascadeFilterRequests = [];
options.autoBind = false;
parent.bind("set", function() {
that.one("set", function(e) {
that._selectedValue = e.value || that._accessor();
});
});
parent.first(CASCADE, that._cascadeHandlerProxy);
if (parent.listView.bound()) {
that._toggleCascadeOnFocus();
that._cascadeSelect(parent);
} else {
parent.one(DAT