Table sort by using textExtraction using data-sort-value attribute in td - jquery-plugins

Added the following td. The date value is coming as a format 01 Aug 1990. I want to sort that column. But it is not working. How can I properly set the data-sort-value so that it sort in correct way
<td data-sort-value="${info.offDate}" class="${someclass}">${info.offDate}</td>
I have the following javascript for sorting -
$(function() {
$("#infoListTable").tablesorter({
textExtraction: function(node) {
var attr = $(node).attr('data-sort-value');
if (typeof attr !== 'undefined' && attr !== false) {
return attr;
}
return $(node).text();
},headers: {
dateFormat: 'dd-mm-yyyy',
6: { sorter:'otherDate' }
}
});
});

The built-in parser for 'dd-mm-yyyy' doesn't understand month names. It is expecting all numerical values.
You can add your own parser. Since modern browsers are able to parse new Date("dd MMM yyyy"), the parser is very simple (demo):
$.tablesorter.addParser({
id: 'date-dd-MM-yyyy',
is: function() {
return false;
},
format: function(str) {
var date = str ? new Date(str) : str;
return date instanceof Date && isFinite(date) ? date.getTime() : str;
},
type: 'numeric'
});
$('table').tablesorter({
headers: {
6: { sorter: 'date-dd-MM-yyyy' }
}
});
Additionally, the textExtraction method can be simplified to:
textExtraction: function(node) {
return $(node).attr('data-sort-value') || $(node).text();
}
since the jQuery .attr() function will return an empty string if undefined instead of false.

Related

How do I retain filters in JqGrid whilst still getting remote data?

I'm using this demo to display text and dropdown list filters in the columns of a JqGrid. The grid has a remote data source and with each sort, filter, or page view etc, it grabs the data from the remote source.
The problem I am having is that when the new data arrives, the grid is refreshed, and the filters revert to default. I've looked at a few examples by Dr Oleg but I can't get it to work with remote data and persistence. Any setting of datatype to "local" or loadonce to true breaks the remote datasource.
Does anyone have any ideas of how to get this to work?
I've tried the following, but as I said, this stops the JqGrid from making API requests:
loadComplete: function () {
var $this = $(this);
var postfilt = $this.jqGrid('getGridParam', 'postData').filters;
var postsord = $this.jqGrid('getGridParam', 'postData').sord;
var postsort = $this.jqGrid('getGridParam', 'postData').sidx;
var postpage = $this.jqGrid('getGridParam', 'postData').page;
console.log(postfilt);
console.log(postsord);
console.log(postsort);
console.log(postsort);*/
if ($this.jqGrid("getGridParam", "datatype") === "json") {
setTimeout(function () {
$this.jqGrid("setGridParam", {
datatype: "local",
postData: { filters: postfilt, sord: postsord, sidx: postsort },
search: true
});
$this.trigger("reloadGrid", [{ page: postpage}]);
}, 25);
}
}
I think the issue has something to do with the select2 dropdown menus. Here you can see it destroys the filter menu and recreates it.
var options = colModelOptions, p, needRecreateSearchingToolbar = false;
if (options != null) {
for (p in options) {
if (options.hasOwnProperty(p)) {
if (options[p].edittype === "select") {
options[p].editoptions.dataInit = initSelect2;
}
if (options[p].stype === "select") {
options[p].searchoptions.dataInit = initSelect2;
}
$grid.jqGrid("setColProp", p, options[p]);
if (this.ftoolbar) { // filter toolbar exist
needRecreateSearchingToolbar = true;
}
}
}
if (needRecreateSearchingToolbar) {
$grid.jqGrid("destroyFilterToolbar");
$grid.jqGrid("filterToolbar", filterToolbarOptions);
}
}
If there was a way this could be done just once per JqGrid load rather than per every request, then that may be a step in the right direction.
The answer to this was quite simple, it just didn't present itself to me until the next morning. I simply wrapped the code that built the search bar in a boolean check, so that it only loaded once.
// somewhere in the class
var gridLoaded = false;
// and in the JqGrid initialization
loadComplete: function (response) {
if (!gridLoaded) {
var options = colModelOptions, p, needRecreateSearchingToolbar = false;
if (options != null) {
for (p in options) {
console.log(p);
if (options.hasOwnProperty(p)) {
if (options[p].edittype === "select") {
options[p].editoptions.dataInit = initSelect2;
}
if (options[p].stype === "select") {
options[p].searchoptions.dataInit = initSelect2;
}
$(this).jqGrid("setColProp", p, options[p]);
if (this.ftoolbar) { // filter toolbar exist
needRecreateSearchingToolbar = true;
}
}
}
if (needRecreateSearchingToolbar) {
$(this).jqGrid("destroyFilterToolbar");
$(this).jqGrid("filterToolbar", filterToolbarOptions);
}
}
gridLoaded = true;
}
}
Thanks again to Dr Oleg for the help.

