jquery - tablesort only works in one direction - tablesorter

This sorts in one direction, but not the other. Is there something wrong with the table specifications. It wold be great if someone could post an HTML sample that has sorting working in both directions on a column with dollar values that include commas in them.
// create sorter
<script type="text/javascript" id="js">
$(document).ready(function() {
// call the tablesorter plugin
$("table.tablesorter").tablesorter({
// enable debug mode
debug: false
});
});
</script>
Not sure if a prefix is needed here (table.tablesorter):
// add parser through the tablesorter addParser method
<script type="text/javascript" id="js">
$.tablesorter.addParser({
// set a unique id
id: 'money',
is: function(s) {
// return false so this parser is not auto detected
return false;
},
format: function(s) {
return s.toLowerCase().replace("\$","").replace(",","");
},
// set type, either numeric or text
type: 'numeric'
});
Not sure if table.tablesorter is needed here:
// specify column
$(function() {
$("table.tablesorter").tablesorter({
headers: {
// column to be handled specially
7: {
sorter:'money'
}
}
});
});
</script>
The following is the top of the table:
<table cellspacing="1" class="tablesorter">
<thead>
<tr>
<th>Name</th>
<th>Major</th>
<th>Gender</th>
<th>English</th>
<th>Japanese</th>
<th>Calculus</th>
<th>Overall grades</th>
<th>Money</th>
</tr>
</thead>
<tbody>
<tr>
<td>Student01</td>
<td>Languages</td>
<td>male</td>
<td>80</td>
<td>70</td>
<td>75</td>
<td>bad</td>
<td>$1.00</td>
</tr>

Since you are working with numbers, you'll need to parse the string into a real number. Change this line in your parser:
format: function(s) {
return parseFloat( s.toLowerCase().replace("\$","").replace(",","") );
}

Related

Enabling jQueryUI tooltips for disabled fields and buttons

