When working with jQuery Mobile you have several ways of enhancing dynamically created content markup. Unfortunately, it’s not enough to dynamically add new content to jQuery Mobile page, it must be enhanced with classic jQuery Mobile styling.
 
Because this task is difficult from the processing point of view, some priorities are required. If possible, jQuery Mobile needs to do as fewer enhancements as possible. Don’t enhance whole page if only one component needs to be enhanced.
 
 

Note: If this tutorial was helpful, need further clarification, something is not working or do you have a request for another Ionic post? Furthermore, if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here, again leave me a comment below. I'm here to help you, I expect the same from you. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com, or follow and mention me on twitter (@gajotres). Thanks and have a nice day!


 
What does this all means? When page plugin dispatches a pageInit event, which most widgets use to auto-initialize themselves, it will automatically enhance any instances of the widgets it finds on that page.
 
However, you can manually trigger content auto-initialization if your have preexisting or generated content on a client side or if that content is loaded using Ajax. This feature can be triggered on any element (even the page container itself), saving you the task of manually initializing each plugin (listview button, select, etc.).
 
With this in mind lets discuss enhancement levels. There are three of them, sorted from the less resource demanding to higher ones:
 
  • Enhance a single component/widget
  • Enhance a page content
  • Enhance a full page content (header, content, footer)

 

Enhance a single component/widget:

 
Every jQuery Mobile widget can be enhanced dynamically:
 

1. Listview:

 
Markup enhancement:
 
$('#mylist').listview('refresh');
 
Removing listview elements:
 
$('#mylist li').eq(0).addClass('ui-screen-hidden'); 
 
Enhancement example:
 
jsFiddle Example
 
 
Method refresh() only affects new nodes appended to the list, mainly to prevent performance problems.
 
One of a listview high-points is a filtering functionality. Unfortunately, for a reasons unknown, jQuery Mobile can’t dynamically add a filter option to existing listview element. Fortunately, there’s a workaround. If possible, remove current listview and add another one with a filter option turned on.
 
Here’s a working example:
 
Working Example
 
$(document).on('pagebeforeshow', '#index', function(){       
    $('<ul>').attr({'id':'test-listview','data-role':'listview', 'data-filter':'true','data-filter-placeholder':'Search...'}).appendTo('#index [data-role="content"]');
    $('<li>').append('<a href="#">Audi</a>').appendTo('#test-listview');
    $('<li>').append('<a href="#">Mercedes</a>').appendTo('#test-listview');
    $('<li>').append('<a href="#">Opel</a>').appendTo('#test-listview');
    $('#test-listview').listview().listview('refresh');
});
 

2. Button

 
Markup enhancement:
 
$('[type="button"]').button();
 
jsFiddle Example
 
One more thing, you don’t need to use a input element to create a button, it can be even done with a basic div, here’s an example:
 
jsFiddle Example
 

3. Navbar

 
Markup enhancement:
 
$('[data-role="navbar"]').navbar();
 
jsFiddle Example
 
Here’s a demo how to add dynamic navbar tab:
 
jsFiddle Example
 
And one more in pagebeforecreate event:
 
jsFiddle Example
 

4. Text inputs, Search inputs & Textareas

 
Markup enhancement:
 
$('[type="text"]').textinput();   
 
jsFiddle Example
 

5. Sliders & Flip toggle switch

 
Markup enhancement:
 
$('[type="range"]').slider();  
 
jsFiddle Example 1 jsFiddle Example 2
 
Sliders are little bit buggy to dynamically create, read more about it here: http://stackoverflow.com/a/15708562/1848600
 

6. Checkbox & Radiobox

 
Markup enhancement:
 
$('[type="radio"]').checkboxradio();
 
or if you want to select/deselect another Radiobox/Checkbox element:
 
$("input[type='radio']").eq(0).attr("checked",false).checkboxradio("refresh");
 
or
 
$("input[type='radio']").eq(0).attr("checked",true).checkboxradio("refresh");
 
jsFiddle Example
 

7. Select menu

 
Markup enhancement:
 
$('select').selectmenu();  
 
jsFiddle Example
 

8. Collapsible

 
Unfortunately collapsible element can’t be enhanced through some specific method, so trigger(‘create’) must be used instead.
 
jsFiddle Example
 

9. Table

 
Markup enhancement:
 
$(".selector").table("refresh");
 
While this is a standard way of table enhancement, at this point I can’t make it work. So instead use trigger(‘create’).
 
jsFiddle Example
 

10. Panels

 
Panel Markup enhancement:
 
$('.selector').trigger('pagecreate');
 
Markup enhancement of content dynamically added to Panel:
 
$('.selector').trigger('pagecreate');
 
jsFiddle Example
 

Enhance a page content

 
If we’re generating/rebuilding entire page content it is best to do it all at once, like this:
 
$('#index').trigger('create');
 
jsFiddle Example
 

Enhance a full page content (header, content, footer)

 
Unfortunately for us trigger(‘create’) can not enhance header and footer markup. In that case, we need big guns:
 
$('#index').trigger('pagecreate');
 
jsFiddle Example
 
