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

前提是你 提交于 2020-01-22 14:44:26

问题


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/those technologies. So every time the user clicks on a box, I want to add the value (JavaScript, Redux, React etc.) to an array that I use in another function to check against my portfolio pieces and filter out what isn't there.

I am finding this very difficult and I think it should be quite simple. Can someone point me in the right direction? Is there a way to simply have a function trigger (onChange callback?) that reads the checked/unchecked status of my form input elements and then updates my state array accordingly? Can I get the status of all the checkboxes simply in React? Do I need to have individual state of checked/unchecked for my checkboxes?

It seems that jQuery makes it pretty possible with selectors with:

$('input[type="checkbox"]:checked').each(function () {}

回答1:


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 })
  }



回答2:


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.



来源:https://stackoverflow.com/questions/37129437/how-do-i-use-react-and-forms-to-get-an-array-of-checked-checkbox-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!