0

I have a simple section in which contains products with multiple checkboxes and default prices, I want when the checkbox is true to show its price and remove all the rest pricess obvious those with the false state. if all checkboxes are false then show all the prices

Live demo : live demo

Here is what I have so far //toppings.js

export const toppings = [
  {
    name: "Capsicum",
    price: 1.2
  },
  {
    name: "Paneer",
    price: 2.0
  },
  {
    name: "Red Paprika",
    price: 2.5
  },
  {
    name: "Onions",
    price: 3.0
  },
  {
    name: "Extra Cheese",
    price: 3.5
  },
  {
    name: "Baby Corns",
    price: 3.0
  },
  {
    name: "Mushroom",
    price: 2.0
  }
];

Here is my solution

import { toppings } from "./utils/toppings";

export default function App() {
  const [checkedState, setCheckedState] = useState(
    new Array(toppings.length).fill(false)
  );

  const handleOnChange = (position) => {
    const updatedCheckedState = checkedState.map((item, index) =>
      index === position ? !item : item
    );

    setCheckedState(updatedCheckedState);

    const elements = updatedCheckedState.filter((currentState, index) => {
      if (currentState === false) {
        delete toppings[index].price;
      } else if (currentState === false) {
        toppings[index] = toppings[index].price;
        console.log("current state", currentState);
      }
      return 0;
    });
    console.log(elements);
  };

  return (
    <div className="App">
      <ul className="toppings-list">
        {toppings.map(({ name, price }, index) => {
          return (
            <li key={index}>
              <div className="toppings-list-item">
                <div className="left-section">
                  <input
                    type="checkbox"
                    id={`custom-checkbox-${index}`}
                    name={name}
                    value={name}
                    checked={checkedState[index]}
                    onChange={() => handleOnChange(index)}
                  />
                  <label htmlFor={`custom-checkbox-${index}`}>{name}</label>
                </div>
              </div>
            </li>
          );
        })}
      </ul>
      <ul className="toppings-list">
        {toppings.map(({ name, price }, index) => {
          return <li key={index}> {price} </li>;
        })}
      </ul>
    </div>
  );
}

Unfortunately this is not working as expected, can someone tell me what am doing wrong here

2
  • You're both deleting the price properties altogether, so you won't be able to retrieve them, and also mutating state with your filter() call. If you don't want to show price of checked items just do it conditionally in the render. Also don't use index as key. Commented Dec 9, 2021 at 13:40
  • you should create a re-usable component to show checkbox and price then, handle toggle by an internal state Commented Dec 9, 2021 at 13:51

1 Answer 1

1

Here is a simple working example. storing all selected item indexes in a state array

Live example - https://codesandbox.io/s/condescending-sara-t5ws3?file=/src/App.js

import { useState } from "react";
import { toppings } from "./utils/toppings";
import "./styles.css";

export default function App() {
  const [checked, setChecked] = useState([]);
  const handleChecked = (e, index) => {
    let prev = checked;
    let itemIndex = prev.indexOf(index);
    if (itemIndex !== -1) {
      prev.splice(itemIndex, 1);
    } else {
      prev.push(index);
    }
    setChecked([...prev]);
  };
  return (
    <div className="App">
      <ul className="toppings-list">
        {toppings.map(({ name, price }, index) => {
          return (
            <>
              <li key={index}>
                <div className="toppings-list-item">
                  <span className="left-section">
                    <input
                      type="checkbox"
                      id={`custom-checkbox-${index}`}
                      // name={name}
                      // value={name}
                      checked={checked.includes(index)}
                      onChange={(e) => handleChecked(e, index)}
                    />
                    <label htmlFor={`custom-checkbox-${index}`}>{name}</label>
                  </span>
                  {(!checked.length || checked.includes(index)) && (
                    <span>{price}</span>
                  )}
                </div>
              </li>
            </>
          );
        })}
      </ul>
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

Comments

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.