Continue Reading

  • Omar

    Great job Dragan!! You’re talented, keep it up!

  • Anonmous Change

    Great information Gajotres

  • Tomislav

    Very good job Dragan. Keep it up.

  • http://www.web4uonline.com Michael

    If I am adding Jquery from JSON/AJAX where do add these enhancements? Do I put them in the html file that is being brought in via json? Or, do I put the enhancements in the original html file?

    Thanks so much.

  • Pingback: jQuery Mobile and how to enhance dynamically added content | Gajotres.net | Hùng Trang @ Thailand()

  • Leo

    Hi, thanks for your post.

    Do you know if this is working with edge versions: jQuery 2.03 and jQuery Mobile 1.3.2?

    As far as I can tell it is not working: http://jsfiddle.net/ljcorreia/m4rjZ/51/

    Ok, it may be something I set incorrectly on jsFiddle, because in my project on Visual Studio it does add the buttons. However it does not add the elements to the DOM on IE9 and most importantly on iPad.

    Can you shed some light on this, please?

    Thanks

  • Leo

    Ok, I realize the issue with my jsFiddler: http://jsfiddle.net/ljcorreia/m4rjZ/53/

    Unfortunately I still could not get to the bottom of what is the issue on my project.

    Cheers.

  • Markus

    Is it somehow possible to enhance the markup off-dom (e.g. with DocumentFragments)?

    We are using Mustache.js & jQueryMobile in combination and the rendering gets slow because we have a lot of steps todo
    – load a mustache-tpl via ajax
    – let Muchstache parse the template and interpolate some values
    – take the given string and put it into the DOM
    – enhance the resulting page

    we would like to enhance the rendered Mustache with jQueryMobile off the DOM though the browser doesn’t have to do this expensive reflows+repaints 2 times (1st while html “plain” html is inserted into the sites’ DOM; 2nd after/while jQueryMobile enhance)..

  • oglegendre

    Hi !
    Thanks for this really useful blog post !
    Unfortunately, the jsfiddle example does not work with jquery 1.4 (it works fine with 1.2). It seems that the pagecreate trigger does not work anymore. I was hoping to use this feature to load each page div from a local file containing only the HTML. All this to avoid putting ALL the pages definition in the same html file (which may be fine on a small project…but not quite maintainable on a real project).
    Speaking of which, it is such a pity there is no way to do that directly (see http://stackoverflow.com/questions/6875404/why-does-html5-not-include-a-way-of-loading-local-html-into-the-document)

    • http://www.gajotres.net Dragan Gaić

      I will check it.

  • simon

    Your notes about radio button enhancment were very useful to me…thanks.
    I think they need updating because I have discovered that as of jQuery 1.9 the ‘.attr(“checked”,false)’ method no longer works and must the substituted with ‘.prop(“checked”,false)’

  • Kiran

    Very nice tutorial.

    I would like to know, how can i pass data from the one to another in jquery mobile.

    What i am trying to achieve is , i need to pass an ID from list item to detailed view page, please guide me how to do this.

    Thanks

    • http://www.gajotres.net Dragan Gaić

      It can be done easily. You will need to prevent list from changing pages on its own, have list element href attribute empty.

      And onClick event to list elements. Each time list is clicked store clicked list element to localstorage and manually change the page. Before detailed page is shown, read id form localstorage abd build page content.

  • Aravinth

    Nice tutorial but i cant find find what i need..look at this one …http://jsfiddle.net/aravinth/Ad22d/90/…… in this fiddle cloned the rows using add row then add expenses shows the popup it is also cloned.. now i click the first row add expense button, 3 rows cloned in popup when click second row add expenses it shows three rows but need to show only one column …Suggest some solutions. Thank you..

  • http://www.flame.nl Robert Broen

    Thank you, this was very helpful.

  • Chaiwut

    Good job!!!

    This is the solution for my work. Many thanks.

  • Max

    Hi
    Thanks for useful post.
    I have a question, can i produce gradient effect for listing screen in jquery mobile.
    if yes, can you please guide me how to achieve ?

  • Tobias Beuving

    Hey Dragan,

    thanks a million for your explanations and tricks. I bumped into all kinds of weird stuff working with jquery mobile and got a ‘adobe flex framework – this shit doesnt work where are the hacks, they dont work either’-dejavu! :)
    Luckily I found your blogpost and could solve my problem with the rendering of a listView.

    Hopefully the guys at JQM will keep it simple and don’t end up building a flex-like monster – fungers crossed, for now – oef! :)
    big up!

  • http://fredyfx.com fredyfx

    Hi! Thank you very much for sharing the knowledge. I have one question, Could you please help me? I have this scenario:
    On each row of a table I have a button and the code for opening dialogs popups. The idea is that if I click on that button a dialog popup will be showed.
    The problem:
    Everything inside my div is rendered inside the table. I am using razor (ASP.net MVC View Engine) that is why my id has an @.
    A partial solution I did was making a new TR and hide that DIV, and the button on each row opens and close that TR.
    Thank you for reading this comment. Have a great day!

    • http://www.gajotres.net Dragan Gaić

      I advise you to ask this question at StackOverflow.

  • http://www.ptqs.it Nicola

    You saved my day! 😀 thanks!

  • Ali Murtaza (AB)

    for popup you can use “$(‘[data-role=”popup”]’).popup();”