12

Source: http://jquerymobile.com/demos/1.0a2/#docs/content/content-collapsible.html When I add an element like this manually to my code, it is displayed properly. But when I try to add it with jQuery like this:

$('body').append('<div data-role="collapsible"><h3>Title</h3><p>Content</p></div>');

It just displays title in h3 and the content below it, so not as a collapsible element. How can I fix this?

Bill
  • 121
  • 1
  • 1
  • 3

11 Answers11

20

The easiest way to achieve this is to call the collapsible() method on the dynamically created divs:

$('div[data-role=collapsible]').collapsible();

source : http://forum.jquery.com/topic/dynamically-add-collapsible-div

ozeebee
  • 1,878
  • 2
  • 23
  • 26
  • This does not work for me. But calling $('#your_new_collapsible_div').trigger('create') after adding the element to the DOM (as proposed by Amit and Basav) works fine. – zitroneneis Jun 24 '13 at 18:17
5

this is what i do. Hope it helps

HTML

<div id="collapsibleSet" data-role="collapsible-set">
   <div id="ranking1"></div>
</div>

Javascript

$('#ranking1').replaceWith('<div id="ranking1" data-role="collapsible" data-collapsed="false">' + htmlRankings(ranking) + '</div>');
$('#collapsibleSet').find('div[data-role=collapsible]').collapsible({refresh:true});

htmlRankings() is a js function that returns some html that i want inside the collapsible div. it can be something like this

<h3>11</h3>
<span>test</span>
Pablo Johnson
  • 1,044
  • 15
  • 21
  • 1
    You sir are my superhero right now! Ive been stuck on this for 2 days, comparing rendered html against what it should look like and its been identical but still not working. The explicit call to .collapsible() fixed my issue. THANK YOU SO MUCH – victor May 18 '20 at 17:40
4

I think

after setting the innerhtml, simply tiggerring a event on it should render the dynamic contnet like below

$('#<divId or elementId').trigger("create");
Basav
  • 3,176
  • 1
  • 22
  • 20
2

This code is for perl, you can modify it for any programming language.

 <a href="javascript:collapsible('$div_instance','$imageID')">
         <IMG id='$imageID' SRC='$imagePath' alt='(Expand / Collaspe Section' title='Expand / Collaspe' width=10 height=10>
          $display_header <br/></a>
          <div id=$div_instance name=$div_instance 
           style="overflow:hidden;display:$display_option;margin-left:30px; margin-top:20px;">
                                       <-- your content -->
            </div>
<script language="JavaScript" type="text/javascript">
    <!--
     function collapsible(theID,imageID) {
          var elemnt = document.getElementById(theID);
          var imageObject =document.getElementById(imageID);
          if(elemnt.style.display == 'block') {
               elemnt.style.display ='none';
               imageObject.src='images/expand_icon.gif';
           }
           else{
           elemnt.style.display ='block';
           imageObject.src='images/expand_icon_down.gif';
           }

    }
    // -->
    </script>

REF: http://www.ssiddique.info/simple-javascript-to-create-dynamic-collapsible-section.html

SS Sid
  • 421
  • 6
  • 12
1

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

Amit
  • 196
  • 4
  • 16
1

you can refresh the collapsible using the following code

$('#element').collapsibleset('refresh');

Hope it helps

Sagar Gala
  • 944
  • 10
  • 10
0

This way you can add small collapsibles in a bigger one dynamically. HTML:

<div data-role="collapsible" data-mini="false" data-theme="b"  >
    <h3>main header text</h3>
    <div id="aCollaps"></div>
</div>

Javascript

//Your could do for(){
    $("#aCollaps").append('<div data-role="collapsible" data-inset="false" data-content-theme="b">' + 
    '<h3>'+HeaderText+'</h3>'+ContentText+'<br/></div>');
//}
//You might want to be more specific here if you have more collapsibles in the page. this just updates all collapsibles
$('div[data-role=collapsible]').collapsible({refresh:true});
Hersker
  • 547
  • 5
  • 11
0

