github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/public/Sortable-1.4.0/README.md (about)

     1  # Sortable
     2  Sortable is a minimalist JavaScript library for reorderable drag-and-drop lists.
     3  
     4  Demo: http://rubaxa.github.io/Sortable/
     5  
     6  
     7  ## Features
     8  
     9   * Supports touch devices and [modern](http://caniuse.com/#search=drag) browsers (including IE9)
    10   * Can drag from one list to another or within the same list
    11   * CSS animation when moving items
    12   * Supports drag handles *and selectable text* (better than voidberg's html5sortable)
    13   * Smart auto-scrolling
    14   * Built using native HTML5 drag and drop API
    15   * Supports [Meteor](meteor/README.md), [AngularJS](#ng), [React](#react) and [Polymer](#polymer)
    16   * Supports any CSS library, e.g. [Bootstrap](#bs)
    17   * Simple API
    18   * [CDN](#cdn)
    19   * No jQuery (but there is [support](#jq))
    20  
    21  
    22  <br/>
    23  
    24  
    25  ### Articles
    26   * [Sortable v1.0 — New capabilities](https://github.com/RubaXa/Sortable/wiki/Sortable-v1.0-—-New-capabilities/) (December 22, 2014)
    27   * [Sorting with the help of HTML5 Drag'n'Drop API](https://github.com/RubaXa/Sortable/wiki/Sorting-with-the-help-of-HTML5-Drag'n'Drop-API/) (December 23, 2013)
    28  
    29  
    30  <br/>
    31  
    32  
    33  ### Usage
    34  ```html
    35  <ul id="items">
    36  	<li>item 1</li>
    37  	<li>item 2</li>
    38  	<li>item 3</li>
    39  </ul>
    40  ```
    41  
    42  ```js
    43  var el = document.getElementById('items');
    44  var sortable = Sortable.create(el);
    45  ```
    46  
    47  You can use any element for the list and its elements, not just `ul`/`li`. Here is an [example with `div`s](http://jsbin.com/luxero/2/edit?html,js,output).
    48  
    49  
    50  ---
    51  
    52  
    53  ### Options
    54  ```js
    55  var sortable = new Sortable(el, {
    56  	group: "name",  // or { name: "...", pull: [true, false, clone], put: [true, false, array] }
    57  	sort: true,  // sorting inside list
    58  	delay: 0, // time in milliseconds to define when the sorting should start
    59  	disabled: false, // Disables the sortable if set to true.
    60  	store: null,  // @see Store
    61  	animation: 150,  // ms, animation speed moving items when sorting, `0` — without animation
    62  	handle: ".my-handle",  // Drag handle selector within list items
    63  	filter: ".ignore-elements",  // Selectors that do not lead to dragging (String or Function)
    64  	draggable: ".item",  // Specifies which items inside the element should be sortable
    65  	ghostClass: "sortable-ghost",  // Class name for the drop placeholder
    66  	chosenClass: "sortable-chosen",  // Class name for the chosen item
    67  	dataIdAttr: 'data-id',
    68  	
    69  	forceFallback: false,  // ignore the HTML5 DnD behaviour and force the fallback to kick in
    70  	fallbackClass: "sortable-fallback"  // Class name for the cloned DOM Element when using forceFallback
    71  	fallbackOnBody: false  // Appends the cloned DOM Element into the Document's Body
    72  	
    73  	scroll: true, // or HTMLElement
    74  	scrollSensitivity: 30, // px, how near the mouse must be to an edge to start scrolling.
    75  	scrollSpeed: 10, // px
    76  	
    77  	setData: function (dataTransfer, dragEl) {
    78  		dataTransfer.setData('Text', dragEl.textContent);
    79  	},
    80  
    81  	// dragging started
    82  	onStart: function (/**Event*/evt) {
    83  		evt.oldIndex;  // element index within parent
    84  	},
    85  	
    86  	// dragging ended
    87  	onEnd: function (/**Event*/evt) {
    88  		evt.oldIndex;  // element's old index within parent
    89  		evt.newIndex;  // element's new index within parent
    90  	},
    91  
    92  	// Element is dropped into the list from another list
    93  	onAdd: function (/**Event*/evt) {
    94  		var itemEl = evt.item;  // dragged HTMLElement
    95  		evt.from;  // previous list
    96  		// + indexes from onEnd
    97  	},
    98  
    99  	// Changed sorting within list
   100  	onUpdate: function (/**Event*/evt) {
   101  		var itemEl = evt.item;  // dragged HTMLElement
   102  		// + indexes from onEnd
   103  	},
   104  
   105  	// Called by any change to the list (add / update / remove)
   106  	onSort: function (/**Event*/evt) {
   107  		// same properties as onUpdate
   108  	},
   109  
   110  	// Element is removed from the list into another list
   111  	onRemove: function (/**Event*/evt) {
   112  		// same properties as onUpdate
   113  	},
   114  
   115  	// Attempt to drag a filtered element
   116  	onFilter: function (/**Event*/evt) {
   117  		var itemEl = evt.item;  // HTMLElement receiving the `mousedown|tapstart` event.
   118  	},
   119  	
   120  	// Event when you move an item in the list or between lists
   121  	onMove: function (/**Event*/evt) {
   122  		// Example: http://jsbin.com/tuyafe/1/edit?js,output
   123  		evt.dragged; // dragged HTMLElement
   124  		evt.draggedRect; // TextRectangle {left, top, right и bottom}
   125  		evt.related; // HTMLElement on which have guided
   126  		evt.relatedRect; // TextRectangle
   127  		// return false; — for cancel
   128  	}
   129  });
   130  ```
   131  
   132  
   133  ---
   134  
   135  
   136  #### `group` option
   137  To drag elements from one list into another, both lists must have the same `group` value.
   138  You can also define whether lists can give away, give and keep a copy (`clone`), and receive elements.
   139  
   140   * name: `String` — group name
   141   * pull: `true|false|'clone'` — ability to move from the list. `clone` — copy the item, rather than move.
   142   * put: `true|false|["foo", "bar"]` — whether elements can be added from other lists, or an array of group names from which elements can be taken. Demo: http://jsbin.com/naduvo/2/edit?html,js,output
   143  
   144  
   145  ---
   146  
   147  
   148  #### `sort` option
   149  Sorting inside list.
   150  
   151  Demo: http://jsbin.com/xizeh/2/edit?html,js,output
   152  
   153  
   154  ---
   155  
   156  
   157  #### `delay` option
   158  Time in milliseconds to define when the sorting should start.
   159  
   160  Demo: http://jsbin.com/xizeh/4/edit?html,js,output
   161  
   162  
   163  ---
   164  
   165  
   166  #### `disabled` options
   167  Disables the sortable if set to `true`.
   168  
   169  Demo: http://jsbin.com/xiloqu/1/edit?html,js,output
   170  
   171  ```js
   172  var sortable = Sortable.create(list);
   173  
   174  document.getElementById("switcher").onclick = function () {
   175  	var state = sortable.option("disabled"); // get
   176  
   177  	sortable.option("disabled", !state); // set
   178  };
   179  ```
   180  
   181  
   182  ---
   183  
   184  
   185  #### `handle` option
   186  To make list items draggable, Sortable disables text selection by the user.
   187  That's not always desirable. To allow text selection, define a drag handler,
   188  which is an area of every list element that allows it to be dragged around.
   189  
   190  Demo: http://jsbin.com/newize/1/edit?html,js,output
   191  
   192  ```js
   193  Sortable.create(el, {
   194  	handle: ".my-handle"
   195  });
   196  ```
   197  
   198  ```html
   199  <ul>
   200  	<li><span class="my-handle">::</span> list item text one
   201  	<li><span class="my-handle">::</span> list item text two
   202  </ul>
   203  ```
   204  
   205  ```css
   206  .my-handle {
   207  	cursor: move;
   208  	cursor: -webkit-grabbing;
   209  }
   210  ```
   211  
   212  
   213  ---
   214  
   215  
   216  #### `filter` option
   217  
   218  
   219  ```js
   220  Sortable.create(list, {
   221  	filter: ".js-remove, .js-edit",
   222  	onFilter: function (evt) {
   223  		var item = evt.item,
   224  			ctrl = evt.target;
   225  
   226  		if (Sortable.utils.is(ctrl, ".js-remove")) {  // Click on remove button
   227  			item.parentNode.removeChild(item); // remove sortable item
   228  		}
   229  		else if (Sortable.utils.is(ctrl, ".js-edit")) {  // Click on edit link
   230  			// ...
   231  		}
   232  	}
   233  })
   234  ```
   235  
   236  
   237  ---
   238  
   239  
   240  #### `ghostClass` option
   241  Class name for the drop placeholder (default `sortable-ghost`).
   242  
   243  Demo: http://jsbin.com/hunifu/1/edit?css,js,output
   244  
   245  ```css
   246  .ghost {
   247    opacity: 0.4;
   248  }
   249  ```
   250  
   251  ```js
   252  Sortable.create(list, {
   253    ghostClass: "ghost"
   254  });
   255  ```
   256  
   257  
   258  ---
   259  
   260  
   261  #### `chosenClass` option
   262  Class name for the chosen item  (default `sortable-chosen`).
   263  
   264  Demo: http://jsbin.com/hunifu/edit?html,css,js,output
   265  
   266  ```css
   267  .chosen {
   268    color: #fff;
   269    background-color: #c00;
   270  }
   271  ```
   272  
   273  ```js
   274  Sortable.create(list, {
   275    delay: 500,
   276    chosenClass: "chosen"
   277  });
   278  ```
   279  
   280  
   281  ---
   282  
   283  
   284  #### `forceFallback` option
   285  If set to `true`, the Fallback for non HTML5 Browser will be used, even if we are using an HTML5 Browser.
   286  This gives us the possiblity to test the behaviour for older Browsers even in newer Browser, or make the Drag 'n Drop feel more consistent between Desktop , Mobile and old Browsers.
   287  
   288  On top of that, the Fallback always generates a copy of that DOM Element and appends the class `fallbackClass` definied in the options. This behaviour controls the look of this 'dragged' Element.
   289  
   290  Demo: http://jsbin.com/pucurizace/edit?html,css,js,output
   291  
   292  
   293  ---
   294  
   295  
   296  #### `scroll` option
   297  If set to `true`, the page (or sortable-area) scrolls when coming to an edge.
   298  
   299  Demo:
   300   - `window`: http://jsbin.com/boqugumiqi/1/edit?html,js,output 
   301   - `overflow: hidden`: http://jsbin.com/kohamakiwi/1/edit?html,js,output
   302  
   303  
   304  ---
   305  
   306  
   307  #### `scrollSensitivity` option
   308  Defines how near the mouse must be to an edge to start scrolling.
   309  
   310  
   311  ---
   312  
   313  
   314  #### `scrollSpeed` option
   315  The speed at which the window should scroll once the mouse pointer gets within the `scrollSensitivity` distance.
   316  
   317  
   318  ---
   319  
   320  
   321  <a name="ng"></a>
   322  ### Support AngularJS
   323  Include [ng-sortable.js](ng-sortable.js)
   324  
   325  Demo: http://jsbin.com/naduvo/1/edit?html,js,output
   326  
   327  ```html
   328  <div ng-app="myApp" ng-controller="demo">
   329  	<ul ng-sortable>
   330  		<li ng-repeat="item in items">{{item}}</li>
   331  	</ul>
   332  
   333  	<ul ng-sortable="{ group: 'foobar' }">
   334  		<li ng-repeat="item in foo">{{item}}</li>
   335  	</ul>
   336  
   337  	<ul ng-sortable="barConfig">
   338  		<li ng-repeat="item in bar">{{item}}</li>
   339  	</ul>
   340  </div>
   341  ```
   342  
   343  
   344  ```js
   345  angular.module('myApp', ['ng-sortable'])
   346  	.controller('demo', ['$scope', function ($scope) {
   347  		$scope.items = ['item 1', 'item 2'];
   348  		$scope.foo = ['foo 1', '..'];
   349  		$scope.bar = ['bar 1', '..'];
   350  		$scope.barConfig = {
   351  			group: 'foobar',
   352  			animation: 150,
   353  			onSort: function (/** ngSortEvent */evt){
   354  				// @see https://github.com/RubaXa/Sortable/blob/master/ng-sortable.js#L18-L24
   355  			}
   356  		};
   357  	}]);
   358  ```
   359  
   360  
   361  ---
   362  
   363  
   364  <a name="react"></a>
   365  ### Support React
   366  Include [react-sortable-mixin.js](react-sortable-mixin.js).
   367  See [more options](react-sortable-mixin.js#L26).
   368  
   369  
   370  ```jsx
   371  var SortableList = React.createClass({
   372  	mixins: [SortableMixin],
   373  
   374  	getInitialState: function() {
   375  		return {
   376  			items: ['Mixin', 'Sortable']
   377  		};
   378  	},
   379  
   380  	handleSort: function (/** Event */evt) { /*..*/ },
   381  
   382  	render: function() {
   383  		return <ul>{
   384  			this.state.items.map(function (text) {
   385  				return <li>{text}</li>
   386  			})
   387  		}</ul>
   388  	}
   389  });
   390  
   391  React.render(<SortableList />, document.body);
   392  
   393  
   394  //
   395  // Groups
   396  //
   397  var AllUsers = React.createClass({
   398  	mixins: [SortableMixin],
   399  
   400  	sortableOptions: {
   401  		ref: "user",
   402  		group: "shared",
   403  		model: "users"
   404  	},
   405  
   406  	getInitialState: function() {
   407  		return { users: ['Abbi', 'Adela', 'Bud', 'Cate', 'Davis', 'Eric']; };
   408  	},
   409  
   410  	render: function() {
   411  		return (
   412  			<h1>Users</h1>
   413  			<ul ref="user">{
   414  				this.state.users.map(function (text) {
   415  					return <li>{text}</li>
   416  				})
   417  			}</ul>
   418  		);
   419  	}
   420  });
   421  
   422  var ApprovedUsers = React.createClass({
   423  	mixins: [SortableMixin],
   424  	sortableOptions: { group: "shared" },
   425  
   426  	getInitialState: function() {
   427  		return { items: ['Hal', 'Judy']; };
   428  	},
   429  
   430  	render: function() {
   431  		return <ul>{
   432  			this.state.items.map(function (text) {
   433  				return <li>{text}</li>
   434  			})
   435  		}</ul>
   436  	}
   437  });
   438  
   439  React.render(<div>
   440  	<AllUsers/>
   441  	<hr/>
   442  	<ApprovedUsers/>
   443  </div>, document.body);
   444  ```
   445  
   446  
   447  ---
   448  
   449  
   450  <a name="ko"></a>
   451  ### Support KnockoutJS
   452  Include [knockout-sortable.js](knockout-sortable.js)
   453  
   454  ```html
   455  <div data-bind="sortable: {foreach: yourObservableArray, options: {/* sortable options here */}}">
   456  	<!-- optional item template here -->
   457  </div>
   458  
   459  <div data-bind="draggable: {foreach: yourObservableArray, options: {/* sortable options here */}}">
   460  	<!-- optional item template here -->
   461  </div>
   462  ```
   463  
   464  Using this bindingHandler sorts the observableArray when the user sorts the HTMLElements.
   465  
   466  The sortable/draggable bindingHandlers supports the same syntax as Knockouts built in [template](http://knockoutjs.com/documentation/template-binding.html) binding except for the `data` option, meaning that you could supply the name of a template or specify a separate templateEngine. The difference between the sortable and draggable handlers is that the draggable has the sortable `group` option set to `{pull:'clone',put: false}` and the `sort` option set to false by default (overridable).
   467  
   468  Other attributes are:
   469  *	options: an object that contains settings for the underlaying sortable, ie `group`,`handle`, events etc.
   470  *	collection: if your `foreach` array is a computed then you would supply the underlaying observableArray that you would like to sort here.
   471  
   472  
   473  ---
   474  
   475  <a name="polymer"></a>
   476  ### Support Polymer
   477  ```html
   478  
   479  <link rel="import" href="bower_components/Sortable/Sortable-js.html">
   480  
   481  <sortable-js handle=".handle">
   482    <template is="dom-repeat" items={{names}}>
   483      <div>{{item}}</div>
   484    </template>
   485  <sortable-js>
   486  ```
   487  
   488  ### Method
   489  
   490  
   491  ##### option(name:`String`[, value:`*`]):`*`
   492  Get or set the option.
   493  
   494  
   495  
   496  ##### closest(el:`String`[, selector:`HTMLElement`]):`HTMLElement|null`
   497  For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
   498  
   499  
   500  ##### toArray():`String[]`
   501  Serializes the sortable's item `data-id`'s (`dataIdAttr` option) into an array of string.
   502  
   503  
   504  ##### sort(order:`String[]`)
   505  Sorts the elements according to the array.
   506  
   507  ```js
   508  var order = sortable.toArray();
   509  sortable.sort(order.reverse()); // apply
   510  ```
   511  
   512  
   513  ##### save()
   514  Save the current sorting (see [store](#store))
   515  
   516  
   517  ##### destroy()
   518  Removes the sortable functionality completely.
   519  
   520  
   521  ---
   522  
   523  
   524  <a name="store"></a>
   525  ### Store
   526  Saving and restoring of the sort.
   527  
   528  ```html
   529  <ul>
   530  	<li data-id="1">order</li>
   531  	<li data-id="2">save</li>
   532  	<li data-id="3">restore</li>
   533  </ul>
   534  ```
   535  
   536  ```js
   537  Sortable.create(el, {
   538  	group: "localStorage-example",
   539  	store: {
   540  		/**
   541  		 * Get the order of elements. Called once during initialization.
   542  		 * @param   {Sortable}  sortable
   543  		 * @returns {Array}
   544  		 */
   545  		get: function (sortable) {
   546  			var order = localStorage.getItem(sortable.options.group);
   547  			return order ? order.split('|') : [];
   548  		},
   549  
   550  		/**
   551  		 * Save the order of elements. Called onEnd (when the item is dropped).
   552  		 * @param {Sortable}  sortable
   553  		 */
   554  		set: function (sortable) {
   555  			var order = sortable.toArray();
   556  			localStorage.setItem(sortable.options.group, order.join('|'));
   557  		}
   558  	}
   559  })
   560  ```
   561  
   562  
   563  ---
   564  
   565  
   566  <a name="bs"></a>
   567  ### Bootstrap
   568  Demo: http://jsbin.com/luxero/2/edit?html,js,output
   569  
   570  ```html
   571  <!-- Latest compiled and minified CSS -->
   572  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"/>
   573  
   574  
   575  <!-- Latest Sortable -->
   576  <script src="http://rubaxa.github.io/Sortable/Sortable.js"></script>
   577  
   578  
   579  <!-- Simple List -->
   580  <ul id="simpleList" class="list-group">
   581  	<li class="list-group-item">This is <a href="http://rubaxa.github.io/Sortable/">Sortable</a></li>
   582  	<li class="list-group-item">It works with Bootstrap...</li>
   583  	<li class="list-group-item">...out of the box.</li>
   584  	<li class="list-group-item">It has support for touch devices.</li>
   585  	<li class="list-group-item">Just drag some elements around.</li>
   586  </ul>
   587  
   588  <script>
   589      // Simple list
   590      Sortable.create(simpleList, { /* options */ });
   591  </script>
   592  ```
   593  
   594  
   595  ---
   596  
   597  
   598  ### Static methods & properties
   599  
   600  
   601  
   602  ##### Sortable.create(el:`HTMLElement`[, options:`Object`]):`Sortable`
   603  Create new instance.
   604  
   605  
   606  ---
   607  
   608  
   609  ##### Sortable.active:`Sortable`
   610  Link to the active instance.
   611  
   612  
   613  ---
   614  
   615  
   616  ##### Sortable.utils
   617  * on(el`:HTMLElement`, event`:String`, fn`:Function`) — attach an event handler function
   618  * off(el`:HTMLElement`, event`:String`, fn`:Function`) — remove an event handler
   619  * css(el`:HTMLElement`)`:Object` — get the values of all the CSS properties
   620  * css(el`:HTMLElement`, prop`:String`)`:Mixed` — get the value of style properties
   621  * css(el`:HTMLElement`, prop`:String`, value`:String`) — set one CSS properties
   622  * css(el`:HTMLElement`, props`:Object`) — set more CSS properties
   623  * find(ctx`:HTMLElement`, tagName`:String`[, iterator`:Function`])`:Array` — get elements by tag name
   624  * bind(ctx`:Mixed`, fn`:Function`)`:Function` — Takes a function and returns a new one that will always have a particular context
   625  * is(el`:HTMLElement`, selector`:String`)`:Boolean` — check the current matched set of elements against a selector
   626  * closest(el`:HTMLElement`, selector`:String`[, ctx`:HTMLElement`])`:HTMLElement|Null` — for each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree
   627  * toggleClass(el`:HTMLElement`, name`:String`, state`:Boolean`) — add or remove one classes from each element
   628  
   629  
   630  ---
   631  
   632  
   633  <a name="cdn"></a>
   634  ### CDN
   635  
   636  ```html
   637  <!-- CDNJS :: Sortable (https://cdnjs.com/) -->
   638  <script src="//cdnjs.cloudflare.com/ajax/libs/Sortable/1.3.0-rc1/Sortable.min.js"></script>
   639  
   640  
   641  <!-- jsDelivr :: Sortable (http://www.jsdelivr.com/) -->
   642  <script src="//cdn.jsdelivr.net/sortable/1.3.0-rc1/Sortable.min.js"></script>
   643  
   644  
   645  <!-- jsDelivr :: Sortable :: Latest (http://www.jsdelivr.com/) -->
   646  <script src="//cdn.jsdelivr.net/sortable/latest/Sortable.min.js"></script>
   647  ```
   648  
   649  
   650  ---
   651  
   652  
   653  <a name="jq"></a>
   654  ### jQuery compatibility
   655  To assemble plugin for jQuery, perform the following steps:
   656  
   657  ```bash
   658    cd Sortable
   659    npm install
   660    grunt jquery
   661  ```
   662  
   663  Now you can use `jquery.fn.sortable.js`:<br/>
   664  (or `jquery.fn.sortable.min.js` if you run `grunt jquery:min`)
   665  
   666  ```js
   667    $("#list").sortable({ /* options */ }); // init
   668    
   669    $("#list").sortable("widget"); // get Sortable instance
   670    
   671    $("#list").sortable("destroy"); // destroy Sortable instance
   672    
   673    $("#list").sortable("{method-name}"); // call an instance method
   674    
   675    $("#list").sortable("{method-name}", "foo", "bar"); // call an instance method with parameters
   676  ```
   677  
   678  And `grunt jquery:mySortableFunc` → `jquery.fn.mySortableFunc.js`
   679  
   680  ---
   681  
   682  
   683  ### Contributing (Issue/PR)
   684  
   685  Please, [read this](CONTRIBUTING.md). 
   686  
   687  
   688  ---
   689  
   690  
   691  ## MIT LICENSE
   692  Copyright 2013-2015 Lebedev Konstantin <ibnRubaXa@gmail.com>
   693  http://rubaxa.github.io/Sortable/
   694  
   695  Permission is hereby granted, free of charge, to any person obtaining
   696  a copy of this software and associated documentation files (the
   697  "Software"), to deal in the Software without restriction, including
   698  without limitation the rights to use, copy, modify, merge, publish,
   699  distribute, sublicense, and/or sell copies of the Software, and to
   700  permit persons to whom the Software is furnished to do so, subject to
   701  the following conditions:
   702  
   703  The above copyright notice and this permission notice shall be
   704  included in all copies or substantial portions of the Software.
   705  
   706  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   707  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   708  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   709  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
   710  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
   711  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
   712  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   713