user3274489
user3274489

Reputation: 304

Is there a cleaner way to parse my HTML data?

I currently populate list boxes (amongst other things) by appending HTML. I get the PHP data from a JSON via an AJAX load, this allows me more flexibility on the page in terms of reloading things and cutting out unnecessary page loads.

function tracker_list(){
    //get a reference to the select element
    $list = $('#tracker_list');
    //remove entries
    $('#tracker_list').empty();
    //request the JSON data and parse into the select element
    $.ajax({
      url: 'data/JSON_dashboard.php',
      dataType:'JSON',
      success:function(data){ 
        //iterate over the data and append a select option
        $.each(data, function(key, val){
          $list.append('<li class="list-group-item"><div style="background: url(\''+val.profile_photo_path+'\');margin-right:10px;margin-left:7px" class="image-circle-30 pull-left"></div><span class="text-muted"><span class="glyphicon glyphicon-time timestamp pull-right" data-toggle="tooltip" data-placement="bottom" title="'+val.last_activity+'"></span></span><strong><a href="#">'+val.first_name+' '+val.last_name+'</a></strong> was on the <strong><a href="#">'+val.last_page+'</a></strong><br /><span class="text-muted small">'+val.since+'</span></li>'); 
          var total = val.total;
        $("#tracker_num").html("<strong>"+total+"</strong>");   // Replace total users number in head  
        })


      },
      error:function(){
      }
    });
    };

If I'm going to be continually doing this, is there a better way? As soon as I use a new line on all that HTML the script breaks and the code is going to start becoming quite unreadable.

Upvotes: 0

Views: 106

Answers (3)

Tomalak
Tomalak

Reputation: 338228

Is there a cleaner way to parse my HTML data?

Yes, that cleaner way is called HTML templating, for example with Handlebars.js. You start off with writing the HTML part you need into a special script tag, with placeholders for the individual values you want to display.

Total: <strong id="tracker_num"></strong>

<script type="text/x-handlebars-template" id="trackerlist-template">
  {{#each .}}
  <li class="list-group-item">
    <div class="profile-image" class="image-circle-30 pull-left" style="background-image: url('{{ profile_photo_path }}'); margin-right:10px; margin-left:7px;"></div>
    <span class="text-muted">
      <span class="glyphicon glyphicon-time timestamp pull-right" data-toggle="tooltip" data-placement="bottom" title="{{last_activity}}"></span>
    </span>
    <strong><a href="#">{{first_name}} {{last_name}}</a></strong> was on the
    <strong><a href="#">{{last_page}}</a></strong><br />
    <span class="text-muted small">{{since}}</span>
  </li>
  {{/each}}
</script>

Then you can use that template in your JavaScript code and don't have to bother with HTML creation, because code and presentation are cleanly separated.

var trackerlistTemplate = Handlebars.compile( $("#trackerlist-template").html() );

function getTrackerList() {
    return $.get('data/JSON_dashboard.php').fail(function () {
        console.err("could not retrieve tracker list");
    });
}

function renderTrackerList(data) {
    $('#tracker_list').html( trackerlistTemplate(data) );
    $("#tracker_num").text(data.length);
}

$("#refreshButton").click(function () {
    getTrackerList().done(renderTrackerList);
});

Notes

  • You don't need to use $.ajax() for such a simple GET request. $.get() is a lot shorter and will work just as fine.
  • It might be useful to separate the function that fetches the data from function that works with the data. This can be achieved easily with jQuery, since you can return the XHR object from the data-fetching function and work with it elsewhere, as shown above.

Upvotes: 1

Reeno
Reeno

Reputation: 5705

To add line breaks you can build the HTML in another var and add this to the HTML:

var html = '<li class="list-group-item"><div style="background';
html = html + 'url(\''+val.profile_photo_path+'\');margin-right';
html = html + '10px;margin-left:7px" class="image-circle-30 pull-left">';
// and so on...
$list.append(html)

Alternatively you can build the HTML with jQuery like this (only the first parts):

var html = $('<li />')
    .addClass('list-group-item')
    .append($('<div />')
        .css({
            background  : 'url('+val.profile_photo_path+')',
            marginRight : 10,
            marginLeft  : 7
        })
        .addClass('image-circle-30 pull-left')
    )
    .append($('<span />')
        .addClass('text-muted')
        .append($('<span />')
            .addClass('glyphicon glyphicon-time timestamp pull-right')
            .data({
                toggle  : 'tooltip',
                placement   : 'bottom'
            })
            .prop({
                title   : val.last_activity
            })
     );
  // and so on ...
  $list.append(html)

But I suggest you tu use a tempating engine like JSRender or Mustache.

Upvotes: 1

ebilgin
ebilgin

Reputation: 1252

For a cleaner and with more performance way.

HTML Manipulation for every element is expensive. Create an array, push into it, in the end join all items. And total count can be outside each iterate.

function tracker_list() {
    //get a reference to the select element
    $list = $('#tracker_list');
    //request the JSON data and parse into the select element
    $.ajax({
        url: 'data/JSON_dashboard.php',
        dataType: 'JSON',
        success: function(data) {
            //remove entries
            $list.empty();

            var strArr = [];
            //iterate over the data and append a select option
            $.each(data, function(key, val) {
                strArr.push('<li class="list-group-item"><div style="background: url(\'' + val.profile_photo_path + '\');margin-right:10px;margin-left:7px" class="image-circle-30 pull-left"></div><span class="text-muted"><span class="glyphicon glyphicon-time timestamp pull-right" data-toggle="tooltip" data-placement="bottom" title="' + val.last_activity + '"></span></span><strong><a href="#">' + val.first_name + ' ' + val.last_name + '</a></strong> was on the <strong><a href="#">' + val.last_page + '</a></strong><br /><span class="text-muted small">' + val.since + '</span></li>');
                .append();
            })

            $list.append(strArr.join(""));

            $("#tracker_num").html("<strong>" + data[data.length - 1].total + "</strong>"); // Replace total users number in head  

        },
        error: function() {}
    });
};

Upvotes: 2

Related Questions