From c8f12bc942148a462127f0ef1d7fa1911c0436e0 Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Thu, 15 Sep 2016 21:04:15 +0100 Subject: [PATCH] Deep merge of user config --- assets/scripts/src/choices.js | 54 ++- assets/scripts/src/lib/utils.js | 7 +- index.html | 722 ++++++++++++++++---------------- package.json | 20 +- server.js | 16 +- webpack.config.dev.js | 60 +-- webpack.config.prod.js | 78 ++-- 7 files changed, 485 insertions(+), 472 deletions(-) diff --git a/assets/scripts/src/choices.js b/assets/scripts/src/choices.js index e4bcb8b..c141453 100644 --- a/assets/scripts/src/choices.js +++ b/assets/scripts/src/choices.js @@ -164,7 +164,8 @@ default class Choices { if (!cuttingTheMustard) console.error('Choices: Your browser doesn\'t support Choices'); // Input type check - const canInit = this.passedElement && isElement(this.passedElement) && ['select-one', 'select-multiple', 'text'].some(type => type === this.passedElement.type); + const canInit = this.passedElement && isElement(this.passedElement) && ['select-one', 'select-multiple', 'text'].some(type => type === this.passedElement + .type); if (canInit) { // If element has already been initalised with Choices @@ -657,7 +658,8 @@ default class Choices { // Remove loading states/text this.containerOuter.classList.remove(this.config.classNames.loadingState); if (this.passedElement.type === 'select-multiple') { - const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') : false; + const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') : + false; if (placeholder) { this.input.placeholder = placeholder; } @@ -1697,9 +1699,11 @@ default class Choices { const classNames = this.config.classNames; const templates = { containerOuter: (direction) => { - return strToEl(` + return strToEl( + ` - `); + ` + ); }, containerInner: () => { return strToEl(` @@ -1707,9 +1711,11 @@ default class Choices { `); }, itemList: () => { - return strToEl(` + return strToEl( + `
- `); + ` + ); }, placeholder: (value) => { return strToEl(` @@ -1718,41 +1724,53 @@ default class Choices { }, item: (data) => { if (this.config.removeItemButton) { - return strToEl(` + return strToEl( + `
${data.label}
- `); + ` + ); } - return strToEl(` + return strToEl( + `
${data.label}
- `); + ` + ); }, choiceList: () => { - return strToEl(` + return strToEl( + `
- `); + ` + ); }, choiceGroup: (data) => { - return strToEl(` + return strToEl( + `
${data.value}
- `); + ` + ); }, choice: (data) => { - return strToEl(` + return strToEl( + `
0 ? 'role="treeitem"' : 'role="option"'}> ${data.label}
- `); + ` + ); }, input: () => { - return strToEl(` + return strToEl( + ` - `); + ` + ); }, dropdown: () => { return strToEl(` diff --git a/assets/scripts/src/lib/utils.js b/assets/scripts/src/lib/utils.js index a9d9fa1..297951a 100644 --- a/assets/scripts/src/lib/utils.js +++ b/assets/scripts/src/lib/utils.js @@ -52,7 +52,6 @@ export const isElement = (o) => { */ export const extend = function() { let extended = {}; - let deep = false; let length = arguments.length; /** @@ -63,7 +62,7 @@ export const extend = function() { for (let prop in obj) { if (Object.prototype.hasOwnProperty.call(obj, prop)) { // If deep merge and property is an object, merge properties - if (deep && isType('Object', obj[prop])) { + if (isType('Object', obj[prop])) { extended[prop] = extend(true, extended[prop], obj[prop]); } else { extended[prop] = obj[prop]; @@ -77,11 +76,9 @@ export const extend = function() { // store argument at position i let obj = arguments[i]; - // If we are in fact dealing with an object, merge it. Otherwise throw error + // If we are in fact dealing with an object, merge it. if (isType('Object', obj)) { merge(obj); - } else { - console.error('Custom options must be an object'); } } diff --git a/index.html b/index.html index 62abb0d..78d7818 100644 --- a/index.html +++ b/index.html @@ -1,407 +1,407 @@ - - - Choices - - - - - - - - - + + + Choices + + + + + + + + + - - - + + + - - - + + + - - - - + + + + - + -
-
- -

Choices.js

-

Choices.js is a lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.

-

For all config options, visit the GitHub repo.

+
+
+ +

Choices.js

+

Choices.js is a lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.

+

For all config options, visit the GitHub repo.

-
+
-

Text inputs

- - +

Text inputs

+ + - - + + - - + + - - + + - - + + - - + + - - + + -
+
-

Multiple select input

- - +

Multiple select input

+ + - - + + - - + + - - + + -
+
-

Single select input

- - +

Single select input

+ + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + -

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'

- - +

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'

+ + - - -
+ +
- - - - - + var example12 = new Choices('[data-choice]', { + placeholderValue: 'This is a placeholder set in the config', + removeButton: true, + }); + + var example13 = new Choices('#choices-single-no-search', { + search: false, + 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'); + + var example14 = new Choices('#choices-single-preset-options', { + placeholder: true, + }).setChoices([{ + label: 'Group one', + 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'}, + ] + }, + { + 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 example15 = new Choices('#choices-single-selected-option', { + choices: [ + {value: 'One', label: 'Label One', selected: true}, + {value: 'Two', label: 'Label Two', disabled: true}, + {value: 'Three', label: 'Label Three'}, + ], + }).setValueByChoice('Two'); + + var example16 = new Choices('#choices-single-no-sorting', { + shouldSort: false, + }); + + var states = new Choices(document.getElementById('states'), { + callbackOnChange: function(value) { + if(value === 'New York') { + boroughs.enable(); + } else { + boroughs.disable(); + } + } + }); + + var boroughs = new Choices(document.getElementById('boroughs')).disable(); + }); + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index af5f6be..1b12d93 100644 --- a/package.json +++ b/package.json @@ -63,14 +63,12 @@ "fuse.js": "^2.2.0" }, "npmName": "choices.js", - "npmFileMap": [ - { - "basePath": "assets", - "files": [ - "scripts/dist/*", - "styles/css/*", - "icons/*" - ] - } - ] -} + "npmFileMap": [{ + "basePath": "assets", + "files": [ + "scripts/dist/*", + "styles/css/*", + "icons/*" + ] + }] +} \ No newline at end of file diff --git a/server.js b/server.js index c628865..31ec6cf 100644 --- a/server.js +++ b/server.js @@ -4,11 +4,11 @@ var config = require('./webpack.config.dev'); var opn = require('opn'); new WebpackDevServer(webpack(config), { - publicPath: config.output.publicPath, - historyApiFallback: true, - quiet: true, // lets WebpackDashboard do its thing -}).listen(3000, 'localhost', function (err, result) { - if (err) console.log(err); - opn('http://localhost:3000'); - console.log('Listening at localhost:3000'); -}); + publicPath: config.output.publicPath, + historyApiFallback: true, + quiet: true, // lets WebpackDashboard do its thing +}).listen(3000, 'localhost', function(err, result) { + if (err) console.log(err); + opn('http://localhost:3000'); + console.log('Listening at localhost:3000'); +}); \ No newline at end of file diff --git a/webpack.config.dev.js b/webpack.config.dev.js index fad6b22..78f1da9 100644 --- a/webpack.config.dev.js +++ b/webpack.config.dev.js @@ -5,34 +5,34 @@ var DashboardPlugin = require('webpack-dashboard/plugin'); var dashboard = new Dashboard(); module.exports = { - devtool: 'eval', - entry: [ - 'webpack-dev-server/client?http://localhost:3000', - './assets/scripts/src/choices' - ], - output: { - path: path.join(__dirname, 'dist'), - filename: 'choices.min.js', - publicPath: '/assets/scripts/dist/', - }, - eslint: { - configFile: '.eslintrc' - }, - plugins: [ - new DashboardPlugin(dashboard.setData), - new webpack.HotModuleReplacementPlugin(), - new webpack.DefinePlugin({ - 'process.env': { - 'NODE_ENV': JSON.stringify('development') - } - }) - ], - module: { - loaders: [{ - test: /\.js$/, - exclude: /(node_modules|bower_components)/, - loaders: ['babel', 'eslint-loader'], - include: path.join(__dirname, 'assets/scripts/src') - }] - } + devtool: 'eval', + entry: [ + 'webpack-dev-server/client?http://localhost:3000', + './assets/scripts/src/choices' + ], + output: { + path: path.join(__dirname, 'dist'), + filename: 'choices.min.js', + publicPath: '/assets/scripts/dist/', + }, + eslint: { + configFile: '.eslintrc' + }, + plugins: [ + new DashboardPlugin(dashboard.setData), + new webpack.HotModuleReplacementPlugin(), + new webpack.DefinePlugin({ + 'process.env': { + 'NODE_ENV': JSON.stringify('development') + } + }) + ], + module: { + loaders: [{ + test: /\.js$/, + exclude: /(node_modules|bower_components)/, + loaders: ['babel', 'eslint-loader'], + include: path.join(__dirname, 'assets/scripts/src') + }] + } }; \ No newline at end of file diff --git a/webpack.config.prod.js b/webpack.config.prod.js index 57cb0fe..42b9fc7 100644 --- a/webpack.config.prod.js +++ b/webpack.config.prod.js @@ -6,48 +6,48 @@ var banner = `/*! ${ package.name } v${ package.version } | (c) ${ new Date().ge var minimize = process.argv.indexOf('--minimize') !== -1; var config = { - devtool: 'cheap-module-source-map', - entry: [ - './assets/scripts/src/choices' - ], - output: { - path: path.join(__dirname, '/assets/scripts/dist'), - filename: minimize ? 'choices.min.js' : 'choices.js', - publicPath: '/assets/scripts/dist/' - }, - plugins: [ - new webpack.DefinePlugin({ - 'process.env': { - // This has effect on the react lib size - 'NODE_ENV': JSON.stringify('production'), - } - }), - new wrapperPlugin({ - header: banner, - }), - ], - module: { - loaders: [{ - test: /\.js$/, - exclude: /(node_modules|bower_components)/, - loaders: ['babel'], - include: path.join(__dirname, 'assets/scripts/src') - }] - } + devtool: 'cheap-module-source-map', + entry: [ + './assets/scripts/src/choices' + ], + output: { + path: path.join(__dirname, '/assets/scripts/dist'), + filename: minimize ? 'choices.min.js' : 'choices.js', + publicPath: '/assets/scripts/dist/' + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + // This has effect on the react lib size + 'NODE_ENV': JSON.stringify('production'), + } + }), + new wrapperPlugin({ + header: banner, + }), + ], + module: { + loaders: [{ + test: /\.js$/, + exclude: /(node_modules|bower_components)/, + loaders: ['babel'], + include: path.join(__dirname, 'assets/scripts/src') + }] + } }; if (minimize) { - config.plugins.unshift(new webpack.optimize.UglifyJsPlugin({ - sourceMap: false, - mangle: true, - output: { - comments: false - }, - compress: { - warnings: false, - screw_ie8: true - } - })); + config.plugins.unshift(new webpack.optimize.UglifyJsPlugin({ + sourceMap: false, + mangle: true, + output: { + comments: false + }, + compress: { + warnings: false, + screw_ie8: true + } + })); } module.exports = config; \ No newline at end of file