Skip to content

Instantly share code, notes, and snippets.

@newyankeecodeshop
Created July 7, 2014 16:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save newyankeecodeshop/8c913c73c650bd5b1157 to your computer and use it in GitHub Desktop.
Save newyankeecodeshop/8c913c73c650bd5b1157 to your computer and use it in GitHub Desktop.
New KendoGrid w/ selection support
/** @jsx React.DOM */
define([
'underscore', 'jquery', 'react', 'kendo'
], function (_, $, React, kendo) {
'use strict';
void kendo;
var PropTypes = React.PropTypes;
function isCellSelection(selectable) {
return _.isString(selectable) ? selectable.indexOf('cell') !== -1 : false;
}
function isMultiSelect(selectable) {
return _.isString(selectable) ? selectable.indexOf('multiple') !== -1 : false;
}
var KendoGrid = React.createClass({
propTypes: {
className: PropTypes.string,
height: PropTypes.string, // Number | String
dataSource: PropTypes.object.isRequired, // Object | Array
autoBind: PropTypes.bool,
columns: PropTypes.array,
rowTemplate: PropTypes.string, // String | Function
pageable: PropTypes.bool, // Boolean | Object
scrollable: PropTypes.bool, // Boolean | Object
selectable: PropTypes.bool, // Boolean | String
sortable: PropTypes.bool, // Boolean | Object
options: PropTypes.object,
value: PropTypes.any,
onChange: PropTypes.func
},
getDefaultProps: function () {
return {
autoBind: true,
pageable: false,
scrollable: true,
selectable: false,
sortable: false
};
},
/*jshint ignore:start */
render: function () {
return (<div className={this.props.className} />);
},
/*jshint ignore:end */
componentDidMount: function () {
var $rootNode = $(this.getDOMNode());
var widgetOptions = _.defaults({
autoBind: this.props.autoBind,
dataSource: this.props.dataSource,
height: this.props.height,
columns: this.props.columns,
rowTemplate: this.props.rowTemplate,
pageable: this.props.pageable,
selectable: this.props.selectable,
scrollable: this.props.scrollable,
sortable: this.props.sortable,
dataBound: this.onGridDataBound,
change: this.onGridChange
}, this.props.options);
$rootNode.kendoGrid(widgetOptions);
},
componentWillUnmount: function () {
$(this.getDOMNode()).data('kendoGrid').destroy();
},
componentDidUpdate: function (prevProps) {
var $el = $(this.getDOMNode());
var grid = $el.data('kendoGrid');
if (this.props.dataSource instanceof Array) {
if (!_.isEqual(this.props.dataSource, prevProps.dataSource)) {
// This better be a datasource that was originally built from inline data.
// I don't know how to detect this to verify it.
grid.dataSource.data(this.props.dataSource);
}
}
else if (prevProps.dataSource !== this.props.dataSource) {
grid.setDataSource(this.props.dataSource);
}
},
onGridDataBound: function (e) {
var grid = e.sender;
if (!grid.selectable) {
return;
}
if (_.isEmpty(this.props.value)) {
grid.selectable.clear(); // Clears the selection without firing a grid "change" event
return;
}
// Fetch the models for the given props
// Get the uid for each model
// Create a jQuery selector for rows with the given uid
grid.select(); // Takes String, Elements, or jQuery
},
onGridChange: function (e) {
var grid = e.sender;
var selectedNodes = grid.select().get(); // get() unwraps the jQuery object
function rowSelection(tr) {
return grid.dataItem(tr);
}
function cellSelection(td) {
return {
cellNode: td,
dataItem: grid.dataItem(td.parentNode)
};
}
var selectedValues = selectedNodes.map(isCellSelection(this.props.selectable) ? cellSelection : rowSelection);
// Don't hand the caller an array if they are doing only single selection. It's nicer that way.
if (!isMultiSelect(this.props.selectable) && (selectedValues.length === 1)) {
selectedValues = selectedValues[0];
}
this.props.onChange(selectedValues);
}
});
return KendoGrid;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment