2 * @author RubaXa <trash@rubaxa.org>
9 if (typeof module != 'undefined' && typeof module.exports != 'undefined') {
10 module.exports = factory(require('./Sortable'));
12 else if (typeof define === 'function' && define.amd) {
13 define(['./Sortable'], factory);
17 window['SortableMixin'] = factory(Sortable);
19 })(function (/** Sortable */Sortable) {
26 var _defaultOptions = {
31 onStart: 'handleStart',
34 onUpdate: 'handleUpdate',
35 onRemove: 'handleRemove',
37 onFilter: 'handleFilter',
42 function _getModelName(component) {
43 return component.sortableOptions && component.sortableOptions.model || _defaultOptions.model;
47 function _getModelItems(component) {
48 var name = _getModelName(component),
49 items = component.state && component.state[name] || component.props[name];
55 function _extend(dst, src) {
56 for (var key in src) {
57 if (src.hasOwnProperty(key)) {
67 * Simple and easy mixin-wrapper for rubaxa/Sortable library, in order to
68 * make reorderable drag-and-drop lists on modern browsers and touch devices.
73 sortableMixinVersion: '0.1.1',
80 _sortableInstance: null,
83 componentDidMount: function () {
84 var DOMNode, options = _extend(_extend({}, _defaultOptions), this.sortableOptions || {}),
85 copyOptions = _extend({}, options),
87 emitEvent = function (/** string */type, /** Event */evt) {
88 var method = this[options[type]];
89 method && method.call(this, evt, this._sortableInstance);
93 // Bind callbacks so that "this" refers to the component
94 'onStart onEnd onAdd onSort onUpdate onRemove onFilter onMove'.split(' ').forEach(function (/** string */name) {
95 copyOptions[name] = function (evt) {
96 if (name === 'onStart') {
97 _nextSibling = evt.item.nextElementSibling;
98 _activeComponent = this;
100 else if (name === 'onAdd' || name === 'onUpdate') {
101 evt.from.insertBefore(evt.item, _nextSibling);
105 oldIndex = evt.oldIndex,
106 newIndex = evt.newIndex,
107 items = _getModelItems(this),
111 if (name === 'onAdd') {
112 remoteItems = _getModelItems(_activeComponent);
113 item = remoteItems.splice(oldIndex, 1)[0];
114 items.splice(newIndex, 0, item);
116 remoteState[_getModelName(_activeComponent)] = remoteItems;
119 items.splice(newIndex, 0, items.splice(oldIndex, 1)[0]);
122 newState[_getModelName(this)] = items;
124 if (copyOptions.stateHandler) {
125 this[copyOptions.stateHandler](newState);
127 this.setState(newState);
130 (this !== _activeComponent) && _activeComponent.setState(remoteState);
133 setTimeout(function () {
134 emitEvent(name, evt);
139 DOMNode = this.getDOMNode() ? (this.refs[options.ref] || this).getDOMNode() : this.refs[options.ref] || this;
141 /** @namespace this.refs — http://facebook.github.io/react/docs/more-about-refs.html */
142 this._sortableInstance = Sortable.create(DOMNode, copyOptions);
145 componentWillReceiveProps: function (nextProps) {
147 modelName = _getModelName(this),
148 items = nextProps[modelName];
151 newState[modelName] = items;
152 this.setState(newState);
156 componentWillUnmount: function () {
157 this._sortableInstance.destroy();
158 this._sortableInstance = null;
164 return SortableMixin;