Here's an example of what I did to dynamically change my collapsible. I had a few arrays that I needed to display as headers, and then I needed a grid in each collapsible set with 2 sides, one for question and one for answer.

   var inputList = '';
    var count = 0;
    var divnum = 999;
    var collit = 'false';
    inputList += '<div data-role="content">';
    inputList += '<div id="fb_showings_collapse" data-role="collapsible-set" data-theme="b">';
    $.each(fbFullStrArray, function(index, item) { 
    //set questions and answers for each appt
    getsetApptFback(fbStrApptArray[index]);
    //write the html to append when done
    inputList += '<div data-role="collapsible" data-collapsed="'+collit+'">';
    inputList += '<h3>'+fbFullStrArray[index]+'</h3>';
    inputList += '<div id="g'+divnum+'" class="ui-grid-a">';
    inputList += '<div id="gb'+divnum+'" class="ui-block-a">';
    inputList += '<div id="fbq'+index+'"><ol>';
    $.each(fbQidArray, function(ind,it) {
        inputList += '<li>'+fbQuestionArray[ind]+'<b></b></li>';
    });
    inputList += '</ol></div></div>'
    inputList += '<div id="ga'+divnum+'" class="ui-block-b">';
    inputList += '<div id="fba'+index+'"><ul>';
    $.each(fbQidArray, function(ind,it){
            inputList += '<li>'+fbAnswerArray[ind]+'<b></b></li>';
    });
    inputList += '</ul></div></div></div></div>';
    collit = "true";
    divnum++;
    count++;
    });
    inputList += '</div></div>';

    $('#fb_showings_collapse [role=collapsible-set]').text('');
    $('#fb_showings_collapse [role=collapsible]').text('');
    if (count > 0) {
    $('#fb_showings_collapse [role=collapsible]').remove();
    $('#fb_showings_collapse').append(inputList).collapsibleset('refresh');
    }
    else if (count == 0){
    inputList = 'Sorry! No Showings To Show Feedback For!';
    $('#fb_showings_collapse [role=collapsible-set').remove();
    $('#fb_showings_collapse [role=collapsible]').text(inputList);
    }
0

See the enhanceWithin() function: jQuery Mobile docs: enhanceWithin

Call enhanceWithin on a jQuery object representing your DOM element's parent to have any jQuery Mobile features added to your HTML.

In this case:

jQuery('[data-role="collapsible"]').parent().enhanceWithin();

Note that if you are adding multiple jQuery Mobile widgets you may only want to call enhanceWithin on an ancestor such as "BODY" after adding all your dynamic HTML.

This would be a pretty good solution for this question as well: Refresh a section after adding HTML dynamically to jquery mobile

Community
  • 1
  • 1
Matthew
  • 8,183
  • 10
  • 37
  • 65
0

You have to append them to the right place (e.g. under a data-role="page" element) then call .page() to initialize the content you appended, like this:

$('<div data-role="collapsible"><h3>Title</h3><p>Content</p></div>')
  .appendTo('#someElement').page();

You can test it out here.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • very nice code - thank you.... followup question, how would you turn the two items into a single seamless item? – pithhelmet Oct 10 '12 at 20:17
  • @pithhelmet - not sure I understand what you're asking to do, can you clarify a bit? – Nick Craver Oct 10 '12 at 21:34
  • sure - your example shows two distinct items, i'm a header and title... they are separated by a space... is there a way to smash those two items into a seamless box... like this http://jquerymobile.com/demos/1.0rc3/docs/content/content-collapsible.html#/demos/1.0rc3/docs/content/content-collapsible-set.html – pithhelmet Oct 10 '12 at 21:50
  • @pithhelmet - just needed a newer version of jquery UI than the fiddle above was using, is this what you're after? http://jsfiddle.net/TYscV/566/ (ignore the missing icons...seems to be an issue with jsfiddle including the CDN CSS) – Nick Craver Oct 10 '12 at 22:13
0

Better than collapsible is updatelayout, it is in the docs. In short...

This event is triggered by components within the framework that dynamically show/hide content, and is meant as a generic mechanism to notify other components that they may need to update their size or position. Within the framework, this event is fired on the component element whose content was shown/hidden, and bubbles all the way up to the document element.

$('div[data-role=collapsible]')
    .trigger( 'updatelayout' );
    //.collapsible();
TMB
  • 4,683
  • 4
  • 25
  • 44