How do I use React and forms to get an array of checked checkbox values?

后端 未结 2 1120
庸人自扰
庸人自扰 2021-02-06 06:08

I am trying to build a filter for my portfolio website. Checkboxes that let you pick a technology (react, redux, jquery etc.) to display a piece of work(s) that contain(s) that/

相关标签:
2条回答
  • 2021-02-06 06:46

    Here's how I'm doing it:

    // util.js
    import getPath from 'lodash/get';
    import setIn from 'lodash/fp/set';
    
    export function linkMultiCheck(name, value) {
        return {
            checked: getPath(this.state, name, []).includes(value),
            onChange: ev => {
                let values = getPath(this.state, name, []);
                if(ev.target.checked) {
                    values = [...values, value];
                } else {
                    values = values.filter(v => v !== value);
                }
                this.setState(setIn(name, values));
            },
        }
    }
    
    // form.js
    <ul>
        {options.branches.map(branch => (
            <li key={branch.id} className="checkbox">
                <label>
                    <input type="checkbox" name={this.id} {...this::linkMultiCheck('formData.branchIds',branch.id)}/>
                    {branch.id}
                </label>
            </li>
        ))}
    </ul>
    

    i.e., if a checkbox is checked, append it to the current array of values. If it's unchecked, filter it out.

    I'm using lodash here so that we can set deeply nested state values using dot notation.

    0 讨论(0)
  • 2021-02-06 06:51

    If you don't care about the order and you just want to append the items to the array as they appear we could definitely do exactly what you suggest in your question. On the change event of the checkbox check if the box is checked or or unchecked (event.target.checked returns true if checked or false if unchecked) and handle the array logic accordingly. this is a simple representation of how that could work:

    import React, { Component } from 'react'
    import { connect } from 'react-redux'
    
    class Portfolio extends Component {
      constructor() {
        super()
        // initialize your options array on your state
        this.state = {
          options: []
        }
      }
    
      onChange(e) {
        // current array of options
        const options = this.state.options
        let index
    
        // check if the check box is checked or unchecked
        if (e.target.checked) {
          // add the numerical value of the checkbox to options array
          options.push(+e.target.value)
        } else {
          // or remove the value from the unchecked checkbox from the array
          index = options.indexOf(+e.target.value)
          options.splice(index, 1)
        }
    
        // update the state with the new array of options
        this.setState({ options: options })
      }
    
      render() {
        return (
          <main className='portfolio'>
    
            <form>
              <div className="input-group">
                <label>cb1</label>
                <input type="checkbox" value={1} onChange={this.onChange.bind(this)} />
              </div>
              <div className="input-group">
                <label>cb2</label>
                <input type="checkbox" value={2} onChange={this.onChange.bind(this)} />
              </div>
              <div className="input-group">
                <label>cb3</label>
                <input type="checkbox" value={3} onChange={this.onChange.bind(this)} />
              </div>
            </form>
    
            <div className="selected-items">
              {this.state.options.map(number => 
                 <p key={number}>item: {number}</p>
              )}
            </div>
    
          </main>
        )
      }
    }
    

    if you DO care about order, if you can append numerical values to the array like I did in this example you could easily give your checkboxes sorted numerical values and you could sort the array before updating your state so it's always in a certain order regardless of the order they are checked.

      onChange(e) {
        // current array of options
        const options = this.state.options
        let index
    
        // check if the check box is checked or unchecked
        if (e.target.checked) {
          // add the numerical value of the checkbox to options array
          options.push(+e.target.value)
        } else {
          // or remove the value from the unchecked checkbox from the array
          index = options.indexOf(+e.target.value)
          options.splice(index, 1)
        }
    
        // sort the array
        options.sort()    
    
        // update the state with the new array of options
        this.setState({ options: options })
      }
    
    0 讨论(0)
提交回复
热议问题