Skip to content

Commit

Permalink
split createLi into buildData and buildList functions. use current.da…
Browse files Browse the repository at this point in the history
…ta for changeAll instead of current.elements. (#2337)
caseyjhol committed Oct 14, 2019
1 parent 38e031a commit 09d11f5
Showing 1 changed file with 100 additions and 81 deletions.
181 changes: 100 additions & 81 deletions js/bootstrap-select.js
Original file line number Diff line number Diff line change
@@ -754,7 +754,7 @@
subtextElement,
iconElement;

textElement.innerHTML = options.label;
textElement.innerHTML = options.display;

if (options.icon) {
var whitespace = elementTemplates.whitespace.cloneNode(false);
@@ -912,6 +912,7 @@
}

this.$newElement = this.createDropdown();
this.buildData();
this.$element
.after(this.$newElement)
.prependTo(this.$newElement);
@@ -1000,7 +1001,7 @@
}

setTimeout(function () {
that.createLi();
that.buildList();
that.$element.trigger('loaded' + EVENT_KEY);
});
},
@@ -1431,13 +1432,11 @@
return updateIndex;
},

createLi: function () {
buildData: function () {
var that = this,
iconBase = this.options.iconBase,
optionSelector = ':not([hidden]):not([data-hidden="true"])',
mainElements = [],
mainData = [],
widestOptionLength = 0,
optID = 0,
startIndex = this.setPlaceholder() ? 1 : 0; // append the titleOption if necessary and skip the first option in the loop

@@ -1465,14 +1464,6 @@
config = config || {};
config.type = 'divider';

mainElements.push(
generateOption.li(
false,
classNames.DIVIDER,
(config.optID ? config.optID + 'div' : undefined)
)
);

mainData.push(config);
}

@@ -1493,6 +1484,8 @@

if (config.optID) optionClass = 'opt ' + optionClass;

config.optionClass = optionClass;
config.inlineStyle = inlineStyle;
config.text = option.textContent;

config.content = option.getAttribute('data-content');
@@ -1501,49 +1494,16 @@
config.icon = option.getAttribute('data-icon');
config.iconBase = iconBase;

var textElement = generateOption.text(config);
var liElement = generateOption.li(
generateOption.a(
textElement,
optionClass,
inlineStyle
),
'',
config.optID
);

if (liElement.firstChild) {
liElement.firstChild.id = that.selectId + '-' + liIndex;
}

mainElements.push(liElement);

option.liIndex = liIndex;

config.display = config.content || config.text;
config.type = 'option';
config.index = liIndex;
config.option = option;
config.disabled = config.disabled || option.disabled;
config.selected = !!option.selected;
config.disabled = config.disabled || !!option.disabled;

mainData.push(config);

var combinedLength = 0;

// count the number of characters in the option - not perfect, but should work in most cases
if (config.display) combinedLength += config.display.length;
if (config.subtext) combinedLength += config.subtext.length;
// if there is an icon, ensure this option's width is checked
if (config.icon) combinedLength += 1;

if (combinedLength > widestOptionLength) {
widestOptionLength = combinedLength;

// guess which option is the widest
// use this when calculating menu width
// not perfect, but it's fast, and the width will be updating accordingly when scrolling
that.selectpicker.view.widestOption = mainElements[mainElements.length - 1];
}
}
}

@@ -1556,12 +1516,13 @@
if (!options.length) return;

var config = {
label: htmlEscape(optgroup.label),
display: htmlEscape(optgroup.label),
subtext: optgroup.getAttribute('data-subtext'),
icon: optgroup.getAttribute('data-icon'),
iconBase: iconBase
type: 'optgroup-label',
iconBase: iconBase,
optgroupClass: ' ' + (optgroup.className || '')
},
optgroupClass = ' ' + (optgroup.className || ''),
headerIndex,
lastIndex;

@@ -1571,18 +1532,9 @@
addDivider({ optID: optID });
}

var labelElement = generateOption.label(config);

mainElements.push(
generateOption.li(labelElement, 'dropdown-header' + optgroupClass, optID)
);
config.optID = optID;

mainData.push({
display: config.label,
subtext: config.subtext,
type: 'optgroup-label',
optID: optID
});
mainData.push(config);

