0

I am getting some strange behaviour within IE which I was hoping someone might be able to explain. I have a simple form with an address lookup input

<form action="http://localhost:8000/processForm" method="post">
    <label for="input_1" class="form-control-label col-xs-12">
        Postcode
    </label>

    <div class="col-xs-12">
        <div class="input-group">
            <input type="text" name="questions[1]" autocomplete="off" id="input_1" class="form-control address" value="" >

            <a class="btn btn-xs input-group-addon address-button" id="input_address_addon" role="button" tabindex="0">
                <img src="http://localhost:8000/images/glyphicons-243-map-marker.png">
                Search
            </a>
        </div>
        <div class="col-xs-12 col-sm-8 col-sm-offset-4 col-md-7">
            <select class="form-control selectpicker addSelect" id="input_address_select" style="display: none;">
                <option value="">Enter above</option>
            </select>
        </div>
    </div>
    <button type="submit" class="btn submit btn-navigation">
        Continue
    </button>
</form>

The address is entered into the input, then the search button is clicked. This makes a call to an API to return addresses and populate the a select input with them. This all works fine in all browsers, but noticed something strange with IE. This is the Javascript that handles the API call and populating of the select.

!function ($, window) {

    $(function () {
        init();
    });

    var getAddresses = function (postcode, callback) {
        var $xhr = $.getJSON('/lookupPostcode/' + postcode);
        $xhr.done(function (data) {
            callback(data);
        });
        $xhr.error(function () {
            callback([]);
        })
    };

    var init = function () {
        $("input.address").each(function () {
            var $input = $(this);
            var $icon = $input.next('.address-button');
            var $select = $input.parents('.row').eq(0).find("select");

            $select.css("display", "none");

            var onKeyUp = function (e) {
                if (e.keyCode === 13) {
                    e.preventDefault();
                    e.stopPropagation();
                    $icon.trigger("click");
                }
            };
            var onKeyDown = function(e) {
                if (e.keyCode === 13) {
                    e.preventDefault();
                    e.stopPropagation();
                }
            };

            $input.on("keyup", onKeyUp);
            $input.on("keydown", onKeyDown);
            $icon.on("keyup", onKeyUp);
            $icon.on("keydown", onKeyDown);
            $select.on("keyup", onKeyUp);

            $icon.on("click", function () {
                getAddresses($input.val(), function (addresses) {
                    //populate select options with addresses
                });
            });

            $select.on('change', function (event) {

                var ua = window.navigator.userAgent;
                var is_ie = /MSIE|Trident/.test(ua);

                if ( !is_ie ) {
                    $select.css("display", "none");
                }
                /*$select.css("display", "none");*/
            });
        });
    };

}(jQuery, window);

So when an address is selected from the select input, I hide the select input. On IE, this hiding of this element seems to make the form submit. You can see above that I have added some code to check that it is not IE and only hide on these devices, and keeping the select in place on IE works fine. Also, if I put an alert at the top of the change event, this also seems to stop the form submitting in IE.

So I was wondering what may be causing this to submit in IE if I hide the select? I have read that IE does not like buttons to be used as form submits, but not sure if this is the issue?

Is there any way to get the select hiding in IE?

Thanks

katie hudson
  • 2,765
  • 13
  • 50
  • 93
  • Have you tried to `return false;` on you `onchange` function? Have you tried to use `keydown` for select element instead of `keyup` and prevent default? Note: if you ware using accessibility change aria attributes. – Observer Nov 05 '18 at 13:48
  • Not related to your issue, but `$(function () { init(); });` could/should just be: `$(init());`. – Scott Marcus Nov 09 '18 at 21:05
  • Are you sure that it's the hiding that causes the submit? Maybe just pressing enter within the form causes it? – johey Nov 10 '18 at 16:46
  • You could try to see what happens if you deactivate a form submit on enter (not a good practice, but it may help to understand the problem). E.g. `$(document).on('keypress', 'form', function (e) { var code = e.keyCode || e.which; if (code == 13) { e.preventDefault(); return false; } });` – johey Nov 10 '18 at 16:50

2 Answers2

3

So I was wondering what may be causing this to submit in IE if I hide the select? I have read that IE does not like buttons to be used as form submits, but not sure if this is the issue?

I can't reproduce your problem, everything works well on my side (IE 11.1.17340.0 version).

Please try to use the following code: (based on your code, please note the part of code with comment)

