Skip to content

Commit

Permalink
text accessor
Browse files Browse the repository at this point in the history
  • Loading branch information
jquense committed Apr 14, 2015
1 parent 695ba05 commit 0df2a02
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 43 deletions.
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = function (config) {
browsers: [ 'PhantomJS'],

preprocessors: {
'_test-bootstrap.js': ['webpack']
'_test-bootstrap.js': ['webpack', 'sourcemap']
},

webpack: require('./webpack.configs').test,
Expand Down
7 changes: 2 additions & 5 deletions src/Combobox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,11 @@ var propTypes = {
listComponent: CustomPropTypes.elementType,

groupComponent: CustomPropTypes.elementType,
groupBy: React.PropTypes.oneOfType([
React.PropTypes.func,
React.PropTypes.string
]),
groupBy: CustomPropTypes.accessor,

data: React.PropTypes.array,
valueField: React.PropTypes.string,
textField: React.PropTypes.string,
textField: CustomPropTypes.accessor,
name: React.PropTypes.string,

onSelect: React.PropTypes.func,
Expand Down
7 changes: 2 additions & 5 deletions src/DropdownList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,14 @@ var propTypes = {

data: React.PropTypes.array,
valueField: React.PropTypes.string,
textField: React.PropTypes.string,
textField: CustomPropTypes.accessor,

valueComponent: CustomPropTypes.elementType,
itemComponent: CustomPropTypes.elementType,
listComponent: CustomPropTypes.elementType,

groupComponent: CustomPropTypes.elementType,
groupBy: React.PropTypes.oneOfType([
React.PropTypes.func,
React.PropTypes.string
]),
groupBy: CustomPropTypes.accessor,

onSelect: React.PropTypes.func,

Expand Down
2 changes: 1 addition & 1 deletion src/List.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = React.createClass({
selectedIndex: React.PropTypes.number,
focusedIndex: React.PropTypes.number,
valueField: React.PropTypes.string,
textField: React.PropTypes.string,
textField: CustomPropTypes.accessor,

optID: React.PropTypes.string,

Expand Down
7 changes: 2 additions & 5 deletions src/ListGroupable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ module.exports = React.createClass({
focused: React.PropTypes.any,

valueField: React.PropTypes.string,
textField: React.PropTypes.string,
textField: CustomPropTypes.accessor,

optID: React.PropTypes.string,

groupBy: React.PropTypes.oneOfType([
React.PropTypes.func,
React.PropTypes.string
]),
groupBy: CustomPropTypes.accessor,

messages: React.PropTypes.shape({
emptyList: React.PropTypes.string
Expand Down
7 changes: 2 additions & 5 deletions src/Multiselect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,14 @@ var propTypes = {
//-------------------------------------------

valueField: React.PropTypes.string,
textField: React.PropTypes.string,
textField: CustomPropTypes.accessor,

tagComponent: CustomPropTypes.elementType,
itemComponent: CustomPropTypes.elementType,
listComponent: CustomPropTypes.elementType,

groupComponent: CustomPropTypes.elementType,
groupBy: React.PropTypes.oneOfType([
React.PropTypes.func,
React.PropTypes.string
]),
groupBy: CustomPropTypes.accessor,

onSelect: React.PropTypes.func,
onCreate: React.PropTypes.func,
Expand Down
3 changes: 2 additions & 1 deletion src/MultiselectTagList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ var React = require('react')
, _ = require('./util/_')
, cx = require('classnames')
, Btn = require('./WidgetButton')
, CustomPropTypes = require('./util/propTypes');

module.exports = React.createClass({

Expand All @@ -17,7 +18,7 @@ module.exports = React.createClass({
value: React.PropTypes.array,

valueField: React.PropTypes.string,
textField: React.PropTypes.string,
textField: CustomPropTypes.accessor,

valueComponent: React.PropTypes.func,

Expand Down
2 changes: 1 addition & 1 deletion src/SelectList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var propTypes = {
listComponent: CustomPropTypes.elementType,

valueField: React.PropTypes.string,
textField: React.PropTypes.string,
textField: CustomPropTypes.accessor,

busy: React.PropTypes.bool,

Expand Down
28 changes: 20 additions & 8 deletions src/mixins/DataHelpersMixin.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
'use strict';
var React = require('react')
, _ = require('../util/_')
, propTypes = require('../util/propTypes')
, { has, isShallowEqual } = require('../util/_')

function accessor(data, field){
var value = data;

if ( typeof field === 'function')
value = field(data)
else if ( data == null )
value = data
else if ( typeof field === 'string' && has(data, field) )
value = data[field]

return value
}

module.exports = {

propTypes: {
valueField: React.PropTypes.string,
textField: React.PropTypes.string,
textField: propTypes.accessor,
},

_dataValue(item){
var field = this.props.valueField;

return field && item && _.has(item, field)
return field && item && has(item, field)
? item[field]
: item
},

_dataText(item){
var field = this.props.textField;

return (field && item && _.has(item, field)
? item[field]
: item) + ''
return accessor(item, field) + ''
},

_dataIndexOf(data, item){
Expand All @@ -36,7 +48,7 @@ module.exports = {
},

_valueMatcher(a, b){
return _.isShallowEqual(
return isShallowEqual(
this._dataValue(a)
, this._dataValue(b))
},
Expand All @@ -49,7 +61,7 @@ module.exports = {
// make an attempt to see if we were passed in dataItem vs just a valueField value
// either an object with the right prop, or a primitive
// { valueField: 5 } || "hello" [ "hello" ]
if( _.has(item, field) || typeof(first) === typeof(val))
if( has(item, field) || typeof(first) === typeof(val))
return item

idx = this._dataIndexOf(data, this._dataValue(item))
Expand Down
5 changes: 5 additions & 0 deletions src/util/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ module.exports = {
React.PropTypes.string,
React.PropTypes.func
]),

accessor: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.func
]),
}


Expand Down
40 changes: 31 additions & 9 deletions test/DataHelperMixin.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,41 @@ describe('when using DATA HELPER MIXIN', function(){
expect(instance._dataValue({ value: { a: 3 } })).to.eql({ a: 3 })
})

it('should get Text Out', function(){
var instance = render(React.createElement(Component))
describe('Reading Data Text', () => {

expect(instance._dataText('hi')).to.equal('hi')
expect(instance._dataText({ a: 3 })).to.equal('[object Object]')
it('should always return a string', function(){
var instance = render(React.createElement(Component))

instance = render(React.createElement(Component, { textField: 'text'}))
expect(instance._dataText('hi')).to.be.a('string')
expect(instance._dataText({ a: 3 })).to.be.a('string')
expect(instance._dataText(null)).to.be.a('string')
expect(instance._dataText(4)).to.be.a('string')
})

expect(instance._dataText('hi')).to.equal('hi')
expect(instance._dataText({ text: 'hi' })).to.equal('hi')
expect(instance._dataText({ text: { a: 3 } })).to.eql('[object Object]')
})
it('should use specified field', function(){
var instance = render(React.createElement(Component, { textField: 'text'}))

expect(instance._dataText('hi')).to.equal('hi')
expect(instance._dataText({ text: 'hi' })).to.equal('hi')
expect(instance._dataText({ text: { a: 3 } })).to.eql('[object Object]')
})

it('should fall back to item when missing field', function(){
var instance = render(React.createElement(Component, { textField: 'text'}))

expect(instance._dataText('hi')).to.equal('hi')
expect(instance._dataText({ missing: 'hi' })).to.equal('[object Object]')
})

it('should work as a function accessor', function(){
var instance = render(React.createElement(Component, { textField: item => item.text + ' hi'}))

expect(instance._dataText({ text: 'hi' })).to.equal('hi hi')
expect(instance._dataText({ text: 'john' })).to.equal('john hi')
expect(instance._dataText({ text: { a: 3 } })).to.eql('[object Object] hi')
})
})


it('should work with indexOf', function(){
var instance = render(React.createElement(Component))
Expand Down
2 changes: 1 addition & 1 deletion test/combobox.browser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('ComboBox', function(){
})

it('should respect textField and valueFields', function(){
var comboBox = render(<ComboBox defaultValue={0} data={dataList} textField='label' valueField='id' />);
var comboBox = render(<ComboBox defaultValue={0} data={dataList} textField={ i => i.label } valueField='id' />);

expect(findClass(comboBox, 'rw-input').getDOMNode().value)
.to.be('jimmy');
Expand Down
2 changes: 1 addition & 1 deletion test/numberpicker.browser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ describe('Numberpicker', function(){
expect(change.calledWithExactly(null)).to.be(true)
})

it.only('should not trigger change at delimiter', function() {
it('should not trigger change at delimiter', function() {
var change = sinon.spy()
, picker = render(<NumberPicker value={1.5} min={12} onChange={change} />)
, input = findClass(picker, 'rw-input').getDOMNode();
Expand Down

0 comments on commit 0df2a02

Please sign in to comment.