for (var j = 0, len = options.length; j < len; j++) {
var option = options[j];
@@ -1595,8 +1547,8 @@
addOption(option, {
headerIndex: headerIndex,
lastIndex: lastIndex,
optID: optID,
optgroupClass: optgroupClass,
optID: config.optID,
optgroupClass: config.optgroupClass,
disabled: optgroup.disabled
});
}
@@ -1616,21 +1568,91 @@
}
}

this.selectpicker.main.elements = mainElements;
this.selectpicker.main.data = mainData;
this.selectpicker.main.data = this.selectpicker.current.data = mainData;
},

buildList: function () {
var that = this,
selectData = this.selectpicker.main.data,
mainElements = [],
widestOptionLength = 0;

function buildElement (item) {
var liElement,
combinedLength = 0;

switch (item.type) {
case 'divider':
liElement = generateOption.li(
false,
classNames.DIVIDER,
(item.optID ? item.optID + 'div' : undefined)
);

this.selectpicker.current = this.selectpicker.main;
break;

case 'option':
liElement = generateOption.li(
generateOption.a(
generateOption.text(item),
item.optionClass,
item.inlineStyle
),
'',
item.optID
);

if (liElement.firstChild) {
liElement.firstChild.id = that.selectId + '-' + item.index;
}

break;

case 'optgroup-label':
liElement = generateOption.li(
generateOption.label(item),
'dropdown-header' + item.optgroupClass,
item.optID
);

break;
}

mainElements.push(liElement);

// count the number of characters in the option - not perfect, but should work in most cases
if (item.display) combinedLength += item.display.length;
if (item.subtext) combinedLength += item.subtext.length;
// if there is an icon, ensure this option's width is checked
if (item.icon) combinedLength += 1;

if (combinedLength > widestOptionLength) {
widestOptionLength = combinedLength;

// guess which option is the widest
// use this when calculating menu width
// not perfect, but it's fast, and the width will be updating accordingly when scrolling
that.selectpicker.view.widestOption = mainElements[mainElements.length - 1];
}
}

for (var len = selectData.length, i = 0; i < len; i++) {
var item = selectData[i];

buildElement(item);
}

this.selectpicker.main.elements = this.selectpicker.current.elements = mainElements;
},

findLis: function () {
return this.$menuInner.find('.inner > li');
},

render: function () {
// ensure titleOption is appended and selected (if necessary) before getting selectedOptions
this.setPlaceholder();

var that = this,
// ensure titleOption is appended and selected (if necessary) before getting selectedOptions
startIndex = this.setPlaceholder() ? 1 : 0,
element = this.$element[0],
selectedOptions = getSelectedOptions(element, this.options.hideDisabled),
selectedCount = selectedOptions.length,
@@ -1659,15 +1681,11 @@

// only loop through all selected options if the count won't be shown
if (showCount === false) {
for (var selectedIndex = 0; selectedIndex < selectedCount; selectedIndex++) {
for (var selectedIndex = startIndex; selectedIndex < selectedCount; selectedIndex++) {
if (selectedIndex < 50) {
var option = selectedOptions[selectedIndex],
titleOptions = {},
thisData = {
content: option.getAttribute('data-content'),
subtext: option.getAttribute('data-subtext'),
icon: option.getAttribute('data-icon')
};
thisData = this.selectpicker.main.data[option.liIndex],
titleOptions = {};

if (this.multiple && selectedIndex > 0) {
titleFragment.appendChild(multipleSeparator.cloneNode(false));
@@ -2675,14 +2693,14 @@

element.classList.add('bs-select-hidden');

for (var i = 0, len = this.selectpicker.current.elements.length; i < len; i++) {
var liData = this.selectpicker.current.data[i],
for (var i = 0, data = this.selectpicker.current.data, len = data.length; i < len; i++) {
var liData = data[i],
option = liData.option;

if (option && !liData.disabled && liData.type !== 'divider') {
if (liData.selected) previousSelected++;
option.selected = status;
if (status) currentSelected++;
if (status === true) currentSelected++;
}
}

@@ -2945,7 +2963,8 @@
this.checkDisabled();
this.setStyle();
this.render();
this.createLi();
this.buildData();
this.buildList();
this.setWidth();

this.setSize(true);

0 comments on commit 09d11f5

Please sign in to comment.