Setting hidden dropdown selected value causes page reload in iOS 11 safari

Here's my scenario. I'm using a bootstrap dropdown to create a fancy select menu. The actual <select>, used for validation and form post purposes, has it's visibility set to hidden. There is corresponding script to set the selected value of the <select> when the bootstrap dropdown <a> link is clicked.

Here's a snippet of my code.

<div class="dropdown dropdown-select">
    <button class="btn btn-default dropdown-toggle" id="cardSelector" type="button" 
        data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        <span class="selected-value">- Select Credit Card -</span>
        <span class="fa fa-angle-down"></span>
    </button>
    <ul class="dropdown-menu" aria-labelledby="cardSelector">
        <li data-bind="visible: model.HasValidCardOnFile()"><a href="#" data-value="1">- Existing Credit Card -</a></li>
        <li><a href="#" data-value="0">- New Credit Card -</a></li>
    </ul>
    @Html.DropDownListFor(m => m.CardTypeId, Model.GetCardTypeSelectList(),
        new { data_bind = "value: modelInput.CardTypeId", @class = "requires-validation" })
</div>
@Html.ValidationMessageFor(m => m.CardTypeId)

$(".dropdown-select").on('click', '.dropdown-menu a', function () {
    var $this = $(this);
    var $dropdownCtrl = $this.closest(".dropdown-select");
    $dropdownCtrl.find("select").val($this.data("value")).trigger("change");
    $dropdownCtrl.find(".selected-value").html($this.html());
    $dropdownCtrl.removeClass("open");
    return false;
});

The problem is that in iOS 11 safari, the page blows up with an error something like "An unexpected problem occurred. The page was reloaded."

I've traced it down to this bit of code $dropdownCtrl.find("select").val($this.data("value")). Setting the value is what causes the issue, I changed it to vanilla javascript and the error still occurred.

In testing I made the <select> visible and the issue went away. So it seems to be an issue specifically with changing the selected value of a <select> when it's not visible. I tried adding script to temporarily make it visible right before setting the selected value but this did not fix the issue, neither did changing the visibility and selecting the new value inside a setTimeout.

1 answer

  • answered 2018-09-21 19:10 Adam

    After many different attempts to solve the issue I found a workaround that works in all browsers, doesnt break my jquery validation or form submission.

    My solution was to clear out the <select> lists and use javascript to re-add the selected option upon item click.

    There were no changes to the html portion, and the script was changed to this

    $(".dropdown-select").on('click', '.dropdown-menu a', function () {
        var $this = $(this);
        var $dropdownCtrl = $this.closest(".dropdown-select");
        var $selectCtrl = $dropdownCtrl.find("select");
        $selectCtrl.empty();
        var $selectedOption = $("<option value='" + $this.data("value") + "' selected='selected'>" + $this.text() + "</option>");
        $selectCtrl.append($selectedOption);
        $selectCtrl.trigger("change");
        $dropdownCtrl.find(".selected-value").html($this.html());
        $dropdownCtrl.removeClass("open");
        return false;
    });
    

    I did a lot of searching but didn't find any viable solutions, so I'm posting this in the off chance it helps someone else.