Created
August 8, 2012 18:59
-
-
Save icodejs/3297586 to your computer and use it in GitHub Desktop.
JS: MS global namespace file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var MS = MS || {}; | |
MS.ajaxEventListener = ({ | |
init: function(w, d) { | |
w.evt = d.createEvent("Event"); | |
w.evt.initEvent("ajaxLoaded", true, true); | |
return this; | |
}, | |
dispatchEvent: function(w, d) { | |
if (w.evt) { | |
d.dispatchEvent(w.evt); | |
} | |
return this; | |
} | |
}).init(window, document); | |
MS.utils = (function () { | |
return { | |
canApplySearchPagination: function($, $elem, max, callback) { | |
var | |
passCount = 0, | |
failCount = 0, | |
rgxIsHtml = /<(.|\n)*?>/g, // matches all HTML tags pairs including attributes in the tags | |
rgxIsHtmlStTag = /<\s*\w.*?>/g, // match all start tags including attributes in the tags | |
rgxIsAnchor = /<\s*a.*?>/g, // matches start tag of specific tag (a) including attibutes | |
$table = $elem.find('table:first'); | |
if (typeof(callback) !== 'function') | |
throw new TypeError(callback + " is not a function!"); | |
if ($elem.find('#searchPaginate').length || !$table.length) | |
return callback(false, null); // one searchPaginate control per page only and dont do anything if we dont find a table | |
if ($table.find('tr').length >= max) { | |
$table.find('tr td').each(function (i) { | |
var $this = $(this), tdText = $this.html(); | |
if (passCount >= max && passCount > failCount) { | |
return callback(true, $table); | |
} else if (failCount >= max && failCount > passCount) { | |
return callback(false, $table); | |
} | |
if ((!rgxIsHtml.test(tdText) && !rgxIsHtmlStTag.test(tdText)) || rgxIsAnchor.test(tdText)) { //allow anchor tags | |
passCount += 1; | |
} else { | |
failCount += 1; | |
} | |
}); | |
} else { | |
return callback(false, $table); | |
} | |
// callback function returns false so returning it will exit the jQuery.each early | |
} | |
}; | |
}()); | |
(function () { | |
/** | |
* Monkey patch Array object with a custom contains method | |
*/ | |
if (typeof Array.prototype.contains !== 'function') { | |
Array.prototype.contains = function (needle, prop) { | |
var i = this.length; | |
while (i--) { | |
if (prop) { | |
if (this[i][prop] === needle) return true; | |
} else { | |
if (this[i] === needle) return true; | |
} | |
} | |
return false; | |
}; | |
} | |
}()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;(function($) { | |
// Pagination and dynamic search | |
// by Russell Wark and Tahir Joseph | |
// | |
// USAGE: | |
// | |
// Results table must be in the following format: | |
// Table ID should be "itemtable" (note: not for the plugin) | |
// The table should have separate <THEAD> and <TBODY> sections, and <TH> tags should have the "col" scope | |
// The table <TBODY> should have a separate ID of "itemlist" | |
// Result TDs should have a class corresponding to the value of each searchable field in the <select> picklist | |
// An empty DIV with an ID of "holder" should be present to contain the pagination | |
// Record count is returned in a SPAN with an ID of "resultscount" | |
// new jQuery expression, "Contains" - works like "contains" but is case-insensitive | |
$.expr[':'].Contains = function(a, i, m) { | |
return $(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; | |
}; | |
$.expr[':'].contains = function(a, i, m) { | |
return $(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; | |
}; | |
/** | |
* Search and Paginate Plugin options | |
* ================================== | |
* minSearchTextLength : int, | |
* searchfilterId : 'string without #', | |
* searchTextboxId : 'string without #', | |
* searchpaginateHtml : 'url path to html file', | |
* excludeColumns : ['lowercase column name with no spaces'], | |
* jPagesOptions: { | |
* containerID : 'string without #', | |
* previous : 'string', | |
* next : 'string', | |
* perPage : int, | |
* delay : int | |
* } | |
*/ | |
$.fn.searchPaginate = function(options) { | |
if (!this.length) return this; | |
var defaults = { | |
minSearchTextLength : 3, | |
searchfilterId : 'searchfilter', | |
searchTextboxId : 'thesearch', | |
searchpaginateHtml : '/static/MS/js/html-templates/searchpaginate.html', | |
excludeColumns : ['options'], | |
jPagesOptions: { | |
containerID : 'itemlist', | |
previous : 'Prev', | |
next : 'Next', | |
perPage : 20, | |
delay : 20 | |
} | |
}, o = $.extend(defaults, options); | |
return this.each(function() { | |
var $table = $(this); | |
// add search page UI code to the page dynamically via ajax | |
insertSearchPaginateHTML($table , o.searchpaginateHtml); | |
var | |
$searchfilter = $('#' + o.searchfilterId), | |
$resultscount = $('<span id="resultscount" />').appendTo('#content h1'), // add results count container to h1 | |
$divHolder = $('div.holder'), | |
$trElements = [], | |
filterClassNames = {}; | |
if ($table) { | |
// dynamic page setup - make sure all the conditions set at the top of page are met | |
filterClassNames = getFilterClassNames($table.find('th')); // class name retrieved from th text | |
setupFilterOptions($searchfilter, filterClassNames); | |
//setupTable($table, filterClassNames, o.jPagesOptions.containerID); | |
$trElements = $table.find('#' + o.jPagesOptions.containerID + ' tr'); | |
addSearchPaginationClasses($trElements, filterClassNames); | |
setResultsCount(false, $trElements, $resultscount); // update h1 with results count | |
$divHolder.jPages(o.jPagesOptions); // activate pagination | |
$('#' + o.searchTextboxId).keyup(function(e) { | |
var | |
$this = $(this), | |
keycode = e.keyCode || e.which, | |
searchfilter = $searchfilter.val(), | |
searchText = $this.val(), | |
showHighlighted = false, | |
$tdElements = []; | |
// reset | |
$table.find("td").removeClass("highlight"); | |
$table.find("tr").show(); | |
if (searchText.length > o.minSearchTextLength) { | |
$divHolder.jPages("destroy"); | |
showHighlighted = (searchfilter.toLowerCase() === 'all'); | |
if (showHighlighted) { | |
$trElements.hide(); | |
$trElements.has('td:Contains("' + searchText + '")').show(); | |
$trElements.find('td:Contains("' + searchText + '")').addClass('highlight'); | |
$divHolder.jPages(o.jPagesOptions); | |
setResultsCount(showHighlighted, $trElements, $resultscount); | |
} else { | |
$trElements .hide(); | |
$tdElements = $trElements.find('td:Contains("' + searchText + '")').filter('td.' + searchfilter); | |
$tdElements.parent('tr').show(); | |
$tdElements.addClass('highlight'); | |
$divHolder.jPages(o.jPagesOptions); | |
setResultsCount(showHighlighted, $trElements, $resultscount); | |
} | |
} else if (searchText.length === 0) { // for when search field is cleared | |
$divHolder.jPages('destroy'); | |
$divHolder.jPages(o.jPagesOptions); | |
setResultsCount(showHighlighted, $trElements, $resultscount); | |
} | |
}); // end keyup | |
} | |
}); // end each | |
function insertSearchPaginateHTML($tbl, searchpaginateHtml) { | |
$.ajax({ | |
url: searchpaginateHtml, | |
type: 'GET', | |
dataType: 'html', | |
async: false, | |
success: function(html, textStatus, xhr) { | |
$tbl.before(html); | |
} | |
}); | |
} | |
function setupFilterOptions($searchfilter, options) { | |
var html = '<option value="all">-- all --</option>'; | |
$.each(options, function (i, obj){ | |
html += '<option value="' + obj.className + '">' + obj.heading + '</option>'; | |
}); | |
$searchfilter.html(html); | |
} | |
function addSearchPaginationClasses($rows, classes) { | |
$rows.each(function (i) { // add classes to each td in each row | |
$(this).find('td').each(function (j) { | |
if (classes[j]) | |
$(this).addClass(classes[j].className); | |
}); | |
}); | |
} | |
function getFilterClassNames($headings) { // add option for excluding columns | |
var classNames = []; | |
$headings.each(function (i) { | |
var | |
heading = $(this).text(), | |
className = heading | |
.toLowerCase() | |
.replace(' ', '') | |
.replace(/[,.;:]/g,'') // delete unwanted characters | |
.replace(/[\n\t]/g,' '); // remove line breaks | |
if (!o.excludeColumns.contains(className)) { | |
classNames.push({ | |
index : i, | |
heading : heading, | |
className : className | |
}); | |
} | |
}); | |
return classNames; | |
} | |
function setResultsCount(showHighlighted, $trElems, $targetElem) { | |
if (showHighlighted) { | |
count = $trElems.has("td.highlight").size(); | |
} else { | |
count = $trElems.size(); | |
} | |
$targetElem.html(' ' + count + ' result' + (count > 1 ? 's' : '')); | |
} | |
}; // end searchPaginate plugin | |
$.fn.setupSearchPaginateTable = function(options) { | |
if (!this.length) {return this;} | |
var defaults = {tbodyId: 'itemlist'}, o = $.extend(defaults, options); | |
return this.each(function() { | |
setupTable($(this), o.tbodyId); | |
}); | |
function setupTable($tbl, tbodyId) { | |
var $html = $tbl | |
.find('tbody:first tr:first') | |
.wrapAll('<thead />') // wrap all header tbl rows in a thead | |
.end() | |
.find('th') | |
.attr('scope', 'col') // add option for excluding columns | |
.end(); | |
$html | |
.find('tr') | |
.not('tr:first') | |
.wrapAll('<tbody id="' + tbodyId + '" />'); // wrap rest of table rows in a tbody with an id of itemlist | |
$tbl.html($html.find('tbody').html()); // cleanup and remove parent tbody tag and insert | |
} | |
}; // end setupSearchPaginateTable plugin | |
$(window).on('ajaxLoaded', function(e) { | |
MS.utils.canApplySearchPagination($, $('body'), 20, function (canApply, $tbl) { | |
if ($tbl) { | |
if (canApply) { | |
$tbl | |
.setupSearchPaginateTable() | |
.searchPaginate() | |
.tablesorter(); | |
} else { | |
$tbl | |
.setupSearchPaginateTable() | |
.tablesorter(); | |
} | |
} | |
return false; | |
}); | |
}); | |
}(jQuery)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment