Dynamically Populating Drop Downs in Different Browsers
I had an issue recently with a pretty standard form in Angular 2. The form had some required fields, one of which was a drop down / select field that wouldn’t populate with options until the user had made some selections earlier in the form. The submit button for the form was disabled until all required fields were filled in.
The issue arose when the client started testing the form in their environment. Despite completely filling out the form, the submit button would stay disabled. Obviously something was wrong.
I could not reproduce the issue on my development machine, so there must have been a difference between the two environments. We knew many of the client’s users were on macs, so were obviously using Safari. Once I got access to a mac and was able to check out the form in Safari, I discovered the issue fairly quickly.
On my development machine, in the Chrome browser, when the user made the the choices earlier in the form that would end up populating options for the drop down / select mentioned above, the field would still appear blank after the options had been added to the element. However in Safari, once the options were added to the element it looked like the first option was automatically selected, despite nothing actually being selected (which we could verify by checking out the bound model’s value).
I made a plunker that demonstrates this effect between different browsers. In that example, there’s an empty select element that populates with data 3 seconds after the page loads. In Chrome, the field will still look empty but in Safari and IE, it looks like the first option in the field is selected.
It turns out this has something to do with the fact that the select element was completely empty when it was populated with options. If there was even one option (even if it was just blank) present in the field, this behavior wouldn’t occur.
This is annoying and not very intuitive behavior, but thankfully a pretty easy fix. In our situation the fix was to explicitly set the field’s bound model’s value to the first option in the array of options we assign to the field. Alternatively, you could do as described above and just pre-populate the field with a blank option as your first option, then append the rest of the options after they’ve loaded.