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