mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-31 21:12:35 +02:00
Reinstate method to remove item by value + general refactoring
This commit is contained in:
parent
ed66199c35
commit
e1d138ba42
2
assets/scripts/dist/bundle.js
vendored
2
assets/scripts/dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,51 +1,51 @@
|
||||||
export const addItem = (value, label, id, optionId) => {
|
export const addItem = (value, label, id, optionId) => {
|
||||||
return {
|
return {
|
||||||
type: 'ADD_ITEM',
|
type: 'ADD_ITEM',
|
||||||
value: value,
|
value,
|
||||||
label: label,
|
label,
|
||||||
id: parseInt(id),
|
id,
|
||||||
optionId: parseInt(optionId)
|
optionId,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeItem = (id, optionId) => {
|
export const removeItem = (id, optionId) => {
|
||||||
return {
|
return {
|
||||||
type: 'REMOVE_ITEM',
|
type: 'REMOVE_ITEM',
|
||||||
id: parseInt(id),
|
id,
|
||||||
optionId: parseInt(optionId)
|
optionId,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const selectItem = (id, selected) => {
|
export const selectItem = (id, selected) => {
|
||||||
return {
|
return {
|
||||||
type: 'SELECT_ITEM',
|
type: 'SELECT_ITEM',
|
||||||
id: parseInt(id),
|
id,
|
||||||
selected: selected,
|
selected,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addOption = (value, label, id, groupId) => {
|
export const addOption = (value, label, id, groupId) => {
|
||||||
return {
|
return {
|
||||||
type: 'ADD_OPTION',
|
type: 'ADD_OPTION',
|
||||||
value: value,
|
value,
|
||||||
label: label,
|
label,
|
||||||
id: parseInt(id),
|
id,
|
||||||
groupId: parseInt(groupId)
|
groupId,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const selectOption = (id, selected) => {
|
export const selectOption = (id, selected) => {
|
||||||
return {
|
return {
|
||||||
type: 'SELECT_OPTION',
|
type: 'SELECT_OPTION',
|
||||||
id: parseInt(id),
|
id,
|
||||||
selected: selected,
|
selected,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addGroup = (value, id) => {
|
export const addGroup = (value, id) => {
|
||||||
return {
|
return {
|
||||||
type: 'ADD_GROUP',
|
type: 'ADD_GROUP',
|
||||||
value: value,
|
value,
|
||||||
id: parseInt(id)
|
id,
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -408,6 +408,7 @@ export class Choices {
|
||||||
|
|
||||||
let passedValue = value.trim();
|
let passedValue = value.trim();
|
||||||
let passedLabel = label || passedValue;
|
let passedLabel = label || passedValue;
|
||||||
|
let passedOptionId = optionId || -1;
|
||||||
|
|
||||||
// If a prepended value has been passed, prepend it
|
// If a prepended value has been passed, prepend it
|
||||||
if(this.options.prependValue) {
|
if(this.options.prependValue) {
|
||||||
|
@ -420,7 +421,7 @@ export class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate unique id
|
// Generate unique id
|
||||||
let id = this.store.getState().items.length + 1;
|
const id = this.store.getState().items.length + 1;
|
||||||
|
|
||||||
// Close dropdown
|
// Close dropdown
|
||||||
if(this.dropdown && this.dropdown.classList.contains('is-active')) {
|
if(this.dropdown && this.dropdown.classList.contains('is-active')) {
|
||||||
|
@ -436,7 +437,7 @@ export class Choices {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.store.dispatch(addItem(passedValue, passedLabel, id, optionId));
|
this.store.dispatch(addItem(passedValue, passedLabel, id, passedOptionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -444,14 +445,14 @@ export class Choices {
|
||||||
* @param
|
* @param
|
||||||
*/
|
*/
|
||||||
removeItem(item, callback = this.options.callbackOnRemoveItem) {
|
removeItem(item, callback = this.options.callbackOnRemoveItem) {
|
||||||
if(!item) {
|
if(!item || !isType('Object', item)) {
|
||||||
console.error('removeItem: No item or value was passed to be removed');
|
console.error('removeItem: No item object was passed to be removed');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = item.id;
|
const id = item.id;
|
||||||
let value = item.value;
|
const value = item.value;
|
||||||
let optionId = item.optionId;
|
const optionId = item.optionId;
|
||||||
|
|
||||||
// Run callback
|
// Run callback
|
||||||
if(callback){
|
if(callback){
|
||||||
|
@ -465,13 +466,27 @@ export class Choices {
|
||||||
this.store.dispatch(removeItem(id, optionId));
|
this.store.dispatch(removeItem(id, optionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeItemsByValue(value) {
|
||||||
|
if(!value || !isType('String', value)) {
|
||||||
|
console.error('removeItemsByValue: No value was passed to be removed');
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = this.getItemsFilteredByActive();
|
||||||
|
|
||||||
|
items.forEach((item) => {
|
||||||
|
if(item.value === value) {
|
||||||
|
this.removeItem(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all items from array
|
* Remove all items from array
|
||||||
* @param {Boolean} selectedOnly Optionally remove only selected items
|
* @param {Boolean} selectedOnly Optionally remove only selected items
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
removeAllItems() {
|
removeAllItems() {
|
||||||
const items = this.getItems();
|
const items = this.getItemsFilteredByActive();
|
||||||
|
|
||||||
items.forEach((item) => {
|
items.forEach((item) => {
|
||||||
if(item.active) {
|
if(item.active) {
|
||||||
|
@ -481,7 +496,7 @@ export class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAllSelectedItems() {
|
removeAllSelectedItems() {
|
||||||
const items = this.getItems();
|
const items = this.getItemsFilteredByActive();
|
||||||
|
|
||||||
items.forEach((item) => {
|
items.forEach((item) => {
|
||||||
if(item.selected && item.active) {
|
if(item.selected && item.active) {
|
||||||
|
@ -628,15 +643,6 @@ export class Choices {
|
||||||
this.presetItems.forEach((value) => {
|
this.presetItems.forEach((value) => {
|
||||||
this.addItem(value);
|
this.addItem(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Subscribe to store
|
|
||||||
this.store.subscribe(this.render);
|
|
||||||
|
|
||||||
// Render any items
|
|
||||||
this.render();
|
|
||||||
|
|
||||||
// Trigger event listeners
|
|
||||||
this.addEventListeners();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -684,7 +690,6 @@ export class Choices {
|
||||||
this.list = list;
|
this.list = list;
|
||||||
this.dropdown = dropdown;
|
this.dropdown = dropdown;
|
||||||
|
|
||||||
// const passedGroups;
|
|
||||||
const passedGroups = Array.from(this.passedElement.getElementsByTagName('OPTGROUP'));
|
const passedGroups = Array.from(this.passedElement.getElementsByTagName('OPTGROUP'));
|
||||||
|
|
||||||
if(passedGroups.length) {
|
if(passedGroups.length) {
|
||||||
|
@ -706,16 +711,6 @@ export class Choices {
|
||||||
this.addOption(option);
|
this.addOption(option);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Subscribe to store
|
|
||||||
this.store.subscribe(this.render);
|
|
||||||
|
|
||||||
// Render any items
|
|
||||||
this.render();
|
|
||||||
|
|
||||||
// Trigger event listeners
|
|
||||||
this.addEventListeners();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -736,29 +731,13 @@ export class Choices {
|
||||||
document.removeEventListener('paste', this.onPaste);
|
document.removeEventListener('paste', this.onPaste);
|
||||||
}
|
}
|
||||||
|
|
||||||
observeStore(store, select, onChange) {
|
|
||||||
let currentState;
|
|
||||||
|
|
||||||
function handleChange() {
|
|
||||||
let nextState = select(store.getState());
|
|
||||||
if (nextState !== currentState) {
|
|
||||||
currentState = nextState;
|
|
||||||
onChange(currentState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let unsubscribe = store.subscribe(handleChange);
|
|
||||||
handleChange();
|
|
||||||
return unsubscribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render DOM with values
|
* Render DOM with values
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
render(callback = this.options.callbackOnRender) {
|
render(callback = this.options.callbackOnRender) {
|
||||||
const classNames = this.options.classNames;
|
const classNames = this.options.classNames;
|
||||||
const items = this.getItems();
|
const activeItems = this.getItemsFilteredByActive();
|
||||||
const options = this.getOptions();
|
const options = this.getOptions();
|
||||||
const groups = this.getGroups();
|
const groups = this.getGroups();
|
||||||
|
|
||||||
|
@ -823,21 +802,21 @@ export class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ITEMS
|
// ITEMS
|
||||||
// Simplify store data to just values
|
if(activeItems) {
|
||||||
const itemsFiltered = this.getItemsReducedToValues();
|
// Simplify store data to just values
|
||||||
|
const itemsFiltered = this.getItemsReducedToValues();
|
||||||
|
|
||||||
// Assign hidden input array of values
|
// Assign hidden input array of values
|
||||||
this.passedElement.value = itemsFiltered.join(this.options.delimiter);
|
this.passedElement.value = itemsFiltered.join(this.options.delimiter);
|
||||||
|
|
||||||
// Clear list
|
// Clear list
|
||||||
this.list.innerHTML = '';
|
this.list.innerHTML = '';
|
||||||
|
|
||||||
// Create a fragment to store our list items (so we don't have to update the DOM for each item)
|
// Create a fragment to store our list items (so we don't have to update the DOM for each item)
|
||||||
const itemListFragment = document.createDocumentFragment();
|
const itemListFragment = document.createDocumentFragment();
|
||||||
|
|
||||||
// Add each list item to list
|
// Add each list item to list
|
||||||
items.forEach((item) => {
|
activeItems.forEach((item) => {
|
||||||
if(item.active) {
|
|
||||||
// Create new list element
|
// Create new list element
|
||||||
const listItem = strToEl(`
|
const listItem = strToEl(`
|
||||||
<li class="${ classNames.item } ${ this.options.removeItems ? classNames.itemSelectable : '' } ${ item.selected ? classNames.selectedState : '' }" data-choice-item data-choice-id="${ item.id }" data-choice-selected="${ item.selected }">
|
<li class="${ classNames.item } ${ this.options.removeItems ? classNames.itemSelectable : '' } ${ item.selected ? classNames.selectedState : '' }" data-choice-item data-choice-id="${ item.id }" data-choice-selected="${ item.selected }">
|
||||||
|
@ -847,15 +826,15 @@ export class Choices {
|
||||||
|
|
||||||
// Append it to list
|
// Append it to list
|
||||||
itemListFragment.appendChild(listItem);
|
itemListFragment.appendChild(listItem);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
this.list.appendChild(itemListFragment);
|
this.list.appendChild(itemListFragment);
|
||||||
|
}
|
||||||
|
|
||||||
// Run callback if it is a function
|
// Run callback if it is a function
|
||||||
if(callback){
|
if(callback){
|
||||||
if(isType('Function', callback)) {
|
if(isType('Function', callback)) {
|
||||||
callback(items, options, groups);
|
callback(activeItems, options, groups);
|
||||||
} else {
|
} else {
|
||||||
console.error('callbackOnRender: Callback is not a function');
|
console.error('callbackOnRender: Callback is not a function');
|
||||||
}
|
}
|
||||||
|
@ -880,7 +859,7 @@ export class Choices {
|
||||||
this.generateMultipleSelectInput();
|
this.generateMultipleSelectInput();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.generateMultipleSelectInput();
|
console.error('renderInput: Input type is not supported');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -892,7 +871,18 @@ export class Choices {
|
||||||
init(callback = this.options.callbackOnInit) {
|
init(callback = this.options.callbackOnInit) {
|
||||||
if (!this.supports) console.error('init: Your browser doesn\'nt support shit');
|
if (!this.supports) console.error('init: Your browser doesn\'nt support shit');
|
||||||
this.initialised = true;
|
this.initialised = true;
|
||||||
|
|
||||||
|
// Render input
|
||||||
this.renderInput(this.passedElement);
|
this.renderInput(this.passedElement);
|
||||||
|
|
||||||
|
// Subscribe to store
|
||||||
|
this.store.subscribe(this.render);
|
||||||
|
|
||||||
|
// Render any items
|
||||||
|
this.render();
|
||||||
|
|
||||||
|
// Trigger event listeners
|
||||||
|
this.addEventListeners();
|
||||||
// Run callback if it is a function
|
// Run callback if it is a function
|
||||||
if(callback){
|
if(callback){
|
||||||
if(isType('Function', callback)) {
|
if(isType('Function', callback)) {
|
||||||
|
@ -951,15 +941,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
const choices5 = new Choices('#choices-5', {
|
const choices5 = new Choices('#choices-5', {
|
||||||
prependValue: 'item-',
|
prependValue: 'item-',
|
||||||
appendValue: `-${Date.now()}`,
|
appendValue: `-${Date.now()}`,
|
||||||
|
// callbackOnRender: function(items, options) {
|
||||||
|
// console.log(items);
|
||||||
|
// },
|
||||||
});
|
});
|
||||||
|
|
||||||
choices5.removeAllItems();
|
choices5.removeAllItems();
|
||||||
|
|
||||||
const choices6 = new Choices('#choices-6', {
|
const choices6 = new Choices('#choices-6', {
|
||||||
items: ['josh@joshuajohnson.co.uk', 'joe@bloggs.co.uk'],
|
items: ['josh@joshuajohnson.co.uk', 'joe@bloggs.co.uk'],
|
||||||
// callbackOnRender: function(items, options, groups) {
|
callbackOnRender: function(items, options, groups) {
|
||||||
// console.log(items);
|
console.log(items);
|
||||||
// },
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const choices7 = new Choices('#choices-7', {
|
const choices7 = new Choices('#choices-7', {
|
||||||
|
@ -975,7 +968,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
// },
|
// },
|
||||||
});
|
});
|
||||||
|
|
||||||
// choices6.addItem('josh2@joshuajohnson.co.uk', () => { console.log('Custom add item callback')});
|
choices6.addItem('josh2@joshuajohnson.co.uk', null, null, () => { console.log('Custom add item callback')});
|
||||||
// choices6.removeItem('josh@joshuajohnson.co.uk');
|
choices6.removeItemsByValue('josh@joshuajohnson.co.uk');
|
||||||
// console.log(choices6.getItemById(1));
|
console.log(choices6.getItemById(3));
|
||||||
});
|
});
|
|
@ -389,7 +389,7 @@ export const getWidthOfInput = (input, initialWidth = 20) => {
|
||||||
document.body.appendChild(testEl);
|
document.body.appendChild(testEl);
|
||||||
|
|
||||||
if(testEl.offsetWidth > initialWidth && testEl.offsetWidth != input.offsetWidth) {
|
if(testEl.offsetWidth > initialWidth && testEl.offsetWidth != input.offsetWidth) {
|
||||||
width = testEl.offsetWidth + initialWidth;
|
width = testEl.offsetWidth + initialWidth/4;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.removeChild(testEl);
|
document.body.removeChild(testEl);
|
||||||
|
|
|
@ -2,7 +2,7 @@ const groups = (state = [], action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_GROUP':
|
case 'ADD_GROUP':
|
||||||
return [...state, {
|
return [...state, {
|
||||||
id: parseInt(action.id),
|
id: action.id,
|
||||||
value: action.value,
|
value: action.value,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -2,7 +2,7 @@ const options = (state = [], action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_OPTION':
|
case 'ADD_OPTION':
|
||||||
return [...state, {
|
return [...state, {
|
||||||
id: parseInt(action.id),
|
id: action.id,
|
||||||
groupId: action.groupId,
|
groupId: action.groupId,
|
||||||
value: action.value,
|
value: action.value,
|
||||||
label: action.label,
|
label: action.label,
|
||||||
|
|
Loading…
Reference in a new issue