1

This question has been asked many times on stack overflow and I have tried all solutions from all the questions. Here is a list of them:

One:

var list = '';
for....
   list += 'html...';
$('#mylist').append(list);
$('#mylist').listview('refresh'); // appending all at once with var

Two:

for....
   $('#mylist').append('html...');
$('#mylist').listview('refresh'); // refresh once after appends

Three:

for....
   $('#mylist').append('html...');
$('#mylist').listview().listview('refresh'); // to init listview

Four:

for....
   $('#mylist').append('html...').listview('refresh'); // refresh after each append - BAD

There are more variations that I tried as well. Without the .listview('refresh') - the style is stripped on append. When I use the refresh call, it works but I get javascript error saying:

`Uncaught Error: cannot call methods on listview prior to initialization; attempted to call method 'refresh'

Using .listview().listview('refresh') does not work.

SEE: https://stackoverflow.com/a/11943886/488407

PS: I am using the latest version of jQuery mobile (v1.3.1) so this solution might have worked with earlier versions. I need to use the latest version as I am using Panels.

Community
  • 1
  • 1
Jash Sayani
  • 1,241
  • 3
  • 12
  • 17

2 Answers2

1

Approach 2 (most recent)

If you're absolutely sure you want to use listview("refresh"), I suggest you use promise() to resolve whether your append is completed or not and then apply the refresh. Like this :

var li = ""; //append to a string
for (var i = 0; i < accounts.length; i++) {
    li += '<li data-oid="' + accounts[i]._oid + '"><a><h2>' + accounts[i].nickname + ' - ' + accounts[i].bankname + '</h2><p>Balance: ' + accounts[i].acccy + " " + accounts[i].acbal + '</p></a></li>';
}

//check if append is done by chaining promise() and done() 
$('#accountlist').append(li).promise().done(function () {
    $(this).listview("refresh"); // refresh here
});  

Demo here : http://jsfiddle.net/hungerpain/u9TcE/4/

More info here : Promise Docs

Approach 1

You need not to refresh listview. listview elements dont need much css manipulation to make them look like how they look. So they are styled on the fly (ie, when you're appending the li into a ul with data-role set to listview. Look at this array here :

var songs = [
             "Sweet Child 'O Mine", 
             "Summer of '69", 
             "Smoke in the Water", 
             "Enter Sandman", 
             "I thought I've seen everything"
            ];

Here's the HTML :

 <ul data-role="listview" id="songlist" data-theme="c" data-divider-theme="a" data-inset="true">
     <li data-role="list-divider" role="heading">Song List</li>
 </ul>

Here's how I'm going to inject this :

    $.each(songs, function (i, song) {
       $("<li/>", {
            "data-icon": "star",
            "class": "vote",
            "html": '<a href="#" id="song' + i + '">' + song + '</a>',
            "id": i
       }).appendTo("#songlist");
    });

THATS IT. You need not do anything more to get this work. The next thing which matters most is placement :

enter image description here

Place your script in body and you're done. The reason this works is because appending is synchronous in <body>. So you when this is used, you can be sure that the element is already loaded in DOM annd ready to be refreshed, which jQM automatically does.

Here's a demo

The options in jsFiddle - from jsFiddle docs

onLoad: wrap the code so it will run in onLoad window event, place it in <head> section

onDomReady: wrap the code so it will run in onDomReady window event, place it in <head> section

no wrap - in <head>: do not wrap the JavaScript code, place it in <head> section

no wrap - in <body>: do not wrap the JavaScript code, place it in <body> section

For your solution to work, copy the <script> tag in which you've written this/ the reference of the js file you've typed this in and paste it as the last element in <body>.

animuson
  • 53,861
  • 28
  • 137
  • 147
krishwader
  • 11,341
  • 1
  • 34
  • 51
  • That is in a function called popualte() - things look good when its called upon init. The function is called again called after adds and then the style is lost. – Jash Sayani Jun 16 '13 at 07:01
  • @JashSayani pls put this in a fiddle @ http://jsfiddle.net and give us the URL :) Sorry im not able to see this clearly.. – krishwader Jun 16 '13 at 07:02
  • @JashSayani: http://jsfiddle.net/hungerpain/u9TcE/1/ I changed the placement of the script from `onLoad` to `no wrap in ` . this option is below the place where u choose the version of jquery – krishwader Jun 16 '13 at 07:11
  • Hmm.. so it works without changing code. Can you update your answer explaining the difference between loading in "onLoad", "onDomReady", "No wrap - head", "No wrap - body". Would be good to understand this. Also, how do I fix this in my code? – Jash Sayani Jun 16 '13 at 07:15
  • @JashSayani i was using the timeout solution sometime back, but i found placing my scripts in `` more performant and it involves less intervention. – krishwader Jun 16 '13 at 07:31
  • Now I moved all script tags just before I close the body. Still same issue. – Jash Sayani Jun 16 '13 at 07:43
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/31817/discussion-between-passionatecoder-and-jash-sayani) – krishwader Jun 16 '13 at 07:44
  • There must be something wrong in the code. I suspect that jQM events he's using is causing this. If adds a delay to refresh I assume it'd work with no issues. Like this issue http://stackoverflow.com/questions/17003064/jquerymobile-uncaught-exception-when-removing-checkboxradio/17009087#17009087 – Omar Jun 16 '13 at 08:18
-1

Try $("#your_list").trigger("refresh");

for(...)
   $('#mylist').append('html...');

// call tirgger refresh after your append.
$("#your_list").trigger("refresh");
yeyene
  • 7,297
  • 1
  • 21
  • 29