ampersand-multiselect-view
Advanced tools
Comparing version 0.0.1 to 0.0.2
@@ -22,5 +22,9 @@ /* $AMPERSAND_VERSION */ | ||
// Set to empty-string if undefined or null, but not if 0, false, etc | ||
if (value === null || value === undefined) value = ''; | ||
if (value === null || value === undefined) { | ||
value = ''; | ||
} | ||
if (disabled) node.disabled = true; | ||
if (disabled) { | ||
node.disabled = true; | ||
} | ||
node.textContent = text; | ||
@@ -36,3 +40,5 @@ node.value = value; | ||
if (typeof opts.name !== 'string') throw new Error('MultiSelectView requires a name property.'); | ||
if (typeof opts.name !== 'string') { | ||
throw new Error('MultiSelectView requires a name property.'); | ||
} | ||
this.name = opts.name; | ||
@@ -76,4 +82,8 @@ | ||
if (opts.beforeSubmit) this.beforeSubmit = opts.beforeSubmit; | ||
if (opts.autoRender) this.autoRender = opts.autoRender; | ||
if (opts.beforeSubmit) { | ||
this.beforeSubmit = opts.beforeSubmit; | ||
} | ||
if (opts.autoRender) { | ||
this.autoRender = opts.autoRender; | ||
} | ||
}, | ||
@@ -84,7 +94,12 @@ | ||
labelEl; | ||
if (this.rendered) return; | ||
if (this.rendered) { | ||
return; | ||
} | ||
elDom = domify(this.template); | ||
if (!this.el) this.el = elDom; | ||
else this.el.appendChild(elDom); | ||
if (!this.el) { | ||
this.el = elDom; | ||
} else { | ||
this.el.appendChild(elDom); | ||
} | ||
@@ -104,5 +119,11 @@ labelEl = this.el.querySelector('[data-hook~=label]'); | ||
} | ||
if (!this.select) throw new Error('no select found in template'); | ||
if (matches(this.el, 'select')) this.select = this.el; | ||
if (this.select) this.select.setAttribute('name', this.name); | ||
if (!this.select) { | ||
throw new Error('no select found in template'); | ||
} | ||
if (matches(this.el, 'select')) { | ||
this.select = this.el; | ||
} | ||
if (this.select) { | ||
this.select.setAttribute('name', this.name); | ||
} | ||
@@ -164,3 +185,5 @@ this.select.selectedIndices = []; | ||
renderOptions: function () { | ||
if (!this.select) return; | ||
if (!this.select) { | ||
return; | ||
} | ||
@@ -189,11 +212,14 @@ this.select.innerHTML = ''; | ||
// Unselect all options (we'll re-select the matching options later if neccessary) | ||
this.getAllOptions().forEach(function(v,i,a) { | ||
this.getAllOptions().forEach(function(v,i) { | ||
this.select.options[i].selected = false; | ||
}.bind(this)); | ||
if (lookupValues === null || lookupValues === undefined || lookupValues === '') | ||
if (lookupValues === null || lookupValues === undefined || lookupValues === '') { | ||
return this; | ||
} | ||
// Make sure values is an array or collection | ||
if (!lookupValues.isCollection && Object.prototype.toString.call(lookupValues) !== '[object Array]') lookupValues = [lookupValues]; | ||
if (!lookupValues.isCollection && Object.prototype.toString.call(lookupValues) !== '[object Array]') { | ||
lookupValues = [lookupValues]; | ||
} | ||
@@ -206,3 +232,3 @@ // Remove any options that don't exist in the collection (if collection is provided for options) | ||
}.bind(this)).map(function(v) { | ||
return lookupValue[this.idAttribute]; | ||
return lookupValues[this.idAttribute]; | ||
}.bind(this)); | ||
@@ -221,3 +247,5 @@ } | ||
remove: function () { | ||
if (this.el && this.el.parentNode) this.el.parentNode.removeChild(this.el); | ||
if (this.el && this.el.parentNode) { | ||
this.el.parentNode.removeChild(this.el); | ||
} | ||
this.el.removeEventListener('change', this.onChange, false); | ||
@@ -245,5 +273,3 @@ }, | ||
setValue: function (values, skipValidationMessage, init) { | ||
var option, model, nullValid; | ||
setValue: function (values, skipValidationMessage) { | ||
if (values === null || values === undefined || values === '' || values === []) { | ||
@@ -259,4 +285,8 @@ this.value = []; | ||
this.validate(skipValidationMessage); | ||
if (this.select) this.updateSelectedOptions(); | ||
if (this.parent && typeof this.parent.update === 'function') this.parent.update(this); | ||
if (this.select) { | ||
this.updateSelectedOptions(); | ||
} | ||
if (this.parent && typeof this.parent.update === 'function') { | ||
this.parent.update(this); | ||
} | ||
return this.value; | ||
@@ -270,3 +300,5 @@ }, | ||
this.valid = true; | ||
if (this.select) this.toggleMessage(skipValidationMessage); | ||
if (this.select) { | ||
this.toggleMessage(skipValidationMessage); | ||
} | ||
return this.valid; | ||
@@ -277,6 +309,10 @@ } | ||
this.valid = false; | ||
if (this.select) this.toggleMessage(skipValidationMessage, this.requiredMessage); | ||
if (this.select) { | ||
this.toggleMessage(skipValidationMessage, this.requiredMessage); | ||
} | ||
} else { | ||
this.valid = true; | ||
if (this.select) this.toggleMessage(skipValidationMessage); | ||
if (this.select) { | ||
this.toggleMessage(skipValidationMessage); | ||
} | ||
} | ||
@@ -317,7 +353,11 @@ | ||
for (var i = this.options.length - 1; i >= 0; i--) { | ||
if (this.options[i][0] == value) return this.options[i]; | ||
if (this.options[i][0] == value) { | ||
return this.options[i]; | ||
} | ||
} | ||
} | ||
// find option, formatted ['valAndText', ...] format | ||
if (this.options.length && this.options.indexOf(value) !== -1) return value; | ||
if (this.options.length && this.options.indexOf(value) !== -1) { | ||
return value; | ||
} | ||
return false; | ||
@@ -343,4 +383,8 @@ } | ||
getOptionValue: function (option) { | ||
if (Array.isArray(option)) return option[0]; | ||
if (this.options.isCollection) return option[this.idAttribute]; | ||
if (Array.isArray(option)) { | ||
return option[0]; | ||
} | ||
if (this.options.isCollection) { | ||
return option[this.idAttribute]; | ||
} | ||
return option; | ||
@@ -350,3 +394,5 @@ }, | ||
getOptionText: function (option) { | ||
if (Array.isArray(option)) return option[1]; | ||
if (Array.isArray(option)) { | ||
return option[1]; | ||
} | ||
if (this.options.isCollection) { | ||
@@ -362,4 +408,8 @@ if (this.textAttribute && option[this.textAttribute] !== undefined) { | ||
getOptionDisabled: function (option) { | ||
if (Array.isArray(option)) return option[2]; | ||
if (this.options.isCollection && this.disabledAttribute) return option[this.disabledAttribute]; | ||
if (Array.isArray(option)) { | ||
return option[2]; | ||
} | ||
if (this.options.isCollection && this.disabledAttribute) { | ||
return option[this.disabledAttribute]; | ||
} | ||
@@ -373,3 +423,5 @@ return false; | ||
if (!mContainer || !mText) return; | ||
if (!mContainer || !mText) { | ||
return; | ||
} | ||
@@ -376,0 +428,0 @@ if (hide) { |
@@ -58,15 +58,10 @@ /*global console*/ | ||
options: ['a', 'b', 'c'], | ||
value: 'c', | ||
value: ['c'], | ||
}), | ||
new MultiSelectView({ | ||
name: 'two.1', | ||
parent: this, | ||
options: [ ['a', 'Option A'], ['b', 'Option B'], ['c', 'Option C'] ], | ||
}), | ||
new MultiSelectView({ | ||
name: 'two.2', | ||
parent: this, | ||
options: [ ['a', 'Option A'], ['b', 'Option B'], ['c', 'Option C'] ], | ||
value: 'b', | ||
value: ['b'], | ||
}), | ||
@@ -89,3 +84,3 @@ | ||
options: collection1, | ||
value: collection1.at(2), | ||
value: [collection1.at(2)], | ||
idAttribute: 'id', | ||
@@ -92,0 +87,0 @@ textAttribute: 'title', |
{ | ||
"name": "ampersand-multiselect-view", | ||
"description": "A view module for intelligently rendering and validating multiple selectbox input. Works well with ampersand-form-view. Based off of ampersand-select-view.", | ||
"version": "0.0.1", | ||
"author": { | ||
"version": "0.0.2", | ||
"author": { | ||
"name": "Kyle Farris", | ||
@@ -11,8 +11,8 @@ "email": "kylefarris@gmail.com" | ||
{ | ||
"name": "Philip Roberts", | ||
"email": "phil@andyet.net" | ||
"name": "Philip Roberts", | ||
"email": "phil@andyet.net" | ||
}, | ||
{ | ||
"name": "Christopher Dieringer", | ||
"url": "https://github.com/cdaringe" | ||
"name": "Christopher Dieringer", | ||
"url": "https://github.com/cdaringe" | ||
} | ||
@@ -19,0 +19,0 @@ ], |
@@ -128,12 +128,4 @@ # ampersand-multiselect-view | ||
``` | ||
## gotchas | ||
* Numeric option values are generally stringified by the browser. Be mindful doing comparisons. You'll generally desire to inspect `selectView.value` (the value of your selected options' input) over `selectView.select.value` (the value returned from the browser). | ||
* Additionally, do **not** use option sets containing values that `==` one another. E.g., do not use options whose values are "2" (string) and 2 (number). Browsers cannot distinguish between them in the select control context, thus nor can ampersand-select-view. | ||
* `null`, `undefined`, or `''` option values are not considered `valid` when the field is required. This does not apply when options are from a collection and `yieldModel` is enabled. | ||
## browser support | ||
[![testling badge](https://ci.testling.com/AmpersandJS/ampersand-select-view.png)](https://ci.testling.com/AmpersandJS/ampersand-select-view) | ||
## changelog | ||
@@ -140,0 +132,0 @@ |
var suite = require('tape-suite'); | ||
var viewConventions = require('ampersand-view-conventions'); | ||
var FormView = require('ampersand-form-view'); | ||
var SelectView = require('../ampersand-select-view'); | ||
var MultiSelectView = require('../ampersand-multiselect-view'); | ||
var AmpersandState = require('ampersand-state'); | ||
@@ -34,3 +34,5 @@ var AmpersandCollection = require('ampersand-collection'); | ||
if (!Function.prototype.bind) Function.prototype.bind = require('function-bind'); | ||
if (!Function.prototype.bind) { | ||
Function.prototype.bind = require('function-bind'); | ||
} | ||
@@ -45,4 +47,4 @@ var fieldOptions = { | ||
viewConventions.view(suite.tape, SelectView, fieldOptions); | ||
viewConventions.formField(suite.tape, SelectView, fieldOptions, 'foo'); | ||
viewConventions.view(suite.tape, MultiSelectView, fieldOptions); | ||
viewConventions.formField(suite.tape, MultiSelectView, fieldOptions, 'foo'); | ||
@@ -61,16 +63,16 @@ //Wrap sync tests | ||
fieldOptions = { | ||
name: 'word', | ||
label: 'Choose a word', | ||
name: 'words', | ||
label: 'Choose some words', | ||
options: ['foo', 'bar', 'baz'], | ||
autoRender: true | ||
}; | ||
view = new SelectView(fieldOptions); | ||
view = new MultiSelectView(fieldOptions); | ||
}); | ||
s.test('autorenders on init', sync(function (t) { | ||
t.ok(view.el.querySelector('select')); | ||
t.ok(view.el.querySelector('select[multiple="multiple"]')); | ||
})); | ||
s.test('empty option-set', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
name: 'num', | ||
@@ -83,3 +85,3 @@ options: [], | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
name: 'num', | ||
@@ -95,8 +97,8 @@ options: [], | ||
var labelText = view.el.querySelector('[data-hook~=label]').textContent; | ||
t.equal(labelText, 'Choose a word'); | ||
t.equal(labelText, 'Choose some words'); | ||
})); | ||
s.test('label text falls back to name', sync(function (t) { | ||
view = new SelectView({ | ||
name: 'word', | ||
view = new MultiSelectView({ | ||
name: 'words', | ||
options: [], | ||
@@ -106,9 +108,9 @@ autoRender: true | ||
var labelText = view.el.querySelector('[data-hook~=label]').textContent; | ||
t.equal(labelText, 'word'); | ||
t.equal(labelText, 'words'); | ||
})); | ||
s.test('works with just <select></select>', sync(function (t) { | ||
view = new SelectView({ | ||
name: 'word', | ||
template: '<select></select>', | ||
s.test('works with just <select multiple></select>', sync(function (t) { | ||
view = new MultiSelectView({ | ||
name: 'words', | ||
template: '<select multiple></select>', | ||
options: ['foo', 'bar', 'baz'] | ||
@@ -121,4 +123,4 @@ }); | ||
s.test('set valid name on select input', sync(function (t) { | ||
view = new SelectView({ | ||
name: 'word', | ||
view = new MultiSelectView({ | ||
name: 'words', | ||
options: [], | ||
@@ -128,7 +130,7 @@ autoRender: true | ||
var selectName = view.el.querySelector('select').getAttribute('name'); | ||
t.equal(selectName, 'word'); | ||
t.equal(selectName, 'words'); | ||
})); | ||
s.test('message container', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -138,4 +140,3 @@ name: 'num', | ||
eagerValidate: false, | ||
required: true, | ||
unselectedText: 'default' | ||
required: true | ||
}); | ||
@@ -145,3 +146,3 @@ | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -151,4 +152,3 @@ name: 'num', | ||
eagerValidate: true, | ||
required: true, | ||
unselectedText: 'default' | ||
required: true | ||
}); | ||
@@ -160,3 +160,3 @@ | ||
s.test('eagerValidation', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -166,4 +166,3 @@ name: 'num', | ||
eagerValidate: true, | ||
required: true, | ||
unselectedText: 'default' | ||
required: true | ||
}); | ||
@@ -181,7 +180,7 @@ | ||
s.test('clear', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
name: 'word', | ||
options: arr, | ||
value: 'two' | ||
value: ['two'] | ||
}); | ||
@@ -201,3 +200,3 @@ | ||
s.test('clear on view with `unselectedText`', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -221,3 +220,3 @@ name: 'word', | ||
s.test('clear on `required` view`', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -244,3 +243,3 @@ name: 'word', | ||
s.test('clear on `required` view with `unselectedText`', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -265,3 +264,3 @@ name: 'word', | ||
s.test('reset on view with initial value', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -286,3 +285,3 @@ name: 'word', | ||
s.test('reset on view with no initial value', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -305,3 +304,3 @@ name: 'word', | ||
var ops = [0, 1, 2]; | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -324,3 +323,3 @@ name: 'word', | ||
var formEl = document.createElement('form'); | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
name: 'word', | ||
@@ -353,3 +352,3 @@ options: arr, | ||
s.test('renders the number options into the select', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -383,3 +382,3 @@ name: 'num', | ||
s.test('renders the options into the select (array)', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -405,3 +404,3 @@ name: 'word', | ||
s.test('renders the empty item', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -425,3 +424,3 @@ name: 'word', | ||
s.test('selects the right item (options: [\'valAndText\'])', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -453,3 +452,3 @@ name: 'word', | ||
s.test('options are enabled', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -477,3 +476,3 @@ name: 'word', | ||
s.test('renders the arr-num options into the select', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -500,3 +499,3 @@ name: 'num', | ||
s.test('renders the arr-str options into the select', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -522,3 +521,3 @@ name: 'word', | ||
s.test('renders the empty item', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -542,3 +541,3 @@ name: 'word', | ||
s.test('selects the right item (options: [[\'val\', \'text\']])', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -570,3 +569,3 @@ name: 'word', | ||
s.test('renders a disabled item if a third value is passed which is truthy', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -597,3 +596,3 @@ name: 'word', | ||
s.test('renders the options into the select (collection)', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -629,3 +628,3 @@ name: 'word', | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -674,3 +673,3 @@ name: 'word', | ||
s.test('renders the options into the select with different id attribute (collection)', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -694,3 +693,3 @@ name: 'word', | ||
s.test('renders the empty item', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -722,3 +721,3 @@ name: 'word', | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -746,3 +745,3 @@ name: 'testNullId', | ||
s.test('selects the right item by id/model (options: collection)', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -781,3 +780,3 @@ name: 'word', | ||
s.test('selects the right item by id/model (options: collection), with yieldModel: false', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -831,3 +830,3 @@ name: 'word', | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -857,3 +856,3 @@ name: 'word', | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -871,3 +870,3 @@ el: el, | ||
s.test('does not fail when el has no parent and remove is invoked', sync(function (t) { | ||
view = new SelectView({ | ||
view = new MultiSelectView({ | ||
autoRender: true, | ||
@@ -874,0 +873,0 @@ name: 'num', |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1169
54784
146