New issue
Advanced search Search tips

Issue 662669 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner:
Closed: Nov 2016
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 3
Type: Bug



Sign in to add a comment

Bug when dyncamilly inserting option elements, and one of the elements have the "selected" attribute set to true ...

Reported by tho...@gaiasoul.com, Nov 5 2016

Issue description

Chrome Version       : 54.0.2840.71
OS Version: 10.0
URLs (if applicable) :
Other browsers tested:
  Nope

What steps will reproduce the problem?
1. Create a select HTML element, populate it with option items.
2. Remove the option elements.
3. Add new option elements with something resembling the JavaScript below, and have one of your elements have its "selected" attribute set.

What is the expected result?

The the option element with the "selected" attribute becomes selected.


What happens instead of that?

The last option elements seems to always be selected instead


Please provide any additional information below. Attach a screenshot if
possible.

Here's the JavaScript;
if (key.indexOf("__p5_add_") !== -1) {

    // Inserting html child widget
    var pos = parseInt(key.substring(9), 10);
    var fragment = document.createDocumentFragment();
    var tmpEl = document.createElement(this.el.tagName);
    tmpEl.innerHTML = value;
    fragment.appendChild(tmpEl.firstChild);
    this.el.insertBefore(fragment, this.el.children[pos]);
} else { ....

UserAgentString: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36

This is at the core of my managed Ajax library (think GWT), which completely abstracts away the JavaScript and Ajax parts, so easily creating a reproducable, without either forcing you guys to download the entire framework (which is .Net based), or handcoding a bunch of JavaScript exclusively for this purpose, would require substantial amounts of work ...

I am also not 100% certain of that I am not doing something wrong in my core JS, however, since it seems to work for all possible other scenarios, creating the correct DOM, and the thing is 100% "generic" for any types of insertions, I am thinking it has to be the browser that creates the mess ...

PS!
The JS parts is 3.1 KB, and this is a 100% "generic" thing, for all types of insertions of elements, and the JS doesn't care, or know for that matter, what types of elements it is supposed to insert. It can be anything really ...

The framework can be found at https://gaiasoul.com - If you wish to download it, and create your reproducable (Open Source)
 
Cwf9U6TWEAARwtT.jpg
161 KB View Download

Comment 1 by tkent@chromium.org, Nov 5 2016

Components: Blink>Forms>Select
Labels: Needs-Feedback Needs-Reduction
Would you make a minimum HTML to reproduce the issue please?
Without it, the priority of this issue would be very low.

Does it work with other browsers?
Does it work with earlier versions of Google Chrome?

OK, I made a small HTML page that is able to reproduce this. The expected behavior is to have "foo 3" being selected after clicking the button. If I inspect the select element, the "foo 3" option element actually IS selected, but when I look at the select element, the last option element is actually selected.

I suspect also if I retrieve the selected element, using e.g. "value" of the select element, the "foo 4" would be returned, even though the inspector clearly says that the "foo 3" is selected. However, that is really quite irrelevant, since graphically it looks like "foo 4" is the selected element.

Hope you can use this ...


sample.html
1.6 KB View Download
So I asked myself if it could be the document fragment, or the fact that I cleared my select element for options that created the mess. Hence, I replaced the JavaScript in my sample.html file with the following, without success;

        function foo_func() {

            // Getting select
            var sel = document.getElementById('foo');

            // Creating new options, first option is selected
            var tmpEl = document.createElement('select');
            tmpEl.innerHTML = '<option id="bar3" value="bar3" selected>bar 3</option>';

            sel.insertBefore(tmpEl.firstChild, sel.children[2]);

            // Second option
            tmpEl = document.createElement('select');
            tmpEl.innerHTML = '<option id="bar4" value="bar4">bar 4</option>';

            sel.insertBefore(tmpEl.firstChild, sel.children[3]);

            // Avoiding postback.
            return false;
        }


Still doesn't work ...

BTW, there might be something I've misunderstood, since it neither works in Brave (which is built upon Chromium I think), nor does it work in FireFox (which is completely unrelated to Chromium I think)

The weird parts though, is that "foo 3" actually IS selected in my DOM, both in FireFox and Chrome, but physically, in my dropdown, when I look at it, "foo 4" is selected ... ???
It seems as though when I add the element to my list, it somehow has a "hidden property" from my "tmpEl", which says it is "selected", which overrides the actual HTML value from me setting the "innerHTML" when creating it.

My guess, is this is actually being tracked on the "select" element (which makes sense actually, since there can be only one selected element) - Then when I invoke my "insertBefore", it uses this "hidden property" as its "selected" property, making it always set the LAST element I insert as the "selected" element. Which makes sense, since from the "select" my "option" is coming from, when I create it, it probably IS declared as "selected" ...

If my assumptions are correct, and hence impossible to fix, which I suspect, since it neither works in FireFox, I would love to have some advice on alternative ways to solve my problems, since it's quite annoying to be honest ...

Also, the function that does this, is 100% generic, and knows nothing about which element types, or how many other elements are added later, etc, etc - So it would be really difficult, if not impossible, to create special logic for select and option elements for me ...
For the record, the attached code here actually works, but is impossible for me to use, since i need to be able to inject my option elements at specific positions, in addition to that it is actually quite ugly I would argue ...

        function foo_func() {

            // Getting select
            var sel = document.getElementById('foo');

            // Creating new options, first option is selected
            sel.innerHTML += '<option id="bar3" value="bar3" selected="selected">bar 3</option>';
            sel.innerHTML += '<option id="bar4" value="bar4">bar 4</option>';

            // Avoiding postback.
            return false;
        }

For the record, I have found a walk around, which implies partial re-rendering of the entire "select" element, every time a change occurs, which is a drag, since I've spent half my professional life trying to *avoid* partial rendering.

This means that every time, anything changes in my "select" element, I need to transmit the *entire* HTML for the "select" element, back from the server, to the client. Which means, that if there's a lot of items in my "select", this increases my bandwidth consumption, by possibly orders of magnitudes (which sucks)

I know it sounds "unlikely" that this is a bug, since it's behaving the same way in FireFox, but it definitely feels like a bug ... :P

Comment 7 by tkent@chromium.org, Nov 7 2016

Labels: -Needs-Reduction -Needs-Feedback
Owner: tkent@chromium.org
Status: WontFix (was: Unconfirmed)
Thank you for the reproduction.
Yeah, this works as intended.

            // Second option
            fragment = document.createDocumentFragment();
            tmpEl = document.createElement('select');
            tmpEl.innerHTML = '<option id="bar4" value="bar4">bar 4</option>';
            fragment.appendChild(tmpEl.firstChild);
            sel.insertBefore(fragment, sel.children[1]);

"bar4" is selected by adding it to tmpEl SELECT element because there are no other selected OPTIONs, and adding selected "bar4" to "sel" deselects "bar3".

I see your point. Do you have any suggestion for how I can use the existing HTML passed from the server to accomplish what I want? That is, making sure bar3 is selected ...?

Comment 9 by tkent@chromium.org, Nov 7 2016

Adding 'multiple' attribute to tmpEl, or

tmpEl.options[i] = tmpEl.options[i].defaultSelected;
for all of tmpEl.options?



> tmpEl.options[i] = tmpEl.options[i].defaultSelected;

Correction:
tmpEl.options[i].selected = tmpEl.options[i].defaultSelected;

Hmm, doesn't work, since the function is 100% generically, and knows nothing about "select", "options" or anything - But you did set me on to an idea though ...

Thx for your time :)


.t

Sign in to add a comment