0

I have been trying to set the classes to radio buttons dynamically but I am unable to do so. I am kind of maintaining a switch with radio buttons "ENABLED, PENDING , DISABLED". Based on the radio button selection, I am trying to assign class names to change the colors .

Help would be appreciated.

Sandbox: https://codesandbox.io/s/complex-logic-to-map-an-array-rkspo

App


import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      switchValue: "pending"
    };
    this.handleButtonChange = this.handleButtonChange.bind(this);
  }

  handleButtonChange(event) {
    this.setState(
      {
        switchValue: event.target.value
      },
      () => {
        console.log(this.state.switchValue);
      }
    );
  }

  render() {
    const { switchValue } = this.state;
    return (
      <div className={"switch-toggle"}>
        <input
          type="radio"
          onChange={this.handleButtonChange}
          name={"disabled"}
          value={"disabled"}
          checked={switchValue === "disabled" ? true : false}
        />{" "}
        <label className={switchValue === "disabled" ? "switch-red" : ""}>
          DISABLED
        </label>
        <input
          type="radio"
          onChange={this.handleButtonChange}
          name={"pending"}
          value={"pending"}
          checked={switchValue === "pending" ? true : false}
        />{" "}
        <label className={switchValue === "pending" ? "switch-pending" : ""}>
          PENDING
        </label>
        <input
          type="radio"
          onChange={this.handleButtonChange}
          name={"enabled"}
          value={"enabled"}
          checked={switchValue === "enabled" ? true : false}
        />{" "}
        <label className={switchValue === "enabled" ? "switch-green" : ""}>
          ENABLED
        </label>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);



CSS

.switch-toggle {
  float: left;
  background: #242729;
}
.switch-toggle input {
  position: absolute;
  opacity: 0;
}
.switch-toggle input + label {
  padding: 7px;
  float: left;
  color: #fff;
  cursor: pointer;
}
.switch-pending {
  background: grey;
}
.switch-disabled {
  background: red;
}
.switch-enabled {
  background: green;
}

2
  • Hmm just wondering, why make the inputs radios if you're not gonna even be able to see them? Commented Aug 16, 2019 at 7:53
  • 1
    Also, you are using "switch-red" as a class name in the component but you don't have that name in your CSS file. It is "switch-disabled" as far as I can see and it seems working. Also, I agree with @ChristopherNgo, it is hard to find those buttons! Commented Aug 16, 2019 at 7:57

2 Answers 2

2

Here's a forked version of your sandbox with the working code: https://codesandbox.io/s/complex-logic-to-map-an-array-8ghfh

Try to be cognizant of the classes that you're working with.

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      switchValue: "pending"
    };
    this.handleButtonChange = this.handleButtonChange.bind(this);
  }

  handleButtonChange(event) {
    this.setState(
      {
        switchValue: event.target.value
      },
      () => {
        console.log(this.state.switchValue);
      }
    );
  }

  render() {
    const { switchValue } = this.state;
    return (
      <div className={"switch-toggle"}>
        <input
          id="disabled"
          type="radio"
          onChange={this.handleButtonChange}
          name={"disabled"}
          value={"disabled"}
          checked={switchValue === "disabled" ? true : false}
        />{" "}
        <label
          htmlFor="disabled"
          className={switchValue === "disabled" ? "switch-disabled" : ""}
        >
          DISABLED
        </label>
        <input
          id="pending"
          type="radio"
          onChange={this.handleButtonChange}
          name={"pending"}
          value={"pending"}
          checked={switchValue === "pending" ? true : false}
        />{" "}
        <label
          className={switchValue === "pending" ? "switch-pending" : ""}
          htmlFor="pending"
        >
          PENDING
        </label>
        <input
          id="enabled"
          type="radio"
          onChange={this.handleButtonChange}
          name={"enabled"}
          value={"enabled"}
          checked={switchValue === "enabled" ? true : false}
        />{" "}
        <label
          htmlFor="enabled"
          className={switchValue === "enabled" ? "switch-enabled" : ""}
        >
          ENABLED
        </label>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Although again, I'm not sure why you would use radio buttons in this case because you wouldn't even see them. Might make more sense just to use standard buttons with click-events. That would ensure less mark-up :)

Something like this sandbox could accomplish the same thing and would be easier to maintain: https://codesandbox.io/s/complex-logic-to-map-an-array-w6hgb

Sign up to request clarification or add additional context in comments.

1 Comment

Would you please help me out with this stackoverflow.com/questions/57529332/…
2

It looks like you have no relation between the label and the input field, if you click on the label, nothing happens:

Adjust the code like this:

<input type="radio" id="foo" />
<label htmlFor="foo">Foo</label>

or

<label>
 <input .../>
</label>

Besides that, your CSS class is called switch-enabled but you set switch-green so nothing happens :)

Also have a look at the radio group documentation:

A radio group is defined by giving each of radio buttons in the group the same name. Once a radio group is established, selecting any radio button in that group automatically deselects any currently-selected radio button in the same group.

A cleaner and semantically correct example could look like this:

function RadioGroup({ defaultChecked = "bar" }) {
  function handleChange(ev) {
    const { value } = ev.target;
    // do something with the value
  }

  return (
    <form>
      <label>
        <input
          defaultChecked={defaultChecked === "foo"}
          type="radio"
          name="name"
          value="foo"
          onChange={handleChange}
        />{" "}
        Foo
      </label>

      <label>
        <input
          defaultChecked={defaultChecked === "bar"}
          type="radio"
          name="name"
          value="bar"
          onChange={handleChange}
        />{" "}
        Bar
      </label>

      <label>
        <input
          defaultChecked={defaultChecked === "baz"}
          type="radio"
          name="name"
          value="baz"
          onChange={handleChange}
        />{" "}
        Baz
      </label>
    </form>
  );
}

If the HTML Markup is correct, you could make use of CSS Pseudo Selector "checked" to set your CSS without Javascript 🎉

Btw, the answer from Christopher solves your exact problem, this is just an addition.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.