Dropdown not working as expected in Safari? - html

I have a dropdown in an Angular 2 project:
<div class="form-group">
<label for="vendors">Vendors</label>
<select class="form-control" id="vendor_id" name="vendor_id" [(ngModel)]="selectedVendor" (ngModelChange)="onVendorChange($event)" required>
<option *ngFor=" let vendor of vendors " [ngValue]="vendor"> {{vendor.business_name}} </option>
</select>
</div>
This works fine in Chrome, but when I open it in Safari, when the page is loaded it shows the first item as selected even if I didn't selected anything. However, if I click "Submit" it will show "This field is mandatory".
In Safari it shows the first item as selected, but actually it's not selected. How to fix this?

In fact, you may find that the accepted answer is insufficient. At least using Angular 5 and Safari, I have found that you must explicitly make the option undefined. In other words:
<option disabled selected value=undefined> --Select-- </option>
Otherwise, the option will simply be marked as disabled and Safari will continue to show that it has the first real option selected, when in fact it isn't (and can't be).

This is not an angular issue, this is the default behavior on safari/mobile safari. An easy solution/workaround is shown below.
If you add another option box such as:
<option disabled selected value> --Select-- </option>
Then your code becomes:
<div class="form-group">
<label for="vendors">Vendors</label>
<select class="form-control" id="vendor_id" name="vendor_id" [(ngModel)]="selectedVendor" (ngModelChange)="onVendorChange($event)" required>
<option disabled selected value> --Select-- </option>
<option *ngFor=" let vendor of vendors " [ngValue]="vendor"> {{vendor.business_name}} </option>
</select>
</div>
This way you cannot re-select the first "Select" box after the user has made a valid selection, answer taken from this answer.

Related

Autofill Broken for Credit Card Expiration Date

For a credit card expiration date, which form elements are “correct” and play nicely with browser autofill?
I’ve seen two main ways of doing it. As a Safari user, this is the most common field that silently fails when I’m auto-filling payment information. Here’s a failure from a real-life experience:
<select>-based field
<label for="billing-cc-exp" class="inputLabelPayment">Expiration Date:</label>
<select name="billing-cc-exp" id="billing-cc-exp" onfocus="methodSelect('pmt-gps')" autocomplete="off">
<option value="0322" selected="selected">03/2022</option>
<option value="0422">04/2022</option>
<option value="0522">05/2022</option>
<option value="0622">06/2022</option>
…
</select>
<input>-based field
<label for="frmCCExp">Expiry</label>
<input name="cc-exp" id="frmCCExp" required placeholder="MM-YYYY" autocomplete="cc-exp">
<input> is more frequently recommended (StackOverflow and tutorial examples), but I’m not sure if <select> StackOverflow example) is specifically a problem, or if it’s just more frequently implemented wrong. So what about the above <select> example breaks autofill, and how would you fix it?
Update: autocomplete isn't the problem
I’ve tested autocomplete="cc-exp”, and the form is still broken for Safari AutoFill, so my self-answer answer is wrong (or at least insufficient).
<select name="billing-cc-exp" id="billing-cc-exp" onfocus="methodSelect('pmt-gps')" autocomplete="cc-exp">
<option value="0322" selected="selected">03/2022</option>
<option value="0422">04/2022</option>
…
</select>
Look at the HTML autocomplete attribute on each of those form fields!
The form elements are not the problem here.
Your broken example has autocomplete=off, as dumb as that is for an expiration date field. The (presumably) working examples have some combination of autocomplete=cc-exp or cc-exp-month and cc-exp-year.
Fixed webform:
<label for="billing-cc-exp" class="inputLabelPayment">Expiration Date:</label>
<select name="billing-cc-exp" id="billing-cc-exp" onfocus="methodSelect('pmt-gps')" autocomplete="cc-exp">
<option value="03/2022" selected="selected">03/2022</option>
<option value="04/2022">04/2022</option>
<option value="05/2022">05/2022</option>
<option value="06/2022">06/2022</option>
…
</select>
There's nothing special about Safari going on here. Chrome looks to the same attribute (related post). Autofill can work without the attribute, as in this JSFiddle example, but autocomplete=off will break it!

Chrome 77 caching <select> selected option, even with autocomplete="off"

If a <select> element has a selected option, Chrome will ignore that selected option even if autocomplete="off" on the <select> element when using the browser's "navigate back" functionality. One workaround I have found is wrapping the select in a <form>, but I don't want extraneous forms in my html.
Question: Is there a way to fix this in Chrome without wrapping in a form element? (This behavior does not occur in Firefox, haven't tested other browsers)
To reproduce, using Chrome 77:
1.) Visit this jsfiddle, and change both selects to "One". Note that "Two" is the selected option for both, so when the page loads this is what should be selected in both elements
2.) Click on the link to google (page navigation won't actually occur, jsfiddle output can't actually navigate to webpages)
3.) With your mouse having clicked in jsfiddle output, click the browser's back button
4.) You'll note that the select element which is wrapped in a form has the correct element selected by default, "Two". The select element which is not wrapped in a form has the incorrect element selected, "One"
https://jsfiddle.net/m5hg8n40/1/
<!-- chrome ignores 'selected' -->
<select autocomplete="off">
<option value="1">One</option>
<option value="2" selected>Two</option>
</select>
<br><br>
google.com
<br><br>
<!-- chrome obeys 'selected' -->
<form autocomplete="off">
<select>
<option value="1">One</option>
<option value="2" selected>Two</option>
</select>
</form>
MAC OS Catalina 10.15
 Browsers