I would like to have the jQueryUI tooltip work on disabled Buttons and Inputs as well. How can I make this happen?
Included is a sample showing various inputs and buttons, both enabled and disabled and how the jQueryUI tooltip seems to skip evaluation of the disabled elements.
Please click on the field/button labels to open the tooltips. My users don't like hover based tooltips on INPUTs and hover does not work on mobile.
If you hover over the disabled INPUT and BUTTON the browser tooltip will appear but not the jQueryUI version. This is obvious because the browser version does not evaluate the HTML but shows it raw.
Note: This question is NOT a duplicate of Show tooltip for disabled items, because that question does not ask about actual disabled tags (buttons or inputs)
// Disable HOVER tooltips for input elements since they are just annoying.
$("input[title]").tooltip({
disabled: true,
content: function() {
// Allows the tooltip text to be treated as raw HTML.
return $(this).prop('title');
},
close: function(event, ui) {
// Disable the Tooltip once closed to ensure it can only open via click.
$(this).tooltip('disable');
}
});
// Basic tooltips for the Buttons only but format HTML.
$("button[title]").tooltip({
content: function() {
// Allows the tooltip text to be treated as raw HTML.
return $(this).prop('title');
}
});
/* Manually Open the Tooltips */
$(".ui-field-help").click(function(e) {
var forId = e.target.getAttribute('for');
if (forId) {
var $forEl = $("#" + forId);
if ($forEl.length)
$forEl.tooltip('enable').tooltip('open');
}
});
// The following is only to load the CSS....
function loadCSS(filename) {
var file = document.createElement("link");
file.setAttribute("rel", "stylesheet");
file.setAttribute("type", "text/css");
file.setAttribute("href", filename);
document.head.appendChild(file);
}
loadCSS("https://code.jquery.com/ui/1.12.1/themes/start/jquery-ui.css");
.ui-field-help {
text-decoration: underline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<table width=100%>
<tr>
<td><label for="A000" class="ui-field-help">Enabled Input</label></td>
<td><input type="Text" id="A000" title="title #A000<hr>Fancy <i>HTML</i>..."></td>
</tr>
<tr>
<td><label for="B000" class="ui-field-help">Disabled Input</label></td>
<td><input disabled=disabled type="Text" id="B000" title="title #B000<hr>Fancy <i>HTML</i>..."></td>
</tr>
<tr>
<td><label for="E000" class="ui-field-help">Enabled Button</label></td>
<td><button id="E000" title="title #E000<hr>Fancy <i>HTML</i>...">Enabled Button</button></td>
</tr>
<tr>
<td><label for="D000" class="ui-field-help">Disabled Button</label></td>
<td><button disabled=disabled type="Text" id="D000" title="title #D000<hr>Fancy <i>HTML</i>...">Disabled Button</button></td>
</tr>
</table>
After not finding the answer I resolved the problem by looping through all disabled items with a [title] and processing them individually to move the tooltip to the label for that input element.
$("[title]:disabled", $container).each(function (ix, el) {
// Since the jQueryUI tooltips don't work on disabled controls we remove them
// and then attempt to add them to the elements label.
var title = el.title;
el.title = ''; // Clear the title to avoid the browser tooltip
// Look for a Label attached to the element and add the tooltip there.
$('label[for=' + el.id + ']').attr('title', title).tooltip({
content: function () {
// Allows the tooltip text to be treated as raw HTML.
return $(this).prop('title');
}
});
});

Generate a column dynamically with JQuery DataTables where table is based on a model

In an ASP.Net MVC application I have a table that's based on a model passed to the view. For this reason, the table is not based on a Json and the fields have no column names that I can reference in the 'columns'[] section of the script (or at least I don't know how!...). Still, the table works fine except that I can't manage to generate a calculated field. In all the various experiments I keep getting a NaN or undefined result, depending on the various attempts, and I understand this is because evidently I'm not referencing the proper data value, but how can I do that if I don't have column names?
The table is properly structured, thead, tbody and tfoot have the same number of columns. This is the html for the table:
<table id="mainTable" class="table table-hover">
<thead>
<tr>
<th>#Html.DisplayNameFor(model => model.Value1)</th>
<th>#Html.DisplayNameFor(model => model.Value2)</th>
<th>test</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Value1)</td>
<td>#Html.DisplayFor(modelItem => item.Value2)</td>
<td></td>
</tr>
}
</tbody>
<tfoot><tr><th></th><th></th><th></th></tr></tfoot>
</table>
The render function on first and second columns works just fine. The third column is where I am trying to calculate and display the difference between first and second column, and that's where I get NaN or undefined. This is the script:
<script>
$(document).ready(function () {
// DataTable
var table = $('#mainTable').DataTable({
responsive: true,
columns: [
{ render: function (data, type, row) { return data + '$' } },
{ render: function (data, type, row) { return data + '$' } },
{ render: function (data, type, row) { return (row.Value1 - row.Value2) + '$' }}]
});
});
</script>
This is the result I'm getting on this particular attempt. I've tried other versions, unfortunately with similar disappointing results:
Value 1 Value 2 test
200.00$ 100.00$ NaN$
etc...
I have also tried this:
columns: [ { data: 'Value1', render: function (data, type, row) { return data + '$' } } ]
and this
columns: [ { name: 'Value1', render: function (data, type, row) { return data + '$' } } ]
and this
columns: [ { data: 'Value1', name: 'Value1', render: function (data, type, row) { return data + '$' } } ]
but in all cases the entire script fails.
I also tried to assign names with columnDefs [...] but no luck.
Would someone be so kind to tell me what I'm doing wrong, or what I should do to make this work?
Thank you!

knockout custom bindinghandler and custom jquery UI widget

I'm trying to create a custom knockout bindingHandler to add a custom jQuery UI widget but have run into trouble trying to access the elements created during binding. I'm sure there's something fundamental about this that I'm missing. I have the following html:
<table data-bind="myGrid: {}">
<thead>
<tr data-bind="foreach: { data: columns, as: 'column' }">
<th data-bind="text: column"></th>
</tr>
</thead>
<tbody data-bind="foreach: { data: rows, as: 'row' }">
<tr data-bind="foreach: { data: $parent.columns, as: 'column' }">
<td data-bind="text: row[column]"></td>
</tr>
</tbody>
</table>
And the following javascript:
var vm = {
columns: [
'A', 'B'
],
rows: []
};
$.widget("my.grid", {
_create: function() {
var columns = this.element.find('th');
}
});
ko.bindingHandlers.myGrid = {
init: function (element) {
//$(element).grid();
},
update: function(element) {
$(element).grid();
}
};
ko.applyBindings(vm);
When the widget is created, it needs to find each th element created from the binding. However, the elements don't appear to be created at that point in time. I have tried both the init and update methods of the bindinghandler.
This works if I manually add the widget to the element, just not within the bindinghandler.
When and how do I access the elements created from data-binding so that my jQuery widget can modify them?
You need to take control of the bindings to your descendant elements within your custom binding handler.
See http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html
But basically, do something like:
ko.bindingHandlers.myGrid = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// bind our child elements (which will create the virtual foreach elements)
ko.applyBindingsToDescendants(bindingContext, element);
// make your grid widget
$(element).grid();
// tell KO we have already bound the children
return { controlsDescendantBindings: true };
},
update: function() { ... }
};

