We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Disable propagation of pressing keys to parent form when in combobox with custom value

Hello,

I'm trying to implement a component for entering tags. Selected tags are shown first, then a combo box should allow to either enter new tags or select from existing tags. That's why I enabled "customValue" on combobox. When combo box value changes then the selected tag is added (and created if not exists). This is working so far. However, my tags input component resides in a form and therefore pressing the ENTER key in combo box input tries to submit the form. How can I disable the propagation of key press from combo box to its parent form?

Best regards
Steffen Harbich

9 Replies 1 reply marked as answer

SP Sureshkumar P Syncfusion Team February 23, 2021 12:04 PM UTC

Hi Steffen, 
 
Greetings from Syncfusion support, 
 
This is the default behavior of form components. when pressing the enter key inside the form the actions will trigger the form submit. If you want to override the functionality then we need to create a form handler that would prevent the default form action. 
 
Please find the code example: 
<form onSubmit={this.submitHandler}> 
 
submitHandler(e) { 
    e.preventDefault(); 
} 
 
 
To know more about these behavior change. Please refer the below stack overflow link: https://stackoverflow.com/questions/43750335/react-prevent-form-submission-when-enter-is-pressed-inside-input/50977097  
 
Regards, 
Sureshkumar P 



SH Steffen Harbich February 23, 2021 03:10 PM UTC

Yes I am aware of that default browser behavior. And I don't want to prevent form submit in general because it is an actual form that can be submitted (with react-hook-form).

In my opinion, it is the responsibility of the combo box to prevent default behavior when enter key is pressed because combobox actually handles the enter key as "change" of combobox value. At least in case of "customValue=true" this should be taken into account.

Do you have another proposal? Is there a non-hacky way to handle key press events in combobox input html element?


SP Sureshkumar P Syncfusion Team February 24, 2021 08:36 AM UTC

Hi Steffen, 
 
Thanks for your update, 
 
You can restrict the enterKey pressing action in the combobox component by using keydown event in the combobox component. please find the code example below. 
 
 <ComboBoxComponent 
                id="customvalue" 
                ref={ComboBox => { 
                  this.listObj = ComboBox; 
                }} 
                dataSource={this.searchData} 
                filtering={this.onFiltering.bind(this)} 
                allowFiltering={true} 
                fields={this.fields} 
                noRecordsTemplate={this.template} 
                created={this.created.bind(this)} 
                placeholder="Select a country" 
                popupHeight="270px" 
              /> 
 
 
this.created = e => { 
      document 
        .getElementById("customvalues") 
        .addEventListener("keydown"function(keys) { 
          if (keys.key === "Enter" || keys.keyCode === 13) { 
            // Do something 
            keys.preventDefault(); 
          } 
        }); 
    }; 
 
 
 
 
We have created the sample based on your requirement. please find the sample here: https://stackblitz.com/edit/react-cycnra-vmrya5?file=index.js  
 
Regards, 
Sureshkumar P 



SH Steffen Harbich February 24, 2021 09:18 AM UTC

Alright, thanks. This is working. But you have to admit that this is only a workaround. The proper fix would be to adapt the combobox component code to call "e.preventDefault" when enter key is pressed and "customValue=true". Why? Because I now need to make the assumption that your component uses the enter key for exactly that behavior. If you change it one day, e.g. add another shortcut key for the action, I will need to adapt my code, too.

Best Regards,
Steffen


PM Ponmani Murugaiyan Syncfusion Team February 25, 2021 11:19 AM UTC

Hi Steffen, 

Thanks for the update. 

Based on the validation of the reported scenario, we would like to inform you that if “Enter” key is pressed in the component inside the Form, the submit action will be triggered. This is default behavior of form. This behavior can be observed in the default HTML5 input as well. The same we have implement in our component. Kindly refer the below link for reference. 


Hence, we couldn’t achieve this in our source code, so we suggest you to use the previously suggested solution to meet your requirement in the application end. 

Regards, 
Ponmani M 



SH Steffen Harbich February 25, 2021 04:24 PM UTC

>Based on the validation of the reported scenario, we would like to inform you that if “Enter” key is pressed in the component inside the Form, the submit action will be triggered.

We already clarified that and I know that.

> This is default behavior of form.

That's the problem. Solution: preventDefault in event handler. Or the workaround you provided which works but is a workaround. I will use it of course to fix the problem.

> This behavior can be observed in the default HTML5 input as well.

This is true but ComboBox is not a default HTML5 component. Also, consider "textarea" input that doesn't trigger a form submit on "enter" but will add a new line.

> The same we have implement in our component.

You do not have implemented it in your component, it's default behavior of the browser, as you mentioned yourself above.

> Hence, we couldn’t achieve this in our source code, so we suggest you to use the previously suggested solution to meet your requirement in the application end.

You couldn't call event.preventDefault() when handling the 'enter' key in your combobox component? What is stopping you to do that? I mean I can see the javascript code and it is handling 'keydown' event. No offence but please discuss this with your developer colleagues.

