Search code examples
jquerydomjquery-mobileselect-menu

jQuery mobile: Why does Select Menu break when I append it to another DOM node on a different page?


I have a jquery mobile site with three pages (<div data-role = 'page'>).

On page 1's header I have a Select Menu being used for a Choose Language component:

<div data-role = 'header'> ... <label></><select><options></></> ... </>.

I do not want multiple instances of the language chooser component throughout the site.

So, following a suggestion from SO I am moving the header-node from page to page upon each page's pageshow event.

When I go to page 2 the Select Menu dis-functions; but when I navigate back to page 1 it works again.


Solution

  • Using "pagebeforeshow" not "pagecreate" event, because pagecreate will be called just one time at creation of that page.

    so, if you want to get a event every time to change a page, you should use 'pagebeforeshow', 'pagebeforehide.'pageshow' or 'pagehide'.

    and i recommend pagebeforeshow for changing UI before page showing. :)


    Did you use .remove() API for moving 'select' from previous to new page? .remove() removes a element from parent and its data & event also. so, you should re-define event handler after removing.

    Additionally, .detach() for just detach element from its parent. but it has some issues about jquery mobile's enhancing.

    i post a jsfiddle about above. jsfiddle.net/cwdoh/ZaVch

    EDIT BY SHANNON ... in case the fiddle gets removed in the future, here is your code:

        <div data-role="page" id="page1">
            <div data-role="header">
                <h1>Page 1</h1>
                <select id="language-select">
                    <option>Korean</option>
                    <option>English</option>
                    <option>JavaScript :)</option>
                </select>
            </div>
    
            <div data-role="content">
                <a data-role="button" href="#page2">go to Page2</a>
            </div>
        </div>
    
        <div data-role="page" id="page2">
            <div data-role="header">
                <h1>Page 2</h1>
            </div>
    
            <div data-role="content">
                <a data-role="button" href="#page1">go to Page1</a>
            </div>
        </div>
    
    $(document).on( "pagebeforeshow", function( e, data ) {
        // move language-select from previous page
        var selectMenu = data.prevPage.find( "#language-select" );
    
        selectMenu
            .remove()     // remove from previous page
            .appendTo( $(e.target)   // append to active page
                .find( "[data-role='header']" ) );
    
        // bind event handler after append
        $("#language-select").bind( "change", function() {
            alert( "language-select changed" );
        });
    
        // re-build 
        selectMenu.selectmenu();
    });