bug: changing itemset of dropdown overwrites current value

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

bug: changing itemset of dropdown overwrites current value

Adrian Baker-2
If a dropdown has it's itemset updated while the form is used but *not*
it's value, the displayed value can become incorrect. Attached is an
example : change the top radio button from "Show Forms" to "List in
table", and you'll see the 'Comparison' dropdown below incorrectly
display 'Any'. The underlying value is still correct on the server (as
you can see to the right of the dropdown) - the dropdown's display value
is just initialised incorrectly when it's options are updated.

This is the javascript which is blowing away the current option, I think
because it's assuming that later the value of the select is also changed
which resets the selected values (but in the attachment, only the
options are changed, the actual value of the select remains unchanged):

} else if (documentElement.tagName == "SELECT") {

    // Case of list / combobox
    var options = documentElement.options;

    // Update select per content of itemset
    var itemCount = 0;
    for (var k = 0; k < itemsetElement.childNodes.length; k++) {
        var itemElement = itemsetElement.childNodes[k];
        if (itemElement.nodeType == ELEMENT_TYPE) {
            if (itemCount >= options.length) {
                // Add a new option
                var newOption = document.createElement("OPTION");
                documentElement.options.add(newOption);
                newOption.text = itemElement.getAttribute("label");
                newOption.value = itemElement.getAttribute("value");
            } else {
                // Replace current label/value if necessary
                var option = options[itemCount];
                if (option.text != itemElement.getAttribute("label"))
                    option.text = itemElement.getAttribute("label");
                if (option.value != itemElement.getAttribute("value"))
                    option.value = itemElement.getAttribute("value");
            }
            itemCount++;
        }
    }

One option is to extend this code so that it preserves any current
options. Another is to force the server to re-output the value of the
select1 to ensure the selected options are reset. I'm not sure which is
the preferred solution, but here's a quick n dirty extension to the
above script that does the former:

   
} else if (documentElement.tagName == "SELECT") {

    // Case of list / combobox
    var options = documentElement.options;
   
    // Remember selected values
    var selectedValueCount = 0;
    var selectedValues = new Array();
    for(var k = 0; k < options.length; k++) {
        if(options[k].selected) {
            selectedValues[selectedValueCount] = options[k].value;
            selectedValueCount++;
        }
    }
   
    // Update select per content of itemset
    var itemCount = 0;
    for (var k = 0; k < itemsetElement.childNodes.length; k++) {
        var itemElement = itemsetElement.childNodes[k];
        if (itemElement.nodeType == ELEMENT_TYPE) {
            if (itemCount >= options.length) {
                // Add a new option
                var newOption = document.createElement("OPTION");
                documentElement.options.add(newOption);
                newOption.text = itemElement.getAttribute("label");
                newOption.value = itemElement.getAttribute("value");
                newOption.selected = xformsArrayContains(selectedValues,
newOption.value);
            } else {
                // Replace current label/value if necessary
                var option = options[itemCount];
                if (option.text != itemElement.getAttribute("label")) {
                    option.text = itemElement.getAttribute("label");
                }
                if (option.value != itemElement.getAttribute("value")) {
                    option.value = itemElement.getAttribute("value");
                }
                option.selected = xformsArrayContains(selectedValues,
option.value);
            }
           
            itemCount++;
        }
    }

Adrian



--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws

badItemsetUpdate.xhtml (33K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: bug: changing itemset of dropdown overwrites current value

Alessandro  Vernet
Administrator
Adrian,

Thank you for the bug report and the fix. It is checked it.

Alex

On 4/9/06, Adrian Baker <[hidden email]> wrote:

> If a dropdown has it's itemset updated while the form is used but *not*
> it's value, the displayed value can become incorrect. Attached is an
> example : change the top radio button from "Show Forms" to "List in
> table", and you'll see the 'Comparison' dropdown below incorrectly
> display 'Any'. The underlying value is still correct on the server (as
> you can see to the right of the dropdown) - the dropdown's display value
> is just initialised incorrectly when it's options are updated.
>
> This is the javascript which is blowing away the current option, I think
> because it's assuming that later the value of the select is also changed
> which resets the selected values (but in the attachment, only the
> options are changed, the actual value of the select remains unchanged):
>
> } else if (documentElement.tagName == "SELECT") {
>
>     // Case of list / combobox
>     var options = documentElement.options;
>
>     // Update select per content of itemset
>     var itemCount = 0;
>     for (var k = 0; k < itemsetElement.childNodes.length; k++) {
>         var itemElement = itemsetElement.childNodes[k];
>         if (itemElement.nodeType == ELEMENT_TYPE) {
>             if (itemCount >= options.length) {
>                 // Add a new option
>                 var newOption = document.createElement("OPTION");
>                 documentElement.options.add(newOption);
>                 newOption.text = itemElement.getAttribute("label");
>                 newOption.value = itemElement.getAttribute("value");
>             } else {
>                 // Replace current label/value if necessary
>                 var option = options[itemCount];
>                 if (option.text != itemElement.getAttribute("label"))
>                     option.text = itemElement.getAttribute("label");
>                 if (option.value != itemElement.getAttribute("value"))
>                     option.value = itemElement.getAttribute("value");
>             }
>             itemCount++;
>         }
>     }
>
> One option is to extend this code so that it preserves any current
> options. Another is to force the server to re-output the value of the
> select1 to ensure the selected options are reset. I'm not sure which is
> the preferred solution, but here's a quick n dirty extension to the
> above script that does the former:
>
>
> } else if (documentElement.tagName == "SELECT") {
>
>     // Case of list / combobox
>     var options = documentElement.options;
>
>     // Remember selected values
>     var selectedValueCount = 0;
>     var selectedValues = new Array();
>     for(var k = 0; k < options.length; k++) {
>         if(options[k].selected) {
>             selectedValues[selectedValueCount] = options[k].value;
>             selectedValueCount++;
>         }
>     }
>
>     // Update select per content of itemset
>     var itemCount = 0;
>     for (var k = 0; k < itemsetElement.childNodes.length; k++) {
>         var itemElement = itemsetElement.childNodes[k];
>         if (itemElement.nodeType == ELEMENT_TYPE) {
>             if (itemCount >= options.length) {
>                 // Add a new option
>                 var newOption = document.createElement("OPTION");
>                 documentElement.options.add(newOption);
>                 newOption.text = itemElement.getAttribute("label");
>                 newOption.value = itemElement.getAttribute("value");
>                 newOption.selected = xformsArrayContains(selectedValues,
> newOption.value);
>             } else {
>                 // Replace current label/value if necessary
>                 var option = options[itemCount];
>                 if (option.text != itemElement.getAttribute("label")) {
>                     option.text = itemElement.getAttribute("label");
>                 }
>                 if (option.value != itemElement.getAttribute("value")) {
>                     option.value = itemElement.getAttribute("value");
>                 }
>                 option.selected = xformsArrayContains(selectedValues,
> option.value);
>             }
>
>             itemCount++;
>         }
>     }
>
> Adrian
>
>
>
>
> --
> You receive this message as a subscriber of the [hidden email] mailing list.
> To unsubscribe: mailto:[hidden email]
> For general help: mailto:[hidden email]?subject=help
> ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
>
>
>
>

--
Blog (XML, Web apps, Open Source):
http://www.orbeon.com/blog/



--
You receive this message as a subscriber of the [hidden email] mailing list.
To unsubscribe: mailto:[hidden email]
For general help: mailto:[hidden email]?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
--
Follow Orbeon on Twitter: @orbeon
Follow me on Twitter: @avernet