0

I used library react-sortable-hoc for drag and drop element, but the library documentation does not have any actions for delete items. I want to delete, drag and drop item when click on close button. Which method is right for removing elements by key from object?

React

const SortableItem = SortableElement(({ value }: { value: string }, onRemove: any) =>
    <div className="dragItems" style={{ background: 'gray' }}>
        <img src={value} alt="" />
        <button className="dragCloseBtn" onClick={() => onRemove(any)} />
    </div>

);

const SortableList = SortableContainer(({ items }: { items: string[] }) => {
    return (
        <div className="dragAndDrop">
            {items.map((value, index) => (
                <SortableItem key={'item-${index}'} index={index} value={value} />
            ))}
        </div>
    );
});

constructor(props: any) {
    super(props);
    this.state = {
        items: [
            { 
                "id": 0, 
                "link": "https://via.placeholder.com/150"
            },
            { 
                "id": 1, 
                "link": "https://via.placeholder.com/150"
            }
        ],
    };
}

public onSortEnd = ({ oldIndex, newIndex }: { oldIndex: number, newIndex: number }) => {
    this.setState({
        items: arrayMove(this.state.items, oldIndex, newIndex),
    });
};

public onRemove(e: { target: { value: any; }; }) {
    const array = [...this.state.items]; 
    const index = array.indexOf(e.target.value)
    if (index !== -1) {
        array.splice(index, 1);
        this.setState({items: array});
    }
}

<SortableList items={this.state.items}
              onSortEnd={this.onSortEnd}
              lockAxis="xy"
              axis="xy" />

2 Answers 2

1

UPDATED:

Hi there, I figured out what went wrong and made a successful remove event on your application.

Everything is illustrated with comments at this codesandbox.

=========

I modified this one, it should do the required using Array's filter method.

public onRemove(e: { target: { value: any; }; }) {
    let array = [...this.state.items];
    const intId = parseInt(e.target.value, 10);
    array = array.filter(item => item.id !== intId);
    this.setState({items: array});
}
Sign up to request clarification or add additional context in comments.

8 Comments

Sorry for that, it seems that JSlent is asking for the second parameter for the parseInt method up there, It's been updated, can you please check it again? @Yavar
The component can't read onRemove function, I can't figure out the construction of your component file, I've got no experience with TS. Did the function work before any of the edits suggested by me?
what about using () => this.onRemove(any) instead of () => onRemove(any)
Functionality drag and drop its work very well, but i can't remove items ( i try many functions, but all is not correct(
|
1

So there were few problems in your code! You seemed to be confuse how react works with passing down props. You have to pass down the method required for remove. And you should bind it inside the class that you will be calling it.

  • onRemove should be bound to current context
  • onRemove should be passed down across the component tree
  • Check my //[NOTE]====> comments for additional explanation
  • Working code sandbox is here
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
  arrayMove,
  SortableContainer,
  SortableElement
} from "react-sortable-hoc";


//[NOTE]====>value contains the relevent object containing the callback. Onclick call it with the relevant id
const SortableItem = SortableElement(
  ({ value }: { value: any }, onRemove: any) => (
    <div className="dragItems" style={{ background: "gray", margin: "20px" }}>
      <img src={value.link} alt="" />
      <button className="dragCloseBtn" onClick={() => value.onRemove(value.id)}>
        {" "}
        X{" "}
      </button>
    </div>
  )
);

const SortableList = SortableContainer(({ items }: { items: string[] }) => {
  return (
    <div className="dragAndDrop">
      {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
      ))}
    </div>
  );
});

class SortableComponent extends React.Component<{}, { items: string[] }> {
  constructor(props: {}) {
    super(props);

    //[NOTE]====>Send the callback on each element bound to the current context
    //This is like telling the function from where exactly the function will be called
    this.state = {
      items: [
        {
          id: 0,
          link: "https://via.placeholder.com/150",
          onRemove: this.onRemove.bind(this)
        },
        {
          id: 1,
          link: "https://via.placeholder.com/150",
          onRemove: this.onRemove.bind(this)
        }
      ]
    };
  }
  public render() {
    return <SortableList items={this.state.items} onSortEnd={this.onSortEnd} />;
  }
  public onSortEnd = ({
    oldIndex,
    newIndex
  }: {
    oldIndex: number;
    newIndex: number;
  }) => {
    this.setState({
      items: arrayMove(this.state.items, oldIndex, newIndex)
    });
  };

  //[NOTE]====>Use the id to filter out and set the new set of items
  public onRemove(id) {
    console.log(id);
    let array = [...this.state.items];
    const intId = parseInt(id, 10);
    array = array.filter((item: any) => item.id !== intId);
    this.setState({ items: array });
  }
}

ReactDOM.render(<SortableComponent />, document.getElementById("root"));

1 Comment

Thanks a lot for getting help !! Great Job !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.