Web API with Knockout.js - Why isn't this working?

I have a web API which successfully returns an array of blog posts in JSON format:
[{"ID":1,"Title":"First Blog Post","Body":"Some Content"},{"ID":2,"Title":"Second BlogPost","Body":"Some other content"}]
For exercise purposes, I want to display all posts in a list using Knockout.js.
Here is my code:
<script>
$(document).ready(function () {
function AppViewModel() {
var self = this;
self.posts = ko.observableArray([
{ Title: 'Default Title', Body: 'Default Body' },
]);
$.getJSON('api/posts', function (data) {
ko.mapping.fromJSON(data, {}, self.posts);
});
}
ko.applyBindings(new AppViewModel());
});
My bindings:
<tbody data-bind="foreach: posts">
<tr>
<td data-bind="text: Title"></td>
<td data-bind="text: Body"></td>
</tr>
</tbody>
My table shows up empty, it's not showing the JSON data for some reason...
ANSWER: I had to change fromJSON to fromJS and it works! Thanks so much for your help everyone
In your case you need to specify the update target for the mapping.
From the Knockout Mapping plugin documentation:
If, like in the example above, you are performing the mapping inside
of a class, you would like to have this as the target of your mapping
operation. The third parameter to ko.mapping.fromJS indicates the
target. For example,
ko.mapping.fromJS(data, {}, someObject);
So in your case:
$.getJSON('api/posts', function (data) {
ko.mapping.fromJSON(data, {}, self.posts);
});
A working JSFiddle
Also note that that the property names are case sensitive and they should match in the JSON and in your viewmodel and bindings. e.g you retrive "Title" but you are using title
The json being returned has title case property names, but the original in self.posts has lowercase property names. I assume you are binding to the lowercase version in your template. Consider changing the json returned to lowercase too.

JQuery drag, drop and sort

I have a table with left and right col. Inside the cols, some small tables (as elements) from PHP loop.
I would like to make possible to drag and drop the elements from left to right cols AND also change the sort inside the col itself. Very hard for me !
Here's my code :
HTML part (left col but the right one is the same)
<style>
.deplace{
cursor:move;
}
</style>
<table width="100%" border="0" cellpadding="0" cellspacing="0"><tr>
<td id="leftMenu" valign="top" style="width:180px;height:800px;border:1px solid black">
<?php
while($rowg = mysql_fetch_assoc($sqlg)){
echo '<table width="100%" cellpadding="5" cellspacing="2"
style="background-color:#CCC;border: 1px solid black;height:100px"
class="deplace" id="left_'.$rowg['id'].'" modulename="'.modif_nom($rowg['module']).'" sourceid="'.$rowg['id'].'">
echo '<tr><td" align="center" style="width:100%">'.$rowg['module'].'</td></tr>';
echo '</table>';
}
?>
</td></tr></table>
And the JS code :
<script language="javascript" type="text/javascript">
$(document).ready(function() { //
$('#leftMenu').Sortable({
//revert: true,
accept: 'deplace',
axis : 'vertically',
onchange: function(event, ui) {
serial = $.SortSerialize('leftMenu');
$.ajax ( {
url : "xhr.php?source=leftMenu",
type : "get",
data : serial.hash,
success: function(data){alert(data);}
});
}
});
$('#rightMenu').Sortable({
//revert: true,
accept: 'deplace',
axis : 'vertically',
onchange: function(event, ui) {
serial = $.SortSerialize('rightMenu');
$.ajax ( {
url : "xhr.php?source=rightMenu",
type : "get",
data : serial.hash,
success: function(data){alert(data);}
});
}
});
//only the functions to move the tables from left to right
$('#rightMenu').draggable({
revert:false,
helper:'original',
});
$('#leftMenu').droppable({
over:function(event, ui){
alert('dropped');
}
});
});
</script>
So, like that, it seems there's a conflict between the functions. If I only let the sortable functions, it's OK but I can't do anything in the receiver col and I would like to send a request to PHP to update a mysql table.
Thanks a lot for your help !
There are a few issues with your code:
Sortable is lower-case
SortSerialize does not exist, I think you mean sortable("serialize")
$('#rightMenu').draggable should be changed to $('#rightMenu').children().draggable because you want to drag the elements inside the menu
Have a look at the jQuery UI Sortable doc too.

Resources