React-js-todo-list-sortable(5)

Building a Todo app with React.js (5) - sort item

TodoListApp

下一步是允許用戶使用拖放來改變ToDoListItem的序列( DND)

我們將允許用戶進行排序使用拖放一個數組。我們首先創建li元素。

var placeholder = document.createElement("li");
    placeholder.className = "placeholder";

Component 1 - ToDoList

我們創建DragStar功能, DragEnd功能的dragover函數來實現(拖放)的DnD過程。

DragStart: function(e){
    this.dragged = e.currentTarget;
    e.dataTransfer.effectAllowed = 'move';
},
DragEnd: function(e){
    this.dragged.style.display="";
    var IshasNode = false

    Array.prototype.forEach.call (this.dragged.parentNode.childNodes, function (node) {
        if(node.className=="placeholder")
                        IshasNode = true;

    } );
    if(!IshasNode)
    return;
    this.dragged.parentNode.removeChild(placeholder);
    var data = this.props.items;
    var from = Number(this.dragged.dataset.id);
    var to = Number(this.over.dataset.id);
    if(from < to) to--;
    if(this.nodePlacement == "after") to++;
    data.splice(to, 0, data.splice(from, 1)[0]);
    this.setState({data: data});    
},
DragOver: function(e) {

    e.preventDefault();
    this.dragged.style.display = "none";

    if(e.target.className == "placeholder") return;
    this.over = e.target;
    // Inside the dragOver method
    var relY = e.clientY - this.over.offsetTop;
    var height = this.over.offsetHeight / 2;
    var parent = e.target.parentNode;

    if(relY > height) {
      this.nodePlacement = "after";
      parent.insertBefore(placeholder, e.target.nextElementSibling);
    }
    else if(relY < height) {
      this.nodePlacement = "before"
      parent.insertBefore(placeholder, e.target);
    }
},

DragStar功能和DragEnd功能被綁定到ToDoListItem組件。

    var createItem = function(itemText,i) {
        return (
            <ToDoListItem key={i} value={i} onDragEnd={this.DragEnd}
onDragStart={this.DragStart} onRemove = {this.Remove}>{itemText}</ToDoListItem>
        );
    };

dragover功能被綁定到UI元素。

<ul onDragOver={this.DragOver}>{allitems.map(createItem,this)}</ul>;

Component 2 - ToDoListItem

我們創造DragEndHandler功能, DragStartHandler功能觸發父的事件,並綁定到li元素。我們還需要設置 li元素上draggable = true屬性。

DragEndHandler : function(e){
    this.props.onDragEnd(e);
},
DragStartHandler : function(e){
    this.props.onDragStart(e);
},
render: function(){
    var _style = "line-through";
    if(!this.props.children.isDone)
    _style ="none";
    return (
      <li data-id={this.props.value} 
                key={this.props.value} draggable="true" onDragEnd={this.DragEndHandler}
            onDragStart={this.DragStartHandler}><button type="button" className="close pull-right" aria-hidden="true" onClick={this.RemoveHandler}>&times;</button><input type="checkbox" onChange={this.ChangeHandler} defaultChecked={this.props.children.isDone} /><span style={{"textDecoration": _style}}>{this.props.children.item}</span></li>
    );
}

你現在應該有下面的截圖
TodoListApp
The complete working demo can be found here .

##Building a Todo app with React.js (1) - A simple todos list

##Building a Todo app with React.js (2) - Improve Component & Remove Component

##Building a Todo app with React.js (3) - Adding Filters for Search and showing complete/incompleted tasks

##Building a Todo app with React.js (4) - Multiple Todos

##Building a Todo app with React.js (5) - Sort item