user1933205
user1933205

Reputation: 362

How to submit a form through onSubmit event handler

I have a ReactJS form with an onSubmit function and a "Submit" input as below.

<Form id="addItem" method="post"
  onSubmit={this.handleSubmit}>
  <Form.Group>
    <Form.Row>
      <Col xs={6}>
.
.
.
  </Form.Group>
  <Form.Control type="submit" id="addItemSubmit" name="add" value="Submit" />

The handleSubmit function is supposed to performs validations not covered by HTML5 validations and then submit the form to an API. The function handleSubmit is as follows

handleSubmit(e) {
    e.preventDefault();
    let isValid = validateAddItemForm(this);
    if (isValid) {
      console.log(isValid);
      //const url = "/api/addItem/" + this.props.matchId;
      console.log("match offer url : " + props);
      const res = fetch(url, {
        method: 'post',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
          'X-CSRFToken': csrftoken
        },
        body: JSON.stringify({
         id: 0,
        }) 
       })
       .then((response) => response.json())
       .then((responseJson) => {
         return null;
       })
       .catch((error) => {
         console.error(error);
       });
    } else {
      console.log(isValid);
      return isValid;
    }
  }

Now I have two questions. How to pass the props to handleSubmit? I need to pass some props from the current Component to fully generate the correct URL for the fetch request. How do I pass Form fields in the "body" of the fetch request? Is the filled form available as an object for the handleSubmit funcion when the Submit button is clicked? Or do I need to gather the values of individual fields using document.getElementById(<field_id>).value and pass it in the body?

EDIT: I am currently accessing each form field using the document.getElementById inside the form validation function. That doesn't seem to be a good idea. That is why I want to access it as an object if possible.

Upvotes: 1

Views: 4978

Answers (1)

Zion Ay
Zion Ay

Reputation: 301

First of all, you have access to the props of the component everywhere on the component using "this.props.propName". You just have to remember that if you are using "this" keyword inside a component method you have to bind it (on constructor or whatever) or use an arrow function instead of class method.

You also have access to the form fields when using onSubmit through the form itself passed with the event object, you can use event.target.elements to get an array of the form controls (inputs, button, selects, etc.)

And lastly, if you want to submit the form, you can use the submit() method inside your handleSubmit with again the form you get from the event like so: event.target.submit(). But I can see you are using the fetch API, so it is like you are already submitting the form like that. You can try to set the url on the form tag as the action attribute and submit the form with the submit() if it passes your validation.

More info on the submit() method on W3Schools

More info on accessing form.elements on W3Schools

Binding functions to components - to use "this" keyword inside them

For example:

<Form id="addItem" method="post" action={`/api/addItem/${this.props.matchId}`} onSubmit={this.handleSubmit}>
  <Form.Group>
    <Form.Row>
      <Col xs={6}>
.
.
.
  </Form.Group>
  <Form.Control type="submit" id="addItemSubmit" name="add" value="Submit" />
  
  
  
  handleSubmit = (e) => {
    e.preventDefault();
    // Your validation logic here
    // You can use e.target.elements to access the array of the form controls
    if (isValid) {
      e.target.submit(); //submitting the form to the link in action
    } else {
      console.log('Errors on form');
    }
  }

On the other hand, as others already commented on your question, you can make your component as controlled component, which basically means that each form control will have a value on your state and you will have access to all the fields values in state.

Controlled components from ReactJS Docs

Upvotes: 2

Related Questions