5

I am creating a mobile app (Phonegap/Cordova 1.5.0, JQM 1.1.0) and testing on iOS 5.1. I have a list of items that the user "owns" or wants to own. Throughout the app, the user can edit their list by adding and removing items. Whenever items are added or removed, the list updates, and it is displaying fine, with all of the JQuery CSS intact except the corners are no longer rounded (I'm thinking because data-inset is getting set to "false").

Here is my html for the list-headers:

<div data-role="page" id="profile">
        <div data-role="header" data-position="fixed">
            <...>
        </div><!-- /header -->
        <div data-role="content" data-theme="a">
            <...>

            <ul id="user-wants-list" data-role="listview" data-inset="true" data-theme="d" data-dividertheme="d" >
            </ul> <!--/Wants list-->
            </br>

            <ul id="user-haves-list" data-role="listview" data-inset="true" data-theme="d" data-dividertheme="d" >
            </ul>  <!--/Has list-->
            </br></br>
        </div> <!--/content-->
</div> <!--/Profile-->

And here is the Javascript where I remove the old list and dynamically add the new one (the parameter 'haves' is an array of objects):

function displayHaves(haves){

var parent = document.getElementById('user-haves-list');
removeChildrenFromNode(parent);
parent.setAttribute('data-inset','true');
$(parent).listview("refresh");

var listdiv = document.createElement('li');
listdiv.setAttribute('id','user-haves-list-divider');
listdiv.setAttribute('data-role','list-divider');
listdiv.innerHTML = "I Have (" + haves.length + ")";
parent.appendChild(listdiv);

//create dynamic list
for(i=0;i<haves.length;i++){
    var sellListing = haves[i].listing;
    var userInfo = haves[i].user;
    var itemData = haves[i].item;

    //create each list item
    var listItem = document.createElement('li');
    listItem.setAttribute('id','user-haves-list-item-'+i);
    parent.appendChild(listItem);
    var link = document.createElement('a');
    link.setAttribute('id','user-haves-link-' + i);
    new FastButton(link, function(listing) {
                   return function() { displaySellListingPage(listing); }
                   }(sellListing));
    listItem.appendChild(link);

    var link = document.getElementById('user-haves-link-' + i);
    var pic = document.createElement('img');
    pic.setAttribute('src',itemData.pictureURL);
    pic.setAttribute('width','80px');
    pic.setAttribute('height','100px');
    pic.setAttribute('style','padding-left: 10px');
    link.appendChild(pic);
    var list = document.getElementById('user-haves-list');
    $(list).listview("refresh");
}

}

and my function removeChildrenFromNode(parent) is as follows:

function removeChildrenFromNode(node){
    while (node.hasChildNodes()){
         node.removeChild(node.firstChild);
    }
}

So my question is, why does the listview lose the data-inset attribute?

Or, equally valid: is there another way I could/should be achieving corner rounding besides "data-inset='true'"?

Here are things I have tried:

  • using .trigger("create") on both the listview and the page
  • adding the listview with explicit styling each time by using $("#page-ID").append(...)
  • I read another post on StackOverflow that said that JQM creates some inner elements when you create an item (this post had to do with dynamic buttons not being the right size), and that there are some classes (like .ui-btn) that you can access (that may be losing styling when I remove the children from the node?), but I was unable to make any headway in that direction.

Thanks in advance for the help!

Tyler Davis
  • 113
  • 1
  • 6

2 Answers2

2

I figured out the answer to my question, but not a solution (yet).

$(list).listview('refresh') was getting called on some elements before they had been put on the page, so it was essentially being called on nothing (or another way to think about it is that each list item being appended happens after the refresh call, so it overrides some of the visual styling).

I know the problem has to do with asynchronous loading in javascript. Essentially, the .listview('refresh) executes before the earlier code, which creates the elements but takes longer to execute. I understand the reasoning behind the design, but is there some way to get around this in this case?

I am thinking some conditional that I could set, like:

var doneLoading = false;
//Then when finished set doneLoading to 'true'
if(doneLoading) $(list).listview('refresh');

but if the refresh gets called first, I figure that doneLoading will just evaluate to false and then not execute once the list is actually done loading.

Is there any kind of onComplete callback I can use, or a way to make it happen synchronously?

Tyler Davis
  • 113
  • 1
  • 6
  • Currently I'm using: `window.setTimeout(function(){ $(listID).listview("refresh"); },300);`, which works for now, but clearly this is less than ideal – Tyler Davis Aug 14 '12 at 09:10
  • I struggle with the same issue; did you ever find a better workaround than the timeout? – occasl Apr 22 '14 at 23:20
1

Try calling listview(refresh) after updating the HTML.

Nirmal Patel
  • 5,128
  • 8
  • 41
  • 52
  • I already call it after every list item added in the for loop. I've also tried moving it around, including at the end of the function, and it's still not working. The weirdest thing is sometimes it shifts back to being rounded after I update the list more times. – Tyler Davis Aug 03 '12 at 22:44