我们如何才能正确地使用react Dnd和可拖动同一项目多次并追加到react状态数组

时间:2019-07-13 14:09:27

标签: javascript reactjs

我正在使用react dnd拖动和放置项目。 左侧,我有一个列表,如文本框,复选框,单选按钮等。 当我开始拖动一个文本框并将其放入中间容器时,它可以正常工作。 例如,我在每一滴上都增加我的状态ID 状态:{id:“ text1”,名称:“”} 当我再次拖动相同的文本框并放入中间容器时,我的状态像 例如state = [{{id:“ text2”,name:“”},{id:“ text2”,name:“”}]

当我多次放下单个物品时想要的精算输出

例如,state = [{id:“ text1”,name:“”},{id:“ text2”,name:“”},{id:“ text3”,name:“”}]像这样< / p>

我已经搜索了所有反应dnd的示例...但是没人能帮助我...请帮助我,伙计们

DummyData.tsx

import type from '../assets/images/type.png'
import paragraph from '../assets/images/paragraph.png'
import dropDownList from '../assets/images/drop-down-list.png'
import text from '../assets/images/text.png'
import checkbox from '../assets/images/checkbox.png'
import radioButton from '../assets/images/radio-button.png'
export const Controls = [
    {
        id: "text", label: "Text Field", fieldClass: "Text", category: "basic", image: type,
        height: 30, width: 200, placeholder: "Enter your name", readOnly: false, disabled: false, required: false
    }
    , {
        id: "textArea", label: "Text Area", fieldClass: "TextArea", category: "basic", image: text
    }
    , {
        id: "dropdown", label: "Dropdown", fieldClass: "Select", category: "basic", image: dropDownList
    }
    , {
        id: "radio", label: "Radio", fieldClass: "Radio", category: "basic", image: radioButton
    }
    , {
        id: "checkbox", label: "Checkbox", fieldClass: "CheckBox", category: "basic", image: checkbox
    }
    , {
        id: "paragraph", label: "Paragraph", fieldClass: "Paragraph", category: "basic", image: paragraph
    }
]

ComponentDetails.tsx

import React, { Component } from 'react';
import { DragSource } from "react-dnd";


interface ComponentDetailProps {
    details: { id: string, label: string, fieldClass: string, category: string, image: string },
    connectDragSource: any
}

class ComponentDetails extends Component<ComponentDetailProps, any> {
    render() {
        const { details, connectDragSource } = this.props;
        return connectDragSource(<div className="boxStyle">{<div ><div style={{ textAlign: "center" }}>{<img src={details.image} width={25} />}</div><span className="nameStyle">{details.label}</span></div>}</div>);
    }
}

function collect(connect: any) {
    return {
        connectDragSource: connect.dragSource()
    };
}



const cardSource = {
    beginDrag(props: any) {
        const item = props.details;
        return item;
    }
};



export default DragSource("SOURCE", cardSource, collect)(ComponentDetails);

MainContainer.tsx

import React, { Component } from 'react';
import { Controls } from './DummyData';
import ComponentDetails from './ComponentDetails';
import MiddleContainer from './MiddleContainer';
import PopUp from './PopUp';


interface mainContainerState {
    controlDetails: { id: string, label: string, fieldClass: string, category: string, image: string, height?: number, width?: number, placeholder?: string, disabled?: boolean, readOnly?: boolean, required?: boolean }[],
    showModal: boolean,
    individualDetails: { id: string, label: string, fieldClass: string, category: string, image: string, height?: number, width?: number, placeholder?: string, disabled?: boolean, readOnly?: boolean, required?: boolean },
    index: number
}

class MainContainer extends Component<any, mainContainerState> {

    constructor(props: any) {
        super(props);
        this.state = {
            controlDetails: [{
                id: "",
                label: "",
                fieldClass: "",
                category: "",
                image: "",
                height: 0,
                width: 0,
                placeholder: "",
                readOnly: false,
                required: false,
                disabled: false
            }],
            showModal: false,
            individualDetails: {
                id: "",
                label: "",
                fieldClass: "",
                category: "",
                image: "",
                height: 0,
                width: 0,
                placeholder: "",
                readOnly: false,
                required: false,
                disabled: false
            },
            index: 0
        }
    }

    onDrop = (ee: any) => {
        console.log("DDDDDDDDDDD",ee);
        this.setState({ controlDetails: [...this.state.controlDetails, ee] })
    }

    openModal = (de: any, index: number) => {
        this.setState({ individualDetails: de });
        this.setState({ showModal: true });
        this.setState({ index: index });
    }

    handleCloseModal = () => {
        this.setState({ showModal: false });
    }

    updatedControls = (updatedControls1: any) => {
        if (this.state.index) {
            const data1: any = [...this.state.controlDetails]
            console.log("222222222222222", data1);
             data1[this.state.index].placeholder = updatedControls1.placeholder;


            this.setState({ controlDetails: data1 });
            this.setState({ showModal: false });
        } else {
            console.log("111111111111111111111111");
        }
    }

    render() {
        console.log("SDssssssssssssss",this.state.controlDetails);
        return (
            <div className="container-fluid" style={{ padding: 0 }}>
                <div className="row" style={{ height: "100vh", margin: 0 }}>
                    <div className="col-sm-3 px-1 bg-dark">
                        <div className="py-2 sticky-top flex-grow-1" style={{ padding: 10 }}>
                            <div className="nav flex-sm-column">
                                <h4 style={{ color: "#fff" }}>Controls</h4>
                                <div style={{
                                    display: "flex",
                                    flexWrap: "wrap",
                                }} >

                                    {Controls.map((data) => {
                                        return (
                                            <div style={{
                                                display: "block",
                                                flex: "none",
                                                width: `${100 / 3}%`,
                                                boxSizing: "border-box",
                                            }} >
                                                <ComponentDetails details={data} />
                                            </div>
                                        )
                                    })}
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className="col" id="main" style={{
                        margin: 10,
                        borderRadius: 5,
                        padding: 10,
                        border: "1px solid #ddd",
                        background: "#fafafa"

                    }}>
                        <MiddleContainer onDrop={this.onDrop} controlDetails={this.state.controlDetails} openModal={this.openModal} />
                    </div>
                </div>
                <PopUp showModal={this.state.showModal} handleCloseModal={this.handleCloseModal}
                    individualDetails={this.state.individualDetails} updatedControls={this.updatedControls} />
            </div>
        )
    }
}

export default MainContainer;
MiddleContainer.tsx

import React, { Component } from 'react';
import { DropTarget } from "react-dnd";

interface MiddleContainerProps {
    connectDropTarget: any,
    onDrop: (event: any) => void;
    controlDetails: { id: string, label: string, fieldClass: string, category: string, image: string }[];
    openModal: (event: any, index: number) => void;
}

class MiddleContainer extends Component<MiddleContainerProps, any> {

    constructor(props: MiddleContainerProps) {
        super(props);
        this.state = {

        }
    }

    editClick = (details: any, index: number) => {
        console.log("sdfffff",details);
        this.props.openModal(details, index);
    }

    render() {
        const { connectDropTarget, controlDetails } = this.props;
        return connectDropTarget(
            <div>
                Drop Items Here
                <div >
                    {controlDetails.map((controlDetails: any, index: any) => {
                        return (
                            <div>
                                {<label >{controlDetails.label}</label>}
                                {controlDetails.fieldClass === "Text" ?
                                    <div>
                                        <input type="text" name={controlDetails.id}
                                            readOnly={controlDetails.readOnly}
                                            disabled={controlDetails.disabled}
                                            placeholder={controlDetails.placeholder}
                                            style={{
                                                height: controlDetails.height, width: controlDetails.width,
                                            }}
                                            onChange={ev => this.setState({ [ev.target.name]: ev.target.value })}
                                        />
                                        <button onClick={() => this.editClick(controlDetails, index)} >Edit</button>
                                    </div>
                                    : controlDetails.fieldClass === "TextArea" ? <div><textarea name={controlDetails.id} /></div>
                                        : controlDetails.fieldClass === "Select" ? <div> <select
                                            name={controlDetails.id}  >
                                            <option value="" disabled selected>Selected</option>
                                            <option>one</option>
                                            <option>two</option>
                                            <option>three</option>
                                        </select></div>
                                            : controlDetails.fieldClass === "Radio" ? <div> <input type="radio" name={controlDetails.id} /></div>
                                                : controlDetails.fieldClass === "CheckBox" ? <div> <input type="checkbox" name={controlDetails.id} /></div>
                                                    : controlDetails.fieldClass === "Paragraph" ? <div><textarea name={controlDetails.id} /></div> : ""}
                            </div>

                        )
                    })}
                </div>
                {this.state.text}
            </div>
        )
    }
}



const spec = {
    drop(props: any, monitor: any) {
        let count = 0;
        const item = monitor.getItem();
        item.id=item.id+(count+1)
        props.onDrop(item);
    }
};
function collect(connect: any, monitor: any,component:any) {
    return {
        connectDropTarget: connect.dropTarget(),
        isOver: monitor.isOver(),
        isOverCurrent: monitor.isOver({ shallow: true }),
        canDrop: monitor.canDrop()
    };
}

export default DropTarget("SOURCE", spec, collect)(MiddleContainer);

我正在

state=[{id:"text2",name:""},{id:"text2",name:""}]

我想要什么

state=[{id:"text1",name:""},{id:"text2",name:""}]

0 个答案:

没有答案