2

I'm developing a simple Reactjs login form while i'm learning reactjs.Now my form is rendering properly on the browser.But it's validation is not working although i have defined validation rules for the form.It has only two fields, one is for email and other is for password.And login button.Following is my Reactjs code,

//React component for input component
var MyInput=React.createClass({
//onchange event
handleChange: function(e){
this.props.onChange(e.target.value);
var isValidField=this.isValid(e.target);
},
//validate function
isValid: function (input){
//check required field
if (input.getAttribute('required') !=null && input.value==="") {
input.classList.add('error');//add class error
input.nextSisling.textContent=this.props.messageRequired;//show error message
return false;
}
else{
input.classList.remove('error');
input.nextSisling.textContent="";
}
//check data type
if (input.getAttribute('type') == "email" && input.value !="") {
if(!this.validateEmail(input.value)){
input.classList.add('error');
input.nextSisling.textContent=this.props.messageEmail;
return false;
}
else{
input.classList.remove('error');
input.nextSisling.textContent="";
}
}
return true;
},
//email validation function
validateEmail: function(value){
var re=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0- 9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z] {2,}))$/;
return re.test(value);
},
componentDidmount: function(){
if(this.props.onComponentMounted){
    this.props.onComponentMounted(this);//register the input in form
}
},
//render
render:function(){
var inputField;
inputField = <input type={this.props.type} ref={this.props.name} name=   {this.props.name} className='form-control' required={this.props.isrequired}   onChange={this.props.handleChange}/>;

return(
    <div className="form-signin">
    <label>{this.props.htmlfor}:</label>
    {inputField}
    <span className="error"></span>
    </div>
    );
}
});

//React component for generate form
var LoginForm=React.createClass({
//get initial statement
getInitialState: function(){
    return {
    Username: '',
    Userpassword: '',
    Fields: [],
    ServerMessage: ''
    }
},
//submit function
handleSubmit: function(e){
    e.preventDefault();
    //validate entire form
    var validForm=true;
    this.state.Fields.forEach(function(field){
        if(typeof field.isValid === "function"){
            var validField=field.isValid(field.refs[field.props.name]);
            validForm=validForm && validField;
        }
    });
    //after validation, data post to server
    if (validForm) {
        var d = {
            Username: this.state.Username,
            Userpassword: this.state.Userpassword
        }

        $.ajax({
            type: "POST",
            url: this.props.actionUrl,
            data: d,
            dataType:"json",
            success: function(data){
                //will clear form upon data submitted
                this.setState({
                    Username: '',
                    Userpassword: '',
                    ServerMessage: data.message
                });
            }.bind(this),
            error: function(e){
                console.log(e);
                alert('Something went wrong..Please try again!');
            }
        });
    }
    },
    //handle change username
    onChangeUsername: function(value){
    this.setState({
        Username: value
    });
    },
    //handle change password
    onChangePassword: function(value){
    this.setState({
                Userpassword: value
            });
    },
    //register input controls
    register: function(field){
    var s=this.state.Fields;
    s.push(field);
    this.setState({
        Fields: s
    });
    },
    //render
    render: function(){
    //render form
    return(
        <form name="loginForm" noValidate onSubmit={this.handleSubmit}>
            <MyInput type={'email'} value={this.state.Username} label=  {'Username'} htmlfor={'Username'} name={'Username'} isrequired={true}
            onChange={this.onChangeUsername} onComponentMounted={this.register} messageRequired={'Invalid username'}/>

            <MyInput type={'password'} value={this.state.Userpassword} label={'Password'} htmlfor={'Password'} name={'Userpassword'} isrequired={true}
            onChange={this.onChangePassword} onComponentMounted={this.register} messageRequired={'Invalid Password'}/>

            <button type="submit" className="btn btn-lg btn-primary btn-block">SignIn</button>
            <p className="servermessage">{this.state.ServerMessage}</p>
        </form>
        );
     }
     });

     //Render react component into the page
     ReactDOM.render(<LoginForm  actionUrl="UserLogin"/>,document.getElementById('ReactJSForm'));

1 Answer 1

1

The first error is inside input tag you mentioned

onChange={this.props.handleChange}

which means the event will be bubbled to parent class (LoginForm), so the handleChange of MyInput is not getting called. from where you are again calling the parent funtion. So change that to

onChange={this.handleChange}

2nd error is in isValid method of MyInput, where you are manipulating DOM using javascript which is not applicable in react.

input.classList.add('error');//add class error
input.nextSisling.textContent=this.props.messageRequired;//show error message

(Though I you meant nextSibling)

In my opinion maintain a state for error and set it inside isValid, the value you are returning. Based on that do the above manipulations. something like

render:function(){
var inputField;
var inputClass ='form-control';
var errorMsg = '';
if( this.state.isError){// guessing you set state isError to true/false inside isValid
 inputClass += ' error';
 errorMsg = this.props.messageEmail;
}
inputField = <input type={this.props.type} ref={this.props.name} name=   {this.props.name} className={inputClass} required={this.props.isrequired}   onChange={this.handleChange}/>;

return(
    <div className="form-signin">
    <label>{this.props.htmlfor}:</label>
    {inputField}
    <span className="error">{errorMsg}</span>
    </div>
    );
}
});
Sign up to request clarification or add additional context in comments.

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.