After my last blog post, Consuming Services - How to get useful data into your app, a friend asked for advice on how to render the data that's returned to his app in a clean, simple way.

Immediately, two simple ways to accomplish this came to my mind. One using string concatenating and one using a hidden block of HTML as a template.

Let's take a closer look at the method of using string concatenation.  

First, the UI:

<div data-role="page" id="twitterDataConcatenate" data-add-back-btn="true">
    <div data-role="header">
        <h1>Twitter Search (concatenate)</h1>
    </div>
    <div data-role="content">
        <div id='searchTermInput'>
            <label for="txtSearchTerm">Enter text to search for:</label>
            <input type="text" id="txtSearchTerm" value="" />
        </div>
        <div id='searchTermText' style="display:block;"></div>
        <div align="center">
            <div data-role="controlgroup" style="display:inline-block;" data-type="horizontal">
                <button data-theme="a" onClick="twitterSearchConcatenate();">Search</button>
            </div>
        </div>
        <div align="center">
            <ul id="twitterResults"></ul>
        </div>
    </div>
</div>

This simple UI allows for the entry of a search term which will be searched for once the user clicks on the 'Search' button. The twitterSearchConcatenate function is called:

function twitterSearchConcatenate() {
    var searchTermElem = document.getElementById('txtSearchTerm');
 
    $.getJSON('http://search.twitter.com/search.json?q=' + searchTermElem.value,
              function(data) {
                  var items = data.results;
                  var list = $('#twitterResults');
 
                  list.html("");
                  $.each(items, function() {
                      var tweet = "<div style=\"float: left;padding-right: 10px;padding-top:10px;\"><img style=\"position: relative\" src=\"" + this.profile_image_url + "\" /></div><div align=\"left\" style=\"padding-bottom: 5px;\" ><label style=\"font-weight: bold;\">" + this.from_user_name + "</label> <label style=\"color: #999;\">@" + this.from_user + "</label><br /><label>" + this.text + "</label></div>";
 
                      list.append($(document.createElement('li')).html(tweet));
                  });
              });
}

In this function a call is made to the Twitter search service and will concatenate together a simple display of each tweet that has been returned. Once we have the complete block of HTML we want we then create a list item object (li tag) and add the block of concatenated text in as the HTML content of this new item object and append it in to our existing unordered list. Yes, the location where the concatenation takes place could have been formatted differently to make it look better but I think anyone who looks at this will see, no matter how the code is formatted it, will always be difficult to support and maintain. A function that implements printf or String.Format() like functionality or better yet use the sprintf library could have made this look better as well. In the end, the HTML would be in you script and that just seams wrong no matter how good you make the code look.

Let’s look at a different way to go about this. First, we will add a div tag that we want and use its content as a template.

<div id="tweetTemplate" style="display: none">
    <li class="listItem-Template"><div class="profileImageURL" style="float: left;"><img class="profileImage" src="" /></div>
        <div class="tweet"><label class="fromUserName"></label> <label class="fromUser"></label></ br>
            <label class="text"></label>
        </div>
    </li>
</div>

As you can see, nothing special here. The style is set to “display: none” so this html will not show up in our UI. With this template we can use some simple jQuery functions to find and clone this over and over for each item we get in our data.

Note: I am not including the UI HTML here as it’s extremely similar to what is above but you can see it in the complete project on GitHub.

function twitterSearchTemplate() {
    var searchTermElem = document.getElementById('txtSearchTermTemplate');
     
    $.getJSON('http://search.twitter.com/search.json?q=' + searchTermElem.value,
        function(data) {
                         
            var items = data.results;
            var list = $('#twitterResultsTemplate');
             
            list.html("");
             
            $.each(items, function() {
                         
                // create a list item template
                var $listItem = $("#tweetTemplate").find(".listItem-Template").clone();
                 
                // Set all the values in the template
                $listItem.find(".profileImage").attr("src", this.profile_image_url);
                $listItem.find(".fromUserName").html(this.from_user_name);
                $listItem.find(".fromUser").html("@" + this.from_user);
                $listItem.find(".text").html(this.text);
 
                // Add the new list itlem to the list
                list.append($listItem);
           });
        });
     
}

The code is quite similar but this time the jQuery.clone and jQuery.find functions are used to accomplish what is needed. For each item in the returned search result the template HTML in the hidden div tag is cloned. In each clone we simply alter the appropriate property of the tag we want to display the data. The benefits are easy to see. With the HTML in the HTML editor it’s quite easy to modify the layout of the UI and the script is quite easy to read as well.

I hope this gives you some options regarding how you can simplify your rendered code.

The full project is available at https://github.com/woodyp/teplateResults-Demo


Related Posts

Comments

Comments are disabled in preview mode.