Sorting Tablesorter columns by input value - javascript

I am using jQuery Tabelsorter and it's working great.
But I want inside every -field an input-tag where the value for the sorting-script is located inside the input value param.
NOW: <td><?php echo $value; ?></td>
GOAL: <td><input value="<?php echo $value; ?>"></td>
How can I tell jQuery Tablesorter the new "value" location?
Found at Tablesorter 2.0 Samples http://tablesorter.com/docs/example-option-text-extraction.html
Example:
textExtraction: function(node) {
// extract data from markup and return it
return node.childNodes[0].childNodes[0].innerHTML;
}
My try but not working:
textExtraction: function(node) {
// extract data from markup and return it
return node.childNodes[0].val();
}

Instead of table sorter use kendoui.its provide more features & easy to use
kendoui

Tthe original tablesorter plugin has an issue using the updateCell method, so this method will not work when updating input values. But you can try my fork of tablesorter which doesn't have this issue.
Here is a demo of the all of the code below put together.
Basically instead of using textExtraction which applies to ALL table cells, you just need to add a parser:
$.tablesorter.addParser({
id: "inputs",
is: function () {
return false;
},
format: function (s, table, cell) {
return $(cell).find('input').val() || s;
},
type: "text"
});
then tell tablesorter which column to apply it to (zero-based index):
$('table').tablesorter({
headers: {
0: { sorter: "inputs" } // zero-based index (first column = column 0)
}
});
Then make sure any changes to the inputs (unless you make them read-only) are recognized by tablesorter and sent to your server
var resort = true, // resort table after update
// update all input types within the tablesorter cache when the change event fires.
// This method only works with jQuery 1.7+
// you can change it to use delegate (v1.4.3+) or live (v1.3+) as desired
// if this code interferes somehow, target the specific table $('#mytable'),
// instead of $('table')
$(window).load(function () {
// this flag prevents the updateCell event from being spammed
// it happens when you modify input text and hit enter
var alreadyUpdating = false;
$('table').find('tbody').on('change', 'input', function (e) {
if (!alreadyUpdating) {
var $tar = $(e.target),
$table = $tar.closest('table');
alreadyUpdating = true;
$table.trigger('updateCell', [ $tar.closest('td'), resort ]);
// *** update your server here ***
setTimeout(function () {
alreadyUpdating = false;
}, 10);
}
});
});

Related

How to customize edit event in JsGrid

I'm using jsGrid and want to know if it's possible how to customize onclick event of editButton. Basically, doing something like displaying modal instead of inline editing. I know that we can get the HTML output of control column like this :
{
type: 'control',
itemTemplate: function() {
var $result = jsGrid.fields.control.prototype.itemTemplate.apply(this, arguments); // Array of string
return $result;
}
}
But how to have control on EditButton?
You can try this:
editItem: function(item) {
var $row = this.rowByItem(item);
if ($row.length) {
console.log('$row: ' + JSON.stringify($row)); // I modify this
this._editRow($row);
}
},
at your jsGrid config.
All lines except line // I modify this are default from original source of jsGrid, so dont change them.

How to use columns().every() to retrieve columns with filtered elements only

