This is a migrated thread and some comments may be shown as answers.

Error when selecting item using javascript when component has a valuemapper

6 Answers 450 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
DD
Top achievements
Rank 1
DD asked on 06 Jul 2020, 09:14 AM

Hi,

I've recently found an issue with the combobox where a user can type in any number on the combobox and it will save if the foreign key exists on the database - regardless of checking whether or not the value is valid for use or not.

Why does the combobox treat typing in a random number as the FK of the control anyway when it doesn't do the same thing if you type in a random character?

Anyway the above is a question for a different time but after finding this out, I've found there's an article on how to avoid these kind of situations using JavaScript on this page: 

https://docs.telerik.com/kendo-ui/knowledge-base/prevent-submission-of-missing-value

While trying to implement this logic, I can see that it's working (by not allowing the random number selection to be saved), but I've noticed there's actually an error on the first round of "select" call as the loading icon is displayed on the combo box.

 

The specific line is the "this.select(0)" line from the code snippet below:

if (this.value() && this.selectedIndex == -1) {   
    this.dataSource.filter({
        value: this.value(),
        field: this.options.dataTextField,
        operator: "contains"
    });
 
    this.select(0);  <=== this line is causing the issue.
 
    if ( this.selectedIndex == -1 ) {                   
        this.text("");
    }
}

 

 

Upon closer inspection, I see that there's a 500 error being thrown due to the "Page" parameter being set to NaN and the "PageSize" parameter being set to 0.

https://.../Items?sort=&group=&filter=NameDisplay~contains~%2712%27&page=NaN&pageSize=0

 

Any subsequent searches works without any issues and sets the "Page" and "PageSize" to the correct values.

https://.../Items?sort=&page=1&pageSize=80&group=&filter=NameDisplay~contains~%2712%27

 

This is very strange as the 500 error (above) only displays the first time this.select(0) is called, but any subsequent times will work without any issues.

 

While trying to reproduce this, I've found that it only occurs when the combobox has a valuemapper set to it.

.Virtual(v => v.ItemHeight(26).ValueMapper("itemsValueMapper"))

 

 

When the valuemapper function is removed from the combobox, the this.select(0) functions runs without any issues.

 

The value mapper is required for my comboboxes as it provides a good way to virtualise my lists.

 

My datasource is using webapi as below:

.DataSource(source =>
{
    source.Custom()
        .ServerFiltering(true)
        .ServerPaging(true)
        .PageSize(80)
        .Type("webapi")
        .Transport(transport =>
        {
            transport.Read(a => a.Url(itemsUrl));
        })
        .Schema(schema =>
        {
            schema.Data("Data")
                    .Total("Total");
        });
})

 

 

Is there any work around that can be done for this?

Or even better, is there a way to prevent the combobox from binding random number values typed into the control?

6 Answers, 1 is accepted

Sort by
0
DD
Top achievements
Rank 1
answered on 07 Jul 2020, 11:08 AM

I've also found while playing around with the knowledge base link (in the previous post), that you can bypass the combo box's "Change" event work around if you navigate away from the control very quickly - such as before the data source is loaded.

While the chance of this happening is low, it's still not ideal as a user may accidentally move away from the combo box control too quickly and hence save the combo box with a ID that isn't valid for them.

 

I was wondering how I was bypassing the "Change" function and it looks like the "Change" event isn't even hit if you move away from the control quickly.

Once you allow the "Change" event to fire once, any subsequent changes are captured by the function.

I initially thought this could be due to the "Autobind" property being set to false, but this does not seem to be the case in my test and also using the knowledge base example (which has static data loaded).

 

An additional question to my previous post, is there any way to fix this so the "Change" event is called regardless of the combo box's state? Or any other event that this check can be hooked onto so it's called with certainty?

0
Veselin Tsvetanov
Telerik team
answered on 08 Jul 2020, 07:44 AM

Hi Daniel,

I will try to address all the questions raised below.

Concerning the number being accepted as a valid value of the ComboBox. In case the ComboBox DataValueField is a Number the observed is expected. By design the ComboBox allows custom values to be populated by the user. When a user types in a custom string in the widget input, that string would be taken as both text and value of the widget. If the widget value is expected to be a Number, the submitted string character (not a number) could not be cast to a number. That, however, is not the case when the user types in a number. In such a case the string from the input will be properly cast as the respective number.

Having the above said if you need to limit the user to choose only among the values present in the widget DataSource, I would recommend you to use the DropDownList widget instead:

https://demos.telerik.com/aspnet-mvc/dropdownlist/virtualization

As per the server error upon the initial select(), please prepare and send me a small isolated runnable sample reproducing it. Please, remove any external dependencies and database calls from that project and use sample data created on the server. This way I will be able to troubleshoot the case locally and to provide you with the most appropriate assistance on the above.

