0

I´d like to know, how can I change the order of elements in some list.

For example I would have this list below and buttons for changing order:

<button onClick={"function for moving the item up"}>Move Up</button>
<button onClick={"function for moving the item down"}>Move Down</button>

<ul>
  <li>Item1</li>
  <li className="selected-item">Item2</li>
  <li>Item3</li>
  <li>Item4</li>
</ul>

So if I would click on button "Move Up", I want item with class name "selected-item" to move up (change the order position). And exactly the same case for clicking on button "Move Down", but of course the item would move down.

Thank you.

Michael Rýdl
  • 97
  • 1
  • 8
  • Does this answer your question? [JavaScript moving element in the DOM](https://stackoverflow.com/questions/1363650/javascript-moving-element-in-the-dom) – Shiverz Nov 12 '20 at 09:54
  • That's not how SO works... You need to show us some code of what you've tried, what's not working etc... https://stackoverflow.com/help/how-to-ask – SakoBu Nov 12 '20 at 09:58
  • This is tagged as a React question. You shouldn't be rendering/ordering things based on their class name. The items should be stored in state, with a unique identifier and then some functions which move them up/down in that state list defined – Jayce444 Nov 12 '20 at 09:58

1 Answers1

0

I know a crude way of doing things.

  1. First, make sure your elements are in a list.
  2. Then, allow selecting a single element.
  3. Only show the Move buttons if there's a selection.
  4. Update the index of both the current and previous or next element, swapping them.
  5. Due to the state update, the app gets re-rendered in the right way.

Here's a demo.

import React, { Component } from "react";
import "./styles.css";

export default class App extends Component {
  state = {
    items: ["Milk", "Curd", "Yogurt"],
    currentSelection: -1
  };
  selectHandler = (idx) => {
    let currentSelection = -1;
    if (this.state.currentSelection !== idx) {
      currentSelection = idx;
    }
    this.setState({
      currentSelection
    });
  };
  handleMove = (dir) => {
    const { currentSelection } = this.state;
    const items = [...this.state.items];
    if (dir === "up") {
      // Swap the currentSelection value with the previous one.
      let a = items[currentSelection];
      items[currentSelection] = items[currentSelection - 1];
      items[currentSelection - 1] = a;
    } else if (dir === "down") {
      // Swap the currentSelection value with the next one.
      let a = items[currentSelection];
      items[currentSelection] = items[currentSelection + 1];
      items[currentSelection + 1] = a;
    }
    this.setState({
      items,
      currentSelection: -1
    });
  };
  render() {
    const { items, currentSelection } = this.state;
    return (
      <div>
        <p>Click to select and again click to deselect.</p>
        <ul>
          {items.map((item, key) => (
            <li
              key={key}
              className={currentSelection === key ? "active" : undefined}
              onClick={() => this.selectHandler(key)}
            >
              {item}
            </li>
          ))}
        </ul>
        {currentSelection !== -1 && (
          <div>
            <p>What do you wanna do?</p>
            <button
              disabled={currentSelection === 0}
              onClick={(e) => {
                e.preventDefault();
                this.handleMove("up");
              }}
            >
              Move Up
            </button>
            <br />
            <button
              disabled={currentSelection === items.length - 1}
              onClick={(e) => {
                e.preventDefault();
                this.handleMove("down");
              }}
            >
              Move Down
            </button>
          </div>
        )}
      </div>
    );
  }
}

Demo: https://uiyq8.csb.app/

Preview

preview

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252