Browse Source

#217: + base react mixin without 'linked lists'

pull/248/merge
RubaXa 10 years ago
parent
commit
dc2b05d8f2
  1. 34
      README.md
  2. 12
      index.html
  3. 6
      package.json
  4. 94
      react-sortable-mixin.js
  5. 74
      st/app.js

34
README.md

@ -12,7 +12,7 @@ Demo: http://rubaxa.github.io/Sortable/
* Supports drag handles *and selectable text* (better than voidberg's html5sortable) * Supports drag handles *and selectable text* (better than voidberg's html5sortable)
* Smart auto-scrolling * Smart auto-scrolling
* Built using native HTML5 drag and drop API * Built using native HTML5 drag and drop API
* Supports [Meteor](meteor/README.md) and [AngularJS](#ng) * Supports [Meteor](meteor/README.md), [AngularJS](#ng) and [React](#react)
* Supports any CSS library, e.g. [Bootstrap](#bs) * Supports any CSS library, e.g. [Bootstrap](#bs)
* Simple API * Simple API
* No jQuery (but there is [support](#jq)) * No jQuery (but there is [support](#jq))
@ -282,6 +282,38 @@ angular.module('myApp', ['ng-sortable'])
--- ---
<a name="react"></a>
### Support React
Include [react-sortable-mixin.js](react-sortable-mixin.js).
See more [here](react-sortable-mixin.js#L37).
```jsx
var SortableList = React.createClass({
mixins: [SortableMixin],
getInitialState: function() {
return {
items: ['Mixin', 'Sortable']
};
},
render: function() {
return <ul>{
this.state.items.map(function (text) {
return <li>{text}</li>
})
}</ul>
}
});
React.render(<SortableList />, document.body);
```
---
### Method ### Method

12
index.html

@ -7,8 +7,8 @@
<title>Sortable. No jQuery.</title> <title>Sortable. No jQuery.</title>
<meta name="keywords" content="sortable, reorder, list, javascript, html5, drag and drop, dnd, animation, groups, angular, ng-sortable, effects, rubaxa"/> <meta name="keywords" content="sortable, reorder, list, javascript, html5, drag and drop, dnd, animation, groups, angular, ng-sortable, react, mixin, effects, rubaxa"/>
<meta name="description" content="Sortable - is a minimalist JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery. Supports Meteor and AngularJS and any CSS library, e.g. Bootstrap."/> <meta name="description" content="Sortable - is a minimalist JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery. Supports Meteor, AngularJS, React and any CSS library, e.g. Bootstrap."/>
<meta name="viewport" content="width=device-width, initial-scale=0.5"/> <meta name="viewport" content="width=device-width, initial-scale=0.5"/>
<link href="//rubaxa.github.io/Ply/ply.css" rel="stylesheet" type="text/css"/> <link href="//rubaxa.github.io/Ply/ply.css" rel="stylesheet" type="text/css"/>
@ -210,6 +210,14 @@
</div> </div>
<!-- React mixin -->
<a name="react"></a>
<div class="container" style="margin-top: 100px">
<div id="react-box" style="margin-left: 30px;"></div>
<div style="clear: both"></div>
</div>
<!-- Code example --> <!-- Code example -->
<a name="c"></a> <a name="c"></a>
<div class="container" style="margin-top: 100px"> <div class="container" style="margin-top: 100px">

6
package.json

@ -22,7 +22,11 @@
"keywords": [ "keywords": [
"sortable", "sortable",
"reorder", "reorder",
"drag" "drag",
"meteor",
"angular",
"react",
"mixin"
], ],
"author": "Konstantin Lebedev <ibnRubaXa@gmail.com>", "author": "Konstantin Lebedev <ibnRubaXa@gmail.com>",
"license": "MIT" "license": "MIT"

94
react-sortable-mixin.js vendored

@ -27,7 +27,99 @@
* @mixin * @mixin
*/ */
var SortableMixin = { var SortableMixin = {
sortableMixinVersion: '0.0.0' sortableMixinVersion: '0.0.0',
/**
* @type {Sortable}
* @private
*/
_sortableInstance: null,
/**
* Sortable options
* @returns {object}
*/
getDefaultProps: function () {
return {
sortable: {
ref: 'list',
model: 'items',
animation: 100,
onStart: 'handleStart',
onEnd: 'handleEnd',
onAdd: 'handleAdd',
onUpdate: 'handleUpdate',
onRemove: 'handleRemove',
onSort: 'handleSort',
onFilter: 'handleFilter'
}
};
},
componentDidMount: function () {
var nextSibling,
sortableProps = this.props.sortable,
sortableOptions = {},
callMethod = function (/** string */type, /** Event */evt) {
var method = this[sortableProps[type]];
method && method.call(this, evt, this._sortableInstance);
}.bind(this);
// Pass through unrecognized options
for (var key in sortableProps) {
sortableOptions[key] = sortableProps[key];
}
// Bind callbacks so that "this" refers to the component
'onEnd onAdd onUpdate onRemove onFilter'.split(' ').forEach(function (/** string */name) {
if (sortableProps[name]) {
sortableOptions[name] = callMethod.bind(this, name);
}
}.bind(this));
sortableOptions.onStart = function (/** Event */evt) {
nextSibling = evt.item.nextSibling;
callMethod('onStart', evt);
}.bind(this);
sortableOptions.onSort = function (/** Event */evt) {
evt.from.insertBefore(evt.item, nextSibling || null);
var modelName = sortableProps.model,
newState = {},
items = this.state[modelName];
if (items) {
items = items.slice(); // clone
items.splice(evt.newIndex, 0, items.splice(evt.oldIndex, 1)[0]);
newState[modelName] = items;
this.setState(newState);
}
callMethod('onSort', evt);
}.bind(this);
/** @namespace this.refs — http://facebook.github.io/react/docs/more-about-refs.html */
if (!sortableProps.ref || this.refs[sortableProps.ref]) {
this._sortableInstance = Sortable.create((this.refs[sortableProps.ref] || this).getDOMNode(), sortableOptions);
}
},
componentWillUnmount: function () {
this._sortableInstance.destroy();
this._sortableInstance = null;
}
}; };

74
st/app.js

@ -1,5 +1,41 @@
(function () { (function () {
'use strict';
var byId = function (id) { return document.getElementById(id); }, var byId = function (id) { return document.getElementById(id); },
loadScripts = function (desc, callback) {
var deps = [], key, idx = 0;
for (key in desc) {
deps.push(key);
}
(function _next() {
var pid,
name = deps[idx],
script = document.createElement('script');
script.type = 'text/javascript';
script.src = desc[deps[idx]];
pid = setInterval(function () {
if (window[name]) {
clearTimeout(pid);
deps[idx++] = window[name];
if (deps[idx]) {
_next();
} else {
callback.apply(null, deps);
}
}
}, 30);
document.getElementsByTagName('head')[0].appendChild(script);
})()
},
console = window.console; console = window.console;
@ -159,9 +195,47 @@
$scope.sortableConfig['on' + name] = console.log.bind(console, name); $scope.sortableConfig['on' + name] = console.log.bind(console, name);
}); });
}]); }]);
// React
loadScripts({
'React': '//fb.me/react-0.12.2.js',
'SortableMixin': 'react-sortable-mixin.js'
}, function (React, SortableMixin) {
var SortableList = React.createClass({
mixins: [SortableMixin],
getInitialState: function() {
return {
items: [
'Mixin',
'Sortable'
]
};
},
render: function() {
return React.DOM.div(null,
React.DOM.h4({ children: 'React mixin', className: 'layer title title_xl', style: { marginBottom: 0 } }),
React.DOM.div({ style: { width: '30%', marginLeft: '10px', cursor: 'move' }, className: 'block__list_words' },
React.DOM.ul({
ref: 'list',
children: this.state.items.map(function (v) {
return React.DOM.li(null, v);
})
})
)
);
}
});
React.render(React.createElement(SortableList, {}), byId('react-box'));
});
})(); })();
// Background // Background
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {
function setNoiseBackground(el, width, height, opacity) { function setNoiseBackground(el, width, height, opacity) {

Loading…
Cancel
Save