Concerning the change handler bypass, can you reproduce that on the sample provided in the KB article (https://dojo.telerik.com/UFoqeYUd)? If yes, could you please prepare and send me a short screencast demonstrating that? If the above is not reproducible on the Dojo, please, explain to me how to replicate it on the sample project that you will prepare.

Based on the scenario in question, once again I would like to recommend you use the DropDownList widget instead of the ComboBox as it will limit the user's choice within the available items in the DataSource.

Regards,
Veselin Tsvetanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
DD
Top achievements
Rank 1
answered on 08 Jul 2020, 11:21 AM

Hi Veselin,

 

Thanks for getting back to me,

 

I should mention I'm using the ComboBoxFor control which binds to the ViewModel.

While the dropdownlist may overcome the current issue, the combobox in comparison looks much cleaner and handles display of nullable values better.

Whereas the dropdownlist requires you to have an optionlabel for a "none" field, it looks out of place compared to the combobox's simple empty state.

 

It's quite a shame that the above is the case as it would have made sense if the combobox binds the values as expected on the ViewModel on the controller, (will try to explain what I mean below) as in my case when a random number is selected that is not part of the datasource, the input field is set as the number with the Id field blank, but the input field is bound on the controller.

 

 

Is there a way to force the control to ignore binding of the "Input" field if the "Id" field is blank?

Image 1 shows what I am trying to explain here regarding the binding.

 

ItemId is the property in the ViewModel which is bound to the ComboBoxFor (i.e. ComboBoxFor(a => a.ItemId).

 

When a value not from the datasource is selected, the ItemId_input field is populated (e.g. 50) but the ItemId field is blank. (e.g. " ")

On the controller side however, the ViewModel binds the value in the ItemId_input field to the ItemId.

 

If you select a value item from the datasource, the ItemId_Input field shows up with the text (e.g. "value1") and ItemId shows up with the ID (e.g. "2") as expected.

Is there any way to prevent the controller from binding the value from the ItemId_Input field if the ItemId field is null or empty?

If there was some way this could be prevented, the above scenario would be fixed.

 

As for the "Change" handler bypass, yes I was able to recreate the issue with the dojo link you've provided.

 

I'm not sure how to save a screencast but it's quite simple to replicate.

All you have to do is type in a value (in my case I was using numbers) and as soon as you type in a number, click outside of the combobox.

You may find that the change event fires usually, but the timing of this is quite easy to replicate where the change evernt doesn't register and you have the non datasource value set on the combobox.

Image 2 is a snippet of myself being able to set the combobox to the value 56 (just a random value I've used for testing). Usually the combobox will set itself to blank if it finds an invalid value being set.

 

When the combobox is in this state, you can click into the combobox and click out and the value will persist (i.e. change event not fired).

Once you type in another value to the existing number, the change event will fire again.

 

Also if you can let me know regarding the select function having issues on a combobox with virtualisation (from the first post) would be great too.

 

 

Thanks 

0
Veselin Tsvetanov
Telerik team
answered on 09 Jul 2020, 02:35 PM

Hello Daniel,

To answer your questions:

The ComboBox widget does not offer any configuration means that would allow you to force the control to ignore the binding of the "Input" field if the "Id" field is blank.

As per the change handler, it should be modified in the following way in order to properly reset the input when the same value is set twice in a row:

change : function (e) {
  if (this.value() && this.selectedIndex == -1) {    
    this.dataSource.filter({
      value: this.value(),
      field: this.options.dataTextField,
      operator: "contains"
    });
    this.select(0);
    if ( this.selectedIndex == -1 ) {                    
      this.text("");
      this.value("");
    }
  }
}

Her is a modified Dojo sample:

https://dojo.telerik.com/UFoqeYUd/3

As per the select function issues in the virtualization scenario, I will need to be able to reproduce and troubleshoot the problem locally. Therefore, I would like to ask you to prepare and send me a small isolated runnable sample replicating the issue. Please, remove any external dependencies and database calls and use sample data created on the server to populate the widget.

Regards,
Veselin Tsvetanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
DD
Top achievements
Rank 1
answered on 09 Jul 2020, 10:53 PM

Thanks Veselin,

 

This is so strange, with the new dojo you've provided I can't replicate the issue I mentioned in my last post, whereas the previous dojo, I can reproduce it quite easily.

I wonder if this only applies to the javascript versions and I'm guessing that the "this.value("");" fixes the issue on this instance because the "change" event is always being triggered and so the value and text are all being set to blank.

 

However, the problem still exists on my solution which uses the MVC wrapper for version 2018 R3 

The reason why the updated dojo doesn't work for me is because the "Change" event isn't even fired.

 

As requested, I've created a sample project (ComboboxEvent.zip) which reproduces this issue and have uploaded it to uploadfiles.io (link expires in 7 days):

https://ufile.io/cbq1u32x

 

The Index file has the Combobox and has been populated by random data from the server.

 

Once you click on the combobox, type in a random value (say the number 5) and quickly click out of the box, you'll see the event does not trigger and you have the random typed in value set on the combobox.

To reproduce, basically click onto the combobox and move the mouse away (to click outside the combobox soon), as soon as you type a value in the combobox click away from it (it's easiest to have one hand on the keyboard and one on the mouse) the change event isn't triggered.

Clicking in and out won't do anything until you write another value to it, then the change event will trigger and reset it to null.

 

Would be great if you can find out why the change event isn't triggering and any fixes for it.

 

Thanks

0
Veselin Tsvetanov
Telerik team
answered on 13 Jul 2020, 12:26 PM

Hello Daniel,

As far as I can understand, the change event issue is no longer present when using the latest Kendo version (the one used on the Dojo in question - 2020.2.617). Is that correct? If that is the case, I noticed that the sample attached uses version 2018.3.1017 of Kendo and the Telerik suite. Could you, please, update to latest and check if the issue is still present? I am asking you to do so as we do not provide hotfixes for older versions of the suite.

Also, I have noticed that the ComboBox definition has its .AutoBind() option set to false. Note that in such a scenario the DataSource of the widget would not be populated until its drop-down gets open. Before that, the change event will not fire. In order to avoid such a scenario simply remove the .AutoBind(false) from the ComboBox definition.

Regards,
Veselin Tsvetanov
Progress Telerik

Tags
ComboBox
Asked by
DD
Top achievements
Rank 1
Answers by
DD
Top achievements
Rank 1
Veselin Tsvetanov
Telerik team
Share this question
or