views:

388

answers:

7

I have a lot of messages, and raw HTML that I hard code in my javascript code, such as:

 var subjectId = $(subject).attr('subjectId'); 
 var subjectName = $(subject).attr('subjectName'); 
 var html = "<table id='invitations' class='invitations' width='100%'><tbody>";
 $(subject).find('group').each( function() {  
  var groupId = $(this).attr('groupId');
  var groupName = $(this).attr('groupName');
  var ownerId = $(this).attr('ownerId');
  var owner = findStudentNameById( subjectId, ownerId );
  html += "<tr>" +
     "<td width='55px'><img src='images/gplg.png' /></td>" +
     "<td>" + subjectId + " <span class='subjectName'>" + subjectName + '</span> <br /> '  + groupId + 
     " - <span class='group'>" + groupName + "</span><br /> Created By "  + owner + "</td>" +
    "</tr>" +
    "<tr>" +
     "<td width='55px'></td>" +
     "<td><img class='accept' src='images/accept.png' />" +
      "<img class='decline' src='images/decline.png' /> " +
     "</td>" +
    "</tr>";     
 });
 html += "</tbody></table>";
 return html;

or ...

$('#inviteform').submit( function (){
      var invitesSent = false;
      var html = '<h3>Invitations have been sent to the following people</h3><br /><ul>';
      $('#inviteform').find('input:checkbox').each( function() {
       if ( $(this).is(':checked')){
        html += '<li>+ <a href="#">' + $(this).val() +'</a></li>';
        invitesSent = true;
       }
      });
      html += '</ul>';

      if ( !invitesSent ){
       html = '<h3>You did not select any invitees, no invitations have been sent.</h3>';
      }

      $('#content').hide().fadeOut(2000);
      $('#content').html(html).slideDown("slow");
      $('#slogan').html('Congratulations! Your group is now complete. ').fadeIn(2000);

      return false;
     });

This is because I have a 2 main areas of the page (i.e title div, and content div), which I need to change the contents of on the fly. Unfortunately I cant separate this content into different files.

So, is there a best practices behind creating the text and DOM elements for these divs instead of hard coding so much stuff.

Im looking for the most elegant solution, so I don't have so much hard coding.

Thanks

+1  A: 

You can use jQuery's selector to create DOM elements. For example,

$('<table>')

Will create a table element which you can then set attributes on and then append to the DOM.

$('<table id="invitations" class="invitations" width="100%">')
    .append('<tbody>')
    .appendTo(selector);
    // etc
Russ Cam
+2  A: 

You should look at a templating library. http://stackoverflow.com/questions/170168/jquery-templating-engines

Craig
+1  A: 

One alternative is to use append(), addClass(), css(), attrib() and other jQuery methods to construct DOM. Chaining will make the code more elegant. This will work well, especially for small DOM trees.

If you need bigger DOM trees, then it would be better to use AJAX methods to fetch them from the server. You will need to adapt your code in order to pass the dynamically generated data.

Also, you may consider redesigning your html and javascript code. You may for example put the DOM tree in the html and hide it (using CSS or javascript). Then you could show it after you have added the dynamically generated data. This is much better from separation of concerns point of view.

kgiannakakis
+1  A: 

The way it encourages you to hardcode HTML strings is one of my pet hates with jQuery.

I generally just end up using the standard Javascript : document.createElement('TD')

If you are creating a lot of nodes of the same type it's best/faster to cache them and use cloneNode(true) to create the new nodes:

var nodeCache;
    nodeCache.td = document.createElement('TD')

var newTD = nodeCache.td.cloneNode(true);

I understand this isn't makeing much use of jQuery but I think jQuery's way of handling this is inelegant.

edeverett
A: 

Try fetching the html via ajax.

This will separate the javascript and the html, breaking the dependencies.

rikh
A: 

Using Ajax to call user controls would be better.

That way you can do all your markup in a html user control.

In my humble opinion.

Malcolm
A: 

In your case I'd separate the messages from the markup. You can have an empty html scaffold in your page like

...<div id="feedback" style="display:none;"><h3 class="headline"></h3><p class="message"></p>...

and later populate it using jQuery. This way, you could refactor all your user messages to an external .js file which greatly eases i18n.

BTW I can't recommend JQuery Template Engines. Either they force you to use a really awkward syntax (like jTemplates), or they limit you to simple element cloning. IMHO you are almost always better off using the .clone() method.

Franz