Consider the following example: Let's say you would change the behavior of combobox code to use 'tab' key for selecting the item (or firing the event for "custom value entered" as in my case after typing some string). Now, the default browser behavior would be "set focus to next focusable element" on 'tab' pressed. That means, the focus would transition away from the combobox. Not really useful then, isn't it? So you would call preventDefault to prevent this default behavior because the action is "select the combobox item" and it is handled by your combobox. Or do you think everyone that uses your combobox should do the preventDefault for herself in that case? I doubt.

I don't say combobox should always preventDefault the 'enter'. It only makes sense for customValue=true.





PM Ponmani Murugaiyan Syncfusion Team March 3, 2021 11:18 AM UTC

Hi Steffen, 

Thanks for the patience. 

We would like to inform you that by default when type and press ENTER key in the component inside the Form, the submit action will be triggered as per default HTML input, which we explained earlier. We have maintained same behavior in our source with both cases allowCustom true or false. Also regarding the mentioned textarea example, since it is a multiline component enter key action adds newline and our combobox is single line component. so it is compared to HTML input alone.   

We can achieve your requirement to prevent the submit action when custom value is entered, using work-around solution for ComboBox component with allowCustom true. Here we have considered the global variable isCustomValue, after typed custom text in input and focus out the customValueSpecifier event will be triggered and there updated the global variable as true. So, while form submit we will prevent the submit action when ENTER key is pressed only on allowCustom true case by comparing the global variable.   

The above suggested solution will meet your requirement for ComboBox with allowCustom as true. Please find the code snippet and sample below for reference. 

<form id="form1"> 
<div> 
    <ComboBoxComponent id="games" dataSource={this.sportsData} allowFiltering={true} created={this.created.bind(this)}        customValueSpecifier={this.customValue.bind(this)} ref={combobox => { this.listObj = combobox; }} fields={this.fields}   placeholder="Select a game" value={this.value} popupHeight="220px" /> 
</div> 
<div> 
    <button className="submit-btn e-btn" id="submit-btn"> 
    Submit 
    </button> 
</div> 
</form> 
 
this.isCustomValue = false; 
this.customValue = e => { 
    this.isCustomValue = true; 
}; 
this.created = e => { 
    var _this = this; 
    document.getElementById("form1").addEventListener("keydown", function(keys) { 
        if (keys.key === "Enter" || keys.keyCode === 13) { 
            if (_this.isCustomValue) { 
            keys.preventDefault(); 
            _this.preventDefault = false; 
            } 
        } 
    }); 
}; 


Please get back us if you need further assistance. 

Regards, 
Ponmani M 



SH Steffen Harbich March 4, 2021 10:00 AM UTC

> Also regarding the mentioned textarea example, since it is a multiline component enter key action adds newline and our combobox is single line component.
> so it is compared to HTML input alone.

Yes textarea and HTML input are different but it was just a pointer to how textarea handles enter key. I can also say 'ComboBoxComponent does not compare to HTML input because it selects values and it is therefore more comparable to HTML select instead' but that's not the point.

By the way, I never doubt that my requirements can be fulfilled using the approaches discussed, and I already have them implemented. So, you do not need to post examples anymore. I only reply here to unterstand and discuss why ComboBoxComponent doesn't call the preventDefault on enter key pressed for custom values.

Now in the meantime of the discussion I stumbled upon the MultiSelectComponent's features that has exactly what I was trying to accomplish with my "tag input" component that uses your ComboBoxComponent. Please see this example: https://stackblitz.com/edit/syncfusion-tag-input?file=index.js
If you play around with entering custom values, pressing enter key adds a new tag (=chip) and does not submit the form. It has to be because MultiSelectComponent does preventDefault in that case, right? All your arguments for ComboBoxComponent regarding why the component should not call preventDefault apply also to MultiSelectComponent, right? If not, please explain the difference.

Have a nice day,
Steffen


PM Ponmani Murugaiyan Syncfusion Team March 10, 2021 08:42 AM UTC

Hi Steffen, 

Thanks for your patience.  

We would like to know you that in Multiselect component while entering custom values, the values will be shown in the popup and also the focus will be maintained in the popup. So, when you press ENTER key in Multiselect inside the form, the custom values in the popup will be updated to the input. So, the form not get submitted. 

 

But in ComboBox component, we have not maintained the custom values in the popup. When entering custom values, the popup shows No records found and the focus will be maintained in the input. So, while press ENTER key in ComboBox component inside the form, it gets submitted. 

 

Also, we would like to know you that in ComboBox component, we able to add the custom values in the popup using the public method AddItem as like Multiselect component behaviour and it can be achieved in sample level. 


Kindly check the above summary for a comparison of Multiselect and ComboBox component behaviour and if that answers your query. 

Regards, 
Ponmani M 


Marked as answer
Loader.
Up arrow icon