26

Possible Duplicate:
Dynamically adding collapsible elements

I've seen a few posts on this but none of them really seem to apply, or I could just be reading it wrong. I've got some HTML that's fed to me from a server that I can't really get changed. What I want to do is, grab that HTML, insert it into a div element & have jQuery mobile do it's styling thing on it. I potentially need to do that multiple times, and that's where the pain happens.

When I insert it the 1st time, it's all fine, jqm picks up the addition & styles it perfectly. If I try a 2nd time, jqm doesn't pick it up at all. I've tried making a 'template' that I copy and modify or just inserting static html & neither work.

I've got a test case below, as you'll see, click add new list once, and it's fine, click it again & you get an unstyled select. I've read somewhere that using the live event may work, but that doesn't work in this case either.

Also, I know about the select list selectmenu method in jQuery mobile, but the item I get back could be single/multiple select lists, a bunch of radio buttons or even a set of free text fields. As you can see, I've also tried running the page method on the topmost element, I've also tried running page on the element I'm about to add, all to no avail. :(

Test:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head>
    <title>List insert test</title> 
    <meta http-equiv="Pragma" content="no-cache" />
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
    <!-- include jQuery -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.2.js"></script>
    <!-- include jQuery Mobile Framework -->
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.js"></script>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.css" />
</head> 
<body>
    <div data-role="page" data-theme="b" id="Dashboard">

        <button id='addlist'>add new list</button>
        <button id='addips'>add templated list</button>
        <button id='clearall'>clear</button>
        <div id='theplace'></div>
        <div id='newtemp'>
            <select id='thelisttemplate'>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5</option>
            </select>
        </div>
        <div id="thelist">
            jkghjkgh
        </div>
    </div>
</body>

<script type="text/javascript">
    $('#addips').live('click', (function() {
        l = $('#thelisttemplate').clone()
        $('#thelist').html('')
        $('#thelist').append($(l))
        $('#thelist').page()

    }))

    $('#addlist').click(function() {
        l = $("<select id='thelisttemplate'><option value='1'>1</option><option value='2'>2</option><option value='3'>3</option><option value='4'>4</option><option value='5'>5</option></select>")
        $('#thelist').html('')
        $('#thelist').append($(l))
        $('#thelist').page()

        //$('#theplace').after($("<select id='thelisttemplate'><option value='1'>1</option><option value='2'>2</option><option value='3'>3</option><option value='4'>4</option><option value='5'>5</option></select>"))
        //$('#thelisttemplate').page()
    })

    $('#clearall').click(function() {
        $('#thelist').html('')
    })
</script>

</html>

Update: Using naugur's answer below, the add new list function would look like...

    $('#addlist').click(function() {
        l = $("<select id='thelisttemplate'><option value='1'>1</option><option value='2'>2</option><option value='3'>3</option><option value='4'>4</option><option value='5'>5</option></select>")
        $('#thelist').html('<div data-role="collapsible-set" id="newstuff"></div>');
        $("#newstuff").html(l).page();            
    })

Update #2: Apparently this is now deprecated, see below for some ideas on how to fix in beta2.

Community
  • 1
  • 1
dochead
  • 1,785
  • 2
  • 18
  • 20

2 Answers2

30

update

As of jquery mobile beta2 you trigger an event - .trigger('create')

FAQ updated: http://demos.jquerymobile.com/1.3.2/faq/injected-content-is-not-enhanced.html

This is deprecated:

use .page() function.

I suggest:

  1. empty the div you populate
  2. create a new div inside
  3. populate the new div
  4. call .page() on that new div
Keith Maurino
  • 3,374
  • 10
  • 40
  • 48
naugtur
  • 16,827
  • 5
  • 70
  • 113
  • 1
    Haha, awesome. I read your solution yesterday & couldn't get it working, but actually just managed to get it running exactly that way. Was just about to put that link in. Thanx. – dochead Apr 06 '11 at 07:36
  • Is there an api page like http://api.jquery.com/ for this? I was struggling to find even the .page method on their website. – Nicky Waites Apr 06 '11 at 07:52
  • .page is not documented there. I am planning to do a better documentation for this on my jquerymobiledictionary. At the moment the dictionaries are auto-generated, but they will be maintained if I find people to help. – naugtur Apr 06 '11 at 11:43
  • 1
    Updated the answer with beta2 coolness – naugtur Aug 11 '11 at 12:57
  • Awesome -- this tackled my first problem following upgrading to beta2 – Tramov Aug 15 '11 at 12:38
  • I'm using JQM 1.0, and neither of these are working: $(html).appendTo("#statlist").trigger("enhance"); $(html).appendTo("#statlist").trigger("create"); $(html).appendTo("#statlist").page("refresh"); I get no errors in the console, but the list remains unstyled. – snipe Dec 11 '11 at 02:31
  • As the FAQ states - you have to trigger create on the wrapping element. So it's more of a `$('#statlist').append(stuff).trigger('create')`. Or you might need to create a wrapping node, everything was already written. None of the other things you tried should work AFAIK – naugtur Dec 12 '11 at 09:19
4

I struggled with this one for hours and nothing was working. I have cascading select menus that were being populated via an ajax call when an option was selected in another menu. The DOM was being updated, but jQM refused to recognize the newly added options.

What finally worked (and it was based on a hunch - I did not find it documented anywhere) was:

$('#controlName').selectmenu('refresh');

I am using JQM 1.0 RC2.

csigrist
  • 424
  • 3
  • 10
  • every widget has its refresh method. It's bettert to use those when avaliable, but when inserting arbitraty html with different components - your only choice is to trigger 'create' – naugtur Dec 12 '11 at 09:20