Column sorting using jQuery tablesorter - jquery-ui

I want to sort a column in table which has data like this "yyyy-mm-dd hh:mm:ss S : few more strings".
This data is string. I am using jquery.tablesorter 2.0 to sort it based on date. I am not able to sort it. Can you please help...
Amy

You'll need to use one of the date-extract parsers available here, and here is a demo of it working:
$.tablesorter.addParser({
id: "extractYYYYMMDD",
is: function (s) {
// don't auto detect this parser
return false;
},
format: function (s, table) {
var date = s.replace(/\s+/g, " ").replace(/[\-.,]/g, "/").match(/(\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2}(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?)/i);
if (date) {
date = date[0].replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$2/$3/$1");
return $.tablesorter.formatFloat((new Date(date).getTime() || ''), table) || s;
}
return s;
},
type: "numeric"
});
$('table').tablesorter({
theme: 'blackice',
headers: {
1: {
sorter: 'extractYYYYMMDD'
}
},
widgets: ['zebra', 'columns']
});

Related

how to change date format sent in filter for kendo grid?

I am using kendo ui grid which have custom filter for all date columns. I used custom date filter because I want to sent date in "yyyy-MM-dd" format while filtering. My grid operated completely server side for paging and filters as well.
Below is the kendo code in MVC which I had used for date column -
columns.Bound(p => p.CreatedOn).Title("Created On").Width("5%").Format("{0:dd/MM/yyyy}").Filterable(filterable => filterable
.Extra(false).UI("CreatedOnFilter"));
And here is my script used for it -
function CreatedOnFilter(e) {
e.kendoDatePicker({
format: "dd/MM/yyyy",
change: function () {
debugger;
var ds = $("#InvoiceGrid").data().kendoGrid.dataSource;
var nd = new Date(this.value());
var day = ("0" + nd.getDate()).slice(-2);
var mnth = ("0" + (nd.getMonth() + 1)).slice(-2);
var formattedDate = [nd.getFullYear(), mnth, day].join("-");
var curr_filters;
if(ds.filter() != undefined){
curr_filters = ds.filter().filters;
var new_filter = {
"filters": [
{
"field": "CreatedOn",
"operator": "contains",///Here is where I want operator as selected by user.
"value": formattedDate
}
]
};
curr_filters.push(new_filter);
}
else{
var new_filter = {
"filters": [
{
"field": "CreatedOn",
"operator": "contains",///Here is where I want operator as selected by user.
"value": formattedDate
}
]
};
curr_filters = new_filter;
}
ds.filter(curr_filters);
this.element.closest("form").data().kendoPopup.close();
// kendo.ui.progress($('#divInvoiceList'), false);
}
});
}
As shown in above code script. In operator I want it to be as selected by user.
Any help will be highly appreciated.
This is how I use in columns
{
field : "ReceivedDate",
title : "Date Received",
template : "#= kendo.toString(kendo.parseDate(ReceivedDate, 'yyyy-MM-dd'), 'MM/dd/yyyy') #",
filterable : {
cell : {
showOperators : false,
operator : "eq",
template : function(args) {
args.element.kendoDatePicker({
format : "MM/dd/yyyy"
});
}
}
}
},
template is used to change the format that I receive from server.

typeahead.js user query in utf-8

