Refresh jQuery Mobile listview after adding dynamic items in BlackBerry

I had a list that needs to be updated with new items from an AJAX response. List items contain some radio buttons and controlgroups that needs to be rendered as jQuery Mobile components. So I had to use .trigger("create") on the listview just before I refresh the listview. Let me show you the HTML bit.
<div data-role="collapsible" id="approve_tr_itinerary_details_wrapper">
<h3>
Itinerary Details</h3>
<ul data-role="listview" id="approve_tr_itinerary_details">
<li>No itinerary details</li>
</ul>
</div>
<div data-role="collapsible" id="approve_tr_travel_options_wrapper">
<h3>
Travel Options</h3>
<ul data-role="listview" id="approve_tr_travel_options">
<li>No travel options</li>
</ul>
</div>
And how I did the new item creation and appending them to the list.
$.each(items, function(index, item) {
 $("#approve_tr_travel_options").append(
 '<li data-role="list-divider">' + (index+1) + '</li>' +
 '<li>' +
 '<span class="tra-info-label tra-width-40">Name:</span>' +
 '<span class="tra-info-text">' + item.name + '</span>' +
 '</li>' +
 '<li>' +
 '<span class="tra-info-label tra-width-40">Cost:</span>' +
 '<span class="tra-info-text">' + item.cost + '</span>' +
 '</li>' +
 '<li>' +
 '<span class="tra-info-label tra-width-40">Valid though (Date / Time):</span>' +
 '<span class="tra-info-text">' + item.exp_date + '</span>' +
 '</li>' +
 '<li>' +
 '<fieldset data-role="controlgroup">' +
 '<input id="approve_tr_travel_option_' + (index+1) + '_1" name="approve_tr_travel_option_' + (index+1) + '" type="radio" value="1" />' +
 '<label for="approve_tr_travel_option_' + (index+1) + '_1">Preferred</label>' +
 '<input id="approve_tr_travel_option_' + (index+1) + '_2" name="approve_tr_travel_option_' + (index+1) + '" type="radio" value="2" />' +
 '<label for="approve_tr_travel_option_' + (index+1) + '_2">Alternate</label>' +
 '</fieldset>' +
 '</li>'
 );
});
Note the controlgroup and input elements. These need to be converted to jQuery Mobile components. So I used .trigger("create") which did a great job on the BlackBerry (also in the Ripple emulator) but not in the Chrome. Let me show the code I used just after adding new elements to the list.
$("#approve_tr_travel_options").trigger("create");
Chrome needs the listviews to be refreshed to render the newly added items as list items. What works for Chrome is,
$("#approve_tr_travel_options").trigger("create").listview("refresh");
However this method doesn't work on BlackBerry. Which was driving me crazy for two days. After messing with the code for few hours I found a solution for this issue, which can be used to render the listviews in both Chrome and BlcakBerry. Instead of refreshing the listview just below where you add new items do that in the pagebeforeshow event handler. Just see the code below.
$("#approve").live("pagebeforeshow", function(event, data) {
$(this).find('ul').listview('refresh');
});
The listview will be refreshed just before the page is shown to the user. So what you do when you want to load set of items to a listview in the next page in a page transition is, load the set of list items first with AJAX and append them to the listview and trigger the create event (.trigger("create")) on the list and call the refresh just before you show the page to the user. Hope this helps someone to save some time without going crazy on the same issue, just like me!!

Saranga
Saranga A web developer and highly passionate about research and development of web technologies around PHP, HTML, JavaScript and CSS.
comments powered by Disqus