I am trying to implement a system where the user can only select one button at a time. So there are a set of colors 'Red, Blue, Black, etc'. If the user clicks on 'Red' label it should receive the class 'check'. If the user decides they want 'Blue' label then the 'check' should be removed from 'Red' label to be on 'Blue' label now.
I cannot simply use the document.querySelectorAll().addEventListener() since this is react. For example in vanilla JS, I could easily do something like this:
const colorBtns = document.querySelectorAll('.color-radio-btn');
let checkedBtn = 0;
let checkedsizeBtn = 0;
let color;
colorBtns.forEach((item,i) => {
item.addEventListener('click', () => {
colorBtns[checkedBtn].classList.remove('check');
item.classList.add('check');
checkedBtn = i;
color = item.innerHTML;
})
})
And here is my react snippet:
const ShowProduct = () => {
return(
<div className='product-details'>
<input type="radio" name="color" value="Black" hidden id="black-color"/>
<label htmlFor="black-color" className="color-radio-btn">Black</label>
<input type="radio" name="color" value="Red" hidden id="red-color"/>
<label htmlFor="red-color" className="check color-radio-btn">Red</label>
<input type="radio" name="color" value="White" hidden id="white-color"/>
<label htmlFor="white-color" className="color-radio-btn">White</label>
<input type="radio" name="color" value="Yellow" hidden id="yellow-color"/>
<label htmlFor="yellow-color" className="color-radio-btn">Yellow</label>
<input type="radio" name="color" value="Green" hidden id="green-color"/>
<label htmlFor="green-color" className="color-radio-btn">Green</label>
<input type="radio" name="color" value="Purple" hidden id="purple-color"/>
<label htmlFor="purple-color" className="color-radio-btn">Purple</label>
<input type="radio" name="color" value="Purple" hidden id="blue-color"/>
<label htmlFor="blue-color" className="color-radio-btn">Blue</label>
<input type="radio" name="color" value="Purple" hidden id="orange-color"/>
<label htmlFor="orange-color" className="color-radio-btn">Orange</label>
<input type="radio" name="color" value="Custom" hidden id="custom-color"/>
<label htmlFor="custom-color" className="color-radio-btn">Custom</label>
<input type="radio" name="color" value="NotCustom" hidden id="not-custom-color"/>
<label htmlFor="not-custom-color" className="color-radio-btn">1-Color</label>
</div>
);
}
ReactDOM.render(<ShowProduct />, document.getElementById("root"));
.product-details .color-radio-btn,
.product-details .size-radio-btn{
display: inline-block;
width: 70px;
height: 70px;
text-align: center;
font-size: 14px;
border: 1px solid #383838;
border-radius: 50%;
margin: 10px;
margin-left: 0;
line-height: 60px;
text-transform: uppercase;
color: #383838;
cursor: pointer;
}
.product-details .color-radio-btn.check,
.product-details .size-radio-btn.check{
background: #383838;
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
CodePudding user response:
This is reactJs. So you can do this using state manipulation... You should take a event handler for onclick.. then you will update the class check using value from state.like below
state:{
selectedColor:'Red'
}
onClickHandler=(event)=>{
this.setState({selectedColor:event.target.value});
}
and html like this..
<input type="radio" checked={this.state.selectedColor==='Black'} name="color" value="Black" hidden id="black-color" onClick={this.onClickHandler}/>
<label htmlFor="black-color" className={"color-radio-btn" (this.state.selectedColor==='Black'?' check':'')}>Black</label>
<input type="radio" checked={this.state.selectedColor==='Red'} name="color" value="Red" hidden id="red-color"/>
<label htmlFor="red-color" className={"color-radio-btn" (this.state.selectedColor==='Red'?' check':'')} onClick={this.onClickHandler}>Red</label>
CodePudding user response:
There is a strong chance you can solve this with CSS only:
.product-details input:checked label{
background: #383838;
color: #fff;
}
This will style the label
following a checked element contained in the .product-details
element.