Column sorting issue in dataTables - javascript
I'm using dataTables Jquery plugin along with twitter bootstrap. I've my td content in HTML format to add popover to it when the data not in particular range.(Orange Color Cells having Popover)
Now the problem is when i sort the column Temperature it's not getting sorted properly.Note that i've sorted Temperature for AS2000 in descending order but only normal cells got sorted.
I've Initialized dataTable like this
$('#summaryTable').dataTable({
"aoColumns":[null,null,{"sType": "num-html"},{"sType": "num-html"}]
});
Normal td cell contains the following code
<td name="temperature_celsius" class="normal sorting_1"><div><span>23.40</span></div> </td>
The cell in Orange background color contains the following code
<td name="temperature_celsius" class="warning sorting_1"> <div> <span data-container="body" data-trigger="hover" data-toggle="popover" data-placement="bottom" data-title="<strong>Alert</strong>" data-html="true" data-content="<p class='text-danger'>Exceeds range limit 30.0 - 20.0 </p>" data-original-title="" title="">61.0</span><i class="icon icon-exclamation-sign pull-right" style="font-size: 21px;"></i></div></td>
Any Help?
Update :
I've this response from server
[{"AS1000":["5.1","0","false","false",null,null],"AS2000":["-","-","-","-","-","-"],"Date":"2014-03-02 08:07:00.0"},
{"AS1000":["5.0","0","false","false",null,null],"AS2000":["-","-","-","-","-","-"],"Date":"2014-03-02 17:58:00.0"},
{"AS1000":["5.0","0","false","false",null,null],"AS2000":["-","-","-","-","-","-"],"Date":"2014-03-30 14:59:00.0"},
{"AS1000":["-","-","-","-","-","-"],"AS2000":["27.0","0","true","false","30.0 - 20.0",null],"Date":"2014-03-30 06:03:00.0"},
{"AS1000":["-","-","-","-","-","-"],"AS2000":["15.0","0","false","false",null,null],"Date":"2014-03-02 02:00:00.0"},
{"AS1000":["5.0","0","false","false",null,null],"AS2000":["-","-","-","-","-","-"],"Date":"2014-03-14 20:06:00.0"},
{"AS1000":["5.0","0","false","false",null,null],"AS2000":["-","-","-","-","-","-"],"Date":"2014-03-30 07:00:00.0"},
{"AS1000":["5.0","0","false","false",null,null],"AS2000":["-","-","-","-","-","-"],"Date":"2014-03-05 06:58:00.0"},
{"AS1000":["5.0","0","false","false",null,null],"AS2000":["-","-","-","-","-","-"],"Date":"2014-03-24 13:01:00.0"},
{"AS1000":["-","-","-","-","-","-"],"AS2000":["23.40","0","true","false","30.0 - 20.0",null],"Date":"2014-03-25 23:56:00.0"},
{"AS1000":["-","-","-","-","-","-"],"AS2000":["23.5","0","true","false","30.0 - 20.0",null],"Date":"2014-03-02 09:03:00.0"},
{"AS1000":["-","-","-","-","-","-"],"AS2000":["61.0","0","false","false",null,null],"Date":"2014-03-17 19:07:59.0"}]
here each key other than date is a device.device key contains an array of following info
[Temperature,Humidity,IsTemperatureRangeExceeds,IsHumidityRangeExceeds,TemperatureRangeLimit,HumidityRangeLimit]
I'm constructing table in the following way
$.ajax({
type : "POST",
url : "http://localhost:8080/tablereports",
data: {svalue:JSON.stringify(options)} ,
success : function(result) {
obj = JSON.parse(result);
$("#reporttabletbodytempsum").empty();
var tablebody = $('#reporttabletbodytempsum');
$.each( obj, function( index, value ) {
var convertedDate=value.Date;
$.each(value,function(index1,value1){
if(index1!="Date"){
//Measurement Type choosen already by the user.it may be Temperature or TemperatureHumidity
if(measurementType =='Temp'){
if(value1[2]=='true'){
sreialloop +='<td name="temperature_celsius" class="warning"> <div> <span data-container="body" data-trigger="hover" '+
'data-toggle="popover" data-placement="bottom" data-title="<strong>Alert</strong>" data-html="true" '+
'data-content="<p class=\'text-danger\'>Exceeds range limit '+value1[4]+' </p>">'+value1[0]+
'</span><i class="icon icon-exclamation-sign pull-right" style="font-size: 21px;"></i></div></td>';
}
else {
sreialloop +='<td name="temperature_celsius" class="normal"><div><span>'+value1[0]+'</span></div></td>';
}
}else{
if(value1[2]=='true'){
sreialloop +='<td name="temperature_celsius" class="warning"> <div> <span data-container="body" data-trigger="hover" '+
'data-toggle="popover" data-placement="bottom" data-title="<strong>Alert</strong>" data-html="true" '+
'data-content="<p class=\'text-danger\'>Exceeds range limit '+value1[4]+' </p>">'+value1[0]+
'</span><i class="icon icon-exclamation-sign pull-right" style="font-size: 21px;"></i></div></td><td>'+value1[1]+'</td>';
}
else if (value1[3]=="true"){
sreialloop +='<td name="temperature_celsius">'+value1[0]+'</td><td class="warning"> <div> <span data-container="body" data-trigger="hover" '+
'data-toggle="popover" data-placement="bottom" data-title="<strong>Alert</strong>" data-html="true" '+
'data-content="<p class=\'text-danger\'>Exceeds range limit '+value1[5]+' </p>">'+value1[1]+
'</span><i class="icon icon-exclamation-sign pull-right" style="font-size: 21px;"></i></div></td>';
}
else{
sreialloop +='<td name="temperature_celsius" class="normal"><div><span>'+value1[0]+'</span></div></td><td><div><span>'+value1[1]+'</span></div></td>';
}
}
}
});
tablebody.append($('<tr class="reporttable"><td>'+ ++sno +'</td><td>'+convertedDate+'</td>'+sreialloop+'</tr>'));
});
$('[data-toggle="popover"]').popover({
'placement': 'auto',
trigger: 'hover'
});
sumTable = $('#summaryTable').dataTable();
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus); alert("Error: " + errorThrown);
}
}) ;
Is there any better way? so that i can do sorting without any error.
Thanks,
Mithun
You should use the mRender function to style your output.
It will just modify the display of the cell, but leaves the underlying data intact, so it can be used for sorting and filtering.
"aoColumns": [null, null, {
mRender: function(data, type, full) {
if (data >= 5) {
return '<div name="temperature_celsius" class="warning sorting_1">' + data + '</div>';
}
return '-';
}
}, {
mRender: function(data, type, full) {
if (data >= 20 && data <= 60) {
return '<div name="temperature_celsius">' + data + '</div>';
}
if (data >= 60) {
return '<div name="temperature_celsius" class="warning sorting_1">' + data + '</div>';
}
return '-';
}
}]
I leave the styling of the returned divs up to you.
Here is a working Plunker with custom rendering and full sorting.
Related
limit displayed selections tom-select
I am using the javascript lib Tom-Select. I would like to limit the display of how many items have been selected. I do not want to limit the number of actual choices - only how many are displayed. Standard functionality shows all selections in a growing box. I would like to set a limit of 3. Then if a user selects more than 3 the box will no longer grow but simply say 4 items selected (or 5, 6, etc). Bonus points if I could limit selections by the element width instead of a count (forcing the element to always remain on one line of the form).
You could trick using the render method and the items.length array, but how will you then let your users delete their own choices as you don't display the selected items? render: { option: function (data, escape) { return '<div class="d-flex"><span>' + escape(data.text) + '</span></div>'; }, item: function (data, escape) { //return '<span class="tag is-info mb-1 mr-1">' + escape(data.text) + '</span>'; if (this.items.length >= 3){ return '<span class="tag is-info mb-1 mr-1" style="display:none">' + escape(data.text) + '</span>'; }else{ return '<span class="tag is-info mb-1 mr-1">' + escape(data.text) + '</span>'; } } }
How to loop data and place it in exact where it is. With Jquery
I'm using jQuery 3 and Laravel 5.8. I've tried so many times for looping data and the result is wrong. I've done in show.blade.php, and there's nothing wrong. But, when I loop using jQuery it makes the result different. // Get Project by po id $('#product_owner').on('change', function() { let product_owner_val = $(this).val() if(product_owner_val) { $.ajax({ url: 'project/get/project-po/' + product_owner_val, type: 'GET', dataType: 'json', beforeSend: function() { $('#loading-project').show() }, success: function(projects) { $('#loading-project').hide() $('#project-list').empty() if(projects.length) { $.each(projects, function(key, project) { // Project Not found Message $('#project-not-found').hide() $('#project-list').append('<div class="box box-solid box-primary"><div class="box-header"><div class="box-title pull-left">' + project.name + ' - ' + project.project_code + '</div><div class="pull-right"><span class="fa fa-eye"></span><span class="fa fa-edit"></span><span class="fa fa-plus"></span><span class="fa fa-circle"></span>Collapsed Button</div></div><div class="box-body">' + $.each(project.project_sprint, function(key, sprint) { }) + '</div></div>') }) // Append Sprint in each project } else { $('#project-not-found').fadeIn() } } }) } else { $('#project-list').empty() $('#project-not-found').hide() } }) So, in this case. I want to fetch data from the projects table based on 'Product Owner [ID]'. but when I fetch the data to view, its return projects list based on Product Owner. But, here, I have sprints table that attached to projects, it's many to many relations. and Target Table that has project_id and sprint_id. The point is, I want to fetch projects based on sprints that attached to the project.
assuming you're fetching the right data from the model you can create a loop in the loop to list the project_sprint and append the inner HTML with the sprint names. You can do something like below: $.each(projects, function(key, project) { $('#project-list').append('<div class="box box-solid box-primary"> <div class="box-header"> <div class="box-title pull-left">' + project.name + ' - ' + project.project_code + '</div> <div class="pull-right"><a href="/dev/projects/' + project.id + '" id="btn-show" class="btn btn-success" title="Detail Project ' + project.name + '"><span class="fa fa-eye"></span></a><a href="/dev/logbook/edit-project/' + project.id + '" class="btn btn-warning" id="btn-modal-show" title="Edit Project ' + project.name + '"><span class="fa fa-edit"></span></a><a href="logbook/add-new-sprint-to-project/' + project.id + '" class="btn btn-primary" id="btn-modal-show" title="Add Sprint to project ' + project.name + '"><span class="fa fa-plus"></span></a><a href="/dev/logbook/add-target/' + project.id + '" class="btn btn-danger" id="btn-modal-show" title="Add new target to ' + project.name + '"><span class="fa fa-circle"></span></a>Collapsed Button </div> </div> <div id="srpint_div_'+project.id+'" class="box-body"></div> </div>') $.each(project.project_sprint, function(key2, value) { $('#sprin_div_'+project.id).append(value.name) }) })
Disable create data table button on click
I am trying to disable the #test button after one click in a create data table. The problem here is that I can disable it at the start but not after a click. viewPending: function() { createDataTable("#pTable", { "ajax":"test.php", "columns": [ { "data": "id", "mRender": function(data, type, full) { $("#test").on('click', function(){ //enables click event $("#test").off('click'); $("#test").prop('disabled', true); //alert("hello"); }); return '<div id="test" style="text-align: center"> <a id="test" class="btn btn-info btn-sm" href="'+app.api+'admin/investor/approve/'+ data +'">' + 'Approve' + '</a></div>'; } } ] }); },
"mRender": function(data, type, full) { $(".test").on('click', function(){ //enables click event $(this).parent().css("pointer-events","none"); //disable all events of pointer }); return '<div style="text-align: center"> <a class="btn btn-info btn-sm test" href="'+app.api+'admin/investor/approve/'+ data +'">' + 'Approve' + '</a></div>'; } }
The on click function works only when registered with document.ready function. The same wont work inside the mRender block. Move the onclick function to document.ready function and try.
Show JSON data based on checkbox choice
I'm wondering if it is possible to show specific JSON data, based on a choice made with a checkbox. At this moment I have specific JSON data with peoples names, department, sex and internet usage. I've managed to show this data by name, department and I drew a bar for the usage. I've made two checkboxes that show this JSON data when checked. However at this particular moment they still show the same data. I need to find a way to sort it out, after trying certain things, it's kinda getting lost on me. This is the code for getting the JSON data, showing it and the checkboxes + the code behind it: JS : $(document).ready(function() { $('input[type="checkbox"]').click(function(){ if($(this).attr("value")=="female") { $(".female").toggle(); } if($(this).attr("value")=="male") { $(".male").toggle(); } }); }); ajax(); function ajax() { $.ajax({ url:"wifi_data.json", dataType:"json", success: function(data) { //if(data.geslacht == "man") { $.each(data, function(index, item) { $('#females').append('<br>Name: ' + data[index].voornaam + ' ' + data[index].achternaam + '<br>Department: ' + data[index].afdeling + '<br>Usage: ' + '<div style="width:'+ data[index].verbruik*0.001 +'px;height:10;border:2px solid ; background-color:red;"></div>' + '<div style="'+ '<br>Sex: ' + data[index].geslacht +'"></div>' ); }); //} //if(data.gelsacht =="vrouw") { $.each(data, function(index, item) { $('#males').append('<br>Name: ' + data[index].voornaam + ' ' + data[index].achternaam + '<br>Department: ' + data[index].afdeling + "<br>Usage: " + '<div style="width:'+ data[index].verbruik*0.001 +'px;height:10;border:2px solid ; background-color:red"></div>' ); }); //} } }) } HTML : <div> <label><input type="checkbox" name="colorCheckbox" value="female"> Show Female Members</label> <br> <label><input type="checkbox" name="colorCheckbox" value="male"> Show Male Members</label> </div> <div class="female box"> <div id="females"></div> </div> <div class="male box"> <div id="males"></div> </div> What I've tried to do here with the commented parts of the code (and some code that is removed) is to only append males when "geslacht"(sex) is man(male) or vrouw(female). I've also tried to append the sex and to then put it in a div and hide it. In order to maybe check if male or female is checked, then show the hidden div's with all the men or females in it. My issue is that I'm having a huge brain fart on the part how to check what is checked, and then only gather the males or females from the JSON file based on choice. The JSON looks like this: { "46": { "voornaam": "Sergio", "achternaam": "Bloemenouw", "verbruik": "100000", "afdeling": "FHACI", "geslacht": "man", "verbruikPercentage": "18.2%" }, "25": { "voornaam": "Chayenne", "achternaam": "Aalberink", "verbruik": "200000", "afdeling": "FHEHT", "geslacht": "vrouw", "verbruikPercentage": "36.4%" }, and so on... Hopefully someone can steer me into the correct direction. I think the most important thing I need to figure out is how to only show either the females or the males including their name, usage("verbruikPercentage") and department("afdeling")
Your question contains two problems. One is to separate data into male and female parts, and the other one is about showing/hiding the elements. For the data separation, you need to do the if statement for each data item, since it is the item that contains the geslacht property. $.each(data, function(index, item) { var target = item.geslacht === 'man' ? $('#males') : $('#females'); target.append('<br>Name: ' + data[index].voornaam + ' ' + data[index].achternaam + '<br>Department: ' + data[index].afdeling + '<br>Usage: ' + '<div style="width:'+ data[index].verbruik*0.001 + 'px;height:10;border:2px solid ; background-color:red;"></div>' + '<div style="'+ '<br>Sex: ' + data[index].geslacht +'"></div>'); }); For the toggling, I didn't see anything wrong for now. You can focus on the data processing part for now, and do more debugging on it later.
Your if condition should be inside $.each() loop as follows: $.each(data, function(index, item) { if(item.geslacht == "man") { } else if(item.geslacht == "vrouw") { } })
Server side pagination with tablesorter - How to refresh it?
I have added a server side pagination with table sorter successfully. I just would like to know how can I refresh it? I would like to create a button to call a refresh function. Does anyone know if there is any method to do it? I do not want to reload the page for it. UPDATE: ajaxProcessing: function(data){ if (data && data.hasOwnProperty('rows')) { var r, row, c, d = data.rows, total = data.total_rows, headers = data.headers, rows = [], len = d.length; for ( r=0; r < len; r++ ) { row = []; // new row array // cells for (c in d[r]) { if (typeof(c) === "string") { row.push(d[r][c]); //add each table cell data to row array } } rows.push(row); // add new row array to rows array } var items=""; $("#tabelaTickets tr:has(td)").remove(); if (rows!==null && rows.length!== 0) { $.each(rows,function(index,item) { $("#tabelaTickets").append('<tr class="danger"><td align="center" style="width: 70px"><a type="button" class="btn btn-primary btn-xs" data-placement="right" title="Visualizar ticket" data-toggle="modal" class="btn btn-primary" href="visualizar.php?ticket='+item[3]+'"> #' + item[3] + '</a></td><td><div style="text-overflow:ellipsis;overflow:hidden;width:250px">' + item[4] + '</div></td><td><div style="text-overflow:ellipsis;overflow:hidden;width:350px;">' + item[5] + '</div></td><td><div style="text-overflow:ellipsis;overflow:hidden;width:250px;">' + item[6] + '</div></td><td><div style="text-overflow:ellipsis;overflow:hidden;width:60px;">' + item[7] + '</div></td><td><div style="text-overflow:ellipsis;overflow:hidden;width:70px;">' + item[8] + '</div></td></tr>'); }); }else{ $("#tabelaTickets").append('<tr><td colspan = "6" align="center">SEM RESULTADO A SER EXIBIDO</td></tr>'); } $("#tabelaTickets").trigger("update"); $("#tabelaTickets").trigger("appendCache"); $("#pleaseWaitDialog").modal('hide'); // in version 2.10, you can optionally return $(rows) a set of table rows within a jQuery object return [ total]; } }, Thanks since now, Erik
your repsonse is JSON, it's easy with a little AJAX function. example your HTML is look like : <div class="wrapper"> <div class="item"> <span>item 01</span> </div> <div class="item"> <span>item 02</span> </div> <div class="item"> <span>item 03 </span> </div> </div> <button class="btn refresh-btn" type="submit"></button> your response JSON maybe look like : response = { { content : item11 }, { content : item12 }, { content : item13 } }; your HTML render function with AJAX will be look like : $('.refresh-btn').on('click', function() { var url = 'yourUrl/?param=refresh&example=true'; var $wrapper = $('.wrapper'); // a div that wrap your new HTML. $.get(url, {}) //call AJAX GET new item. .done(function(data) { $wrapper.html(''); // clear old list; var $template = $('<div/>', {class : 'item'} ); // create item's HTML. data.arrayItemList.forEach(function(item) { var itemTemplate = $template.clone(); itemTemplate.append($('<span/>').text(item.content)); $wrapper.append(itemTemplate); // add new item in list. }); }); }) that's mean : you create new HTML, and fill it with your data, everything worked fine. Some time I create a empty template some where in view and clone it. <div class="sample-template"> <div class="item"> <span> </span> </div> </div> when I need it, I call the jQuery var $template = $('.sample-template').clone(); then fill data with $template.find('span').text(item.content);