AdminLTE v2.3.8. Datatable DateTime column sort - javascript

Consider this code (I use razor ASP.NET C# but it doesn't really matter).
I'am able to sort all column but the last one is a datetime which is sorted as string.
I just want to know if it is possible to have a sorting datetime column with AdminLTE datatables, with or without (better) adding plugins.
<div class="table-responsive">
<table id="tableClienti" class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Zona</th>
<th>Classe</th>
<th>Rag Soc</th>
<th>Indirizzo</th>
<th>Email/Telefono</th>
<th>Contatto</th>
<th>Email/Telefono</th>
<th>Ultimo Pass.</th>
</tr>
</thead>
<tbody>
#{
foreach (var r in Model)
{
<tr>
<td>#r.Zona</td>
<td>#r.ClasseCliente</td>
<td>#r.RagioneSociale</td>
<td><b>#r.Citta #r.CAP</b><br /> #r.Indirizzo</td>
<td>#r.Email<br /> #r.Telefono</td>
<td><b>#r.NomeContatto<br /> #r.CognomeContatto</b></td>
<td>#r.EmailContatto<br /> #r.TelefonoContatto</td>
<td>#r.DataUltimoPassaggio</td>
</tr>
}
}
</tbody>
</table>
</div>
$(function () {
var table = $("#tableClienti").DataTable({
paging: false,
"sDom": '<"top"i>rt<"bottom"><"clear">',
"scrollX": true,
"scrollY": "45vh",
"bSort": true
]
});

If you stumble upon this question, I solved after having issues using data-order.
This link shows how data-order works but this comment found on same page was the key for me:
Its important to notethat the data-* attributes with search() will
only work if you use this on every COL!!! You can not mix it like:
< tr>< td>Value1< /td>< /tr> < tr>< td data-search='Value 2
XYZ'>Value2< /td>< /tr> It seems the Plugin-Code always check the first
row and then use this value for all search operations. Maybe for the
future would be very cool if you can mix it ;):
Best Regards Tom
Previously, I tried to add data-order to < td> only if the "DateTime variable" was not null.
Thanks to this comment I set data-order = "DateTime variable".Ticks when "DateTime variable" is not null and data-order = 0 when "DateTime variable" is null.
So, I changed this piece of code
<td>#r.DataUltimoPassaggio</td>
in this way
#{
DateTime data;
if (DateTime.TryParse(r.DataUltimoPassaggio.ToString(), out data))
{
<td data-order="#(data.Ticks)">#(data.ToString())</td>
}
else
{
<td data-order="0"></td>
}
}

Related

Jquery - Access table values (tr children - td) and change them

Found a few posts about this but none answered my question properly.
I want to access some values in my table and change them using a click function in js using jquery. How can I access this and change it without using innerHTML?
<table class="tg">
<tr>
<th class="tg-031e">Race</th>
<th class="tg-031e">space holder lol</th>
</tr>
</table>
var tableArray = $("table").children().children();
$("#input img.Majin").click(function() {
//tableArray[0].innerHTML = "";
});
Use following find function :
$("table").find('classname');

Looping over an array of objects with mustache

