Skip to content

Instantly share code, notes, and snippets.

@jamesreggio
Forked from petehunt/React sortable
Last active December 31, 2015 04:39
Show Gist options
  • Save jamesreggio/7935417 to your computer and use it in GitHub Desktop.
Save jamesreggio/7935417 to your computer and use it in GitHub Desktop.
This Gist demonstrates how to use an invasive jQuery plugin (UI Sortable) with the latest version of React (0.5.1). It is a simplified (and perhaps unconventional) approach to what @petehunt built in https://gist.github.com/petehunt/7882164.
<html>
<head>
<title>Test</title>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://fb.me/react-0.5.1.js"></script>
<script src="http://fb.me/JSXTransformer-0.5.1.js"></script>
</head>
<body>
<script type="text/jsx">
/** @jsx React.DOM */
var TestItem = React.createClass({
getInitialState: function() {
return {count: 0};
},
componentDidMount: function() {
this.interval = setInterval(this.handleTick, 1000);
},
componentWillUnmount: function() {
clearInterval(this.interval);
},
handleTick: function() {
this.setState({count: this.state.count + 1});
},
render: function() {
return <span>{this.props.children}{': '}{this.state.count}</span>;
}
});
var SmartSortable = React.createClass({
render: function() {
return <ul>{this.props.children}</ul>;
},
componentDidMount: function() {
jQuery(this.getDOMNode()).children().each(function(i) {
this.dataset.index = i;
});
jQuery(this.getDOMNode()).sortable({stop: this.handleDrop});
},
handleDrop: function() {
// Map the `data-index` values to a new item ordering.
var newOrder = jQuery(this.getDOMNode()).children().get()
.map(function(child) { return child.dataset.index; });
// Restore the list to its original ordering, which is necessary to
// ensure that React applies the correct transform after `onSort`.
jQuery(this.getDOMNode()).children().sort(function(a, b) {
return (a.dataset.index > b.dataset.index ? 1 : -1);
}).appendTo(this.getDOMNode());
// Notify our parent of the new item ordering.
this.props.onSort(newOrder);
}
});
var App = React.createClass({
getInitialState: function() {
return {items: ['test 0', 'test 1', 'test 2'], counter: 3};
},
handleSort: function(newOrder) {
var newItems = newOrder.map(function(index) {
return this.state.items[index];
}.bind(this));
this.setState({items: newItems});
},
handleAdd: function() {
var newItems = this.state.items.concat(['test ' + this.state.counter]);
this.setState({items: newItems, counter: this.state.counter + 1});
},
handleRemove: function() {
this.setState({items: this.state.items.slice(0, this.state.items.length - 1)});
},
render: function() {
var items = this.state.items.map(function(item) {
return <li key={item}><TestItem>{item}</TestItem></li>;
});
return (
<div>
<h1>React + Sortable</h1>
<SmartSortable onSort={this.handleSort}>
{items}
</SmartSortable>
<p>Current order: {JSON.stringify(this.state.items)}</p>
<p><button onClick={this.handleAdd}>Add an item</button></p>
<p><button onClick={this.handleRemove}>Remove an item</button></p>
</div>
);
}
});
React.renderComponent(<App />, document.body);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment