Reputation:
I've made this checkbox which should be a "Three-State-Checkbox" it's using the indeterminate state not only as "visual-value" but also as a "real"-value. It work's fine if I'm only using the standard checkbox but if I use the bootstrap custom checkbox it doesn't work anymore because the ReactDOM.findDOMNode(this).indeterminate
can't access the checkbox.
So ReactDOM.findDOMNode(this).indeterminate = true;
doesn't set indeterminate to true
.
This is my component:
import React from "react";
import ReactDOM from 'react-dom';
import PropTypes from "prop-types";
import FormsStatic from "../FormsStatic";
class ThreeStateCheckbox extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.value || "0",
checked: false
}
}
componentDidMount() {
if (this.state.value != "0") {
this.state.value == "1" ? this.setState({ checked: true }) : ReactDOM.findDOMNode(this).indeterminate = true;
}
}
changeCbState() {
if (this.state.value == "0") {
this.state.value = "1";
this.setState({ checked: true })
ReactDOM.findDOMNode(this).indeterminate = false;
}
else if (this.state.value == "1") {
this.state.value = "2";
this.setState({ checked: false })
ReactDOM.findDOMNode(this).indeterminate = true;
}
else {
this.state.value = "0";
this.setState({ checked: false })
ReactDOM.findDOMNode(this).indeterminate = false;
}
this.props.onChange(this.state.value);
}
render() {
const uniqueId = FormsStatic.guid();
return (
<div className="custom-control custom-checkbox">
<input
type="checkbox"
className="custom-control-input"
id={"others-" + uniqueId}
checked={this.state.checked}
onChange={() => {
this.changeCbState();
}}
/>
<label className="custom-control-label" htmlFor={"others-" + uniqueId}>
</label>
</div>
);
}
}
ThreeStateCheckbox.propTypes = {
className: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func
}
export default ThreeStateCheckbox;
What is the way to set the indeterminate of the checkbox?
Edit: in changeCbState
I can pass the access the checkbox via eventargs (ev.target) but I also need it in componentDidMount()
. Still have no idea how to access it there.
Upvotes: 1
Views: 2694
Reputation: 7212
Here's a working solution based on this blog post.
IndeterminateCheckbox.tsx
import React, { useEffect, useRef } from 'react';
import FormCheck, { FormCheckProps } from 'react-bootstrap/FormCheck';
export enum IndeterminateCheckboxValue {
Unchecked,
Checked,
Indeterminate,
}
export interface IndeterminateCheckboxProps extends FormCheckProps {
value: IndeterminateCheckboxValue;
}
export default function IndeterminateCheckbox(props: IndeterminateCheckboxProps) {
const { value, ...otherProps } = props
const checkRef = useRef<HTMLInputElement>();
useEffect(() => {
if (checkRef.current) {
checkRef.current.checked = value === IndeterminateCheckboxValue.Checked
checkRef.current.indeterminate = value === IndeterminateCheckboxValue.Indeterminate
}
})
return (
<FormCheck type="checkbox" ref={checkRef} {...otherProps} />
)
}
Usage:
<IndeterminateCheckbox value={IndeterminateCheckboxValue.Indeterminate} />
Upvotes: 1
Reputation:
So I finally found the answer:
@NonameSL answers was on the right way but I couldn't change the indeterminate state because the ref
is frozen in reactjs.
My solution is to create a ref
like this:
this.checkboxRef = React.createRef();
Add the ref
to my checkbox:
<input
type="checkbox"
className="custom-control-input"
id={"others-" + uniqueId}
checked={this.state.checked}
ref={this.checkboxRef}
onChange={() => this.changeCbState()}
/>
just as @NonameSL said.
But now I can access the indeterminate state like this:
ReactDOM.findDOMNode(this.checkboxRef.current).indeterminate = true;
Upvotes: 0
Reputation: 1475
Create a ref
and use that to control the indeterminate in the DOM level:
constructor(props) {
//...
this.checkboxRef = React.createRef();
//...
}
Then add the ref
prop to your checkbox.
<input
type="checkbox"
...
ref={this.checkboxRef}
/>
Now you can use the following code to set the indeterminate sate:
this.checkboxRef.indeterminate = true
Upvotes: 1