Chinomso Johnson
Chinomso Johnson

Reputation: 189

How can I create dynamic input sliders with react?

I am trying to create a modal component for my application and my modal needs a slider to dynamically scale the image in the modal based on the user's input. I am done creating this modal and it looks like this: enter image description here

The problem I have is when I click on the slider especially on the value in the middle, the slider jumps to the third value. It only comes to the second value after going to the third value.

This is my JSX code

class pizzaModal extends Component {
  state = {
    toggle: false
  }
  toggleHandler = ()=>{
    this.setState({
            toggle: !this.state.toggle
        });
  }
  render (){
    return (
      <div className={styles.Pizzamodal}>
          <div className={styles.ModalContainer}>
            <div className={styles.ImageContainer}>
              <img src={pizzapicture} alt="pizzapicture"/>
            </div>
            <div className={styles.DetailsContainer}>
              <div>
                <div className={styles.TextDetails}>
                  <h1>Chicken Curry</h1>
                  <p>Red onions, bell peppers, <br/> chicken, pineapple, mozarella, <br/> tomatosauce, curry, chilli peppers.</p>
                </div>
                <div>
                <form className={styles.switchButton}>
                  <input type="radio" name="pizza" id="small" value="small" onChange={this.toggleHandler}
                              checked={!this.state.toggle}/>
                  <label for="small">25cm</label>
                  <input type="radio" name="pizza" id="medium" value="medium" onChange={this.toggleHandler}
                              checked={this.state.toggle}/>
                  <label for="medium">30cm</label>
                  <input type="radio" name="pizza" id="large" value="large" onChange={this.toggleHandler}
                              checked={this.state.toggle}/>
                  <label for="large">35cm</label>
                </form>
              </div>
              </div>
            </div>
            
          </div>
      </div>
    )
  }
}
export default pizzaModal;

This is the CSS

*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.Pizzamodal{
  position: fixed;
  z-index: 300;
  top: 25px;
  left: 250px;
  width: 880px;
  height: 610px;
  background-color: white;
  border-radius: 20px;
}
.ModalContainer{
  display: flex;
  justify-content: space-between;
}
.ImageContainer img{
  margin-top: 150px;
  margin-left: 90px;
}
.DetailsContainer{
  margin-right: 20px;
  margin-top: 40px;
}
.TextDetails h1{
  font-size: 1.2rem;
  font-family: 'Roboto', sans-serif;
  padding-bottom: 40px;
}
.TextDetails p{
  font-size: 1.1rem;
  font-family: 'Roboto', sans-serif;
  padding-bottom: 40px;
}
.switchButton input{
  position: absolute;
  clip: rect(0, 0, 0, 0);
  height: 1px;
  width: 1px;
  border: 0;
  overflow: hidden;
}
.switchButton label{
  display: inline-block;
  width: 100px;
  background-color: #e4e4e4;
  color: rgba(0, 0, 0, 0.6);
  font-size: 14px;
  font-weight: normal;
  text-align: center;
  text-shadow: none;
  padding: 6px 14px;
  border: 1px solid rgba(0, 0, 0, 0.2);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
  transition: all 0.1s ease-in-out;
}
.switchButton input:checked + label{
  background-color: #F07718;
    color: #fff;
  box-shadow: none;
}
.switch-field label:first-of-type {
  border-radius: 4px 0 0 4px;
}

.switch-field label:last-of-type {
  border-radius: 0 4px 4px 0;
}

Upvotes: 0

Views: 300

Answers (1)

Luke Storry
Luke Storry

Reputation: 6702

You're using a boolean toggle state (either true or false) to represent a three-way choice.

Instead use:

state = {
    selected: "small"
}

toggleHandler = (size)=> () =>{
    this.setState({
        toggle: size
    });
}

and in the inputs:

onChange={this.toggleHandler("small")} checked={this.state.toggle==="small"}
onChange={this.toggleHandler("medium")} checked={this.state.toggle==="medium"}
onChange={this.toggleHandler("large")} checked={this.state.toggle==="large"}

Upvotes: 1

Related Questions