I have the same issue that the one answered here : Transliteration in typeahead.js
But I can't use the workaround in the answer because the list of suggestion is dynamic !
Is there a way to let the user use non-ascii character (é,à,è,ë,etc..) in their query ?
This is the solution a found :
HTML
$('.typeahead').typeahead(
{
minLength: 3,
},
{
name: 'place',
displayKey: 'city',
source: function (query, process) {
return $.get("{% url 'profil:search_place_request' search_term='user-query' %}".replace('user-query', query), { query: query }, function (data) {
objects = [];
$.each(data, function(i, object) {
objects.push({
city : object.city,
zipcode : object.zipcode,
id : object.id,
});
});
return process(objects);
});
}
}
);
View
#login_required
def search_place_request(request, search_term):
search_term = search_term.encode("utf-8")
response, response_dict = selfcare.libs.core.utils.MyAPIRequests.get("place/?term={}".format(search_term))
if response.ok :
log.info('[profil] request GET places. Search term : {}, USER : {}'.format(search_term, request.user.username))
return HttpResponse(json.dumps(response_dict['results']), content_type="application/json")
else :
log.warning('[profil] request DELETE customer address failed. Status code : {}, USER: {}'.format(response.status_code, request.user.username))
return HttpResponse("", content_type="application/json")
return HttpResponse("", content_type="application/json")
I explicitly encode in utf8 in my view, and it did the trick !

How to initialize the selection for rails-select2 in BackboneForms schema?

The project uses marionette-rails, backbone-on-rails, select2-rails and this port to BackboneForms to provide a multiselect form field. The select options are available to the user. They are retrieved from the collection containing the total list of options:
MyApp.module("Products", function(Products, App, Backbone, Marionette, $, _) {
Products.CustomFormView = Products.CustomView.extend({
initialize: function(options) {
this.model.set("type", "Product");
Products.EntryView.prototype.initialize.apply(this, arguments);
},
schemata: function() {
var products = this.collection.byType("Product");
var productTypes = products.map(function(product){
return {
val: product.id,
label: product.get("name")
};
});
return {
productBasics: {
name: {
type: "Text",
title: "Name",
editorAttrs: {
maxLength: 60,
}
},
type: {
type: 'Select2',
title: "Product type",
options: {
values: productTypes,
value: [3, 5],
initSelection: function (element, callback) {
var data = [];
$(element.val().split(",")).each(function () {
data.push({id: this, text: this});
});
callback(data);
}
},
editorAttrs: {
'multiple': 'multiple'
}
}
}
};
}
});
});
Do I initialize the value correctly in options.value? How comes initSelection is never called? I copied the function from the documentation - it might be incomplete for my case. None of the products with the IDs 3 and 5 is displayed as the selection.
initSelection is only used when data is loaded asynchronously. My understanding is that there is no way of specifying the selection upon initialization if you are using an array as the data source for a Select2 control.
The best way of initializing the selection is by using setValue after the form is created. Here is a simplified example based on the code in your example.
var ProductForm = Backbone.Form.extend({
schema: {
type: {
type: 'Select2',
title: "Product type",
options: {
values: productTypes,
},
editorAttrs: {
'multiple': 'multiple'
}
}
});
var form = new ProductForm({
model: new Product()
}).render();
form.setValue("type", [3, 5]);
You can use value function (http://ivaynberg.github.io/select2/#documentation) in setValue. I personally recomend you to use this backbonme-forms plugin: https://gist.github.com/powmedia/5161061
There is a thread about custom editors: https://github.com/powmedia/backbone-forms/issues/144

Select2 dropdown but allow new values by user?

I want to have a dropdown with a set of values but also allow the user to "select" a new value not listed there.
I see that select2 supports this if you are using it in tags mode, but is there a way to do it without using tags?
The excellent answer provided by #fmpwizard works for Select2 3.5.2 and below, but it will not work in 4.0.0.
Since very early on (but perhaps not as early as this question), Select2 has supported "tagging": where users can add in their own value if you allow them to. This can be enabled through the tags option, and you can play around with an example in the documentation.
$("select").select2({
tags: true
});
By default, this will create an option that has the same text as the search term that they have entered. You can modify the object that is used if you are looking to mark it in a special way, or create the object remotely once it is selected.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
}
});
In addition to serving as an easy to spot flag on the object passed in through the select2:select event, the extra property also allows you to render the option slightly differently in the result. So if you wanted to visually signal the fact that it is a new option by putting "(new)" next to it, you could do something like this.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(" <em>(new)</em>");
}
return $result;
}
});
For version 4+ check this answer below by Kevin Brown
In Select2 3.5.2 and below, you can use something like:
$(selector).select2({
minimumInputLength:1,
"ajax": {
data:function (term, page) {
return { term:term, page:page };
},
dataType:"json",
quietMillis:100,
results: function (data, page) {
return {results: data.results};
},
"url": url
},
id: function(object) {
return object.text;
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
});
(taken from an answer on the select2 mailing list, but cannot find the link now)
Just for the sake of keep the code alive, I'm posting #rrauenza Fiddle's code from his comment.
HTML
<input type='hidden' id='tags' style='width:300px'/>
jQuery
$("#tags").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
multiple: false,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Since many of these answers don't work in 4.0+, if you are using ajax, you could have the server add the new value as an option. So it would work like this:
User searches for value (which makes ajax request to server)
If value found great, return the option. If not just have the server append that option like this: [{"text":" my NEW option)","id":"0"}]
When the form is submitted just check to see if that option is in the db and if not create it before saving.
There is a better solution I think now
simply set tagging to true on the select options ?
tags: true
from https://select2.org/tagging
Improvent on #fmpwizard answer:
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
}).length===0) {
return {id:term, text:term};
}
},
//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Thanks for the help guys, I used the code below within Codeigniter I I am using version: 3.5.2 of select2.
var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
ajax: {
url: location_url,
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
results = [];
$.each(data, function(index, item){
results.push({
id: item.location_id,
text: item.location_name
});
});
return {
results: results
};
}
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, results) {
if ($(results).filter( function() {
return term.localeCompare(this.text)===0;
}).length===0) {
return {id:term, text:term + ' [New]'};
}
},
});
I just stumbled upon this from Kevin Brown.
https://stackoverflow.com/a/30019966/112680
All you have to do for v4.0.6 is use tags: true parameter.
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;
In most cases we need to compare values with insensitive register. And this code will return false, which will lead to the creation of duplicate records in the database. Moreover String.prototype.localeCompare () is not supported by browser Safary and this code will not work in this browser;
return this.text.localeCompare(term)===0;
will better replace to
return this.text.toLowerCase() === term.toLowerCase();