How to use a normal pagination with jQuery Isotope?

I've implemented Isotope this way http://jsfiddle.net/circlecube/LNRzZ/ to my Joomla website. Sorting and filtering work perfeclty but only in the current page.
I would like to sort/filter all items but display only 20 items per page. I wish to keep a numeric navigation, like this http://tutorials.vinnysingh.co/quicksand/.
Can Isotope handle this or should I use another plugin? Any help is greatly appreciated. Thanks in advance.
Here is my full code:
jQuery( document ).ready( function ($) {
// cache container
var $container = $('#container');
// initialize isotope
$container.isotope({
getSortData : {
author : function ( $elem ) {
return $elem.find('.author').text();
},
city : function ( $elem ) {
return $elem.find('.city').text();
},
country : function ( $elem ) {
return $elem.find('.country').text();
},
price : function( $elem ) {
return parseFloat( $elem.find('.price').text().replace( /[\(\)]/g, '') );
},
rating : function ( $elem ) {
return parseInt( $elem.find('.rating').text(), 10 );
},
review : function ( $elem ) {
return parseInt( $elem.find('.review').text(), 10 );
},
perfDate: function (element) {
// parse out the performance date from the css classes
var classList = element.attr('class').split(/\s+/);
var dateClassPrefix = 'date-';
var date;
$.each(classList, function(index, cssClassName){
if (cssClassName.substring(0, dateClassPrefix.length) === dateClassPrefix) {
// Should be a date in format 'yyyy-MM-dd'
var dateString = cssClassName.substring(dateClassPrefix.length);
date = SF.parseDate('dd/mm/yyyy').getTime();
}
});
return date;
}
}
});
$('#sort-by a').click(function(){
// get href attribute, minus the '#'
var sortName = $(this).attr('href').slice(1);
$('#container').isotope({ sortBy : sortName });
return false;
});
// filter items when filter link is clicked
$('#filters a').click(function(){
var selector = $(this).attr('data-filter');
$container.isotope({ filter: selector });
return false;
});
var $optionSets = $('#options .option-set'),
$optionLinks = $optionSets.find('a');
$optionLinks.click(function(){
var $this = $(this);
// don't proceed if already selected
if ( $this.hasClass('selected') ) {
if ($this.hasClass('lock')){
//return false;
}
else if ($this.hasClass('asc')){
$this.removeClass('asc').addClass('desc');
}
else if ($this.hasClass('desc')){
$this.removeClass('desc').addClass('asc');
}
}
var $optionSet = $this.parents('.option-set');
$optionSet.find('.selected').removeClass('selected');
$this.addClass('selected');
// make option object dynamically, i.e. { filter: '.my-filter-class' }
var options = {},
key = $optionSet.attr('data-option-key'),
value = $this.attr('data-option-value');
// parse 'false' as false boolean
value = value === 'false' ? false : value;
options[ key ] = value;
if ($this.hasClass('asc') || $this.hasClass('desc'))
options[ 'sortAscending' ] = $this.hasClass('asc');
if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
// changes in layout modes need extra logic
changeLayoutMode( $this, options )
} else {
// otherwise, apply new options
$container.isotope( options );
}
return false;
});
});
Isotope doesn't do pagination. You'll need to implement the pagination in Joomla.

