Search code examples
jqueryjquery-mobilejquery-mobile-fieldsetjquery-mobile-select

Can't physically select checkbox the first time through


When I test the page and click the checkbox nothing happens. If I go to another page and come back, the checkbox works.

HTML

<fieldset data-role="controlgroup" data-type="vertical" data-mini="true">
       <input id="checkbox8" name="addTo" data-theme="b" type="checkbox">
       <label for="checkbox8"> add to</label>
</fieldset>

JQuery

$("input[type = 'checkbox']").change(function(){
        var item=$(this);
        if(item.is(":checked")){    
            $('#myMenu').append( $('<li>').attr('class','ui-li ui-li-static ui-btn-up-c ui-li-last').append('test'));
            $('#myMenu').listview('refresh');
        }
        else {
                $( "#myMenu li:last-child" ).remove().closest( "[data-role=listview]" ).listview( "refresh" );  
        }
});

Why is that? I don't want the checkbox to be set initially. The idea is to check the box, the selected object dynamically updates and appears on the listview of another page.


Solution

  • You need to be sure your page is loaded into the DOM before doing this in the first place. Don't use document ready because it can trigger before jQM page is loaded into the DOM. Instead you should use proper jQuery Mobile page event.

    $(document).on('pageinit', '#index', function(){ 
        $(document).on('change','input[type="checkbox"]',function(){
            var item=$(this);
            if(item.is(":checked")){    
                $('#myMenu').append( $('<li>').attr('class','ui-li ui-li-static ui-btn-up-c ui-li-last').append('test'));
                $('#myMenu').listview('refresh');
            }
            else {
                $( "#myMenu li:last-child" ).remove().closest( "[data-role=listview]" ).listview( "refresh" );  
            }
        });      
    });
    

    Where #index is an id of your page. Pageinit event is a jQuery Mobile alternative to classic jQuery document ready state.

    Or like in my example you can bind a change event a little bit different:

    $(document).on('change','input[type="checkbox"]',function(){
    

    This solution is called delegated binding and it don't care if element is loaded into the DOM or not.

    And here's a working example

    EDIT

    Working HTML example:

    <!DOCTYPE html>
    <html>
        <head>
            <title>jQM Complex Demo</title>
            <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
            <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
            <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
            <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
            <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>    
            <script>
                $(document).on('pageinit', '#index', function(){ 
                    $(document).on('change','#checkbox8',function(){
                        var item=$(this);
                        if(item.is(":checked")){    
                            alert('Checked');
                        } else {
                            alert('Unchecked');
                        }
                    });      
                });     
            </script>
        </head>
        <body>
            <div data-role="page" id="index">
                <div data-theme="b" data-role="header">
                    <h1>Index page</h1>
                </div>
    
                <div data-role="content">
                    <fieldset data-role="controlgroup" data-type="vertical" data-mini="true">
                        <input id="checkbox8" name="addTo" data-theme="b" type="checkbox"/>
                        <label for="checkbox8"> add to</label>
                    </fieldset>
                </div>
            </div>    
        </body>
    </html>