<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script type="text/javascript">
        !function ($, window) {

            $(function () {
                init();
            });

            var getAddresses = function (postcode, callback) {
                //var $xhr = $.getJSON('/lookupPostcode/' + postcode);

                //$xhr.done(function (data) {
                //    callback(data);
                //});
                //$xhr.error(function () {
                //    callback([]);
                //})
                //using the following array to populate the select.
                var datalist = [{ "ID": "1", "ParentID": "0", "Name": "Parent1" }, { "ID": "2", "ParentID": "0", "Name": "Parent2" },
                { "ID": "3", "ParentID": "1", "Name": "Child 1.1" }, { "ID": "4", "ParentID": "1", "Name": "Child 1.2" },
                { "ID": "5", "ParentID": "3", "Name": "SubChild 1.1.1" }, { "ID": "6", "ParentID": "2", "Name": "Child 2.1" }];

                callback(datalist);
            };

            var init = function () {
                $("input.address").each(function () {
                    var $input = $(this);
                    var $icon = $input.next('.address-button');
                    //you are using the .row class to find the select control, but from your form, I can't find this class.
                    var $select = $input.parents('.row').eq(0).find("select");
                    //debugger;
                    $select.css("display", "none");

                    var onKeyUp = function (e) {
                        if (e.keyCode === 13) {
                            e.preventDefault();
                            e.stopPropagation();
                            $icon.trigger("click");
                        }
                    };
                    var onKeyDown = function (e) {
                        if (e.keyCode === 13) {
                            e.preventDefault();
                            e.stopPropagation();
                        }
                    };

                    $input.on("keyup", onKeyUp);
                    $input.on("keydown", onKeyDown);
                    $icon.on("keyup", onKeyUp);
                    $icon.on("keydown", onKeyDown);
                    $select.on("keyup", onKeyUp);

                    $icon.on("click", function () {
                        $select.empty();
                        $select.append("<option value=''>Enter above</option>");
                        getAddresses($input.val(), function (addresses) {
                            //populate select options with addresses                           
                            $.each(addresses, function (index, item) {
                                //debugger;
                                $select.append("<option value='" + item.ID + "'>" + item.Name + "</option>");
                            });

                            $select.css("display", "block");
                        });
                    });

                    $select.on('change', function (event) {

                        var ua = window.navigator.userAgent;
                        var is_ie = /MSIE|Trident/.test(ua);
                        //get the selected text and populate the input text.
                        $input.val($(this).find("option:selected").text());

                        //hide the select control
                        if (!is_ie) {
                            $select.css("display", "none");
                        }
                        $select.css("display", "none");

                    });
                });
            };

        }(jQuery, window);
    </script>
</head>
<body>
    <form action="http://localhost:8000/processForm" method="post">
        <label for="input_1" class="form-control-label col-xs-12">
            Postcode
        </label>

        <div class="col-xs-12 row">
            <div class="input-group">
                <input type="text" name="questions[1]" autocomplete="off" id="input_1" class="form-control address" value="" />

                <a class="btn btn-xs input-group-addon address-button" id="input_address_addon" role="button" tabindex="0">
                    <img src="http://i.imgur.com/H9FIags.jpg" style="height:10px;width:10px" />
                    Search
                </a>
            </div>
            <div class="col-xs-12 col-sm-8 col-sm-offset-4 col-md-7">
                <select class="form-control selectpicker addSelect" id="input_address_select" >
                    <option value="">Enter above</option>
                </select>
            </div>
        </div>
        <button type="submit" class="btn submit btn-navigation">
            Continue
        </button>
    </form>
</body>

The output as below:

enter image description here

Zhi Lv
  • 18,845
  • 1
  • 19
  • 30
  • Thanks for the comment. From your GIF, I can see that you are using your mouse. This issue occurs from an accessibility point of view. So if you tab into the postcode, enter a postcode, tab to search, press enter to search, tab onto the select, then use spacebar to open it, it is when you select something using the enter key. Sorry if the above is confusing, basically try to do this using only your keyboard :-) – katie hudson Nov 02 '18 at 22:53
  • I would sprinkle around some preventDefault's. I see you have them on a few items, but I would try #input_1, and then the form element itself. Also you may want to look at this: https://stackoverflow.com/questions/1000597/event-preventdefault-function-not-working-in-ie I believe IE has some ... quirks... with the standard preventDefault. – Ethan Green Nov 06 '18 at 21:07
0

The reason why your form submits is the fact that you have a button of type "submit" in your form.

<button type="submit"...>

Whenever you press enter, this will cause your form to submit. You need to change your submit button to another type like "button" and add a Javascript event handler to it (for example onClick="submit()").

<button type="button" class="btn submit btn-navigation" onClick="submit(this.form)">
    Continue
</button>

function submit(form){
    form.submit();
}
ESP32
  • 8,089
  • 2
  • 40
  • 61