Findlay
Findlay

Reputation: 134

Count checked checkboxes in React.js

I'm using a document structure like this

render() {
return (
    <div className="MyComponent">
        <ul className="">
            {parseRecommendations(this.props.recommendations)}
        </ul>
    </div>
);
}

function parseRecomendations(recommendations) {
    return recommendations.map((recommendation, key) => {
        return (<Recommendation data={recommendation} key={key} />);
    });
}

Where each Recommendation is its own component containing a checkbox

class Recommendation extends Component {
    const recommendation = this.props.data;
    const pageUrl = recommendation.url;

    return (
        <li className="article-item" key={key}>
            <div className="article-info">
                <input type="checkbox" defaultChecked="checked" aria-described-by={recommendation.pii} />
                <a className="journal-title" href={pageUrl} id={recommendation.pii}>{recommendation.title}</a>
            </div>
        </li>
    );

I'd like to have a title saying [Download (x) PDFs], where x is the number of selected checkboxes. How do I find the value of x in this case?

Upvotes: 3

Views: 10027

Answers (3)

Cassio Seffrin
Cassio Seffrin

Reputation: 8560

You also could obtain the total of selected checkboxes by element type. The "console.log(totalSelectedCheckboxes)" will print them when the state of totalSelectedCheckboxes change using useEffect Hook.

import React, { useState, useEffect } from 'react';

const RenderCheckboxes = () => {
    const [totalSelectedCheckboxes, setTotalSelectedCheckboxes] = useState(0);
    function handleChk() {
        setTotalSelectedCheckboxes(document.querySelectorAll('input[type=checkbox]:checked').length);
    }
    useEffect(() => {
        console.log(totalSelectedCheckboxes);
    }, [totalSelectedCheckboxes]);
    return (<div>
        <div>
            <input type="checkbox" value={1} onChange={() => handleChk()} />Chk1
        </div>
        <div>
            <input type="checkbox" value={2} onChange={() => handleChk()} />Chk2
        </div>
        <div>
            <input type="checkbox" value={2} onChange={() => handleChk()} />Chk2
        </div>
    </div>);
}
export default RenderCheckboxes;

Upvotes: 0

WitVault
WitVault

Reputation: 24130

If you just want to get the number of selected check-boxes you can try this

let checkedBoxes = document.querySelectorAll('input[name=chkBox]:checked');

Then get the total checked boxes via checkedBoxes.length

Edit:

Instead of querying whole document. You can get the nearest possible parent via getElementsByClassName or getElementById and then apply querySelectorAll on that element.

e.g

let elem = document.getElementsByClassName("MyComponent");

let checkedBoxes = elem.querySelectorAll('input[name=chkBox]:checked');

Upvotes: 2

Andreyco
Andreyco

Reputation: 22862

You need to store information about whether input is "checked" in your data. Then, simply count items with truthy "checked" flag.

Here is my solution. You should be able to get principle here and modify your code.

const data = [
    { checked: false, value: 'document 1' },
    { checked: true, value: 'document 2' },
    { checked: true, value: 'document 3' },
    { checked: false, value: 'document 4' },
    { checked: false, value: 'document 5' },
];

const Item = props => (
    <div>
        <input type="checkbox" checked={props.checked} onChange={props.onCheckChange} />
        { props.value }
    </div>
)
var Hello = React.createClass({
    getInitialState() {
        return {
            items: this.props.items.concat(),
        };
    },

    onCheckChange(idx) {
        return () => {
            const items = this.state.items.concat();
            items[idx].checked = !items[idx].checked;
            this.setState({items});
        }
    },

    totalChecked() {
        return this.state.items.filter(props => props.checked).length;
    },

  render() {
    return (
            <div>
                { this.state.items.map((props, idx) => (
                    <Item {...props} key={idx} onCheckChange={this.onCheckChange(idx)} />
                )) }
                Total checked: { this.totalChecked() }
            </div>
        );
  }
});

ReactDOM.render(
  <Hello items={data} />,
  document.getElementById('container')
);

Upvotes: 6

Related Questions