mirror of
https://github.com/Choices-js/Choices.git
synced 2024-06-01 05:22:21 +02:00
Render items from store
This commit is contained in:
parent
174aa399c2
commit
d8620f433f
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,12 +1,17 @@
|
||||||
export const addItemToStore = (value, element, id) => {
|
export const addItemToStore = (value, id) => {
|
||||||
return {
|
return {
|
||||||
type: 'ADD_ITEM',
|
type: 'ADD_ITEM',
|
||||||
value: value,
|
value: value,
|
||||||
element: element,
|
|
||||||
id: id
|
id: id
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const unselectAllFromStore = () => {
|
||||||
|
return {
|
||||||
|
type: 'UNSELECT_ALL'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const removeItemFromStore = (id) => {
|
export const removeItemFromStore = (id) => {
|
||||||
return {
|
return {
|
||||||
type: 'REMOVE_ITEM',
|
type: 'REMOVE_ITEM',
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { createStore } from 'redux';
|
import { createStore } from 'redux';
|
||||||
import choices from './reducers/index.js';
|
import choices from './reducers/index.js';
|
||||||
import { addItemToStore, removeItemFromStore, selectItemFromStore } from './actions/index';
|
import { addItemToStore, removeItemFromStore, selectItemFromStore, unselectAllFromStore } from './actions/index';
|
||||||
import { hasClass, wrap, getSiblings, isType, strToEl } from './lib/utils.js';
|
import { hasClass, wrap, getSiblings, isType, strToEl } from './lib/utils.js';
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ export class Choices {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
const fakeEl = document.createElement("fakeel");
|
const fakeEl = document.createElement("fakeel");
|
||||||
const userOptions = options || {};
|
const userOptions = options || {};
|
||||||
const store = createStore(choices);
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
element: document.querySelector('[data-choice]'),
|
element: document.querySelector('[data-choice]'),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
@ -44,7 +43,7 @@ export class Choices {
|
||||||
|
|
||||||
// Merge options with user options
|
// Merge options with user options
|
||||||
this.options = this.extend(defaultOptions, userOptions || {});
|
this.options = this.extend(defaultOptions, userOptions || {});
|
||||||
this.store = store;
|
this.store = createStore(choices);
|
||||||
|
|
||||||
this.initialised = false;
|
this.initialised = false;
|
||||||
this.supports = 'querySelector' in document && 'addEventListener' in document && 'classList' in fakeEl;
|
this.supports = 'querySelector' in document && 'addEventListener' in document && 'classList' in fakeEl;
|
||||||
|
@ -62,6 +61,7 @@ export class Choices {
|
||||||
// Bind methods
|
// Bind methods
|
||||||
this.onKeyDown = this.onKeyDown.bind(this);
|
this.onKeyDown = this.onKeyDown.bind(this);
|
||||||
this.onClick = this.onClick.bind(this);
|
this.onClick = this.onClick.bind(this);
|
||||||
|
this.renderItems = this.renderItems.bind(this);
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
@ -183,12 +183,11 @@ export class Choices {
|
||||||
|
|
||||||
// All is good, add
|
// All is good, add
|
||||||
if(canAddItem) {
|
if(canAddItem) {
|
||||||
this.addItem(this.list, value);
|
this.addItem(value);
|
||||||
this.updateInputValue(value);
|
this.updateInputValue(value);
|
||||||
this.clearInput(this.element);
|
this.clearInput(this.element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -212,7 +211,7 @@ export class Choices {
|
||||||
// If editing the last item is allowed and there is a last item and
|
// If editing the last item is allowed and there is a last item and
|
||||||
// there are not other selected items (minus the last item), we can edit
|
// there are not other selected items (minus the last item), we can edit
|
||||||
// the item value. Otherwise if we can remove items, remove all items
|
// the item value. Otherwise if we can remove items, remove all items
|
||||||
if(this.options.editItems && lastItem && selectedItems.length === 1) {
|
if(this.options.editItems && lastItem && selectedItems.length === 0) {
|
||||||
this.input.value = lastItem.innerHTML;
|
this.input.value = lastItem.innerHTML;
|
||||||
this.removeItem(lastItem);
|
this.removeItem(lastItem);
|
||||||
} else {
|
} else {
|
||||||
|
@ -269,16 +268,12 @@ export class Choices {
|
||||||
|
|
||||||
selectItem(item) {
|
selectItem(item) {
|
||||||
let id = item.getAttribute('data-choice-id');
|
let id = item.getAttribute('data-choice-id');
|
||||||
item.classList.add('is-selected');
|
|
||||||
this.store.dispatch(selectItemFromStore(id, true));
|
this.store.dispatch(selectItemFromStore(id, true));
|
||||||
console.log(this.store.getState());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unselectItem(item) {
|
unselectItem(item) {
|
||||||
let id = item.getAttribute('data-choice-id');
|
let id = item.getAttribute('data-choice-id');
|
||||||
item.classList.remove('is-selected');
|
|
||||||
this.store.dispatch(selectItemFromStore(id, false));
|
this.store.dispatch(selectItemFromStore(id, false));
|
||||||
console.log(this.store.getState());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selectAll(items) {
|
selectAll(items) {
|
||||||
|
@ -307,7 +302,7 @@ export class Choices {
|
||||||
this.element.value = this.valueArray.join(this.options.delimiter);
|
this.element.value = this.valueArray.join(this.options.delimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
addItem(parent, value) {
|
addItem(value) {
|
||||||
if (this.options.debug) console.debug('Add item');
|
if (this.options.debug) console.debug('Add item');
|
||||||
|
|
||||||
let passedValue = value;
|
let passedValue = value;
|
||||||
|
@ -322,25 +317,20 @@ export class Choices {
|
||||||
passedValue = passedValue + this.options.appendValue.toString();
|
passedValue = passedValue + this.options.appendValue.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate unique id
|
||||||
let id = this.store.getState().length + 1;
|
let id = this.store.getState().length + 1;
|
||||||
|
|
||||||
// Create new list element
|
|
||||||
let item = strToEl(`<li class="choices__item" data-choice-id=${id}>${passedValue}</li>`);
|
|
||||||
|
|
||||||
// Append it to list
|
|
||||||
parent.appendChild(item);
|
|
||||||
|
|
||||||
// Run callback if it is a function
|
// Run callback if it is a function
|
||||||
if(this.options.callbackOnAddItem){
|
if(this.options.callbackOnAddItem){
|
||||||
if(isType('Function', this.options.callbackOnAddItem)) {
|
if(isType('Function', this.options.callbackOnAddItem)) {
|
||||||
this.options.callbackOnAddItem(item, value);
|
this.options.callbackOnAddItem(id, value);
|
||||||
} else {
|
} else {
|
||||||
console.error('callbackOnAddItem: Callback is not a function');
|
console.error('callbackOnAddItem: Callback is not a function');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.store.dispatch(addItemToStore(passedValue, item, id));
|
this.store.dispatch(addItemToStore(passedValue, id));
|
||||||
console.log(this.store.getState());
|
this.store.dispatch(unselectAllFromStore(passedValue, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
removeItem(item) {
|
removeItem(item) {
|
||||||
|
@ -351,7 +341,6 @@ export class Choices {
|
||||||
|
|
||||||
let id = item.getAttribute('data-choice-id');
|
let id = item.getAttribute('data-choice-id');
|
||||||
let value = item.innerHTML;
|
let value = item.innerHTML;
|
||||||
item.parentNode.removeChild(item);
|
|
||||||
|
|
||||||
// Run callback
|
// Run callback
|
||||||
if(this.options.callbackOnRemoveItem){
|
if(this.options.callbackOnRemoveItem){
|
||||||
|
@ -363,7 +352,6 @@ export class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.store.dispatch(removeItemFromStore(id));
|
this.store.dispatch(removeItemFromStore(id));
|
||||||
console.log(this.store.getState());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAll(items) {
|
removeAll(items) {
|
||||||
|
@ -380,7 +368,7 @@ export class Choices {
|
||||||
init() {
|
init() {
|
||||||
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;
|
||||||
this.render(this.element);
|
this.renderInput(this.element);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTextInput() {
|
renderTextInput() {
|
||||||
|
@ -434,7 +422,7 @@ export class Choices {
|
||||||
if (this.element.value !== '') {
|
if (this.element.value !== '') {
|
||||||
// Add any preset values
|
// Add any preset values
|
||||||
this.valueArray.forEach((value) => {
|
this.valueArray.forEach((value) => {
|
||||||
this.addItem(this.list, value);
|
this.addItem(value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,13 +431,32 @@ export class Choices {
|
||||||
this.list.addEventListener('click', this.onClick);
|
this.list.addEventListener('click', this.onClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderItems(){
|
||||||
|
let items = this.store.getState();
|
||||||
|
|
||||||
render() {
|
this.list.innerHTML = '';
|
||||||
|
|
||||||
|
items.forEach((item) => {
|
||||||
|
if(item.active) {
|
||||||
|
// Create new list element
|
||||||
|
let listItem = strToEl(`<li class="choices__item ${ item.selected ? 'is-selected' : '' }" data-choice-id="${item.id}" data-choice-selected="${item.selected}">${item.value}</li>`);
|
||||||
|
|
||||||
|
// Append it to list
|
||||||
|
this.list.appendChild(listItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderInput() {
|
||||||
if (this.options.debug) console.debug('Render');
|
if (this.options.debug) console.debug('Render');
|
||||||
|
|
||||||
switch (this.element.type) {
|
switch (this.element.type) {
|
||||||
case "text":
|
case "text":
|
||||||
this.renderTextInput();
|
this.renderTextInput();
|
||||||
|
this.store.subscribe(this.renderItems);
|
||||||
|
this.renderItems();
|
||||||
break;
|
break;
|
||||||
case "select-one":
|
case "select-one":
|
||||||
// this.renderSelectInput();
|
// this.renderSelectInput();
|
||||||
|
@ -461,7 +468,6 @@ export class Choices {
|
||||||
this.renderTextInput();
|
this.renderTextInput();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
@ -482,36 +488,37 @@ export class Choices {
|
||||||
let choices1 = new Choices({
|
let choices1 = new Choices({
|
||||||
element : input1,
|
element : input1,
|
||||||
// delimiter: ' ',
|
// delimiter: ' ',
|
||||||
// maxItems: 5,
|
editItems: true,
|
||||||
// callbackOnRemoveItem: function(value) {
|
maxItems: 5,
|
||||||
// console.log(value);
|
callbackOnRemoveItem: function(value) {
|
||||||
// },
|
console.log(value);
|
||||||
// callbackOnAddItem: function(item, value) {
|
},
|
||||||
// console.log(item, value);
|
callbackOnAddItem: function(item, value) {
|
||||||
// }
|
console.log(item, value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// let choices2 = new Choices({
|
let choices2 = new Choices({
|
||||||
// element : input2,
|
element : input2,
|
||||||
// allowDuplicates: false,
|
allowDuplicates: false,
|
||||||
// editItems: true,
|
editItems: true,
|
||||||
// });
|
});
|
||||||
|
|
||||||
// let choices3 = new Choices({
|
let choices3 = new Choices({
|
||||||
// element : input3,
|
element : input3,
|
||||||
// allowDuplicates: false,
|
allowDuplicates: false,
|
||||||
// editItems: true,
|
editItems: true,
|
||||||
// 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,}))$/
|
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,}))$/
|
||||||
// });
|
});
|
||||||
|
|
||||||
// let choices4 = new Choices({
|
let choices4 = new Choices({
|
||||||
// element : input4,
|
element : input4,
|
||||||
// addItems: false
|
addItems: false
|
||||||
// });
|
});
|
||||||
|
|
||||||
// let choices5 = new Choices({
|
let choices5 = new Choices({
|
||||||
// element: input5,
|
element: input5,
|
||||||
// prependValue: 'item-',
|
prependValue: 'item-',
|
||||||
// appendValue: `-${Date.now()}`
|
appendValue: `-${Date.now()}`
|
||||||
// });
|
});
|
||||||
})();
|
})();
|
|
@ -5,11 +5,18 @@ const choices = (state = [], action) => {
|
||||||
return [...state, {
|
return [...state, {
|
||||||
id: parseInt(action.id),
|
id: parseInt(action.id),
|
||||||
value: action.value,
|
value: action.value,
|
||||||
element: action.element,
|
|
||||||
active: true,
|
active: true,
|
||||||
selected: false
|
selected: false
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
case 'UNSELECT_ALL':
|
||||||
|
return state.map((item) => {
|
||||||
|
if(item.selected) {
|
||||||
|
item.selected = false;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
case 'REMOVE_ITEM':
|
case 'REMOVE_ITEM':
|
||||||
// Set item to inactive
|
// Set item to inactive
|
||||||
return state.map((item) => {
|
return state.map((item) => {
|
||||||
|
|
51
index.html
51
index.html
|
@ -6,50 +6,23 @@
|
||||||
<link rel="stylesheet" href="assets/styles/css/choices.css">
|
<link rel="stylesheet" href="assets/styles/css/choices.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<label for="1">Text input with no values and a limit of 5 items</label>
|
<div class="container">
|
||||||
<input id="1" type="text" data-choice value="preset-1, preset-2">
|
<label for="1">Text input with no values and a limit of 5 items</label>
|
||||||
<!--
|
<input id="1" type="text" data-choice value="preset-1, preset-2">
|
||||||
<label for="2">Text input with preset values, custom classes and a placeholder. No duplicate values allowed</label>
|
|
||||||
<input id="2" type="text" data-choice value="preset-1, preset-2" placeholder="This is a placeholder" class="custom class">
|
|
||||||
|
|
||||||
<label for="3">Text input that only allows email addresses</label>
|
<label for="2">Text input with preset values, custom classes and a placeholder. No duplicate values allowed</label>
|
||||||
<input id="3" type="text" data-choice placeholder="This is a placeholder">
|
<input id="2" type="text" data-choice value="preset-1, preset-2" placeholder="This is a placeholder" class="custom class">
|
||||||
|
|
||||||
<label for="4">Text input that disables adding items</label>
|
<label for="3">Text input that only allows email addresses</label>
|
||||||
<input id="4" type="text" data-choice value="josh@joshuajohnson.co.uk, joe@bloggs.co.uk" placeholder="This is a placeholder">
|
<input id="3" type="text" data-choice placeholder="This is a placeholder">
|
||||||
|
|
||||||
<label for="5">Text input that prepends and appends a value to each item</label>
|
<label for="4">Text input that disables adding items</label>
|
||||||
<input id="5" type="text" data-choice value="preset-1, preset-2" placeholder="This is a placeholder"> -->
|
<input id="4" type="text" data-choice value="josh@joshuajohnson.co.uk, joe@bloggs.co.uk" placeholder="This is a placeholder">
|
||||||
|
|
||||||
<!-- <label for="3">Select input with two options</label>
|
<label for="5">Text input that prepends and appends a value to each item</label>
|
||||||
<select id="3" name="3" data-choice>
|
<input id="5" type="text" data-choice value="preset-1, preset-2" placeholder="This is a placeholder">
|
||||||
<option value="Value 1">Value 1</option>
|
|
||||||
<option value="Value 2">Value 2</option>
|
|
||||||
<option value="Value 3">Value 3</option>
|
|
||||||
<option value="Value 4">Value 4</option>
|
|
||||||
<option value="Value 5">Value 5</option>
|
|
||||||
<option value="Value 6">Value 6</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select id="4" name="4" data-choice>
|
</div>
|
||||||
<optgroup label="Group 1">
|
|
||||||
<option value="Value 1">Value 1</option>
|
|
||||||
<option value="Value 2">Value 2</option>
|
|
||||||
<option value="Value 3">Value 3</option>
|
|
||||||
</optgroup>
|
|
||||||
<optgroup label="Group 2">
|
|
||||||
<option value="Value 4">Value 4</option>
|
|
||||||
<option value="Value 5">Value 5</option>
|
|
||||||
<option value="Value 6">Value 6</option>
|
|
||||||
</optgroup>
|
|
||||||
</select> -->
|
|
||||||
|
|
||||||
<!-- <label for="4">Multiple select input with two options</label>
|
|
||||||
<select id="4" name="4" data-choice multiple>
|
|
||||||
<option value="Value 1">Value 1</option>
|
|
||||||
<option value="Value 2">Value 2</option>
|
|
||||||
</select>
|
|
||||||
-->
|
|
||||||
<script src="assets/scripts/dist/bundle.js"></script>
|
<script src="assets/scripts/dist/bundle.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Reference in a new issue