End*_*der 5 javascript grid draggable jquery-ui-sortable reactjs
我有一个 React with JS ES6 的任务,过去两周我一直在努力完成它。示例和代码在这篇文章的底部。
我的目标是制作一个“动态可排序的网格”。
我在这里阅读了一些材料,在谷歌上搜索并尝试了React Sortable (HOC)、react-sortablejs、React Sortable等库。我试图重写一个库,但没有成功。
在这种情况下您会使用哪个库,或者您可以建议我在这种情况下做什么?
在输入中,我有一个来自 API 的 JSON,如下所示:
{
"items":[
{
"sub_items":[
{
"id":1,
"name":"Item 1"
}
],
"type":"Type 1"
},
{
"sub_items":[
{
"id":2,
"name":"Item 2"
},
{
"id":3,
"name":"Item 3"
}
],
"type":"Type 2"
},
{
"sub_items":[
{
"id":4,
"name":"Item 4"
}
],
"type":"Type 3"
},
{
"sub_items":[
{
"id":5,
"name":"Item 5"
},
{
"id":6,
"name":"Item 6"
},
{
"id":7,
"name":"Item 7"
}
],
"type":"Type 4"
}
]
}
Run Code Online (Sandbox Code Playgroud)
JSON 保存在 React 状态中,然后在render()方法内部访问。
我的代码:
索引.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Run Code Online (Sandbox Code Playgroud)
应用程序.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
// import { SortableItem, swapArrayPositions } from 'react-sort-list';
// import {SortableContainer, SortableElement} from 'react-sortable-hoc';
import { Container, Row, Col, Form, Nav, NavItem } from 'reactstrap';
import NewItem from "./NewItem";
import './App.css';
class App extends Component {
constructor(props){
super(props);
this.state = {
draggable: true,
items: [
{
"sub_items": [
{
"id": 1,
"name": "Item 1"
}
],
"type": "Type 1"
},
{
"sub_items": [
{
"id": 2,
"name": "Item 2"
},
{
"id": 3,
"name": "Item 3"
}
],
"type": "Type 2"
},
{
"sub_items": [
{
"id": 4,
"name": "Item 4"
}
],
"type": "Type 3"
},
{
"sub_items": [
{
"id": 5,
"name": "Item 5"
},
{
"id": 6,
"name": "Item 6"
},
{
"id": 7,
"name": "Item 7"
}
],
"type": "Type 4"
}
]
}
}
dragStart( event ){
var c = event.target.closest(".td");
var p = c.closest(".tr");
event.dataTransfer.setData("text", c.id);
c.style.width = "150px";
if ( p.children.length !== 3 ){
p.classList.remove("full_row")
}
}
dragEnter(event){
}
dragEnd(event){
var data = event.dataTransfer.getData("text");
var p = document.getElementById(data);
var p = event.target.closest(".tr");
if ( p.children.length === 0 ){
try{
p.remove();
}catch( err ){
console.log( err )
}
}else if ( p.children.length === 1 ){
p.classList.remove("full_row")
}else if ( p.children.length === 2 ){
p.classList.remove("full_row")
for ( var i=0, item; item=p.children[i]; i++ ){
item.classList.remove("row_1");
item.classList.remove("row_3");
item.classList.add("row_2");
}
}else if ( p.children.length === 3 ){
for ( var i=0, item; item=p.children[i]; i++ ){
item.classList.remove("row_1");
item.classList.remove("row_2");
item.classList.add("row_3");
}
}
event.target.style.width = null;
var empty_table_rows = document.getElementsByClassName("tr");
for (var i=0, item; item=empty_table_rows[i]; i++ ){
if ( item.children.length === 0 ){
try{
item.remove();
}catch( err ){
console.log( err );
}
}else{
switch ( item.children.length ){
case 1:
item.children[0].classList.remove("row_3");
item.children[0].classList.remove("row_2");
item.children[0].classList.add("row_1");
break;
case 2:
for (var j=0, child; child=item.children[j]; j++ ){
child.classList.remove("row_1");
child.classList.remove("row_3");
child.classList.add("row_2");
}
break;
case 3:
for (var j=0, child; child=item.children[j]; j++ ){
child.classList.remove("row_1");
child.classList.remove("row_2");
child.classList.add("row_3");
}
break;
}
}
}
var new_rows = document.getElementsByClassName("tr_for_drop");
for ( var i=0; i < new_rows.length; i++ ){
if ( new_rows[i].children.length === 1 || new_rows[i].children.length === 0 ){
new_rows[i].remove();
}
}
var new_items = document.getElementsByClassName("new_item");
for ( var i=0; i < new_items.length; i++ ){
var k = new_itms[i].parentNode;
var m = k.closest(".tr");
k.remove();
if ( m.children.length === 0 ){
m.remove();
}
}
}
dragOver( event ){
event.preventDefault();
event.target.closest(".td").classList.remove("row_1");
event.target.closest(".td").classList.remove("row_2");
event.target.closest(".td").classList.add("row_3");
}
tableRowDragOver( event ){
var _this = this;
console.log("TABLE ROW DRAG OVER")
var table_row = event.target.closest(".tr");
var child_number = table_row.children.length;
console.log(child_number);
switch( child_number ){
case 1:
var d = document.createElement("div");
ReactDOM.render(<NewItem
draggable={ _this.state.draggable }
dragStart={ _this.dragStart.bind( _this ) }
dragEnd={ _this.dragEnd.bind( _this ) }
dragOver={ _this.dragOver.bind( _this ) }
dragEnter={ _this.dragEnter.bind( _this ) }
/>, d)
table_row.appendChild(d)
}
}
drop( event ){
var trigger = event.target.closest(".tr").classList.contains("full_row");
if ( trigger ){
event.preventDefault();
return 0;
}else{
event.preventDefault();
var data = event.dataTransfer.getData("text");
var t = document.getElementById( data );
var p = event.target.closest(".tr");
p.appendChild(t);
if (p.children.length === 3){
p.classList.add("full_row")
for ( var i=0, item; item=p.children[i]; i++ ){
item.classList.remove("row_1");
item.classList.remove("row_2");
item.classList.add("row_3");
}
}else if ( p.children.length === 2 ){
for ( var i=0, item; item=p.children[i]; i++ ){
item.classList.remove("row_1");
item.classList.remove("row_3");
item.classList.add("row_2");
}
}
}
var empty_table_rows = document.getElementsByClassName("tr");
for (var i=0, item; item=empty_table_rows[i]; i++ ){
if ( item.children.length === 0 ){
try{
item.remove()
}catch( err ){
console.log( err )
}
}else{
switch ( item.children.length ){
case 1:
item.children[0].classList.remove("row_3");
item.children[0].classList.remove("row_2");
item.children[0].classList.add("row_1");
break;
case 2:
for (var j=0, child; child=item.children[j]; j++ ){
child.classList.remove("row_1");
child.classList.remove("row_3");
child.classList.add("row_2");
}
break;
case 3:
for (var j=0, child; child=item.children[j]; j++ ){
child.classList.remove("row_1");
child.classList.remove("row_2");
child.classList.add("row_3");
}
break;
}
}
}
var new_rows = document.getElementsByClassName("tr_for_drop");
for ( var i=0; i < new_rows.length; i++ ){
if ( new_rows[i].children.length === 1 || new_rows[i].children.length === 0 ){
new_rows[i].remove();
}
}
var new_items = document.getElementsByClassName("new_item");
for ( var i=0; i < new_items.length; i++ ){
var item = new_items[i];
var ch = item.closest(".tr_for_drop").children;
console.log(item.closest(".tr_for_drop"))
if ( ch.length === 1 ){
// item.closest(".tr_for_drop").remove();
}else{
item.closest(".tr_for_drop").classList.add("real_row");
item.closest(".tr_for_drop").classList.remove("tr_for_drop");
item.remove();
}
}
return false;
}
render() {
const Items = (data) => {
console.log(data.items.length)
switch (data.items.length) {
case 1:
return (
<div onDragOver={this.tableRowDragOver.bind(this)}
onDrop={this.drop.bind(this)}
className="tr real_row">
{
data.items.map((item, item_index) => {
return (
<div key={item_index}
onDragStart={this.dragStart.bind(this)}
onDragEnd={this.dragEnd.bind(this)}
onDragOver={this.dragOver.bind(this)}
onDragEnter={this.dragEnter.bind(this)}
draggable={this.state.draggable}
id={"item" + item.id}
className="disable_select td real_item item_cell row_1 ui-sortable itemParent"
data-name={item.name}
data-parent-row="1"
data-col={item_index + 1}>
<div className="command_navigate" style={{
opacity: "0.5",
position: "absolute",
transform: "rotateZ(90deg)",
left: "10px",
top: "10px"
}}>
<i className="ion-ios-more"/>
<i style={{marginTop: "-5px", position: "absolute", left: "0"}}
className="ion-ios-more"/>
</div>
<div data-type="draft_item" className="item_container disable_select">
{item.name}
</div>
</div>
)
})
}
</div>
);
case 2:
return (
<div onDragOver={this.tableRowDragOver.bind(this)}
onDrop={this.drop.bind(this)}
className="tr real_row">
{
data.items.map((item, item_index) => {
return (
<div key={item_index}
onDragStart={this.dragStart.bind(this)}
onDragEnd={this.dragEnd.bind(this)}
onDragOver={this.dragOver.bind(this)}
onDragEnter={this.dragEnter.bind(this)}
draggable={this.state.draggable}
id={"item_" + item.id}
className="disable_select td real_item item_cell row_2 ui-sortable itemParent"
data-id={item.id}
data-name={item.name}
data-col={item_index + 1}>
<div className="item_navigate" style={{
opacity: "0.5",
position: "absolute",
transform: "rotateZ(90deg)",
left: "10px",
top: "10px"
}}>
<i className="ion-ios-more"/>
<i style={{marginTop: "-5px", position: "absolute", left: "0"}}
className="ion-ios-more"/>
</div>
<div data-type="draft_item" className="item_container">
{item.name}
</div>
</div>
)
})
}
</div>
);
case 3:
return (
<div onDragOver={this.tableRowDragOver.bind(this)}
onDrop={this.drop.bind(this)}
className="tr real_row full_row">
{
data.items.map((item, item_index) => {
return (
<div key={item_index}
onDragStart={this.dragStart.bind(this)}
onDragEnd={this.dragEnd.bind(this)}
onDragOver={this.dragOver.bind(this)}
onDragEnter={this.dragEnter.bind(this)}
draggable={this.state.draggable}
id={"item_" + item.id}
className="disable_select td real_item item_cell row_3 ui-sortable itemParent" data-id={item.id}
data-name={item.name}
data-parent-row="1"
data-col={item_index + 1}>
<div className="item_navigate" style={{
opacity: "0.5",
position: "absolute",
transform: "rotateZ(90deg)",
left: "10px",
top: "10px"
}}>
<i className="ion-ios-more"/>
<i style={{marginTop: "-5px", position: "absolute", left: "0"}}
className="ion-ios-more"/>
</div>
<div data-type="draft_item" className="item_container">
{item.name}
</div>
</div>
)
})
}
</div>
)
}
};
return (
<div>
<div className="table ui-sortable">
<div className="tbody">
{
this.state.items.map((item, index) => {
return (
| 归档时间: |
|
| 查看次数: |
1519 次 |
| 最近记录: |