Skip to content

Commit

Permalink
Ref JedWatson#25 - Allows numbers (not just strings) as option labels…
Browse files Browse the repository at this point in the history
… and values.

If a multi-select, passes an array to the onChange function (instead of concatenated string)
which is empty when nothing is selected.

If a single select, passes the single value to the onChange function and null if nothing
is selected.
  • Loading branch information
jacobdfriedmann committed Dec 10, 2014
1 parent 9a39bfb commit 57e9386
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 41 deletions.
30 changes: 20 additions & 10 deletions dist/react-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ var Select = React.createClass({
if ('string' === typeof values) {
values = values.split(this.props.delimiter);
} else {
values = values ? [values] : []
values = values ? [values] : [];
}
};

return values.map(function(val) {
return ('string' === typeof val) ? val = _.findWhere(this.state.options, { value: val }) || { value: val, label: val } : val;
return ('string' === typeof val || 'number' === typeof val) ? val = _.findWhere(this.state.options, { value: val }) || { value: val, label: val } : val;
}.bind(this));

},
Expand All @@ -122,10 +122,17 @@ var Select = React.createClass({
this._optionsFilterString = '';

var values = this.initValuesArray(value),
filteredOptions = this.filterOptions(this.state.options, values);

filteredOptions = this.filterOptions(this.state.options, values),
val;

if (this.props.multi) {
val = values.map(function(v) { return v.value });
} else {
val = val = values.length > 0 ? values[0] : null;
}

return {
value: values.map(function(v) { return v.value }).join(this.props.delimiter),
value: val,
values: values,
inputValue: '',
filteredOptions: filteredOptions,
Expand Down Expand Up @@ -335,11 +342,11 @@ var Select = React.createClass({
if (this.props.multi && _.contains(exclude, op.value)) return false;
if (this.props.filterOption) return this.props.filterOption.call(this, op, filterValue);
return !filterValue || (this.props.matchPos === 'start') ? (
(this.props.matchProp !== 'label' && op.value.toLowerCase().substr(0, filterValue.length) === filterValue) ||
(this.props.matchProp !== 'value' && op.label.toLowerCase().substr(0, filterValue.length) === filterValue)
(this.props.matchProp !== 'label' && op.value.toString().toLowerCase().substr(0, filterValue.length) === filterValue) ||
(this.props.matchProp !== 'value' && op.label.toString().toLowerCase().substr(0, filterValue.length) === filterValue)
) : (
(this.props.matchProp !== 'label' && op.value.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) ||
(this.props.matchProp !== 'value' && op.label.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
(this.props.matchProp !== 'label' && op.value.toString().toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) ||
(this.props.matchProp !== 'value' && op.label.toString().toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
);
}
return _.filter(options, filterOption, this);
Expand Down Expand Up @@ -518,7 +525,10 @@ var Option = React.createClass({
displayName: 'Value',

propTypes: {
label: React.PropTypes.string.isRequired
label: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number
]).isRequired
},

blockEvent: function(event) {
Expand Down
2 changes: 1 addition & 1 deletion dist/react-select.min.js

Large diffs are not rendered by default.

30 changes: 20 additions & 10 deletions examples/dist/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ var Option = React.createClass({
displayName: 'Value',

propTypes: {
label: React.PropTypes.string.isRequired
label: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number
]).isRequired
},

blockEvent: function(event) {
Expand Down Expand Up @@ -152,12 +155,12 @@ var Select = React.createClass({
if ('string' === typeof values) {
values = values.split(this.props.delimiter);
} else {
values = values ? [values] : []
values = values ? [values] : [];
}
};

return values.map(function(val) {
return ('string' === typeof val) ? val = _.findWhere(this.state.options, { value: val }) || { value: val, label: val } : val;
return ('string' === typeof val || 'number' === typeof val) ? val = _.findWhere(this.state.options, { value: val }) || { value: val, label: val } : val;
}.bind(this));

},
Expand All @@ -168,10 +171,17 @@ var Select = React.createClass({
this._optionsFilterString = '';

var values = this.initValuesArray(value),
filteredOptions = this.filterOptions(this.state.options, values);

filteredOptions = this.filterOptions(this.state.options, values),
val;

if (this.props.multi) {
val = values.map(function(v) { return v.value });
} else {
val = val = values.length > 0 ? values[0] : null;
}

return {
value: values.map(function(v) { return v.value }).join(this.props.delimiter),
value: val,
values: values,
inputValue: '',
filteredOptions: filteredOptions,
Expand Down Expand Up @@ -381,11 +391,11 @@ var Select = React.createClass({
if (this.props.multi && _.contains(exclude, op.value)) return false;
if (this.props.filterOption) return this.props.filterOption.call(this, op, filterValue);
return !filterValue || (this.props.matchPos === 'start') ? (
(this.props.matchProp !== 'label' && op.value.toLowerCase().substr(0, filterValue.length) === filterValue) ||
(this.props.matchProp !== 'value' && op.label.toLowerCase().substr(0, filterValue.length) === filterValue)
(this.props.matchProp !== 'label' && op.value.toString().toLowerCase().substr(0, filterValue.length) === filterValue) ||
(this.props.matchProp !== 'value' && op.label.toString().toLowerCase().substr(0, filterValue.length) === filterValue)
) : (
(this.props.matchProp !== 'label' && op.value.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) ||
(this.props.matchProp !== 'value' && op.label.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
(this.props.matchProp !== 'label' && op.value.toString().toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) ||
(this.props.matchProp !== 'value' && op.label.toString().toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
);
}
return _.filter(options, filterOption, this);
Expand Down
30 changes: 20 additions & 10 deletions examples/dist/standalone.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ var Select = React.createClass({
if ('string' === typeof values) {
values = values.split(this.props.delimiter);
} else {
values = values ? [values] : []
values = values ? [values] : [];
}
};

return values.map(function(val) {
return ('string' === typeof val) ? val = _.findWhere(this.state.options, { value: val }) || { value: val, label: val } : val;
return ('string' === typeof val || 'number' === typeof val) ? val = _.findWhere(this.state.options, { value: val }) || { value: val, label: val } : val;
}.bind(this));

},
Expand All @@ -122,10 +122,17 @@ var Select = React.createClass({
this._optionsFilterString = '';

var values = this.initValuesArray(value),
filteredOptions = this.filterOptions(this.state.options, values);

filteredOptions = this.filterOptions(this.state.options, values),
val;

if (this.props.multi) {
val = values.map(function(v) { return v.value });
} else {
val = val = values.length > 0 ? values[0] : null;
}

return {
value: values.map(function(v) { return v.value }).join(this.props.delimiter),
value: val,
values: values,
inputValue: '',
filteredOptions: filteredOptions,
Expand Down Expand Up @@ -335,11 +342,11 @@ var Select = React.createClass({
if (this.props.multi && _.contains(exclude, op.value)) return false;
if (this.props.filterOption) return this.props.filterOption.call(this, op, filterValue);
return !filterValue || (this.props.matchPos === 'start') ? (
(this.props.matchProp !== 'label' && op.value.toLowerCase().substr(0, filterValue.length) === filterValue) ||
(this.props.matchProp !== 'value' && op.label.toLowerCase().substr(0, filterValue.length) === filterValue)
(this.props.matchProp !== 'label' && op.value.toString().toLowerCase().substr(0, filterValue.length) === filterValue) ||
(this.props.matchProp !== 'value' && op.label.toString().toLowerCase().substr(0, filterValue.length) === filterValue)
) : (
(this.props.matchProp !== 'label' && op.value.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) ||
(this.props.matchProp !== 'value' && op.label.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
(this.props.matchProp !== 'label' && op.value.toString().toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) ||
(this.props.matchProp !== 'value' && op.label.toString().toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
);
}
return _.filter(options, filterOption, this);
Expand Down Expand Up @@ -518,7 +525,10 @@ var Option = React.createClass({
displayName: 'Value',

propTypes: {
label: React.PropTypes.string.isRequired
label: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number
]).isRequired
},

blockEvent: function(event) {
Expand Down
25 changes: 16 additions & 9 deletions src/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ var Select = React.createClass({
if ('string' === typeof values) {
values = values.split(this.props.delimiter);
} else {
values = values ? [values] : []
values = values ? [values] : [];
}
};

return values.map(function(val) {
return ('string' === typeof val) ? val = _.findWhere(this.state.options, { value: val }) || { value: val, label: val } : val;
return ('string' === typeof val || 'number' === typeof val) ? val = _.findWhere(this.state.options, { value: val }) || { value: val, label: val } : val;
}.bind(this));

},
Expand All @@ -120,10 +120,17 @@ var Select = React.createClass({
this._optionsFilterString = '';

var values = this.initValuesArray(value),
filteredOptions = this.filterOptions(this.state.options, values);

filteredOptions = this.filterOptions(this.state.options, values),
val;

if (this.props.multi) {
val = values.map(function(v) { return v.value });
} else {
val = val = values.length > 0 ? values[0] : null;
}

return {
value: values.map(function(v) { return v.value }).join(this.props.delimiter),
value: val,
values: values,
inputValue: '',
filteredOptions: filteredOptions,
Expand Down Expand Up @@ -333,11 +340,11 @@ var Select = React.createClass({
if (this.props.multi && _.contains(exclude, op.value)) return false;
if (this.props.filterOption) return this.props.filterOption.call(this, op, filterValue);
return !filterValue || (this.props.matchPos === 'start') ? (
(this.props.matchProp !== 'label' && op.value.toLowerCase().substr(0, filterValue.length) === filterValue) ||
(this.props.matchProp !== 'value' && op.label.toLowerCase().substr(0, filterValue.length) === filterValue)
(this.props.matchProp !== 'label' && op.value.toString().toLowerCase().substr(0, filterValue.length) === filterValue) ||
(this.props.matchProp !== 'value' && op.label.toString().toLowerCase().substr(0, filterValue.length) === filterValue)
) : (
(this.props.matchProp !== 'label' && op.value.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) ||
(this.props.matchProp !== 'value' && op.label.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
(this.props.matchProp !== 'label' && op.value.toString().toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) ||
(this.props.matchProp !== 'value' && op.label.toString().toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
);
}
return _.filter(options, filterOption, this);
Expand Down
5 changes: 4 additions & 1 deletion src/Value.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ var Option = React.createClass({
displayName: 'Value',

propTypes: {
label: React.PropTypes.string.isRequired
label: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number
]).isRequired
},

blockEvent: function(event) {
Expand Down

0 comments on commit 57e9386

Please sign in to comment.