I have an input type of range with 2 state values of input1 and input2. I want to make the left input unmovable and not pass when it hits the right input. How can i implement that using state values? I have tried something like this but it didn't work
import React, { Component } from 'react'
class SearchForm extends Component {
constructor(props) {
super(props)
this.state = {
rateMinValue: 0,
rateMaxValue: 300000,
minGap: 0,
}
}
rateMinHandler = (event) => {
this.setState(
{
rateMinValue: event.target.value
}
)
}
rateMaxHandler = (event) => {
this.setState(
{
rateMaxValue: event.target.value
}
)
}
slideOne = (event) => {
if (this.state.rateMaxValue - this.state.rateMinValue <= this.state.minGap) {
this.setState({
rateMinValue: this.state.rateMaxValue
- this.state.minGap
})
}
}
slideTwo = (event) => {
if (this.state.rateMaxValue - this.state.rateMinValue <= this.state.minGap) {
this.setState({
rateMaxValue: this.state.rateMinValue
this.state.minGap
})
}
}
render() {
return (
<div>
<div className='filter-rate-slider'>
<div className='rate-range-values'>
{this.state.rateMinValue < this.state.rateMaxValue ? <span>{this.state.rateMinValue}-{this.state.rateMaxValue}</span> : <span>{this.state.rateMaxValue}-{this.state.rateMinValue}</span>}
</div>
<div className='rate-range-container'>
<div className='slider-track'></div>
<input onInput={this.slideOne} type='range' min='0' max='300000' step='10000' defaultValue='0' id='slider-1' onChange={this.rateMinHandler}></input>
<input onInput={this.slideTwo} type='range' min='0' max='300000' step='10000' defaultValue='300000' id='slider-2' onChange={this.rateMaxHandler}></input>
</div>
</div>
</div>
)
}
}
export default SearchForm
I don't know what is wrong someone help me.
CodePudding user response:
I copied your code and wasn't able to reproduce the UI (since I don't have your stylings), but have a suggested solution.
- Use a clamping function to clamp the slide one
rateMinValue
state between0
andthis.state.rateMaxValue
, and clamp the slide tworateMaxValue
state betweenthis.state.rateMinValue
and300000
. - Use only the
onInput
or theonChange
, but not both.
const clamp = (min, max, val) => Math.max(min, Math.min(val, max));
class SearchForm extends React.Component {
state = {
rateMinValue: 0,
rateMaxValue: 300000,
minGap: 0
};
slideOne = (event) => {
this.setState((prevState) => ({
rateMinValue: clamp(
0,
prevState.rateMaxValue - prevState.minGap,
event.target.value
)
}));
};
slideTwo = (event) => {
this.setState((prevState) => ({
rateMaxValue: clamp(
prevState.rateMinValue prevState.minGap,
300000,
event.target.value
)
}));
};
render() {
return (
<div>
<div className="filter-rate-slider">
<div className="rate-range-values">
{this.state.rateMinValue}-{this.state.rateMaxValue}
</div>
<div className="rate-range-container">
<div className="slider-track"></div>
<input
onInput={this.slideOne}
type="range"
min="0"
max="300000"
step="10000"
value={this.state.rateMinValue}
id="slider-1"
/>
<input
onInput={this.slideTwo}
type="range"
min="0"
max="300000"
step="10000"
value={this.state.rateMaxValue}
id="slider-2"
/>
</div>
</div>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<SearchForm />
</React.StrictMode>,
rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root" />