Need help writing clean organized javascript code
I am a newb with javascript and JQuery, so I am having a lot of trouble writing clean, organized code. The code below just feels sloppy and I know it is. Here is a sample of what my code looks like. If anyone has suggestions or comments about how to improve it via functions, objects, classes, that would be awesome.
The code below uses a datatable plugin, and generally would contain all the code for my page. There are still many more event handlers to write and such, but I would like to first get a handle on what I have already written before I get in too deep.
var plannerTable;
$(function () {
// Initialize datatable object
plannerTable = $('#plannerTable').dataTable
({
"bJQueryUI": true,
"bFilter": true,
"sPaginationType": "full_numbers",
"oLanguage":
{
"sZeroRecords": "Add some tasks to your planner"
},
"aoColumns":
[
{ "bSortable": true, "bSearchable": false }, // task id
{"bSortable": true, "bSearchable": false }, // course
{"bSortable": false, "bSearchable": false }, // Edit
{"iDataSort": 2 }, // due date
null, // task
{"bSortable": false, "bSearchable": false }, // Options
{"bSortable": false, "bSearchable": false} // Delete
]
});
/* Insert Time Filter Controls into datatable */
var filterHtml = [
'<ul id="plannerTable_TimeFilter" class="dataTables_TimeFilter">',
'<li><a href="#">Day</a></li>',
'<li><a href="#">Week</a></li>',
'<li><a href="#">Month</a></li>',
'<li><a href="#">All</a></li>',
'<li><a href="#">Last 30 Days</a></li>',
'</ul>'
]
$('#plannerTable_filter').after(filterHtml.join(''));
var dateFilters = $('#plannerTable_TimeFilter li');
/* setup filter click event */
dateFilters.click(function ()
{
var dateFilter = $(this).text().replace(/\s+/g, '');
/* Get tasks by date range */
$.getJSON('/Planner/Planner/GetTasksByDateRange', { 'dateFilter': dateFilter }, function (data)
{
plannerTable.fnClearTable();
$.each(data, function (key, value)
{
var row = createTableRow(value);
/* add row to table */
plannerTable.fnAddTr($(row)[0], true);
});
});
});
/*
* Function: createTableRow
* Purpose: Creates an HTML Row using the html in this function
* Returns: constructed html row
* Inputs: row data object
*/
function createTableRow(value)
{
var date = new Date(parseInt(value.DueDate.substr(6)));
/* convert date to proper format */
/* construct html row */
var row = [
'<tr>',
'<td style="display: none;">' + value.TaskId + '</td>',
'<td class="tag-bg" style="width: 10px;">',
'<span class="tag" style="background-color:' + value.CourseBackgroundColor + '" title="' + value.CoursePrefix + '"> ' + '</span>',
'<span style="display: none;">' + value.CoursePrefix + '</span>',
'</td>',
'<td class="edit">',
'<a href="#"><img src="../../../../Content/Images/Planner/edit-icon.png" /></a>',
'</td>',
'<td class="due-date">' + value.DueDate + '</td>',
'<td class="task-col">' + value.TaskName + '</td>',
'<td class="options">',
'<a class="desc" href="#"><img src="../../../../Content/Images/Planner/desc-off-icon.png" /></a>',
'&l开发者_StackOverflow社区t;a class="alert" href="#"><img src="../../../../Content/Images/Planner/bell-off-icon.png" /></a>',
'</td>',
'<td class="delete">',
'<a href="#"><img src="../../../../Content/Images/Planner/delete-icon.png" /></a>',
'</td>',
'</tr>'
]
return row.join('');
}
});
There's one tip that will make your code a little cleaner, but also be more efficient in performance. Don't create html in js using string concatenation. Use arrays.
var filterHtml = [
'<ul id="plannerTable_TimeFilter" class="dataTables_TimeFilter">',
'<li><a href="#">Day</a></li>',
'<li><a href="#">Week</a></li>',
'<li><a href="#">Month</a></li>',
'<li><a href="#">All</a></li>',
'<li><a href="#">Last 30 Days</a></li>',
'</ul>'
]
$('#plannerTable_filter').after(filterHtml.join(''));
You can use the same technique if you need to build out a list from a js array:
var data = [1,2,3,4,5,6],
html = ['<ul>'];
for(var i=0,len=data.length; i<len; i++){
html.push('<li>'+data[i]+'</li>');
}
html.push('</ul>');
$(target).html( html.join('') );
Also, don't be afraid of vertical whitespace. It helps break up the code so its not clumped together vertically.
Add generous doses of comments too. If you are using an editor that has code syntax highlighting, usually comments are in different colors than code. So not only are you helping yourself later on by continuously documenting what is going on in your code, you get the added benefit of color helping to make your code more understandable.
I would agree with Luke. If you are writing out large amounts of html with your javascript, I would look into outputting JSON and using jQuery Templates, Mustache, or PURE.
I am in the midst of trying to implement something like it in my current project which is turning out to be much more JS-based then I originally thought. As so, outputting a bunch of HTML and having to perform DOM operations over and over has become performance inhibiting.
I would just google 'jQuery Best Practices' and 'jQuery Performance' -- You will find quite a few things regarding best practices with jQuery.
One thing I've learned over the years is to just continually program. I find myself getting caught up in what should be right instead of just doing what I want to do. Program. I make sure that I test and build in benchmarks of my code where it is acceptable. From there, I just continually refactor as I find better and new ways to do things.
Good luck!
/* Insert Time Filter Controls into datatable */
var filterHtml = '<ul id="plannerTable_TimeFilter" class="dataTables_TimeFilter">' +
'<li><a href="#">Day</a></li>' +
'<li><a href="#">Week</a></li>' +
'<li><a href="#">Month</a></li>' +
'<li><a href="#">All</a></li>' +
'<li><a href="#">Last 30 Days</a></li>' +
'</ul>';
$('#plannerTable_filter').after(filterHtml);
into
var timefiller = $("<ul></ul>").addClass("dataTables_TimeFilter");
$(["Day", "Week", "Month", "All", "Last 30 Days"]).each(function() {
$("<a></a>").text(this).attr("href", "myhref").wrap("<li />").appendTo(timefiller);
});
THis is nothing you should use, it is just a way to use recursive stuff in a better way, so if you want to change the "a" into a "b" you dont have to do it 6 or nth times.
But for your work i would suggest you highly jquery templ plugin, it´s beta, but it´s working as you need it, because something like this is for me personally a no-go.
var row = '<tr>' +
'<td style="display: none;">' + value.TaskId + '</td>' +
'<td class="tag-bg" style="width: 10px;">' +
'<span class="tag" style="background-color:' + value.CourseBackgroundColor + '" title="' + value.CoursePrefix + '"> ' + '</span>' +
'<span style="display: none;">' + value.CoursePrefix + '</span>' +
'</td>' +
'<td class="edit">' +
'<a href="#"><img src="../../../../Content/Images/Planner/edit-icon.png" /></a>' +
'</td>' +
'<td class="due-date">' + value.DueDate + '</td>' +
'<td class="task-col">' + value.TaskName + '</td>' +
'<td class="options">' +
'<a class="desc" href="#"><img src="../../../../Content/Images/Planner/desc-off-icon.png" /></a>' +
'<a class="alert" href="#"><img src="../../../../Content/Images/Planner/bell-off-icon.png" /></a>' +
'</td>' +
'<td class="delete">' +
'<a href="#"><img src="../../../../Content/Images/Planner/delete-icon.png" /></a>' +
'</td>' +
'</tr>';
精彩评论