Home > OS >  trigger functions with radio buttons React/TS
trigger functions with radio buttons React/TS

Time:03-23

I have radio buttons that look like this:

<div className="row">
    <div className="col-md-4">
        <label className="radio">
            <input onChange={() => {serviceCalc()}} type="radio" name="radio-btn-product" value="standard" id="standard" checked />
            <i></i>Standard
        </label>
    </div>
    <div className="col-md-4">
        <label className="radio">
            <input onChange={() => {serviceCalc()}} type="radio" name="radio-btn-product" value="premium" id="premium" />
            <i></i>Premium
        </label>
    </div>
    <div className="col-md-4">
        <label className="radio">
            <input onChange={() => {serviceCalc()}} type="radio" name="radio-btn-product" value="excelium" id="excelium" />
            <i></i>Excelium
        </label>
    </div>
  </div>

I'm trying to get the serviceCalc function to trigger the three other functions depending on which radio button is clicked like so:

const serviceCalc = () => {

    const standard1 = (document.getElementById("standard") as HTMLInputElement);
    const premium1 = (document.getElementById("premium") as HTMLInputElement);
    const excelium1 = (document.getElementById("excelium") as HTMLInputElement);

    if (standard1.checked){            
        standard();
    }
    else if (premium1.checked) {
        premium();
    }
    else if (excelium1.checked) {
        excelium();
    }
}

but when I select the standard option for example, this wont trigger:

    const standard = () => {

    console.log('stand_test')

}

any help is greatly appreciated.

CodePudding user response:

The isssue is that your radio buttons are controlled (you have an onChange on them and you have checked on one of them), but you're only ever setting checked on standard. Since standard is always checked, clicking standard isn't changing anything, so the change event isn't raised.

Separately, onChange={() => {serviceCalc()}} should almost always be onChange={serviceCalc}.

Normally, when you're using controlled inputs, you store the state in the component state. Here's an example:

const { useState } = React;

const Example = () => {
    const [serviceLevel, setServiceLevel] = useState("standard");
    const serviceCalc = ({currentTarget: {value}}/*: {currentTarget: HTMLInputElement}*/) => {
        setServiceLevel(value);
        // If you need to run other functions here, you can do that
        // with an `if`/`else`/etc. on `value`, which is
        // `"standard"`, `"premium"`, or `"excelium"
    };
    
    // This is purely to show the new service level
    console.log(`service level is ${serviceLevel}`);

    return (
        <div className="row">
            <div className="col-md-4">
                <label className="radio">
                    <input onChange={serviceCalc} type="radio" name="radio-btn-product" value="standard" checked={serviceLevel === "standard"} />
                    <i></i>Standard
                </label>
            </div>
            <div className="col-md-4">
                <label className="radio">
                    <input onChange={serviceCalc} type="radio" name="radio-btn-product" value="premium" checked={serviceLevel === "premium"} />
                    <i></i>Premium
                </label>
            </div>
            <div className="col-md-4">
                <label className="radio">
                    <input onChange={serviceCalc} type="radio" name="radio-btn-product" value="excelium" checked={serviceLevel === "excelium"} />
                    <i></i>Excelium
                </label>
            </div>
        </div>
    );
};

ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

CodePudding user response:

Pass a parameter depending on which button was checked:

const serviceCalc = (service: "standard" | "premium" | "excelium") => {
    if (service === "standard") {
        return standard();
    }
    
    if (service === "premium") {
        return premium();
    }
    
    if (service === "excelium") {
        return excelium();
    }
}

And you would use it like so:

    <div className="col-md-4">
        <label className="radio">
            <input onChange={() => {serviceCalc("excelium")}} type="radio" name="radio-btn-product" value="excelium" id="excelium" />
            <i></i>Excelium
        </label>
    </div>
  • Related