3

I have a form which has 5 input text type fields and a input file type field. I used onChange function.

this is the form

<form onSubmit ={this.onSubmit.bind(this)} >
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Company Name" name="companyName" ref="companyName"/>
            </FormGroup>
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Account Name" name="AccountName" ref="AccountName" />
            </FormGroup>
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Bank Name" name="bankName" ref="bankName"/>
            </FormGroup>
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Branch" name="branch" ref="branch"/>
            </FormGroup>
            <FormGroup bssize="sm">
                <input onChange={this.handleChange} className="form-control" type="text" placeholder="Account Number" name="accountNo" ref="accountNo"/>
            </FormGroup>
<FormGroup>

            <span>Bank Book Copy</span>  &nbsp; 
            <input style={{display :'none'}} type="file" onChange={this.fileSelectedHandler} ref={fileInput => this.fileInput = fileInput } />
            <Button onClick={()=>this.fileInput.click()} >
                  <Icon type="upload" /> Click to upload
            </Button>
            </FormGroup>
                <input onClick={this.fileUploadHandler} className="btn btn-primary" bsstyle="success" name="submit" type="submit" value="Submit" />
            </form>

now my problem is which filed filled at last only post into my API.I used AXIOS for HTTP request. I used storage-connector for upload images

below I mentioned my onChange function

constructor(props){
        super(props);
        this.state = {
            companyName : '',
            AccountName : '',
            bankName : '' , 
            bankBookCpy : '' ,
            accountNo : '' ,
            branch : '' , 
            BankList : '',
            selectedFile : null,
        }
    }

    fileSelectedHandler = event =>{
        this.setState({
            selectedFile: event.target.files[0]
        })

    }
    handleChange = event => {
        this.setState({ 
            companyName: event.target.value,
            AccountName: event.target.value,
            bankName: event.target.value,
            accountNo: event.target.value,
            branch: event.target.value
         });

    }
    fileUploadHandler = () => {
        const fd = new FormData();
        fd.append('image',this.state.selectedFile, this.state.selectedFile.name )
        axios.post('http://localhost:3000/api/attachmentBanks/bankBookCpy/upload',fd , {
            onUploadProgress : ProgressEvent => {
                console.log('Upload Progress: ' + Math.round(ProgressEvent.loaded / ProgressEvent.total *100) + '%')
            }
        })
        .then(res => {
            this.setState({
                BankList: res.data.result.files.image[0].name,
            });

        });
    }

    AddMeetup(newMeetup){
        axios.request({
            method:'post',
            url:'http://localhost:3000/api/companyBankDetails',
            data : newMeetup
        }).then(response => {
            this.props.history.push('/');
        }).catch(err => console.log(err));
    onSubmit(e){
        const newMeetup = {
            companyName: this.state.companyName,
            AccountName : this.state.AccountName,
            bankName : this.state.bankName,
            branch : this.state.branch,
            accountNo : this.state.accountNo,
            bankBookCpy : this.state.BankList
        }
        this.AddMeetup(newMeetup);
        e.preventDefault();
    }

Above functions are only stored last onChange value

4 Answers 4

5

You can handle it like this:

  handleChange = event => {
    this.setState({ [event.target.name]: event.target.value });
  };
Sign up to request clarification or add additional context in comments.

Comments

2

First change you handleChange function to the following :

handleChange = name => event => {
    this.setState({ [name]: event.target.value} );
}

Then send your name argument to the onChange function :

<form onSubmit ={this.onSubmit.bind(this)} >
    {
        Object.entries({
            "Company Name": "companyName",
            "Account Name": "AccountName",
            "Bank Name": "bankName",
            "Branch": "branch",
            "Account Number": "accountNo"
        }).map(([field, name]) => 
        <FormGroup bssize="sm" key={name}>
                <input onChange={this.handleChange(name)} className="form-control" type="text" placeholder={field} name={name} ref={name}  />
        </FormGroup>)
    }
<FormGroup>

You can avoid repetitions in your code by also mapping an array to create your form

2 Comments

sir, thing is I have to handle image uploading also. How can I?
You are going to need an input with a "file" type, you will find all infos about the image in the event.target.value variable. you may want to add the input type to each fields in the JSON I made
1

Here your issue is you call same handleChange() Function on each onChange event. let's assume you change "company name" input field. When you change it you will call the handleChange() function. Then inside that function, you assign event.target.value to all of the fields(companyName, AccountName, etc). But event.target.value only give you the data from the field that you are changing to call the handleChange() method, In this case, it is "company Name" input. So this will replace all of your form data states with the text you entered in "Company Name".

So, the hard way is you can create separate functions to handle each input fields. But it is not good practice. Instead, you can do as answered by SakoBu.

that method will take state name from event.target.name and state data from event.target.value. So if you change the value of "Company Name" your state update code in the handleChange() will be the same as companyName: event.target.value, but only change CompanyName state, not other form states.

You don't need to worry about image uploading system. Because you can use your existing fileUploadHandler() method to handle the changes of the file uploading.

Comments

1

As answered by SakoBu, the approach would solve your problem. One thing I noticed is you are assigning ref to each input field, you don't need to do so.

Please do remember that if input type is checkbox,radiobutton you will get corresponding value by event.taget.checked.

It's always a good practise to check event type, by event.target.type.

For more details visit :- https://reactjs.org/docs/forms.html

Hope this Helps,

Cheers !!

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.