Manish Vyaspareek
Manish Vyaspareek

Reputation: 57

handle validation scenario in React js

I came across a validation scenario in React js in which the validation must happen on the single row rather than all the rows present.

I am hereby providing an screenshot in which I am adding wrong value of External port and Its displaying an error message on all the rows present,

enter image description here

Below is the code which I have written inside map,

<div className="tab-data-cointainer">
                    <div className="tab-data-section">
                        <div className="content-section port-farwarding">
                            <p className="small-title">Port forwarding for single static Public IP</p>
                            <div className="port-layout">

                                <div className="port-row">
                                    <div className="port-column">
                                        <span>Enable</span>
                                    </div>
                                    <div className="port-column">
                                        <span>Protocol</span>
                                    </div>
                                    <div className="port-column">
                                        <span>External ports</span>
                                    </div>
                                    <div className="port-column">
                                        <span>Port to IP address</span>
                                    </div>
                                    <div className="port-column">
                                        <span>Forward to port</span>
                                    </div>
                                    <div className="port-column"></div>
                                </div>


                                {
                                    this.state.portForwardSettings && this.state.portForwardSettings.map((portForwardSettingsIterate, index) => {

                                        if (null != portForwardSettingsIterate) {
                                            return (
                                                <React.Fragment>
                                                    <div className="port-row">
                                                        <div className="port-column">
                                                            <span className="responsive-label">Port 1:</span>
                                                            <label className={portForwardSettingsIterate.enabled ? "mark-label active" : "mark-label"}>
                                                                <input className="mark-check" type="checkbox" checked={!!portForwardSettingsIterate.enabled} onChange={(e) => this.checkboxHandler(e, index)} />
                                                                <svg focusable="false" aria-hidden="true" className="icon"><use xlink="http://www.w3.org/1999/xlink" href="#icon-tick"></use></svg>
                                                            </label>
                                                        </div>
                                                        <div className="port-column column-select">
                                                            <span className="responsive-label">Protocol</span>
                                                            <select value={portForwardSettingsIterate.protocol} onChange={(e) => this.selectProtocolDropDownHandler(e,index)}>
                                                                <option value="TCPUDP">TCP/UDP</option>
                                                                <option value="TCP">TCP</option>
                                                                <option value="UDP">UDP</option>
                                                            </select>
                                                            <svg focusable="false" aria-hidden="true" className="icon"><use xlink="http://www.w3.org/1999/xlink" href="#icon-chevron-down"></use></svg>
                                                        </div>
                                                        <div className="port-column">
                                                            <span className="responsive-label">External ports</span>
                                                            <input type="text" className="inputPort externalPorts" placeholder="65535" value={portForwardSettingsIterate.externalPort} onChange={(e) => this.externalPortChangeHandler(e,index)} />
                                                            { !this.state.isExternalPortValid && <span className="field-error">Please enter valid values</span> }
                                                        </div>
                                                        <div className="port-column">
                                                            <span className="responsive-label">Port to IP address</span>
                                                            <input type="text" className="inputPort portIP" placeholder="123.456.789.123" value={portForwardSettingsIterate.internalClientIpAddress} onChange={(e) => this.internalIPAddressChangeHandler(e,index)} />
                                                            { !this.state.isInternalClientIPAddressValid && <span className="field-error">Please enter valid values</span>}
                                                        </div>
                                                        <div className="port-column">
                                                            <span className="responsive-label">Forward to port</span>
                                                            <input type="text" className="inputPort forwardingIP" placeholder="65535" value={portForwardSettingsIterate.internalClientPort} onChange={(e) => this.internalClientPortChangeHandler(e,index)} />
                                                            { !this.state.isInternalClientPortValid && <span className="field-error">Please enter valid values</span> }
                                                        </div>
                                                        <div className="port-column">
                                                            <label className="delete-label">
                                                                <input className="delete-check" type="checkbox" />
                                                                <svg onClick={() => this.deletePortSetting(index)} focusable="false" aria-hidden="true" class="icon" automationid="PortForwarding_Svg_DeleteIcon_1">
                                                                    <use xlink="http://www.w3.org/1999/xlink" href="#icon-delete"></use>
                                                                </svg>
                                                            </label>
                                                        </div>
                                                        <div className="port-column">
                                                            
                                                        </div>
                                                    </div>
                                                </React.Fragment>
                                            )
                                        }
                                    })
                                }

                                <a className="btn-add-port" onClick={() => this.addNewPortHandler()}>+ Add new port</a>
                                {/* <p className="max-port-msg">Maximum ports have been added</p> */}

                            </div>
                        </div>
                        <div className="section-btn-row">
                            <div className="btn-group">
                                <a>CANCEL</a>
                                <a className={this.state.portUpdateDisabled}>UPDATE</a>
                            </div>
                        </div>
                    </div>
                </div >

externalPortChangeHandler = (e,index) => {
        let temp_arr = JSON.parse(JSON.stringify(this.state.portForwardSettings))
        let temp_object = temp_arr[index];
        temp_object.externalPort = e.target.value;
        this.setState({ portForwardSettings: temp_arr });

        if(PortForwardConstants.PORT_RANGE.test(e.target.value)){
            this.setState({ isExternalPortValid: true });
        }
        else{
            this.setState({ isExternalPortValid: false });
        }
    }

There is an option given to user for adding the rows - so there is no fixed size row and managing Its validation to particular row is difficult. Can anyone have Idea to manage It?