Google Chrome Version 77.0.3865.120 (Official Build) (64-bit)
Safari Version 13.0.2 (15608.2.30.1.1)
Firefox 70.0
 Actions tested:
Onload the jsfiddle i see both with the two option selected
If i click google link and go back, both keeps two selected
If i modify first select (without form) to one, go google and go
back, it keeps the one selected
If i modify the second select (with form) to one, go google, and go
back, it will show the two option selected
So as far as i see.
On load works for both, but the window History treats slightly different both input select, if they are wrapped or not in a <form>tag
One will keep the last action executed, and the other will take priority of the form to reset its inputs to the default state.
Excepcion: Firefox treat both with the same behavior (like without the form)
For me it seems legit to use the tag there if you need it, they can be use to collect data even if they are going to be used locally or remotely.
( is not worse than pages having 1047248 <div>'s everywhere and zero semantic HTML ) so its really up to you i think. And if you need to store data in another way you could use LocalStorage
I think you can't do anything without js.
<body onload="document.querySelector('select').value = document.querySelector('select [selected]').value">
<select>
<option value="1">One</option>
<option value="2" selected>Two</option>
</select>
<br><br>
google.com
<br><br>
<form autocomplete="off">
<select>
<option value="1">One</option>
<option value="2" selected>Two</option>
</select>
</form>
</body>

Requiring dropdown selection in Chrome

Using "required" on a dropdown form element with a "disabled" selection works in Firefox to prevent users from submitting a form without selecting something from the dropdown list, but not in Chrome. Can you help?
<select id="topic" class="form-control" required="required">
<option disabled selected>select genre</option>
<option>All genres (whatever works)</option>
<option>boogers</option>
<option>cheese</option>
<option>dumplings</option>
</select>
This may work
<option selected="true" disabled="disabled">select genre</option>
src: How to show disable HTML select option in by default?
To get it working just add value="" to your default option. This answer provides some HTML5 documentation on the matter.
Can I apply the required attribute to <select> fields in HTML5?

html select option in internet explorer

I have the following code ;
<label for="courseLevel">Level</label>
<select name="courseLevel" id="courseLevel">
<option label="courseLevel">Foundation</option>
<option label="courseLevel">Undergraduate</option>
<option label="courseLevel">Postgraduate</option>
</select>
In firefox and chrome i get "Foundation","Undergraduate","Postgraduate" as the options. In internet explorer i get "courseLevel","courseLevel","courseLevel". Why? and how can it be fixed?
label is not being used correctly (only IE 7+ and Opera support it). You don't need it.
<label for="courseLevel">Level</label>
<select name="courseLevel" id="courseLevel">
<option>Foundation</option>
<option>Undergraduate</option>
<option>Postgraduate</option>
</select>
What you are probably looking for is value. For example, you could assign numeric values to each of the options like so:
<label for="courseLevel">Level</label>
<select name="courseLevel" id="courseLevel">
<option value='0'>Foundation</option>
<option value='1'>Undergraduate</option>
<option value='2'>Postgraduate</option>
</select>
However, you don't need them. When no values are specified, the text between <option> and </option> will be used.
option tags don't need a label attribute. It might be the cause of this problem.
because firefox ignores the label elements assigned to each option.
http://www.w3schools.com/TAGS/att_option_label.asp , http://www.w3schools.com/TAGS/tag_option.asp
seems like only IE7+ and Opera supports this tag
The label attribute is only supported by IE/Opera and will replace the option's innerText value.
Your XHTML is wrong.
You actually want <option value=""> tags; the label property makes no sense there. Furthermore, each value of an <option> tag should be unique. The label tag is correct there, since it corresponds to the id of the <select> tag and will make the drop-down menu appear when the 'Level' text is clicked.
<label for="courseLevel">Level</label>
<select name="courseLevel" id="courseLevel">
<option value="1">Foundation</option>
<option value="2">Undergraduate</option>
<option value="3">Postgraduate</option>
</select>

DropDownList with Firefox and ASP.NET MVC

I have been hitting a brick wall on this for about an hour now. I have a list of counties that I build and add to my view data (counties) and then render the list with a: html.DropDownList('invoice.county', counties) in my view.
It appears to render correctly but FF REFUSES to set the selected item. I have tried swapping the values out for integers (so they don't match the display text) and that did not work. FF just displays the first item in the list
<select id="invoice_county" name="invoice.county">
...
<option value="Lander">Lander</option>
<option selected="selected" value="Laramie">Laramie</option>
<option value="Larimer">Larimer</option>
...
</select>
I have trimmed the values to the ones surrounding the selected item.
Can anyone give me insight into this????
Firefox has a weird bug/feature that means if you just refresh the page, it will select the option already selected regardless of whether the selected attribute is on another option. For example, if I put in:
<select id="invoice_county" name="invoice.county">
<option value="Lander">Lander</option>
<option selected="selected" value="Laramie">Laramie</option>
<option value="Larimer">Larimer</option>
</select>
Saved and refreshed in Firefox, then put:
<select id="invoice_county" name="invoice.county">
<option selected="selected" value="Lander">Lander</option>
<option value="Laramie">Laramie</option>
<option value="Larimer">Larimer</option>
</select>
instead and just refreshed after saving, it would keep "Laramie" selected. To stop this, try Ctrl-F5 rather than just F5 or refresh.
If you are using XHTML, you need a valid attribute/value pair:
<option selected="selected" value="x">
If you are using HTML, the mere presence of the attribute is enough:
<option selected value="x">
More information on W3C.