Added keyCode to choice objects

This commit is contained in:
Andrew Whalley 2017-07-19 13:48:46 -04:00
parent a7ee256a85
commit dba6093297
10 changed files with 478 additions and 417 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
export const addItem = (value, label, id, choiceId, groupId, customProperties) => {
export const addItem = (value, label, id, choiceId, groupId, customProperties, keyCode) => {
return {
type: 'ADD_ITEM',
value,
@ -6,7 +6,8 @@ export const addItem = (value, label, id, choiceId, groupId, customProperties) =
id,
choiceId,
groupId,
customProperties
customProperties,
keyCode
};
};
@ -26,7 +27,7 @@ export const highlightItem = (id, highlighted) => {
};
};
export const addChoice = (value, label, id, groupId, disabled, elementId, customProperties) => {
export const addChoice = (value, label, id, groupId, disabled, elementId, customProperties, keyCode) => {
return {
type: 'ADD_CHOICE',
value,
@ -35,7 +36,8 @@ export const addChoice = (value, label, id, groupId, disabled, elementId, custom
groupId,
disabled,
elementId: elementId,
customProperties
customProperties,
keyCode
};
};

View file

@ -838,7 +838,8 @@ class Choices {
true,
false,
-1,
item.customProperties
item.customProperties,
null
);
} else {
this._addItem(
@ -846,7 +847,8 @@ class Choices {
item.label,
item.id,
undefined,
item.customProperties
item.customProperties,
null
);
}
} else if (itemType === 'String') {
@ -856,7 +858,8 @@ class Choices {
item,
true,
false,
-1
-1,
null
);
} else {
this._addItem(item);
@ -901,7 +904,8 @@ class Choices {
foundChoice.label,
foundChoice.id,
foundChoice.groupId,
foundChoice.customProperties
foundChoice.customProperties,
foundChoice.keyCode
);
} else if (!this.config.silent) {
console.warn('Attempting to select choice already selected');
@ -951,7 +955,8 @@ class Choices {
result.selected,
result.disabled,
undefined,
result['customProperties']
result['customProperties'],
null
);
}
});
@ -1158,8 +1163,12 @@ class Choices {
// If we are clicking on an option
const id = element.getAttribute('data-id');
const choice = this.store.getChoiceById(id);
const passedKeyCode = activeItems[0].keyCode !== null ? activeItems[0].keyCode : null
const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);
// Update choice keyCode
choice.keyCode = passedKeyCode
triggerEvent(this.passedElement, 'choice', {
choice,
});
@ -1173,7 +1182,8 @@ class Choices {
choice.label,
choice.id,
choice.groupId,
choice.customProperties
choice.customProperties,
choice.keyCode
);
this._triggerChange(choice.value);
}
@ -1346,7 +1356,8 @@ class Choices {
result.selected,
result.disabled,
undefined,
result['customProperties']
result['customProperties'],
null
);
}
});
@ -1542,7 +1553,7 @@ class Choices {
if (this.isTextElement && target.value) {
const value = this.input.value;
const canAddItem = this._canAddItem(activeItems, value);
// All is good, add
if (canAddItem.response) {
if (hasActiveDropdown) {
@ -1565,6 +1576,8 @@ class Choices {
// If we have a highlighted choice
if (highlighted) {
// add enter keyCode value
activeItems[0].keyCode = enterKey
this._handleChoiceAction(activeItems, highlighted);
}
@ -2102,8 +2115,9 @@ class Choices {
* @return {Object} Class instance
* @public
*/
_addItem(value, label = null, choiceId = -1, groupId = -1, customProperties = null) {
_addItem(value, label = null, choiceId = -1, groupId = -1, customProperties = null, keyCode = null) {
let passedValue = isType('String', value) ? value.trim() : value;
let passedKeyCode = keyCode
const items = this.store.getItems();
const passedLabel = label || passedValue;
const passedOptionId = parseInt(choiceId, 10) || -1;
@ -2124,7 +2138,7 @@ class Choices {
passedValue += this.config.appendValue.toString();
}
this.store.dispatch(addItem(passedValue, passedLabel, id, passedOptionId, groupId, customProperties));
this.store.dispatch(addItem(passedValue, passedLabel, id, passedOptionId, groupId, customProperties, passedKeyCode));
if (this.isSelectOneElement) {
this.removeActiveItems(id);
@ -2137,12 +2151,14 @@ class Choices {
value: passedValue,
label: passedLabel,
groupValue: group.value,
keyCode: passedKeyCode
});
} else {
triggerEvent(this.passedElement, 'addItem', {
id,
value: passedValue,
label: passedLabel,
keyCode: passedKeyCode
});
}
@ -2198,7 +2214,7 @@ class Choices {
* @return
* @private
*/
_addChoice(value, label = null, isSelected = false, isDisabled = false, groupId = -1, customProperties = null) {
_addChoice(value, label = null, isSelected = false, isDisabled = false, groupId = -1, customProperties = null, keyCode = null) {
if (typeof value === 'undefined' || value === null) {
return;
}
@ -2216,7 +2232,8 @@ class Choices {
groupId,
isDisabled,
choiceElementId,
customProperties
customProperties,
keyCode
));
if (isSelected) {
@ -2225,7 +2242,8 @@ class Choices {
choiceLabel,
choiceId,
undefined,
customProperties
customProperties,
keyCode
);
}
}

View file

@ -16,7 +16,8 @@ const choices = (state = [], action) => {
selected: false,
active: true,
score: 9999,
customProperties: action.customProperties
customProperties: action.customProperties,
keyCode: null
}];
}

View file

@ -10,7 +10,8 @@ const items = (state = [], action) => {
label: action.label,
active: true,
highlighted: false,
customProperties: action.customProperties
customProperties: action.customProperties,
keyCode: null
}];
return newState.map((item) => {

View file

@ -1,5 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
@ -24,7 +25,7 @@
<!-- Choices includes -->
<link rel="stylesheet" href="assets/styles/css/choices.min.css?version=2.8.8">
<script src="assets/scripts/dist/choices.min.js?version=2.8.8"></script>
<script src="assets/scripts/dist/choices.js?version=2.8.8"></script>
<!-- End Choices includes -->
<!--[if lt IE 9]>
@ -34,6 +35,7 @@
</style>
<![endif]-->
</head>
<body>
<div class="container">
<div class="section">
@ -41,7 +43,8 @@
<img src="assets/images/logo.svg" alt="Choices.js logo" class="logo__img hidden-ie">
<h1 class="visible-ie">Choices.js</h1>
</a>
<p>Choices.js is a lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.</p>
<p>Choices.js is a lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without
the jQuery dependency.</p>
<p>For all config options, visit the <a href="https://github.com/jshjohnson/Choices">GitHub repo</a>.</p>
<hr>
@ -51,7 +54,8 @@
<input class="form-control" id="choices-text-remove-button" type="text" value="preset-1,preset-2" placeholder="Enter something">
<label for="choices-text-unique-values">Unique values only, no pasting</label>
<input class="form-control" id="choices-text-unique-values" type="text" value="preset-1, preset-2" placeholder="This is a placeholder" class="custom class">
<input class="form-control" id="choices-text-unique-values" type="text" value="preset-1, preset-2" placeholder="This is a placeholder"
class="custom class">
<label for="choices-text-email-filter">Email addresses only</label>
<input class="form-control" id="choices-text-email-filter" type="text" placeholder="This is a placeholder">
@ -75,7 +79,8 @@
<h2>Multiple select input</h2>
<label for="choices-multiple-default">Default</label>
<select class="form-control" data-trigger name="choices-multiple-default" id="choices-multiple-default" placeholder="This is a placeholder" multiple>
<select class="form-control" data-trigger name="choices-multiple-default" id="choices-multiple-default" placeholder="This is a placeholder"
multiple>
<option value="Dropdown item 1" selected>Dropdown item 1</option>
<option value="Dropdown item 2">Dropdown item 2</option>
<option value="Dropdown item 3">Dropdown item 3</option>
@ -83,7 +88,8 @@
</select>
<label for="choices-multiple-remove-button">With remove button</label>
<select class="form-control" name="choices-multiple-remove-button" id="choices-multiple-remove-button" placeholder="This is a placeholder" multiple>
<select class="form-control" name="choices-multiple-remove-button" id="choices-multiple-remove-button" placeholder="This is a placeholder"
multiple>
<option value="Dropdown item 1" selected>Dropdown item 1</option>
<option value="Dropdown item 2">Dropdown item 2</option>
<option value="Dropdown item 3">Dropdown item 3</option>
@ -91,7 +97,8 @@
</select>
<label for="choices-multiple-groups">Option groups</label>
<select class="form-control" name="choices-multiple-groups" id="choices-multiple-groups" placeholder="This is a placeholder" multiple>
<select class="form-control" name="choices-multiple-groups" id="choices-multiple-groups" placeholder="This is a placeholder"
multiple>
<optgroup label="UK">
<option value="London">London</option>
<option value="Manchester">Manchester</option>
@ -130,7 +137,8 @@
<select class="form-control" name="choices-multiple-remote-fetch" id="choices-multiple-remote-fetch" multiple></select>
<label for="choices-multiple-rtl">Right-to-left</label>
<select class="form-control" data-trigger name="choices-multiple-rtl" id="choices-multiple-rtl" placeholder="This is a placeholder" multiple dir="rtl">
<select class="form-control" data-trigger name="choices-multiple-rtl" id="choices-multiple-rtl" placeholder="This is a placeholder"
multiple dir="rtl">
<option value="Dropdown item 1" selected>Dropdown item 1</option>
<option value="Dropdown item 2">Dropdown item 2</option>
<option value="Dropdown item 3">Dropdown item 3</option>
@ -194,7 +202,8 @@
</select>
<label for="choices-single-rtl">Right-to-left</label>
<select class="form-control" data-trigger name="choices-single-rtl" id="choices-single-rtl" placeholder="This is a placeholder" dir="rtl">
<select class="form-control" data-trigger name="choices-single-rtl" id="choices-single-rtl" placeholder="This is a placeholder"
dir="rtl">
<option value="Dropdown item 1">Dropdown item 1</option>
<option value="Dropdown item 2">Dropdown item 2</option>
<option value="Dropdown item 3">Dropdown item 3</option>
@ -242,7 +251,8 @@
<option value="Vue">Vue</option>
</select>
<p>Below is an example of how you could have two select inputs depend on eachother. 'Boroughs' will only be enabled if the value of 'States' is 'New York'</p>
<p>Below is an example of how you could have two select inputs depend on eachother. 'Boroughs' will only be enabled if
the value of 'States' is 'New York'</p>
<label for="states">States</label>
<select class="form-control" name="states" id="states" placeholder="Choose a state">
<option value="Michigan">Michigan</option>
@ -263,7 +273,7 @@
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('DOMContentLoaded', function () {
var textRemove = new Choices(document.getElementById('choices-text-remove-button'), {
delimiter: ',',
editItems: true,
@ -282,10 +292,10 @@
duplicateItems: false,
editItems: true,
maxItemCount: 5,
addItemText: function(value) {
addItemText: function (value) {
return 'Appuyez sur Entrée pour ajouter <b>"' + String(value) + '"</b>';
},
maxItemText: function(maxItemCount) {
maxItemText: function (maxItemCount) {
return String(maxItemCount) + 'valeurs peuvent être ajoutées';
},
uniqueItemText: 'Cette valeur est déjà présente',
@ -322,14 +332,14 @@
placeholder: true,
placeholderValue: 'Pick an Strokes record',
maxItemCount: 5,
}).ajax(function(callback) {
}).ajax(function (callback) {
fetch('https://api.discogs.com/artists/55980/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
.then(function(response) {
response.json().then(function(data) {
.then(function (response) {
response.json().then(function (data) {
callback(data.releases, 'title', 'title');
});
})
.catch(function(error) {
.catch(function (error) {
console.error(error);
});
});
@ -342,46 +352,46 @@
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'},
{ 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: '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) {
choicesSelect.passedElement.addEventListener('addItem', function (event) {
document.getElementById('message').innerHTML = 'You just added "' + event.detail.label + '"';
});
choicesSelect.passedElement.addEventListener('removeItem', function(event) {
choicesSelect.passedElement.addEventListener('removeItem', function (event) {
document.getElementById('message').innerHTML = 'You just removed "' + event.detail.label + '"';
});
var singleFetch = new Choices('#choices-single-remote-fetch', {
placeholder: true,
placeholderValue: 'Pick an Arctic Monkeys record'
}).ajax(function(callback) {
}).ajax(function (callback) {
fetch('https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
.then(function(response) {
response.json().then(function(data) {
.then(function (response) {
response.json().then(function (data) {
callback(data.releases, 'title', 'title');
singleFetch.setValueByChoice('Fake Tales Of San Francisco');
});
})
.catch(function(error) {
.catch(function (error) {
console.error(error);
});
});
var singleXhrRemove = new Choices('#choices-single-remove-xhr', {
removeItemButton: true,
}).ajax(function(callback) {
}).ajax(function (callback) {
var request = new XMLHttpRequest();
request.open('get', 'https://api.discogs.com/artists/83080/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW', true);
request.onreadystatechange = function() {
request.onreadystatechange = function () {
var status;
var data;
if (request.readyState === 4) {
@ -406,14 +416,14 @@
searchEnabled: false,
removeItemButton: true,
choices: [
{value: 'One', label: 'Label One'},
{value: 'Two', label: 'Label Two', disabled: true},
{value: 'Three', label: 'Label Three'},
{ 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: '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', {
@ -423,9 +433,9 @@
id: 1,
disabled: false,
choices: [
{value: 'Child One', label: 'Child One', selected: true},
{value: 'Child Two', label: 'Child Two', disabled: true},
{value: 'Child Three', label: 'Child Three'},
{ value: 'Child One', label: 'Child One', selected: true },
{ value: 'Child Two', label: 'Child Two', disabled: true },
{ value: 'Child Three', label: 'Child Three' },
]
},
{
@ -433,20 +443,22 @@
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: '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', {
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'
}},
{ 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');
@ -456,8 +468,8 @@
var states = new Choices(document.getElementById('states'));
states.passedElement.addEventListener('change', function(e) {
if(e.detail.value === 'New York') {
states.passedElement.addEventListener('change', function (e) {
if (e.detail.value === 'New York') {
boroughs.enable();
} else {
boroughs.disable();
@ -469,13 +481,13 @@
var classNames = this.config.classNames;
var itemSelectText = this.config.itemSelectText;
return {
item: function(data) {
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) +'"\
data-value="'+ String(data.value) + '"\
'+ String(data.active ? 'aria-selected="true"' : '') + '\
'+ String(data.disabled ? 'aria-disabled="true"' : '') + '\
>\
@ -483,15 +495,15 @@
</div>\
');
},
choice: function(data) {
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-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) +'"\
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) + '\
@ -504,15 +516,20 @@
var boroughs = new Choices(document.getElementById('boroughs')).disable();
});
document.getElementById('choices-single-default').addEventListener('addItem', function (e) {
console.log(e)
})
</script>
<!-- Google Analytics - Ignore me -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
window.ga = window.ga || function () { (ga.q = ga.q || []).push(arguments) }; ga.l = +new Date;
ga('create', 'UA-31575166-1', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics -->
</body>
</html>
</html>

View file

@ -14,7 +14,8 @@
"css:min": "csso assets/styles/css/base.css assets/styles/css/base.min.css && csso assets/styles/css/choices.css assets/styles/css/choices.min.css",
"js:build": "concurrently --prefix-colors yellow,green \"webpack --minimize --config webpack.config.prod.js\" \"webpack --config webpack.config.prod.js\"",
"version": "node version.js --current $npm_package_version --new $npm_config_newVersion",
"postversion": "npm run js:build"
"postversion": "npm run js:build",
"dev": "dev"
},
"repository": {
"type": "git",

View file

@ -975,7 +975,8 @@ describe('Choices', () => {
label: 'label',
customProperties: {
foo: 'bar'
}
},
keyCode: null
};
const expectedState = [{
@ -986,7 +987,8 @@ describe('Choices', () => {
label: randomItem.label,
active: true,
highlighted: false,
customProperties: randomItem.customProperties
customProperties: randomItem.customProperties,
keyCode: randomItem.keyCode
}];
const action = addItemAction(
@ -995,7 +997,8 @@ describe('Choices', () => {
randomItem.id,
randomItem.choiceId,
randomItem.groupId,
randomItem.customProperties
randomItem.customProperties,
randomItem.keyCode
);
expect(itemReducer([], action)).toEqual(expectedState);
@ -1011,7 +1014,8 @@ describe('Choices', () => {
disabled: false,
customProperties: {
foo: 'bar'
}
},
keyCode: null
};
const expectedState = [{
@ -1024,7 +1028,8 @@ describe('Choices', () => {
selected: false,
active: true,
score: 9999,
customProperties: randomChoice.customProperties
customProperties: randomChoice.customProperties,
keyCode: randomChoice.keyCode
}];
const action = addChoiceAction(
@ -1034,7 +1039,8 @@ describe('Choices', () => {
randomChoice.groupId,
randomChoice.disabled,
randomChoice.elementId,
randomChoice.customProperties
randomChoice.customProperties,
randomChoice.keyCode
);
expect(choiceReducer([], action)).toEqual(expectedState);