edit: updated this thread to clarify my question.
I make an ajax call that returns a dataset in json which looks like this:
Everything (including the correct column names) has already been taken care of via DB views so I wanted to write a script that just grabs a dataset and spits it out in a nicely formatted html table. This way the DB's table\view can be changed (columns added and removed) and the code will not have to be updated. I've been trying to get this to work with mustache but there doesn't seem to be a simple way of doing it. In the examples I find of people using mustache with an array of objects they are all explicitly referencing the objects properties in the template. I don't know the number or name of the objects' properties (the dataset's columns) will be a head of time so I can't enter them statically in the template.
Right now I'm using two templates, one for the headers and one just for the table rows:
<script id="datasetTable" type="text/template">
<table class="table table-hover table-bordered">
<thead>
<tr>
{{#headers}}
<th>{{.}}</th>
{{/headers}}
</tr>
</thead>
<tbody>
</tbody>
</table></script>
<script id="datasetTableRows" type="text/template">
<tr>
{{#rows}}
<td>{{.}}</td>
{{/rows}}
</tr>
</script>
And here is how I'm using it:
//Build table headers from dataset's columns
datasetCols = [];
for (var keyName in dataset[0]){
datasetCols.push(keyName);
};
//Build table rows from dataset rows
var renderedTableRows = '';
var tplRows = document.getElementById('datasetTableRows').innerHTML;
datasetLength = dataset.length;
for (var i=0; i<datasetLength; i++) {
var currentRow = dataset[i];
var rowValues = [];
for (var prop in currentRow){
rowValues.push(currentRow[prop]);
}
var renderedHtml = Mustache.render(tplRows, {rows: rowValues});
renderedTableRows += renderedHtml;
}
//render table with headers
var $renderedTable = $(Mustache.render('datasetTable', {headers: datasetCols}));
$renderedTable.find('tbody').html(renderedTableRows);
$(htmlContainer).html($renderedTable);
This works fine, but I really would like to simplify it further by using only one template. Can mustache process this in a more efficient way- without me having to explicitly reference the objects properties' names in the template?
I'd also like to add that I am already using mustache in a bunch of other places (code I don't feel like re-writing with a new engine right now) so if mustache can't do it I'll stick to pure js for the time being.
I've not personally used moustache, but they're all very similar.
Also, since it is logic-less you really want to return a more useful format. I.e an array of arrays would be better in this instance.
[["234", "ddg", "aa"], ["and, so on", "and so on", "and so on"]]
But if you know that there will always be three columns returned, you could do something like:
<table class="table table-hover table-bordered">
<thead>
<th> Whatever your headers are </th>
</thead>
<tbody>
{{#.}}
<tr>
<td>{{col1}}</td>
<td>{{col2}}</td>
<td>{{col3}}</td>
</tr>
{{/.}}
<tbody>
</table>
Or enumerate the object:
<table class="table table-hover table-bordered">
<thead>
<th> Whatever your headers are </th>
</thead>
<tbody>
{{#.}}
<tr>
{{#each dataSet}}
<td>{{this}}</td>
{{/each}}
</tr>
{{/.}}
<tbody>
</table>
Also, when creating HTML in javascript, use an array, it's faster.
var somehtml = [];
somehtml.push('something');
somehtml.push('something else');
somehtml = somehtml.join('');

how to convert/transform an HTML table tbody (with rowspans) TO json?

I have an HTML table with combined row td's, or how to say, I don't know how to express myself (I am not so good at English), so I show it! This is my table:
<table border="1">
<thead>
<tr>
<th>line</th>
<th>value1</th>
<th>value2</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">1</td>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr>
<td>1.3</td>
<td>1.4</td>
</tr>
<tr>
<td rowspan="2">2</td>
<td>2.1</td>
<td>2.2</td>
</tr>
<tr>
<td>2.3</td>
<td>2.4</td>
</tr>
</tbody>
</table>
(you can check it here)
I want to convert this table to a JSON variable by jquery or javascript.
How should it look like, and how should I do it? Thank you, if you can help me!
if you want to convert only text use this one :
var array = [];
$('table').find('thead tr').each(function(){
$(this).children('th').each(function(){
array.push($(this).text());
})
}).end().find('tbody tr').each(function(){
$(this).children('td').each(function(){
array.push($(this).text());
})
})
var json = JSON.stringify(array);
To make a somehow representation of your table made no problem to me, but the problem is how to parse it back to HTML! Here a JSON with the first 6 tags:
{"table":{"border":1,"thead":{"th":{"textContent":"line","tr":"textContent":"value1",...}}}}}...
OR for better understanding:
{"tag":"table","border":1,"child":{"tag":"thead","child":{"tag":"th","textContent":"line",
"child":{"tag":"tr","textContent":"value1","child":...}}}}...
Closing tags are included.
For further explanations I need to know whether your table is a string or part of the DOM.
I belive this is what you want:
var jsonTable = {};
// add a new array property named: "columns"
$('table').find('thead tr').each(function() {
jsonTable.columns = $(this).find('th').text();
};
// now add a new array property which contains your rows: "rows"
$('table').find('tbody tr').each(function() {
var row = {};
// add data by colum names derived from "tbody"
for(var i = 0; i < jsonTable.columnsl.length; i++) {
row[ col ] = $(this).find('td').eq( i ).text();
}
// push it all to the results..
jsonTable.rows.push( row );
};
alert(JSON.stringify(jsonTable));
I think there should be some corrections, but this is it I think.

Assign ID to datatable row from json data

i'm new to datatable jquery plugin.
I got stuck with this for more than 2 days. I have a Json Data, i still cant load the table and i also want to assign first column to be id of the row
Here is html:
<table cellpadding="0" cellspacing="0" border="0" class="display"
id="accDetailTable">
<thead>
<tr>
<th>Currency</th>
<th>Current/Savings Account No.</th>
<th>Securities Account No.</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
and my initialization
var oTable=$('#accDetailTable').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": contextPath + "/user/investorAjax?method=getInvestorAccDetailList",
"iDeferLoading": 57,
} );
Return jsonData from server :
{"sEcho":1,"iColumns":4,"iTotalRecords":16,"iTotalDisplayRecords":16,
"aaData":
[{"DT_RowId":2032,"currency":1,"currentAccNo":"aa","secureAccNo":"aa"},
{"DT_RowId":2033,"currency":1,"currentAccNo":"111","secureAccNo":"111"},
{"DT_RowId":2034,"currency":1,"currentAccNo":"a","secureAccNo":"aa"},
]}
}
But it always hit :
DataTables warning (table id = 'accDetailTable'): Added data (size undefined) does not match known number of columns (3)
Your datatables is waiting for three entries per line and you give it four. In your table declaration (in html part) specify a new header cell <th> at the beginning of your row. You will put ids in it. Then after your dataTables initialization you can hide the first column using fnSetColumnVis(index, visibility) function :
oTable.fnSetColumnVis(0, false); //It will hide your first column
Doing that each row is containing his id (DT_RowId) but not displaying it.
It's kind of easy. Let's just do a tiny change, since you want the first column contains id, you may need to use fnRender, please check the api of datatables, I didn't add this part of code:
var oTable=$('#accDetailTable').dataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": contextPath + "/user/investorAjax?method=getInvestorAccDetailList",
"aoColumns":[
{"mDataProp":"currency"},
{"mDataProp":"currentAccNo"},
{"mDataProp":"secureAccNo"}
]
});

Data sorting in a dojox.grid.EnhancedGrid

First of all, thank you a lot for what you are doing here. That is very nice.
I am developing a web application with Dojo, and I am facing a problem with ordering my rows in a dojox.grid.EnhancedGrid.
Let's say i have a product with product status, my JSON file looks like:
[
{"id":1,"name":"Car A","price":"1000","productstatus":{"id":1,"name":"new"}},
{"id":2,"name":"Car B","code":"2000","productstatus":{"id":2,"name":"old"}}
]
I want to put that data in my grid and change the order of the rows by clicking in the header.
I have in my HTML file:
<table id="lstProduct" jsId="lstProduct" dojoType="dojox.grid.EnhancedGrid" >
<thead>
<tr>
<th field="id">Id</th>
<th field="name" width="100px">Name</th>
<th field="price" width="100px">Price</th>
<th field="id" formatter="formatterStatus">Status</th>
</tr>
</thead>
</table>
and my Javascript file:
dojo.addOnLoad(function() {
productStore = new dojo.data.ItemFileReadStore({data: { items: ${products} }});
dijit.byId("lstProduct").setStore(productStore);
});
// formatter
function formatterStatus(val, rowIndex) {
return lstTasks.getItem(rowIndex)['productstatus'][0]['name'];
}
The problem? I cannot order by status (status's name), it only orders by product.id when I click in the status header.
Any workaround for that?
Thanks in advance.
I believe you need to add clientSort="true" to enable client-side sorting. Add this to the <table> declaration.

Categories