Search code examples
jqueryselectjquery-mobilerefreshclone

Why a SELECT in a cloned DIV has a wrong behavior when refreshed?


I'm using the .clone() function of jQuery Mobile to clone a div in a form so I can have repeatable sections, but now I have a problem with nested selects.
Once the div is cloned and the nested selects are updated with the new id, something strange happens after the next 'refresh'.

What happens is very strange, the select just double and place itself inside the existing select, so the result is this:

Strange behavior with JQM and cloned selects

The browser is Safari, I've not made any test with other browser because I only need this code working on Safari.

What I do to clone the div is:

var div = $.mobile.activePage.find('.repeatable').last().clone();

to clone, then I update the IDs:

var newValue = pid +'-' + index;
$(this).attr('id', newValue);
$("label[for='"+ old +"']").attr('for', newValue);

and, at the end, I refresh all selects to have the right value selected once .val() is called:

if ($(this).data('role') === 'select') {
    $(this).selectmenu();
    $(this).selectmenu('refresh');
}

The problem happens when the last part of the code is called. Before the select shows correctly, but doesn't work properly, once the select is refreshed, it starts working in the right way, but the UI is messed because has been doubled and placed as child of the original element.

I add the div in the following way, before the clone button:

$('#clone_button').before(div);

What can be the origin of this problem?

Edit: It looks like this could be a bug of jQuery Mobile: example.


Solution

  • I finally found out a workaround to this problem. At the moment, clones of expandable items are not supported by jQuery mobile.

    The only way to do this, is to edit and fix manually the cloned div, deleting style items around selects and isolating them.

    What we've to do is pretty simple, but tricky:

    • Navigate all DIVs with class ui-select
    • Extrapolate the nested SELECT removing useless tags
    • Append the HTML code of the SELECT after or before the ui-select DIV
    • Remove the ui-select DIV
    • Append the repeatable DIV
    • Call trigger('create') in the parent to re-generate the correct style.

    It's messy, but it works.

    I've updated the example in JSFiddle. (edit: another good solution from arschmitz on JSFiddle)

    P.S. If you're using labels you've to save them somewhere and re-append them in the correct position.