Custom YTD Option in HighStock Range Selector

Using the Highstock charting library, Is there any way using the Highstock Range selector to display a custom YTD option?
Current when you use a type of 'ytd' in the range selector, it defaults to using the calendar year. For my use case (and i would have thought for financial institutions as well) i need to display data running from 1st April - 31st March as a 'ytd' option
It's probably not possible without hacking sources, find in Highstock:
else if (type === 'ytd') {
now = new Date(dataMax);
year = now.getFullYear();
newMin = rangeMin = mathMax(dataMin || 0, Date.UTC(year, 0, 1));
now = now.getTime();
newMax = mathMin(dataMax || now, now);
}
So as you can see, dates are hardcoded. You can change them to needed.
Here's how i've done it. Doesn't cope with looking at a previous Financial YTD (Which is a common use case for what i need it for), but i'm sure i could hack something up to do it.
JSFiddle here
$(function() {
var startDate = new Date("April 01, 2012 00:00:00");
var today = new Date();
var count = parseInt((today.getTime() - startDate)/(24*3600*1000)) -1;
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=?', function(data) {
// Create the chart
window.chart = new Highcharts.StockChart({
chart : {
renderTo : 'container'
},
rangeSelector : {
selected: 1,
buttonTheme: {
width:100
},
buttons: [{
type: 'ytd',
count: 1,
text: 'Calendar YTD'
},
{
type: 'day',
count: count,
text: 'Financial YTD'
}]
},
title : {
text : 'AAPL Stock Price'
},
series : [{
name : 'AAPL',
data : data,
tooltip: {
valueDecimals: 2
}
}]
} );
});
});

Resources