Home > Back-end >  Input checkbox didn't work what I expected
Input checkbox didn't work what I expected

Time:11-07

I tried to make an input checkbox when I click the input checkbox, it should be displayed a check image like this. enter image description here

However, it didn't show the checkbox and I am not sure how to check that the input box was checked or not. Could you help me with what part do I missed and where is something wrong? I really appreciate your help!

This is CSS inputl and label part

.colors {
        display: flex;
        flex-direction: column;
        span {
          margin-bottom: 20px;
        }
        .colorLists {
          margin-left: 10px;
          display: flex;
          flex-wrap: wrap;
          .colorLayout {
            display: flex;
            flex-direction: column;
            position: relative;
            width: 33%;
            height: 80px;
            flex-shrink: 0;
            align-items: center;
            justify-content: center;
            .checkboxLabel {
              background-color: beige;
              border: 1px solid #ccc;
              border-radius: 50%;
              cursor: pointer;
              height: 28px;
              left: 0;
              position: absolute;
              top: 40;
              width: 28px;
              &:after {
                border: 2px solid #fff;
                border-top: none;
                border-right: none;
                content: '';
                height: 6px;
                left: 7px;
                opacity: 0;
                position: absolute;
                top: 8px;
                transform: rotate(-45deg);
                width: 12px;
                // opacity: 0.2;
              }
            }
            input[type='checkbox'] {
              visibility: hidden;
            }
            input[type='checkbox']:checked {
              &   label {
                background-color: beige;
                border-color: beige;
                &:after {
                  opacity: 1;
                }
              }
            }

            .productColor {
              margin-top: 70px;
              font-size: 13px;
              margin-right: 21px;
            }
          }
        }
      }

      .sizes {
        .HorizontalLine {
          margin-top: 25px;
        }

        .span {
        }

        .sizeLists {
          margin-top: 20px;
          margin-bottom: 20px;

          button {
            margin: 5px;
            width: 44px;
            height: 32px;
            background-color: white;
            border: 1px solid silver;
            border-radius: 15%;
          }
        }
      }

This is js part

<div className="colors">
              <span>색상</span>
              <ul className="colorLists">
                {COLOR_LISTS.map((color, idx) => {
                  return (
                    <li className="colorLayout" key={idx}>
                      <input type="checkbox" />
                      <label
                        className="checkboxLabel"
                        for="checkbox"
                        style={{ backgroundColor: color.colorProps }}
                      />
                      <span className="productColor">{color.color_name}</span>
                    </li>
                  );
                })}
              </ul>
            </div>

CodePudding user response:

In react you have to set the htmlFor property for the label instead of for. The value should be the same as the id from the input. Then you can add a value property for the input which is used for adding/removing the item in the list of selected items. For this purpose a handleChange function can be defined.

  const [selectedItems, setSelectedItems] = useState([]);

  function handleChange(e) {
    let newSelected = [];
    if (selectedItems.includes(e.target.value)) {
      newSelected = selectedItems.filter((item) => item !== e.target.value);
    } else {
      newSelected = [...selectedItems, e.target.value];
    }
    setSelectedItems(newSelected);
  }

  return (
    <div className="colors">
      <span>색상</span>
      <ul className="colorLists">
        {COLOR_LISTS.map((color, idx) => {
          return (
            <li className="colorLayout" key={idx}>
              <input
                onChange={handleChange}
                type="checkbox"
                id={idx}
                value={color.color_name}
                checked={selectedItems.includes(color.color_name)}
              />
              <label
                className="checkboxLabel"
                htmlFor={idx}
                style={{ backgroundColor: color.colorProps }}
              />
              <span className="productColor">{color.color_name}</span>
            </li>
          );
        })}
      </ul>
    </div>
  );

EDIT: Since you are using a class component it can be rewrittenlike this:

export default class CheckboxListComponent extends Component {
  constructor(props) {
    super(props);
    this.state = { selectedItems: [] };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    let newSelected = [];
    if (this.state.selectedItems.includes(e.target.value)) {
      newSelected = this.state.selectedItems.filter(
        (item) => item !== e.target.value
      );
    } else {
      newSelected = [...this.state.selectedItems, e.target.value];
    }
    this.setState({ selectedItems: newSelected });
  }
  render() {
    return (
      <div className="colors">
        <span>색상</span>
        <ul className="colorLists">
          {COLOR_LISTS.map((color, idx) => {
            return (
              <li className="colorLayout" key={idx}>
                <input
                  onChange={this.handleChange}
                  type="checkbox"
                  id={idx}
                  value={color.color_name}
                  checked={this.state.selectedItems.includes(color.color_name)}
                />
                <label
                  className="checkboxLabel"
                  htmlFor={idx}
                  style={{ backgroundColor: color.colorProps }}
                />
                <span className="productColor">{color.color_name}</span>
              </li>
            );
          })}
        </ul>
      </div>
    );
  }
}

CodePudding user response:

You must tell react that your input is checked so that your CSS will apply it. selected ids must be kept in a place for future existence check. in the following code, I named this array selecetedIdx. You also need to add idx on selection(via onChange event handler) or wrap them all in form and add them via extra dom attribute.


class Main extends Component {
  // initialize selectedIdx with [] in your state (esp constructor)
  // e.g. this.state = {/* rest of state, */ selectedIdx: []}

render() {
 return (
{COLOR_LISTS.map((color, idx) => {
  return (
    // ...
    <input 
      type="checkbox" 
      checked={selectedIdx.includes(idx)} 
      onChange={() => this.setState(state => ({
       selectedIdx: [...state.selectedIdx, idx]
      }))}
    />
   // ...
  )}
 )
}

CodePudding user response:

Your checkbox element needs name and value properties and would normally be a child of the <form> element.

  • Related