using jquery to validate postal code based on country

Working on site where we currently accept US zip codes. I already have jquery validate working for that. What i want to do now is add a drop down for the user to select country, and then based on the country they selected, it will validate the postal code to make sure it matches.
Can someone give me some pointers on how i can do this? Basically, i just need to change the regex the validator function is using based on the country drop down. The (what i assume is) relevant section of the jquery validator function is this:
(function ($) {
$.fn.validate = function (options) {
var defaults = {
invalidClass: 'error',
rules: {
req: /.{1,}/g,
email: /[\w\.=-]+#[\w\.-]+\.[\w]{2,3}/g,
phone: /\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})/g,
zip: /\d{5}$|^\d{5}-\d{4}/g,
//password: /^(?=.*\d)(?=.*[a-zA-Z]).{8,20}$/g,
password: /^(?=.{8,20}$)(?=.*\d)(?=.*[a-zA-Z]).*/g,
//nospecialchars: /[^<>?,\/\\\[\]\{\}\|!##$%^&*()_+;:"]{1,}/g
nospecialchars: /^(?!.*[?<>;]).+$/g
},
error_messages: {
req: 'Oops..',
email: 'Please enter your email address.',
phone: '',
zip: 'Please give me a valid zip.',
max: 'too many characters.',
password: '',
nospecialchars: ''
},
success: null,
failure: null
},
errors = [],
opts = $.extend(true, defaults, options);
return this.each(function () {
var $this = $(this);
$(this).find('input[type="submit"]:not(.cancel), button').click(function () {
errors = [];
validate_fields($this);
if ($this.find('.error').length === 0) {
if (typeof opts.success == 'function')
return opts.success();
}
else {
if (typeof opts.failure == 'function')
return opts.failure(errors);
}
});
});
I'm not very familiar with jquery so i don't know what the syntax is here for me to create an if-else or case statement to set the regex.
Thanks if advance for any help.
edit: Here's the bit of code that actually calls the validation
<script type="text/javascript">
$(function () {
setForm();
$('form').validate({
error_messages: {
req: null
},
failure: function (errors) {
var sel = '';
$(".errMsg").hide();
for (x in errors) {
sel += ',#' + errors[x][0];
}
if (sel.length > 0) {
sel = sel.substring(1);
$(sel).parent().find(".errMsg").show(0, function () {
$('#home .orange_box, #home .HomeRight').height('auto');
$('#infov .white_box, #infov .orangeRight').height('auto');
$('#findt .orange_box, #findt .HomeRight').height('auto');
if ($.browser.msie && $.browser.version == 8) {
evenColumns('#home .orange_box', '#home .HomeRight', -16);
evenColumns('#infov .white_box', '#infov .orangeRight', -16);
evenColumns('#findt .orange_box', '#findt .HomeRight', -16);
}
else {
evenColumns('#home .orange_box', '#home .HomeRight', -15);
evenColumns('#infov .white_box', '#infoforv .orangeRight', -15);
evenColumns('#findt .orange_box', '#findt .HomeRight', -15);
}
});
}
return false;
},
success: function () {
$(".errMsg").hide();
return true;
}
});
I would create an object, witch has:
function for the validation
object for all other countries
object for default rules
validation = {
validate : function( sCountryName, sToValidate ){
return ( null != sToValidate.match( this.countries[ sCountryName ] ? this.countries[ sCountryName ].zip : this.defaultRules.zip ))
},
countries : {
england : {
zip : /\d{5}$|^\d{5}-\d{4}/g
}
},
defaultRules : {
zip : /\d{5}$|^\d{5}-\d{4}/g
}
}

Retrieve the selected value from jQUery AutoComplete control

I need two questions answer if possible:
How to set the key\value within the jQuery Autocomplete control.
Retrieve the selected value from the jQuery Autocomplete control once a user selects a school name.
Thank in advance for your help.
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>
function RetrieveSchoolsBasedOnSchoolTypeSelected() {
//Item Selected Value
var ItemSelectedValue = $("#selSchoolTypes: option[selected]").val();
$("#example").val("");
$.getJSON("http://devportal2/apps/parisinterndb/_vti_bin/ListData.svc/Schools?$filter=SchoolTypeId eq " + ItemSelectedValue + "", function(DataResults) {
var count = 0;
var resultDataItems = "";
$.each(DataResults.d.results, function(i, result) {
var title = result.Title;
resultDataItems += title +",";
});
resultDataItems += "";
var data = resultDataItems.split(',');
$("#example").autocomplete(data,
{ delay: 10,
minChars: 1,
cacheLength: 10,
autoFill: true
});
});
$("#example").result(findValueCallback).next().click(function() {
$(this).prev().search();
});
}
function findValueCallback(event, data, formatted) {
alert(formatted+" "+data);
}
for getting the selected value,just parse the data paramter in the findValueCallback function.You may need to parse the "data" using split function and all.
ex : if (data != null) {
var model = "";
model = data.toString().split(".")[1];
selectedItem= data.toString().split(".")[0];
}
For setting the key value pair in the autosuggest dropdown,u can use the autocomplete function with a server page which can load data,
$("#txtSearchKey").autocomplete("Lib/ajaxpages/GetModelOptions.aspx", {
minChars: 2,
width: 550,
max: 4,
highlight: false,
scroll: true,
scrollHeight: 300,
formatItem: function(data, i, n, value) {
return "<b>" + value.split(".")[0] + "</b>";
},
formatResult: function(data, value) {
return value.split(".")[0];
}
});
the GetModelOptions.aspx can retun data in the form a string like
1.Alaska \n 2.Mexico \n 3.Michigan \n
and in the javascript u extract it

Jquery bassistance: validate that end date is after start date

I am using jquery bassistance validation and need to verify that a start date is after an end date. I am wondering if anyone knows if this functionality exists and if I can add rules to do this or if I have to add a custom check. I am having difficulty finding any examples of this that work with my code which forwards to another function if the form is valid. (pasted below)
$("#hotels").validate({
rules: {
checkinDate: {
date: true
},
checkoutDate: {
date: true
}
}
});
$("#hotels input.submit").click(function() {
var isValid = $("#hotels").valid();
if (isValid == true) {
} else {
hComp();
return false;
}
} else {
return false;
}
});
I saw this in another example, but am not sure how I could use it.
var startDate = new Date($('#startDate').val());
var endDate = new Date($('#endDate').val());
if (startDate < endDate){
// Do something
}
Thanks in advance for any assistance.
That example looks like it's exactly what you need. Have a look here.
Borrowing from that jquery example, suppose you have the following HTML:
<input id="startDate" value="Jan 12, 2009" />
<input id="endDate" value="Jan 12, 2010" />
Then this JavaScript code should show the alert "Start date is before end date!" (assuming the values aren't modified):
var startDate = new Date($('#startDate').val());
var endDate = new Date($('#endDate').val());
if (startDate < endDate){
alert("Start date is before end date!");
}
I ended up solving this problem before validation, which is probably a much better idea anyway. Here's the solution using the jquery ui datepicker. Then I can just use the same logic to do a final validation check.
$('input').filter('.datepicker').datepicker({
beforeShow: customRange,
showOn: 'both',
buttonImage: contextPath + '/assets/images/icon-calendar.gif',
buttonImageOnly: true,
buttonText: 'Show Date Picker'
});
function customRange(a) {
var b = new Date();
var c = new Date(b.getFullYear(), b.getMonth(), b.getDate());
if (a.id == 'checkoutDate') {
if ($('#checkinDate').datepicker('getDate') != null) {
c = $('#checkinDate').datepicker('getDate');
}
}
return {
minDate: c
}
}

Resources