Building a Todo app with React.js (5) - sort item
下一步是允許用戶使用拖放來改變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}>×</button><input type="checkbox" onChange={this.ChangeHandler} defaultChecked={this.props.children.isDone} /><span style={{"textDecoration": _style}}>{this.props.children.item}</span></li>
);
}
你現在應該有下面的截圖
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