Fix search + use choice placeholder on remove button

This commit is contained in:
Josh Johnson 2017-08-03 10:56:49 +01:00
parent 171f59cf65
commit 565d659c0a
2 changed files with 264 additions and 244 deletions

View file

@ -174,13 +174,12 @@ class Choices {
this.highlightPosition = 0; this.highlightPosition = 0;
this.canSearch = this.config.searchEnabled; this.canSearch = this.config.searchEnabled;
this.placeholder = this.config.placeholder ?
(this.config.placeholderValue || this.passedElement.getAttribute('placeholder')) :
false;
this.placeholder = false; this.placeholder = false;
if (!this.isSelectOneElement) { if (!this.isSelectOneElement) {
this.placeholder = (this.config.placeholderValue || this.passedElement.getAttribute('placeholder')) || false; this.placeholder = this.config.placeholder ?
(this.config.placeholderValue || this.passedElement.getAttribute('placeholder')) :
false;
} }
// Assign preset choices from passed object // Assign preset choices from passed object
@ -406,14 +405,16 @@ class Choices {
const sortedChoices = [...placeholderChoices, ...normalChoices]; const sortedChoices = [...placeholderChoices, ...normalChoices];
if (this.isSearching) { if (this.isSearching) {
choiceLimit = Math.min(searchResultLimit, sortedChoices.length - 1); choiceLimit = searchResultLimit;
} else if (renderChoiceLimit > 0 && !withinGroup) { } else if (renderChoiceLimit > 0 && !withinGroup) {
choiceLimit = Math.min(renderChoiceLimit, sortedChoices.length - 1); choiceLimit = renderChoiceLimit;
} }
// Add each choice to dropdown within range // Add each choice to dropdown within range
for (let i = 0; i < choiceLimit; i++) { for (let i = 0; i < choiceLimit; i++) {
appendChoice(sortedChoices[i]); if (sortedChoices[i]) {
appendChoice(sortedChoices[i]);
}
}; };
return choicesFragment; return choicesFragment;
@ -1148,13 +1149,31 @@ class Choices {
this._removeItem(itemToRemove); this._removeItem(itemToRemove);
this._triggerChange(itemToRemove.value); this._triggerChange(itemToRemove.value);
if (this.isSelectOneElement && this.placeholder) { if (this.isSelectOneElement) {
const placeholderItem = this._getTemplate('placeholder', this.placeholder); this._selectPlaceholderChoice();
this.itemList.appendChild(placeholderItem);
} }
} }
} }
/**
* Select placeholder choice
*/
_selectPlaceholderChoice() {
const placeholderChoice = this.store.getPlaceholderChoice();
if (placeholderChoice) {
this._addItem(
placeholderChoice.value,
placeholderChoice.label,
placeholderChoice.id,
placeholderChoice.groupId,
null,
placeholderChoice.placeholder
);
this._triggerChange(placeholderChoice.value);
}
}
/** /**
* Process click of an item * Process click of an item
* @param {Array} activeItems The currently active items * @param {Array} activeItems The currently active items
@ -1402,20 +1421,8 @@ class Choices {
); );
} }
if (this.passedElement.type === 'select-one') { if (this.isSelectOneElement) {
const placeholderChoice = this.store.getPlaceholderChoice(); this._selectPlaceholderChoice();
if (placeholderChoice) {
this._addItem(
placeholderChoice.value,
placeholderChoice.label,
placeholderChoice.id,
placeholderChoice.groupId,
null,
placeholderChoice.placeholder
);
this._triggerChange(placeholderChoice.value);
}
} }
}); });
} else { } else {

View file

@ -53,7 +53,7 @@
</p> </p>
<hr> <hr>
<h2>Text inputs</h2> <!-- <h2>Text inputs</h2>
<label for="choices-text-remove-button">Limited to 5 values with remove button</label> <label for="choices-text-remove-button">Limited to 5 values with remove button</label>
<input class="form-control" id="choices-text-remove-button" type="text" value="preset-1,preset-2" placeholder="Enter something"> <input class="form-control" id="choices-text-remove-button" type="text" value="preset-1,preset-2" placeholder="Enter something">
@ -272,254 +272,267 @@
<option value="Manhattan">Manhattan</option> <option value="Manhattan">Manhattan</option>
<option value="Queens">Queens</option> <option value="Queens">Queens</option>
<option value="Staten Island">Staten Island</option> <option value="Staten Island">Staten Island</option>
</select> -->
<select class="form-control" name="test" id="test" placeholder="Choose a borough">
<option selected placeholder>Placeholder</option>
<option value="The Bronx">The Bronx</option>
<option value="Brooklyn">Brooklyn</option>
<option value="Manhattan">Manhattan</option>
<option value="Queens">Queens</option>
<option value="Staten Island">Staten Island</option>
</select> </select>
</div> </div>
</div> </div>
<script> <script>
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
var textRemove = new Choices(document.getElementById('choices-text-remove-button'), { var test = new Choices('.form-control', {
delimiter: ',', removeItemButton: true
editItems: true,
maxItemCount: 5,
removeItemButton: true,
}); });
var textUniqueVals = new Choices('#choices-text-unique-values', { // var textRemove = new Choices(document.getElementById('choices-text-remove-button'), {
paste: false, // delimiter: ',',
duplicateItems: false, // editItems: true,
editItems: true, // maxItemCount: 5,
}); // removeItemButton: true,
// });
var texti18n = new Choices('#choices-text-i18n', { // var textUniqueVals = new Choices('#choices-text-unique-values', {
paste: false, // paste: false,
duplicateItems: false, // duplicateItems: false,
editItems: true, // editItems: true,
maxItemCount: 5, // });
addItemText: function (value) {
return 'Appuyez sur Entrée pour ajouter <b>"' + String(value) + '"</b>';
},
maxItemText: function (maxItemCount) {
return String(maxItemCount) + 'valeurs peuvent être ajoutées';
},
uniqueItemText: 'Cette valeur est déjà présente',
});
var textEmailFilter = new Choices('#choices-text-email-filter', { // var texti18n = new Choices('#choices-text-i18n', {
editItems: true, // paste: false,
regexFilter: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, // duplicateItems: false,
}).setValue(['joe@bloggs.com']); // editItems: true,
// maxItemCount: 5,
// addItemText: function (value) {
// return 'Appuyez sur Entrée pour ajouter <b>"' + String(value) + '"</b>';
// },
// maxItemText: function (maxItemCount) {
// return String(maxItemCount) + 'valeurs peuvent être ajoutées';
// },
// uniqueItemText: 'Cette valeur est déjà présente',
// });
var textDisabled = new Choices('#choices-text-disabled', { // var textEmailFilter = new Choices('#choices-text-email-filter', {
addItems: false, // editItems: true,
removeItems: false, // regexFilter: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
}).disable(); // }).setValue(['joe@bloggs.com']);
var textPrependAppendVal = new Choices('#choices-text-prepend-append-value', { // var textDisabled = new Choices('#choices-text-disabled', {
prependValue: 'item-', // addItems: false,
appendValue: '-' + Date.now(), // removeItems: false,
}).removeActiveItems(); // }).disable();
var textPresetVal = new Choices('#choices-text-preset-values', { // var textPrependAppendVal = new Choices('#choices-text-prepend-append-value', {
items: ['Josh Johnson', { // prependValue: 'item-',
value: 'joe@bloggs.co.uk', // appendValue: '-' + Date.now(),
label: 'Joe Bloggs', // }).removeActiveItems();
customProperties: {
description: 'Joe Blogg is such a generic name'
}
}],
});
var multipleDefault = new Choices(document.getElementById('choices-multiple-groups')); // var textPresetVal = new Choices('#choices-text-preset-values', {
// items: ['Josh Johnson', {
// value: 'joe@bloggs.co.uk',
// label: 'Joe Bloggs',
// customProperties: {
// description: 'Joe Blogg is such a generic name'
// }
// }],
// });
var multipleFetch = new Choices('#choices-multiple-remote-fetch', { // var multipleDefault = new Choices(document.getElementById('choices-multiple-groups'));
placeholder: true,
placeholderValue: 'Pick an Strokes record',
maxItemCount: 5,
}).ajax(function (callback) {
fetch('https://api.discogs.com/artists/55980/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
.then(function (response) {
response.json().then(function (data) {
callback(data.releases, 'title', 'title');
});
})
.catch(function (error) {
console.error(error);
});
});
var multipleCancelButton = new Choices('#choices-multiple-remove-button', { // var multipleFetch = new Choices('#choices-multiple-remote-fetch', {
removeItemButton: true, // placeholder: true,
}); // placeholderValue: 'Pick an Strokes record',
// maxItemCount: 5,
// }).ajax(function (callback) {
// fetch('https://api.discogs.com/artists/55980/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
// .then(function (response) {
// response.json().then(function (data) {
// callback(data.releases, 'title', 'title');
// });
// })
// .catch(function (error) {
// console.error(error);
// });
// });
/* Use label on event */ // var multipleCancelButton = new Choices('#choices-multiple-remove-button', {
var choicesSelect = new Choices('#choices-multiple-labels', { // removeItemButton: true,
removeItemButton: true, // });
choices: [
{ value: 'One', label: 'Label One' },
{ value: 'Two', label: 'Label Two', disabled: true },
{ value: 'Three', label: 'Label Three' },
],
}).setChoices([
{ value: 'Four', label: 'Label Four', disabled: true },
{ value: 'Five', label: 'Label Five' },
{ value: 'Six', label: 'Label Six', selected: true },
], 'value', 'label', false);
choicesSelect.passedElement.addEventListener('addItem', function (event) { // /* Use label on event */
document.getElementById('message').innerHTML = 'You just added "' + event.detail.label + '"'; // var choicesSelect = new Choices('#choices-multiple-labels', {
}); // removeItemButton: true,
// choices: [
// { value: 'One', label: 'Label One' },
// { value: 'Two', label: 'Label Two', disabled: true },
// { value: 'Three', label: 'Label Three' },
// ],
// }).setChoices([
// { value: 'Four', label: 'Label Four', disabled: true },
// { value: 'Five', label: 'Label Five' },
// { value: 'Six', label: 'Label Six', selected: true },
// ], 'value', 'label', false);
choicesSelect.passedElement.addEventListener('removeItem', function (event) { // choicesSelect.passedElement.addEventListener('addItem', function (event) {
document.getElementById('message').innerHTML = 'You just removed "' + event.detail.label + '"'; // document.getElementById('message').innerHTML = 'You just added "' + event.detail.label + '"';
}); // });
var singleFetch = new Choices('#choices-single-remote-fetch', { // choicesSelect.passedElement.addEventListener('removeItem', function (event) {
placeholder: true, // document.getElementById('message').innerHTML = 'You just removed "' + event.detail.label + '"';
placeholderValue: 'Pick an Arctic Monkeys record', // });
searchPlaceholderValue: 'Search for an Arctic Monkeys record',
}).ajax(function (callback) {
fetch('https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
.then(function (response) {
response.json().then(function (data) {
callback(data.releases, 'title', 'title');
singleFetch.setValueByChoice('Fake Tales Of San Francisco');
});
})
.catch(function (error) {
console.error(error);
});
});
var singleXhrRemove = new Choices('#choices-single-remove-xhr', { // var singleFetch = new Choices('#choices-single-remote-fetch', {
removeItemButton: true, // placeholder: true,
}).ajax(function (callback) { // placeholderValue: 'Pick an Arctic Monkeys record',
var request = new XMLHttpRequest(); // searchPlaceholderValue: 'Search for an Arctic Monkeys record',
request.open('get', 'https://api.discogs.com/artists/83080/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW', true); // }).ajax(function (callback) {
request.onreadystatechange = function () { // fetch('https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
var status; // .then(function (response) {
var data; // response.json().then(function (data) {
if (request.readyState === 4) { // callback(data.releases, 'title', 'title');
status = request.status; // singleFetch.setValueByChoice('Fake Tales Of San Francisco');
if (status === 200) { // });
data = JSON.parse(request.responseText); // })
callback(data.releases, 'title', 'title'); // .catch(function (error) {
singleXhrRemove.setValueByChoice('How Soon Is Now?'); // console.error(error);
} else { // });
console.error(status); // });
}
}
}
request.send();
});
var genericExamples = new Choices('[data-trigger]', { // var singleXhrRemove = new Choices('#choices-single-remove-xhr', {
placeholderValue: 'This is a placeholder set in the config', // removeItemButton: true,
searchPlaceholderValue: 'This is a search placeholder' // }).ajax(function (callback) {
}); // var request = new XMLHttpRequest();
// request.open('get', 'https://api.discogs.com/artists/83080/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW', true);
// request.onreadystatechange = function () {
// var status;
// var data;
// if (request.readyState === 4) {
// status = request.status;
// if (status === 200) {
// data = JSON.parse(request.responseText);
// callback(data.releases, 'title', 'title');
// singleXhrRemove.setValueByChoice('How Soon Is Now?');
// } else {
// console.error(status);
// }
// }
// }
// request.send();
// });
var singleNoSearch = new Choices('#choices-single-no-search', { // var genericExamples = new Choices('[data-trigger]', {
searchEnabled: false, // placeholderValue: 'This is a placeholder set in the config',
removeItemButton: true, // searchPlaceholderValue: 'This is a search placeholder'
choices: [ // });
{ value: 'One', label: 'Label One' },
{ value: 'Two', label: 'Label Two', disabled: true },
{ value: 'Three', label: 'Label Three' },
],
}).setChoices([
{ value: 'Four', label: 'Label Four', disabled: true },
{ value: 'Five', label: 'Label Five' },
{ value: 'Six', label: 'Label Six', selected: true },
], 'value', 'label', false);
var singlePresetOpts = new Choices('#choices-single-preset-options', { // var singleNoSearch = new Choices('#choices-single-no-search', {
placeholder: true, // searchEnabled: false,
}).setChoices([{ // removeItemButton: true,
label: 'Group one', // choices: [
id: 1, // { value: 'One', label: 'Label One' },
disabled: false, // { value: 'Two', label: 'Label Two', disabled: true },
choices: [ // { value: 'Three', label: 'Label Three' },
{ value: 'Child One', label: 'Child One', selected: true }, // ],
{ value: 'Child Two', label: 'Child Two', disabled: true }, // }).setChoices([
{ value: 'Child Three', label: 'Child Three' }, // { value: 'Four', label: 'Label Four', disabled: true },
] // { value: 'Five', label: 'Label Five' },
}, // { value: 'Six', label: 'Label Six', selected: true },
{ // ], 'value', 'label', false);
label: 'Group two',
id: 2,
disabled: false,
choices: [
{ value: 'Child Four', label: 'Child Four', disabled: true },
{ value: 'Child Five', label: 'Child Five' },
{ value: 'Child Six', label: 'Child Six' },
]
}], 'value', 'label');
var singleSelectedOpt = new Choices('#choices-single-selected-option', { // var singlePresetOpts = new Choices('#choices-single-preset-options', {
searchFields: ['label', 'value', 'customProperties.description'], // placeholder: true,
choices: [ // }).setChoices([{
{ value: 'One', label: 'Label One', selected: true }, // label: 'Group one',
{ value: 'Two', label: 'Label Two', disabled: true }, // id: 1,
{ // disabled: false,
value: 'Three', label: 'Label Three', customProperties: { // choices: [
description: 'This option is fantastic' // { value: 'Child One', label: 'Child One', selected: true },
} // { value: 'Child Two', label: 'Child Two', disabled: true },
}, // { value: 'Child Three', label: 'Child Three' },
], // ]
}).setValueByChoice('Two'); // },
// {
// label: 'Group two',
// id: 2,
// disabled: false,
// choices: [
// { value: 'Child Four', label: 'Child Four', disabled: true },
// { value: 'Child Five', label: 'Child Five' },
// { value: 'Child Six', label: 'Child Six' },
// ]
// }], 'value', 'label');
var singleNoSorting = new Choices('#choices-single-no-sorting', { // var singleSelectedOpt = new Choices('#choices-single-selected-option', {
shouldSort: false, // searchFields: ['label', 'value', 'customProperties.description'],
}); // choices: [
// { value: 'One', label: 'Label One', selected: true },
// { value: 'Two', label: 'Label Two', disabled: true },
// {
// value: 'Three', label: 'Label Three', customProperties: {
// description: 'This option is fantastic'
// }
// },
// ],
// }).setValueByChoice('Two');
var states = new Choices(document.getElementById('states')); // var singleNoSorting = new Choices('#choices-single-no-sorting', {
// shouldSort: false,
// });
states.passedElement.addEventListener('change', function (e) { // var states = new Choices(document.getElementById('states'));
if (e.detail.value === 'New York') {
boroughs.enable();
} else {
boroughs.disable();
}
});
var customTemplates = new Choices(document.getElementById('choices-single-custom-templates'), { // states.passedElement.addEventListener('change', function (e) {
callbackOnCreateTemplates: function (strToEl) { // if (e.detail.value === 'New York') {
var classNames = this.config.classNames; // boroughs.enable();
var itemSelectText = this.config.itemSelectText; // } else {
return { // boroughs.disable();
item: function (data) { // }
return strToEl('\ // });
<div\
class="'+ String(classNames.item) + ' ' + String(data.highlighted ? classNames.highlightedState : classNames.itemSelectable) + '"\
data-item\
data-id="'+ String(data.id) + '"\
data-value="'+ String(data.value) + '"\
'+ String(data.active ? 'aria-selected="true"' : '') + '\
'+ String(data.disabled ? 'aria-disabled="true"' : '') + '\
>\
<span style="margin-right:10px;">🎉</span> ' + String(data.label) + '\
</div>\
');
},
choice: function (data) {
return strToEl('\
<div\
class="'+ String(classNames.item) + ' ' + String(classNames.itemChoice) + ' ' + String(data.disabled ? classNames.itemDisabled : classNames.itemSelectable) + '"\
data-select-text="'+ String(itemSelectText) + '"\
data-choice \
'+ String(data.disabled ? 'data-choice-disabled aria-disabled="true"' : 'data-choice-selectable') + '\
data-id="'+ String(data.id) + '"\
data-value="'+ String(data.value) + '"\
'+ String(data.groupId > 0 ? 'role="treeitem"' : 'role="option"') + '\
>\
<span style="margin-right:10px;">👉🏽</span> ' + String(data.label) + '\
</div>\
');
},
};
}
});
var boroughs = new Choices(document.getElementById('boroughs')).disable(); // var customTemplates = new Choices(document.getElementById('choices-single-custom-templates'), {
// callbackOnCreateTemplates: function (strToEl) {
// var classNames = this.config.classNames;
// var itemSelectText = this.config.itemSelectText;
// return {
// item: function (data) {
// return strToEl('\
// <div\
// class="'+ String(classNames.item) + ' ' + String(data.highlighted ? classNames.highlightedState : classNames.itemSelectable) + '"\
// data-item\
// data-id="'+ String(data.id) + '"\
// data-value="'+ String(data.value) + '"\
// '+ String(data.active ? 'aria-selected="true"' : '') + '\
// '+ String(data.disabled ? 'aria-disabled="true"' : '') + '\
// >\
// <span style="margin-right:10px;">🎉</span> ' + String(data.label) + '\
// </div>\
// ');
// },
// choice: function (data) {
// return strToEl('\
// <div\
// class="'+ String(classNames.item) + ' ' + String(classNames.itemChoice) + ' ' + String(data.disabled ? classNames.itemDisabled : classNames.itemSelectable) + '"\
// data-select-text="'+ String(itemSelectText) + '"\
// data-choice \
// '+ String(data.disabled ? 'data-choice-disabled aria-disabled="true"' : 'data-choice-selectable') + '\
// data-id="'+ String(data.id) + '"\
// data-value="'+ String(data.value) + '"\
// '+ String(data.groupId > 0 ? 'role="treeitem"' : 'role="option"') + '\
// >\
// <span style="margin-right:10px;">👉🏽</span> ' + String(data.label) + '\
// </div>\
// ');
// },
// };
// }
// });
// var boroughs = new Choices(document.getElementById('boroughs')).disable();
}); });
</script> </script>