Upvotes: 3

Views: 134

Answers (1)

Shafqat Jamil Khan
Shafqat Jamil Khan

Reputation: 1037

You can add validation for each object of the array. I changed it for the ExternalPort, you can do the same for other columns.

<div className="tab-data-cointainer">
                <div className="tab-data-section">
                    <div className="content-section port-farwarding">
                        <p className="small-title">Port forwarding for single static Public IP</p>
                        <div className="port-layout">

                            <div className="port-row">
                                <div className="port-column">
                                    <span>Enable</span>
                                </div>
                                <div className="port-column">
                                    <span>Protocol</span>
                                </div>
                                <div className="port-column">
                                    <span>External ports</span>
                                </div>
                                <div className="port-column">
                                    <span>Port to IP address</span>
                                </div>
                                <div className="port-column">
                                    <span>Forward to port</span>
                                </div>
                                <div className="port-column"></div>
                            </div>


                            {
                                this.state.portForwardSettings && this.state.portForwardSettings.map((portForwardSettingsIterate, index) => {

                                    if (null != portForwardSettingsIterate) {
                                        return (
                                            <React.Fragment>
                                                <div className="port-row">
                                                    <div className="port-column">
                                                        <span className="responsive-label">Port 1:</span>
                                                        <label className={portForwardSettingsIterate.enabled ? "mark-label active" : "mark-label"}>
                                                            <input className="mark-check" type="checkbox" checked={!!portForwardSettingsIterate.enabled} onChange={(e) => this.checkboxHandler(e, index)} />
                                                            <svg focusable="false" aria-hidden="true" className="icon"><use xlink="http://www.w3.org/1999/xlink" href="#icon-tick"></use></svg>
                                                        </label>
                                                    </div>
                                                    <div className="port-column column-select">
                                                        <span className="responsive-label">Protocol</span>
                                                        <select value={portForwardSettingsIterate.protocol} onChange={(e) => this.selectProtocolDropDownHandler(e,index)}>
                                                            <option value="TCPUDP">TCP/UDP</option>
                                                            <option value="TCP">TCP</option>
                                                            <option value="UDP">UDP</option>
                                                        </select>
                                                        <svg focusable="false" aria-hidden="true" className="icon"><use xlink="http://www.w3.org/1999/xlink" href="#icon-chevron-down"></use></svg>
                                                    </div>
                                                    <div className="port-column">
                                                        <span className="responsive-label">External ports</span>
                                                        <input type="text" className="inputPort externalPorts" placeholder="65535" value={portForwardSettingsIterate.externalPort} onChange={(e) => this.externalPortChangeHandler(e,index)} />
                                                        { !portForwardSettingsIterate.isExternalPortValid && <span className="field-error">Please enter valid values</span> }
                                                    </div>
                                                    <div className="port-column">
                                                        <span className="responsive-label">Port to IP address</span>
                                                        <input type="text" className="inputPort portIP" placeholder="123.456.789.123" value={portForwardSettingsIterate.internalClientIpAddress} onChange={(e) => this.internalIPAddressChangeHandler(e,index)} />
                                                        { !this.state.isInternalClientIPAddressValid && <span className="field-error">Please enter valid values</span>}
                                                    </div>
                                                    <div className="port-column">
                                                        <span className="responsive-label">Forward to port</span>
                                                        <input type="text" className="inputPort forwardingIP" placeholder="65535" value={portForwardSettingsIterate.internalClientPort} onChange={(e) => this.internalClientPortChangeHandler(e,index)} />
                                                        { !this.state.isInternalClientPortValid && <span className="field-error">Please enter valid values</span> }
                                                    </div>
                                                    <div className="port-column">
                                                        <label className="delete-label">
                                                            <input className="delete-check" type="checkbox" />
                                                            <svg onClick={() => this.deletePortSetting(index)} focusable="false" aria-hidden="true" class="icon" automationid="PortForwarding_Svg_DeleteIcon_1">
                                                                <use xlink="http://www.w3.org/1999/xlink" href="#icon-delete"></use>
                                                            </svg>
                                                        </label>
                                                    </div>
                                                    <div className="port-column">
                                                        
                                                    </div>
                                                </div>
                                            </React.Fragment>
                                        )
                                    }
                                })
                            }

                            <a className="btn-add-port" onClick={() => this.addNewPortHandler()}>+ Add new port</a>
                            {/* <p className="max-port-msg">Maximum ports have been added</p> */}

                        </div>
                    </div>
                    <div className="section-btn-row">
                        <div className="btn-group">
                            <a>CANCEL</a>
                            <a className={this.state.portUpdateDisabled}>UPDATE</a>
                        </div>
                    </div>
                </div>
            </div >

externalPortChangeHandler = (e,index) => {
    
    let portForwardSettings = [...this.state.portForwardSettings]


    let temp_arr = JSON.parse(JSON.stringify(this.state.portForwardSettings))
    let temp_object = temp_arr[index];
    temp_object.externalPort = e.target.value;
    this.setState({ portForwardSettings: temp_arr });

    if(PortForwardConstants.PORT_RANGE.test(e.target.value)){
        //this.setState({ isExternalPortValid: true });
        portForwardSettings[index].isExternalPortValid = true;
    }
    else{
        portForwardSettings[index].isExternalPortValid = false;
        //this.setState({ isExternalPortValid: false });
    }
    this.setState({portForwardSettings})
}

Upvotes: 4

Related Questions