form.submit callback not getting invoked

为君一笑 提交于 2019-12-24 06:35:50

问题


I'm using the react-bootstrap-typeahead module in one of my application. This is working fine, except in one case.

I'm not able to submit the form by pressing the ENTER key if there are no results.

ie; if there are suggestions provided by react-bootstrap-typeahead, I'm able to select one of the options and submit the form. In this case, able to invoke the callback onSubmit.

if there are no suggestions provided by react-bootstrap-typeahead, not able to submit the form.

If I submit the form using form.submit() method onKeyDown event, the form will be submitted, however, the page gets refreshed instead of invoking callback, which results in complete out of my control result.

The desired result: I should be able to invoke onSubmit callback even if there is no suggestion provided by if there are suggestions provided by react-bootstrap-typeahead.

Here is my code.

<form ref={(form) => this.form = form} onSubmit={this.sendMessage}>
  <Typeahead
    id="rbt-example"
    dropup={true}
    ref={(typeahead) => this.typeahead = typeahead}
    onChange={this.valueChanged}
    onInputChange={this.updateQuery}
    onBlur={(e) => this.updateQuery(e.target.value, e)}
    onKeyDown={(e) => {
      // Submit the form when the user hits enter.
      if (e.keyCode === 13) {
        this.form.submit();
      }
    }}
    options={options}
    placeholder="Type your queries here..."
    renderMenu={(results, menuProps) => {
      // Hide the menu when there are no results.
      if (!results.length) {
        return null;
      }
      return <TypeaheadMenu {...menuProps} options={results} />;
    }}
  />
  <button type="submit">Submit</button>
</form>

回答1:


The issue is likely calling this.form.submit(), which handles the form submission in the DOM (instead of React), and as you say, takes it out of your control. It's refreshing the page because you don't have control over the event to call event.preventDefault().

Instead of this.form.submit, you should call this.sendMessage when the user presses enter. Presumably you're calling event.preventDefault in sendMessage, so you should pass the event through from onKeyDown:

onKeyDown={e => {
  if (e.keyCode === 13) {
    this.sendMessage(e);
  }
}}

This way, you will be handling form submission the same whether in response to the user pressing the submit button or enter.




回答2:


If you noticed the code in my question, I'm handling multiple events. Especially onChange and onKeyDown.

Couple of things we need to understand about react-bootstrap-typeahead is

  1. onChange, react-bootstrap-typeahead will pass the selected object to callback whereas onKeyDown react-bootstrap-typeahead will pass the event, from which, I will get the value using event.target.value
  2. onChange will be triggered only after onKeyDown. therefore, if we want to do some operation based on the selected object and that value to be used in onKeyDown callback will not work.

To overcome this situation, I used setTimeout also removed form element. so my solution simply becomes

<Typeahead
    id="rbt-example"
    dropup={true}
    ref={(typeahead) => this.typeahead = typeahead}
    onChange={this.valueChanged}
    onInputChange={this.updateQuery}
    onBlur={(e) => this.updateQuery(e.target.value, e)}
    onKeyDown={(e) => {
      // Submit the form when the user hits enter.
      if (e.keyCode === 13) {
          if (this.timerid) {
            clearTimeout(this.timerid);
          }
          this.timerid = setTimeout(
            () => {
              this.sendMessage();
            },
            300
          );
      }
    }}
    options={options}
    placeholder="Type your queries here..."
    renderMenu={(results, menuProps) => {
      // Hide the menu when there are no results.
      if (!results.length) {
        return null;
      }
      return <TypeaheadMenu {...menuProps} options={results} />;
    }}
  />
  <button onClick={() => this.sendMessage() }>Send</button>

This way, I'm calling sendMessage method onKeyDown and on button click. I'm also able to make use of the selected option object.



来源:https://stackoverflow.com/questions/56922191/form-submit-callback-not-getting-invoked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!