I have a DataTable that requires me to retrieve the longest .text() element of each column. To achieve this, I've implemented the following script.
$('#example').DataTable({
deferRender: true,
autoWidth: false,
drawCallback: function () {
var table = $('#example').DataTable();
table.columns().every(function () {
var longestSoFar = -1;
var longestItem;
this.nodes().to$().each(function () {
var text = $(this).text();
if (text.length > longestSoFar) {
longestSoFar = text.length;
longestItem = this;
}
});
var longestTD = $(longestItem).html();
console.log(longestTD);
});
}
});
This scripts works proper and logs the longest .text() element of each column, but if you filter, it continues to pull from the entire list of rows per column regardless if their visible or not.
Example... "unfiltered"
FISH
Trout (visible)
Catfish (visible)
Coelacanth (visible)
In this scenario, my function returns "Coelacanth", which is proper.
Example... "filtered"
If I filter this DataTable for "Cat"... only one visible row would be displayed... "Catfish".
FISH
Trout (hidden)
Catfish (visible)
Coelacanth (hidden)
In this scenario, my function should return "Catfish", but instead it continues to return "Coelacanth". Is there a way to have this ignore any filtered rows and only pull from the "filtered" items visible on screen?
Thanks in advance.
SOLUTION
Use appropriate selector-modifier ({ search: 'applied' }) to account for current search query, if applicable:
// ... skipped ...
table.columns().every(function (index) {
var longestSoFar = -1;
var longestItem;
var column = table.column(index, { search: 'applied' });
column.nodes().to$().each(function () {
// ... skipped ...
DEMO
See this jsFiddle for code and demonstration.
NOTES
There was a issue with jQuery DataTables versions 1.10.6 - 1.10.9 where selector-modifier ({ search: 'applied' }) couldn't be used as a parameter to columns().every() API method, see this issue #679.
If using nightly build or jQuery DataTables version released after 1.10.9, it is possible to use the code below:
// ... skipped ...
var table = $('#example').DataTable();
table.columns({ search: 'applied' }).every(function (index) {
this.nodes().to$().each(function () {
// ... skipped ...

Custom rendering when using server side processing

I was wondering if the rendering of the table after receiving an ajax response can be modified. This seems related to the render function described here: https://www.datatables.net/manual/orthogonal-data.
My server returns Data like
{
"name":
{
id: "123456",
value: "Tiger Nixon"
}
}
I want to add to each name cell the id of the name as data-attribute or as id for the td and want to add a .on( "click", handler ) for each cell.
Is this possible?
Thanks in advance
You can use DT_RowData or DT_RowAttr (requires DataTables 1.10.5 or higher) parameters in your returned data to assign attributes to <tr> element which you can later retrieve in click handler, see Server-side processing chapter in the manual.
Alternatively you can use render method but it may not be as effective. I assumed below that index of your name column is 0 and that you want to set data-id attribute.
var table = $('#example').DataTable({
"columnDefs": [{
"data": "name.value",
"targets": 0,
"render": function ( data, type, full, meta ) {
if(type === 'display'){
$('#example').DataTable().cell(meta.row, meta.col).nodes().to$().attr('data-id', full['name']['id']);
}
return data;
}
}]
});
You can add click event handler using the code below:
$(document).ready(function(){
var table = $('#example').DataTable({
// Define DataTables initialization options here
});
$('#example tbody').on('click', 'td', function(){
// Use table to access various API function
//
// For example:
// var data_cell = table.cell(this).data();
});
});
This is possible by using the columns.createdCell function.
The answer of Gyrocode is correct for an old DataTables version.

Create Generic Javascript/Jquery ajax function

I'm new to javascript, jquery, and ajax and need help making my code more efficient. I have the following javascript/jquery function that works fine:
<script type="text/javascript">
$(document).ready(function()
{
$("#promo1").change(function() //select menu id that triggers script on change
{
//data here
$.ajax
({
//ajax stuff here
{
//individual values from json array
//set each value textbook value
$("#discprice1").val(disc);
$("#itemprice1").val(total);
$("#tax").val(tax);
$("#grandtotal").val(grand);
}
});
});
});
</script>
I change my original function to this after a suggestion:
<script type="text/javascript">
$(document).ready(function()
{
var setupCalculation = function(index) {
$("#promo" + index).on("change", function() //select menu id that triggers script on change
{
//rest of the function is here....
and change my select to this:
<select name="promo<?php echo $i; ?>" id="promo<?php echo $i; ?>"
onchange="setupCalculation('<?php echo $i; ?>');">
However, it is not working. What am I missing?
However, I need to do the same thing 10 times for 10 different rows of calculations. How can I make it so I can use this function generically and just pass the "id" of the select box to the function and not repeat this code 10 times for each of the selectors, e.g. #promo1, #promo2, #promo3, etc....
I'm assuming I need to add onchange="javascript function here();" to the html code, but I can't get it to work.
Thanks!
This is a case when you should write a little plugin. Take a look how it can look like (I did'nt get what exectly you need but you will grasp the idea):
$.fn.myFirstPlugin = functin() {
return this.each(function() {
// This is currect select box
var $select = $(this);
// Change event
$select.change(function() {
// Do something for this select box; $(this) will point to current select element
$.ajax({ ... })
});
})
};
Then you would use it like:
$('#promo1, #promo2, #promo3').myFirstPlugin();
Instead of using an "onchange" attribute inline, I would use your current approach to wireup the event handler. That way you can define a function setupCalculation that wires up the logic for a given select list.
$(document).ready(function() {
var setupCalculation = function(id) {
$("#" + id).on("change", function() {
// ajax/calculation logic
});
}
setupCalculation("promo1");
setupCalculation("promo2");
// ...etc
});
If the result elements are different (eg discprice2, discprice3, etc), then it may be better to pass an index to the function instead, and hard-code the name part of the ids:
var setupCalculation = function(index) {
$("#promo" + index).on("change", function() {
// ajax stuff
$("#discprice" + index).val(disc);
// etc
});
}
Edit Using the form onchange=setupCalculation(), the function should look like this (no need to wire up the change event):
$(document).ready(function()
{
window.setupCalculation = function(index) {
//rest of the function is here....
sounds like your select boxes look like
<select id="promo1">...</select>
<select id="promo2">...</select>
add a class to each one
<select id="promo1" class="promo">...</select>
<select id="promo2" class="promo">...</select>
so that you can select all the boxes with one simple selector for the change event function:
$(".promo").change(function() {
...
});
You could set up a jQuery function and call it from the selected object:
$.fn.changePromo = function() {
/* return this jQuery object to allow chaining and execute in an 'each()' to allow multiple elements */
return this.each( function() {
$( this ).change( function() {
/* your ajax call here */
} );
} );
}
/* call examples */
$( '#promo1' ).changePromo();
$( '#promo1,#promo2' ).changePromo();

Jquery delegate method application

How can I apply the .delegate method to this line of jquery?
$(function() {
$("input[type='checkbox']").on('change', function() {
if (this.checked) {
$(".loadingItems").fadeIn(300);
var color = encodeURI(this.value);
$(".indexMain").load('indexMain.php?color=' + color, function() {
$(".indexMain").fadeIn(slow);
});
$(".loadingItems").fadeOut(300);
} else {
$(".loadingItems").fadeIn(300);
$(".indexMain").load('indexMain.php', function() {
$(".loadingItems").fadeOut(300);
});
}
});
});
Form:
echo "<input type='checkbox' class='regularCheckbox' name='color[]' value='".$colorBoxes[color_base1]."' /><font class='similarItemsText'> ".$colorBoxes[color_base1]."</font><br />";
PHP receiving colors:
$color = $_GET['color'];
$items = $con -> prepare("SELECT * FROM item_descr WHERE color_base1 = :colorbase1");
$items -> bindValue(":colorbase1", $color);
while($info = $items->fetch(PDO::FETCH_ASSOC))
{ ....
I need to allow multiple selections in a checkbox set.
Now that you've shown us a little more about what you're really trying to do, you will have to change how your code works and .delegate() is not useful for solving that issue.
Right now, you are examining the value of only one checkbox when constructing the URL that you will use with indexMain.php. Instead, you need to examine the values of all the checked checkboxes when constructing that URL.
You don't say how you want to construct the URL when multiple checkboxes are checked, but structurally the code would go something like this:
$(function() {
$("input[type='checkbox']").on('change', function() {
var colors = [];
$("input[type='checkbox']:checked").each(function() {
colors.push(this.value);
});
if (colors.length) {
$(".loadingItems").fadeIn(300);
$(".indexMain").load('indexMain.php?color=' + colors.join("+"), function() {
$(".indexMain").fadeIn(slow);
});
$(".loadingItems").fadeOut(300);
} else {
$(".loadingItems").fadeIn(300);
$(".indexMain").load('indexMain.php', function() {
$(".loadingItems").fadeOut(300);
});
}
});
});
This code will produce a URL for the .load() command like this when one or more colors are selected:
indexMain.php?color=blue+yellow+green+orange
If no colors are selected, it will call indexMain.php with no other arguments.
It will be up to your server code to parse the colors from the URL and create the desired response.
$(document).on('change', 'input[type=checkbox]', function() {
// code
});
Using jQuery .on() you can do that.
Syntax of .on():
$(static_parent).on( eventName, target, handlerFunction);
Where static_parent means a non-dynamic container of target and target is the element to bind event(s).
Delegate can be written as below
$("table").delegate("td", "click", function(){$(this).toggleClass("chosen");});
and the same thing can be achieved using latest(available from jquery 1.7) on() like below
$("table").on("click", "td", function(){$(this).toggleClass("chosen");});

Categories

Resources