Browse Source

完成列表例子

方正 7 years ago
parent
commit
3ff4bcaece
3 changed files with 188 additions and 78 deletions
  1. 29 9
      src/SortableList/index.tsx
  2. 2 2
      src/index.tsx
  3. 157 67
      src/lib/dragactList/dragactList.tsx

+ 29 - 9
src/SortableList/index.tsx

@@ -14,14 +14,26 @@ const Words = [
 const Cell = (props: any) => {
     const item = props.item;
     return (
-        <div className='layout-Cell' style={{ width: 400, height: 50 }}>
+        <div className='layout-Cell' style={{ width: 400, height: 50, border: '1px solid black' }}>
             <img src={item.img} style={{ width: 45, height: 45 }} draggable={false} alt='card'></img>
             <div style={{ paddingLeft: 12, color: '#595959' }}>{item.content}</div>
         </div>
     )
 }
 
+const dataList = [
+    { y: 0, ...Words[0], key: '0' },
+    { y: 1, ...Words[1], key: '1' },
+    { y: 2, ...Words[2], key: '2' },
+    { y: 3, ...Words[3], key: '3' }
+]
 
+const dataList2 = [
+    { y: 0, ...Words[0], key: '100' },
+    { y: 1, ...Words[1], key: '101' },
+    { y: 2, ...Words[2], key: '201' },
+    { y: 3, ...Words[3], key: '301' }
+]
 
 
 
@@ -30,18 +42,26 @@ export class SortableList extends React.Component<{}, {}> {
     two: DragactList | null;
 
 
+
+
     render() {
+        const list = [dataList, dataList2];
+
         return (
             <div style={{ display: 'flex', justifyContent: 'center' }}>
                 <div>
-                    <h1 style={{ textAlign: 'center' }}>Sorted Table Demo</h1>
-                    <DragactList width={400} rowHeight={60} margin={[50, 5]} className='normal-layout' ref={node => this.one = node}>
-                        {Words.map((el, index) => {
-                            return <Cell item={el} key={index} data-set={{ y: index }} />
-                        })}
-                        {Words.map((el, index) => {
-                            return <Cell item={el} key={index + 100} data-set={{ y: index }} />
-                        })}
+                    <h1 style={{ textAlign: 'center' }}>Sort list Demo</h1>
+                    <DragactList
+                        layout={list}
+                        width={450}
+                        rowHeight={60}
+                        margin={[50, 5]}
+                        className='normal-layout'
+                        ref={node => this.one = node}
+                    >
+                        {(child: any, index: number) => {
+                            return <Cell item={child} />
+                        }}
                     </DragactList>
                 </div>
             </div>

+ 2 - 2
src/index.tsx

@@ -6,7 +6,7 @@ import { SortedTableWithStatic } from "./StaticHeader/index";
 import { LayoutRestore } from "./LayoutRestore/index";
 import { HandleLayout } from "./HandleLayout/index";
 import { AddRemove } from "./AddRemove/index";
-// import { SortableList } from "./SortableList/index";
+import { SortableList } from "./SortableList/index";
 import './index.css'
 
 
@@ -18,7 +18,7 @@ const DemoMap: any = {
     LayoutRestore: <LayoutRestore />,
     HandleLayout: <HandleLayout />,
     AddRemove: <AddRemove />,
-    // SortableList: <SortableList />
+    SortableList: <SortableList />
 }
 
 class DemoDispatcher extends React.Component<{}, {}> {

+ 157 - 67
src/lib/dragactList/dragactList.tsx

@@ -25,6 +25,8 @@ export interface DragactLayoutItem {
 }
 
 export interface DragactProps {
+    layout: any;
+
     /** 
      * 容器的宽度
     */
@@ -105,13 +107,14 @@ export class Column extends React.Component<{}, {}>{
 }
 
 interface ListItemEvent {
-    key: any,
-    x: number,
+    key: any
+    x: number
     y: number
+    currentListIndex: number
 }
 
 interface ListCellProps {
-    x: number
+    currentListIndex: number
     y: number
     isUserMove: Boolean
     style: React.CSSProperties
@@ -135,6 +138,8 @@ const checkInContainer = (GridX: number, GridY: number) => {
 
 export class ListCell extends React.Component<ListCellProps, {}>{
 
+
+
     calGridXY(x: number, y: number) {
         const { margin, width, col, rowHeight } = this.props
         const containerWidth = width * col + margin[0];
@@ -149,30 +154,31 @@ export class ListCell extends React.Component<ListCellProps, {}>{
 
     onDragStart = (x: number, y: number) => {
         const { GridX, GridY } = this.calGridXY(x, y);
-        const { UniqueKey } = this.props;
+        const { UniqueKey, currentListIndex } = this.props;
 
-        this.props.onDragStart({ key: UniqueKey, x: GridX, y: GridY });
+        this.props.onDragStart({ key: UniqueKey, x: GridX, y: GridY, currentListIndex: currentListIndex });
     }
     onDrag = (event: any, x: number, y: number) => {
         const { GridX, GridY } = this.calGridXY(x, y);
-        const { UniqueKey } = this.props;
+        const { UniqueKey, currentListIndex } = this.props;
 
-        this.props.onDrag({ key: UniqueKey, x: GridX, y: GridY });
+        this.props.onDrag({ key: UniqueKey, x: GridX, y: GridY, currentListIndex: currentListIndex });
     }
 
     onDragEnd = (event: any, x: number, y: number) => {
         const { GridX, GridY } = this.calGridXY(x, y);
-        const { UniqueKey } = this.props;
-        this.props.onDragEnd({ key: UniqueKey, x: GridX, y: GridY });
+        const { UniqueKey, currentListIndex } = this.props;
+        console.log(this.props)
+        this.props.onDragEnd({ key: UniqueKey, x: GridX, y: GridY, currentListIndex: currentListIndex });
     }
 
 
     render() {
-        const { x, y, isUserMove, width, style, rowHeight, margin } = this.props;
+        const { currentListIndex, y, isUserMove, width, style, rowHeight, margin } = this.props;
 
         return (
             <Dragger
-                x={x * width}
+                x={currentListIndex * width}
                 y={Math.round(y * rowHeight + margin[1] * (y + 1))}
                 style={{ ...style, width: width, transition: this.props.isUserMove ? '' : 'all .2s', }}
                 isUserMove={isUserMove}
@@ -205,7 +211,7 @@ const swapList = (list: any, movingItem: any, firstKey: any) => {
             const num = collision(oldItem.y, movingItem.y)
             if (num > 0) {
                 // console.log(num)
-                var offset = oldItem.y - 1
+                var offset = movingItem.y - 1
                 // if (movingItem.y > oldItem.y && movingItem.y < oldItem.y + 1) {
                 //     /**
                 //      * 元素向上移动时,元素的上面空间不足,则不移动这个元素
@@ -280,14 +286,14 @@ export const compactList = (list: any, movingItem: any) => {
         if (a.y > b.y) return 1
         return 0
     })
-    // console.log('sor',sort)
     const needCompact = Array(list.length)
     const after: any = [];
+    const mapList: any = {};
     for (const i in sort) {
         const finished = compactCell(after, sort[i]);
-
         if (movingItem) {
             if (movingItem.key === finished.key) {
+                // finished.y = movingItem.y;
                 finished.isUserMove = true
             } else
                 finished.isUserMove = false
@@ -297,10 +303,13 @@ export const compactList = (list: any, movingItem: any) => {
 
         after.push(finished);
         needCompact[(i as any)] = finished;
+        mapList[finished.key] = finished;
     }
 
-
-    return needCompact;
+    return {
+        compacted: needCompact,
+        maped: mapList
+    };
 }
 
 
@@ -311,15 +320,18 @@ export class DragactList extends React.Component<DragactProps, any> {
         super(props)
         // const layout = getDataSet(props.children);
 
+        const array: any = [];
 
-        const layout = props.children.map((child: any) => {
-            return child.map((el: any) => {
-                return { ...el.props['data-set'], key: el.key, isUserMove: false };
+        const layout = props.layout.map((child: any, idx: number) => {
+            return child.map((el: any, index: number) => {
+                if (!array[idx]) array[idx] = {};
+                array[idx][el.key] = { ...el, key: el.key, isUserMove: false, currentListIndex: idx }
+                return { ...el, key: el.key, isUserMove: false, currentListIndex: idx };
             })
         })
-        // console.log(layout)
-        // console.log(layout);
 
+
+        console.log(array)
         this.state = {
             GridXMoving: 0,
             GridYMoving: 0,
@@ -332,7 +344,9 @@ export class DragactList extends React.Component<DragactProps, any> {
             dragType: 'drag',
             mapLayout: undefined,
             col: 3,
-            currentList: 0
+            currentList: 0,
+            maped: array,
+            lastList: void 666
         }
     }
 
@@ -384,15 +398,21 @@ export class DragactList extends React.Component<DragactProps, any> {
 
     componentDidMount() {
 
-        setTimeout(() => {
-            const swp = [...this.state.layout[0]]
-            this.state.layout[0] = this.state.layout[1];
-            this.state.layout[1] = swp;
-            this.setState({
-                layout: this.state.layout
-            })
+        // setTimeout(() => {
+        //     const swp = [...this.state.layout[0]]
+        //     this.state.layout[0] = this.state.layout[1];
+        //     this.state.layout[1] = swp;
 
-        }, 1000);
+        //     const swpMap = { ...this.state.maped[0] }
+        //     this.state.maped[0] = this.state.maped[1];
+        //     this.state.maped[1] = swpMap;
+
+        //     this.setState({
+        //         layout: this.state.layout,
+        //         maped: this.state.maped
+        //     })
+        //     // console.log(this.state.layout)
+        // }, 1000);
     }
 
 
@@ -407,94 +427,164 @@ export class DragactList extends React.Component<DragactProps, any> {
                 break;
             }
         }
+
         this.setState({
             layout: this.state.layout,
-            currentList: x
+            lastList: x
         })
-        console.log(this.state.layout)
     }
 
     onDrag = (e: ListItemEvent) => {
-        const { key, x, y } = e;
+        const { key, x, y, currentListIndex } = e;
 
+        if (!this.state.layout[x]) return;//如果超出列表,就返回
 
-        const newList = swapList(this.state.layout[x], { y, key }, key)
-        const compacted = compactList(newList, { y, key });
-        this.state.layout[x] = compacted;
+        if (x !== e.currentListIndex) {
+            //移动到别的列表
+            const i = this.state.maped[x][key];
+            if (!i) {
+                this.state.layout[x].push({ y, isUserMove: false, key, content: 'placeholder', currentListIndex })
+            }
+        }
+
+        // if (x !== this.state.lastList && this.state.lastList !== e.currentListIndex) {
+        //     const { lastList } = this.state;
+        //     //跟上一个不一样的时候
+        //     this.state.layout[lastList] = this.state.layout[lastList].filter((item: any) => {
+        //         if (item.key !== key) {
+        //             return item
+        //         }
+        //     })
+
+        //     const compact = compactList(this.state.layout[lastList], undefined);
+        //     this.state.layout[lastList] = compact.compacted;
+        //     console.log(`上一次:${lastList}`, this.state.layout)
+
+        //     delete this.state.maped[lastList][key]
+        //     console.log(this.state.maped)
+        // }
 
+        console.log(e)
+        const newList = swapList(this.state.layout[x], { y, key }, key);
+        const { compacted, maped } = compactList(newList, { y, key });
+        this.state.layout[x] = compacted;
+        this.state.maped[x] = maped;
         this.setState({
-            layout: [...this.state.layout]
+            layout: [...this.state.layout],
+            maped: [...this.state.maped],
+            lastList: x
         })
     }
 
     onDragEnd = (e: ListItemEvent) => {
-        const { x, y } = e;
-
-        if (this.state.currentList !== x) {
-            this.state.layout[x].push({ y, key: "10203", isUserMove: false })
-            const compacted = compactList(this.state.layout[x], undefined);
-            this.state.layout[x] = compacted;
-            this.setState({
-                layout: [...this.state.layout]
+        const { x, key, currentListIndex } = e;
+
+
+        if (x !== currentListIndex) {//如果跨列表操作
+
+            //1.删除原来list中的数据
+            this.state.layout[currentListIndex] = this.state.layout[currentListIndex].filter((item: any) => {
+                if (item.key !== key) {
+                    return item
+                }
             })
+            //2.删除原来map中的数据
+            delete this.state.maped[currentListIndex][key];
 
-        } else {
-            const compacted = compactList(this.state.layout[x], undefined);
-            this.state.layout[x] = compacted;
-            this.setState({
-                layout: [...this.state.layout]
+            const compact = compactList(this.state.layout[currentListIndex], undefined);
+            this.state.layout[currentListIndex] = compact.compacted;
+            this.state.maped[currentListIndex] = compact.maped;
+
+            this.state.layout[x] = this.state.layout[x].map((item: any) => {
+                if (key === item.key) {
+                    return { ...item, currentListIndex: x }
+                }
+                return item;
             })
         }
 
+        const { compacted, maped } = compactList(this.state.layout[x], undefined);
+        this.state.layout[x] = compacted;
+        this.state.maped[x] = maped;
+
+        console.log(this.state.layout)
+        this.setState({
+            layout: [...this.state.layout],
+            maped: [...this.state.maped]
+        })
+        // if (this.state.currentList !== x) {
+        //     this.state.layout[x].push({ y, key: "10203", isUserMove: false })
+        //     const compacted = compactList(this.state.layout[x], undefined);
+        //     this.state.layout[x] = compacted;
+        //     this.setState({
+        //         layout: [...this.state.layout]
+        //     })
+
+        // } else {
+
+        // }
+
     }
 
     renderList = () => {
-        return this.props.children.map((child: any, index: number) => <div className='list-oneof' key={index}>{this.renderColumn(child, index)}</div>)
+        // console.log('set', this.props.layout)
+        return this.props.layout.map((child: any, index: number) =>
+            <div
+                className='list-oneof'
+                style={{
+                    background: 'red',
+                    height: 60 * this.state.layout[index].length,
+                    width: 400
+                }}
+                key={index}
+            >
+                {this.renderColumn(child, index)}
+            </div>
+        )
     }
     renderColumn = (child: any, index: number) => {
         // const column = this.state.layout[index];
-
         const { width, margin, rowHeight } = this.props;
 
-        
-
         return child.map((c: any, idx: any) => {
             const key = c.key;
             var renderItem: any;
-            for (const i in this.state.layout[index]) {
-                if (this.state.layout[index][i].key === key) {
-                    renderItem = this.state.layout[index][i];
-                }
+            // renderItem = this.state.maped[index][key];
+
+            for (const i in this.state.maped) {
+                renderItem = this.state.maped[i][key];
+                if (renderItem) break;
             }
-            console.log(index,key)
+            // console.log(renderItem)
+            // if (renderItem.key === '1') console.log(renderItem.listPosition)
             return <ListCell
                 margin={margin}
                 rowHeight={rowHeight}
                 width={width}
-                col={this.props.children.length}
-                x={index}
-                y={renderItem.y}
+                col={this.state.layout.length}
+                currentListIndex={renderItem.currentListIndex}
+                y={renderItem ? renderItem.y : c.y}
                 style={{ position: 'absolute' }}
                 key={idx}
                 UniqueKey={key}
-                isUserMove={renderItem.isUserMove}
+                isUserMove={renderItem ? renderItem.isUserMove : false}
                 onDragStart={this.onDragStart}
                 onDrag={this.onDrag}
                 onDragEnd={this.onDragEnd}
             >
-                {c}
+                {this.props.children(c, idx)}
             </ListCell>
         })
     }
 
     render() {
-        const { width, className, children } = this.props;
-        const numberOfCol = children.length;
+        const { width, className } = this.props;
+        const numberOfCol = this.state.layout.length;
 
         return (
             <div
                 className={stringJoin('DraggerLayout', className + '')}
-                style={{ left: 100, width: width * numberOfCol, height: '', zIndex: 1 }}
+                style={{ left: 100, width: width * numberOfCol, height: '', zIndex: 1, display: 'flex' }}
             >
                 {this.renderList()}
             </div>