Search code examples
javascriptreactjshtmlrangeinput-type-range

html5 input type range always pointing to min value and not getting onChange on text input


I am trying to use input type text along with input type range where three usecases are there. 1. defaultcase: when page is loaded the slider should point to the value as given in the text input field. 2. when user enters the text value, the slider pointer should also update. 3. when user uses the slider to change value, the text value should get updated.

In my below code

  1. In default case: in input type range when i give defaultValue="200" the slider pointer points always to min value.
  2. When i enter value in text area, the slider is not getting updated.

i tried some ways to fix it but failing.

          if (
          Type == "integer" &&
          LowerBound &&
          UpperBound !== 0
        ) {
          editComponent = (
            <div className="SettingsTreeValueNode__InputField">
              <input
                type="text"
                pattern="[0-9]*"
                ref="text"
                value={this.state.value}
                oninput={this.handleinputChanged.bind(this)}
                className="inputtext"
                onBlur={e => this.focusOfInputLost(e)}
              />
              {LowerBound}
              <input
                type="range"
                className="sliderinput"
                defaultValue="200"
                min={LowerBound}
                max={UpperBound}
                step="1"
                oninput={this.handleSliderChange.bind(this)}
                onMouseUp={this.handleWhenMouseReleased.bind(this)}
              />
              {UpperBound}
            </div>
          );
        }
        handleSliderChange(event) {
      var value = event.target.value;
      var slidervalue = parseInt(value);
      this.setState({ value: slidervalue });
    }

    handleInputChanged(event) {
    var value = event.target.validity.valid
     ? event.target.value
     : this.state.value;
    this.setState(
      {
       value: value,
       inputValid: this.isInputValid()
      });
      }

´´´[![slider along with text area][1]][1]


  [1]: https://i.sstatic.net/w5MZ6.png

Solution

  • Below code will solve your problems, only use single state object to display value in both controls now it will works in both way either change value on input or slider.

    class App extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          value: ""
        };
      }
    
      handleSliderChange = (event) => {
        var value = event.target.value;
        var slidervalue = parseInt(value);
        this.setState({ value: slidervalue });
      }
    
      handleInputChanged = (event) => {
        var value = event.target.validity.valid
          ? event.target.value
          : this.state.value;
        this.setState(
          {
            value: value
          });
      }
      render() {
        let LowerBound = 0;
        let UpperBound = 200
        return (
          <div>
            <button onClick={this.handleCopy}>click me</button>
            <div className="SettingsTreeValueNode__InputField">
              <input
                type="text"
                pattern="[0-9]*"
                ref="text"
                value={this.state.value}
                onInput={this.handleInputChanged}
                className="inputtext"
              />
              {LowerBound}
              <input
                type="range"
                className="sliderinput"
                defaultValue="200"
                min="0"
                max="200"
                step="1"
                value={this.state.value ? this.state.value : UpperBound}
                onInput={this.handleSliderChange}
              />
              {UpperBound}
            </div>
          </div>
        );
      }
    }
    export default App;