Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indeterminate checkbox in React JSX

How do I render an indeterminate checkbox via JSX?

Here's what I've tried:

function ICB({what}) {
  return <input type="checkbox"
                checked={what === "checked"} 
                indeterminate={what === "indeterminate"} />;
}

However, indeterminate is not an attribute on the HTMLElement, but a property. How do I set properties from React / JSX?


Solution:

As most of the answers below use findDOMNode or string refs, both of which are no longer considered good practice in React, I've written a more modern implementation:

function ICB() {
  const [state, setState] = React.useState(0);
  const indetSetter = React.useCallback(el => {
    if (el && state === 2) {
      el.indeterminate = true;
    }
  }, [state]);
  const advance = () => setState(prev => (prev + 1) % 3);
  
  return <input type="checkbox"
                checked={state === 1}
                ref={indetSetter}
                onClick={advance} />;
}
                
ReactDOM.render(<ICB />, document.getElementById("out"));
<div id="out"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
like image 462
ᅙᄉᅙ Avatar asked Aug 21 '15 11:08

ᅙᄉᅙ


People also ask

How do I set an indeterminate checkbox?

A checkbox cannot be set to indeterminate state by an HTML attribute - it must be set by a JavaScript. This state can be used to force the user to check or uncheck the checkbox.

What happens when you click an indeterminate checkbox?

A checkbox usually has two states: checked and unchecked. But indeterminate checkboxes are in a third state: neither checked nor unchecked. The “checkedness” is not determined.


2 Answers

You can also use the ref function directly:

ReactDOM.render(
  <label>
    <input
      type="checkbox"
      ref={input => {
        if (input) {
          input.indeterminate = true;
        }
      }}
    />
    {' '}
    Un test
  </label>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
like image 188
Kévin Berthommier Avatar answered Sep 23 '22 08:09

Kévin Berthommier


I would probably create a composite component that encapsulates the necessary hooks to set or unset the checkbox's indeterminate property. It looks like you're using ES2015 syntax, so I'll use some of those features here.

class IndeterminateCheckbox extends React.Component {
  componentDidMount() {
    if (this.props.indeterminate === true) {
      this._setIndeterminate(true);
    }
  }

  componentDidUpdate(previousProps) {
    if (previousProps.indeterminate !== this.props.indeterminate) {
      this._setIndeterminate(this.props.indeterminate);
    }
  }

  _setIndeterminate(indeterminate) {
    const node = React.findDOMNode(this);
    node.indeterminate = indeterminate;
  }

  render() {
    const { indeterminate, type, ...props } = this.props;
    return <input type="checkbox" {...props} />;
  }
}

// elsewhere

render() {
  return <IndeterminateCheckbox
           checked={this.props.state === "checked"} 
           indeterminate={this.props.state === "indeterminate"} />
}

Working example: https://jsbin.com/hudemu/edit?js,output

like image 24
Michelle Tilley Avatar answered Sep 23 '22 08:09

Michelle Tilley