Sort HTML Table, that gets appended via JQuery - javascript

Hello i'm trying to use Tablesorter(https://github.com/christianbach/tablesorter) to sort a table of mine which i generate throu JQuery.appends. This is how my code looks:
$(document).ready(function() {
*Lotsa more code .....*
$.get("../skillqueue",{keyid: keyid, charid: charid},function(xmlskillqueue){
console.log("XML Skillqueue");
console.log(xmlskillqueue);
//Variables for
var rowsets = xmlskillqueue.getElementsByTagName("rowset");
var skillrows;
for(var i = 0; i < rowsets.length; i++){
if(rowsets[i].getAttribute("name") == "skillqueue"){
skillrows = rowsets[i].getElementsByTagName("row");
}
}
//Defines Table Headers
$("#tableskillqueuelist").append(
"<thead>" +
"<tr>" +
"<th>Order: </th> "+
"<th>Skill Name: </th> "+
"<th>Training to: </th> "+
"<th>Starts:</th> "+
"<th>Ends:</th> "+
"</tr> "+
"</thead>"+
"<tbody>"
);
for(var i = 0; i < skillrows.length; i++){
(function(i, skillrows) {
$.get("../getitemname", {itemid:skillrows.getAttribute("typeID")},function(itemname){
$("#tableskillqueuelist").append(
"<tr> " +
"<td>" + skillrows.getAttribute("queuePosition") + ". " +
"<td>" + itemname + "</td>" +
"<td>" + "|Train to: " + skillrows.getAttribute("level") + "</td>" +
"<td>" + "|Training Starts: " + skillrows.getAttribute("startTime") + "</td>" +
"<td>" + "|Training Ends: " + skillrows.getAttribute("endTime") + "<td>" +
"</tr>"
);
})
})(i, skillrows[i]);
}
//Ends the table body
$("#tableskillqueuelist").append("</tbody>");
});
});
Now i'm wondering what i need to do to have it successfully run the $("#tableskillqueuelist").tablesorter(); method. Since it seems like whenever i try and run it, the #tableskillqueuelist seems to be empty.

You need to tell table sorter that you've changed the data and that you want to sort it by triggering events.
Example from the docs: http://tablesorter.com/docs/example-ajax.html
$("table").tablesorter();
$("#ajax-append").click(function() {
$.get("assets/ajax-content.html", function(html) {
// append the "ajax'd" data to the table body
$("table tbody").append(html);
// let the plugin know that we made a update
$("table").trigger("update");
// set sorting column and direction, this will sort on the first and third column
var sorting = [[2,1],[0,0]];
// sort on the first column
$("table").trigger("sorton",[sorting]);
});
return false;
});
HTH

Related

How to loop through and print out correctly

I Know why I'm getting undefined but i have no idea how to solve.
Tried to put null, but it is taking in as a text
var text ='{"employees":[' +
'{"name":"Tony","mobile":"99221111","email":"tony#json.com"},' +
'{"name":"Linda","mobile":"98981111","email":"linda#json.com"},' +
'{"name":"Patrick","mobile":"90902222","email":"patrick#json.com"},' +
'{"name":"Isabella","mobile":"99552222"}]}';
obj = JSON.parse(text);
for(var i in obj.employees)
{
document.getElementById("table").innerHTML += "<tr><td>" + obj.employees[i].name + "</td>" + "<td>" + obj.employees[i].mobile + "</td>"
+ "<td>" + obj.employees[i].email + "</td></tr>";
}
Hi, for Isabella there is no email, hence I'm getting undefined when I loop through to print out their details on html, however what I'm expecting is for the email portion to be empty in the table for Isabella. Is there a way to solve it?
You can use logical OR (|| in JavaScript), which will use the second value (empty string in this case) if the first value (email) is undefined:
var text = '{"employees":[' +
'{"name":"Tony","mobile":"99221111","email":"tony#json.com"},' +
'{"name":"Linda","mobile":"98981111","email":"linda#json.com"},' +
'{"name":"Patrick","mobile":"90902222","email":"patrick#json.com"},' +
'{"name":"Isabella","mobile":"99552222"}]}';
obj = JSON.parse(text);
for (var i in obj.employees) {
document.getElementById("table").innerHTML += "<tr><td>" + obj.employees[i].name + "</td>" + "<td>" + obj.employees[i].mobile + "</td>" +
"<td>" + (obj.employees[i].email || '') + "</td></tr>";
}
<table id="table"></table>

I want to fix the code concisely

var template is used as redundant I want to know how to fix it so you can use this section only once
function pluscal(data) {
var idx = index++
var form = parseInt($("#plusstr1").val()) + $("#plus_op").text() + parseInt($("#plusstr2").val())
var cal = parseInt($("#plusstr1").val()) + parseInt($("#plusstr2").val())
var template = "<tr>" +
"<td>" + idx + "</td>" +
"<td>" + form + "</td>" +
"<td>" + data.result + "</td>" +
"<td><button class='ul icon button' id='remove_btn'><i class='trash alternate icon'></i></button></td>" +
"</tr>"
$("tbody").append(template)
}
and
function minuscal(data) {
var idx = index++
var form = parseInt($("#minusstr1").val()) + $("#minus_op").text() + parseInt($("#minusstr2").val())
var cal = parseInt($("#minusstr1").val()) - parseInt($("#minusstr2").val())
var template = "<tr>" +
"<td>" + idx + "</td>" +
"<td>" + form + "</td>" +
"<td>" + data.result + "</td>" +
"<td><button class='ul icon button' id='remove_btn'><i class='trash alternate icon'></i></button></td>" +
"</tr>"
$("tbody").append(template)
}
Simply separate the logic related to template. Here I have organized it in one function. And I have merged pluscal and minuscal function.
function cal(data, calType) {
// calType need to be either plus or minus
var idx = index++
var form = parseInt($(`#${calType}str1`).val()) + $(`#${calType}_op`).text() + parseInt($(`#${calType}str2`).val())
var cal = parseInt($(`#${calType}str1`).val()) + parseInt($(`#${calType}str2`).val())
generateTemplate(idx, form, cal, data);
}
function generateTemplate(idx, form, cal, data) {
var template = `<tr>
<td> ${idx} </td>
<td> ${form} </td>
<td> ${data.result} </td>
<td><button class='ul icon button' id='remove_btn'><i class='trash alternate icon'></i></button></td>
</tr>`
$("tbody").append(template)
}
Create another function what returns the template
function getTemplate(idx, form, result) {
return "<tr>" +
"<td>" + idx + "</td>" +
"<td>" + form + "</td>" +
"<td>" + result + "</td>" +
"<td><button class='ul icon button' id='remove_btn'><i class='trash alternate icon'></i></button></td>" +
"</tr>";
}
So then you can use like this
function pluscal(data) {
var idx = index++
var form = parseInt($("#plusstr1").val()) + $("#plus_op").text() + parseInt($("#plusstr2").val())
var cal = parseInt($("#plusstr1").val()) + parseInt($("#plusstr2").val())
var template = getTemplate(idx, form, data.result);
$("tbody").append(template)
}
try this
function multiCase(caseType, data) {
if (caseType === 'Maj') {
str1 = "#plusstr1",
str2 = "#plusstr2",
op = "#plus_op"
} else {
str1 = "#minusstr1",
str2 = "#minusstr2",
op = "#minus_op"
}
var idx = index++
var form = parseInt($(str1).val()) + $(op).text() + parseInt($(str2).val())
var cal = parseInt($(str1).val()) + parseInt($(str2).val())
/* And other part of your function
...
...
*/
Hope it helps

Imitate mouse click

I need to imitate mouse click on "Name" td after table draws, so it looks like sorting by name is default.
var link = "https://jsonplaceholder.typicode.com/users";
var usersData = [];
$(".buttonLoad").click(function () {
$(".buttonLoad").remove();
$.getJSON(link, function (data) {
usersData = data;
// Table draw
for(var i = 0; i < usersData.length; i++){
$("#users").append("<tr><td>" + usersData[i].id + "</td>" + "<td>" + usersData[i].name + "</td>"
+ "<td>" + usersData[i].username + "</td>" + "<td>" + usersData[i].email + "</td>"
+ "<td>" + usersData[i].address.street + "</td>" + "<td>" + usersData[i].address.suite + "</td>"
+ "<td>" + usersData[i].address.city + "</td>" + "<td>" + usersData[i].address.zipcode + "</td>"
+ "<td>" + usersData[i].address.geo.lat + "</td>"
+ "<td>" + usersData[i].phone + "</td>"
+ "<td>" + usersData[i].website + "</td>" + "<td>" + usersData[i].company.name + "</td>"
+ "<td>" + usersData[i].company.catchPhrase + "</td>" + "<td>" + usersData[i].company.bs + "</td></tr>" )
}
});
$("table").removeClass("hide");
$('th.sort').click(function(){
var table = $(this).parents('table').eq(0)
var rows = table.find('tr:gt(0)').toArray().sort(comparer($(this).index()))
this.asc = !this.asc;
if (!this.asc){rows = rows.reverse()}
for (var i = 0; i < rows.length; i++){table.append(rows[i])}
})
function comparer(index) {
return function(a, b) {
var valA = getCellValue(a, index), valB = getCellValue(b, index)
return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.localeCompare(valB)
}
}
function getCellValue(row, index){ return $(row).children('td').eq(index).html() }
});
.hide{
display: none;
}
button{
margin: 3px;
}
table {
width: 100%;
margin: auto;
margin: 3px;
}
table th {
font-weight: bold;
}
table th, table td {
padding: 3px;
border: 1px solid #000;
}
thead th{
font: bold italic 100% sans-serif;
background-color: #f7e1b5;
}
.sort{
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<button class="buttonLoad">Load data</button>
<table id="users" border="1" class="hide">
<thead>
<tr>
<th>ID</th>
<th class="sort" id="defaultSort">Name</th>
<th class="sort">Username</th>
<th class="sort">Email</th>
<th class="sort">Street</th>
<th>Suite</th>
<th>City</th>
<th>Zipcode</th>
<th>Geo</th>
<th>Phone</th>
<th>Website</th>
<th class="sort">CompanyName</th>
<th>CatchPhrase</th>
<th>bs</th>
</tr>
</thead>
</table>
Things like .trigger("click") or element.click() don't work at all.
Calls to methods like click or trigger should be made after your dom elements are ready for the purpose of the scenario that you want to achieve.
if your case, you were trying to sort them before the elements are fully loaded into the page, so whatever solution that you will be trying, it will simply not work cause that we are missing something here.
Now, consider this modified version of your getJson function:
$.getJSON(link, function(data) {
usersData = data;
// Table draw
for (var i = 0; i < usersData.length; i++) {
$("#users").append("<tr><td>" + usersData[i].id + "</td>" + "<td>" + usersData[i].name + "</td>" + "<td>" + usersData[i].username + "</td>" + "<td>" + usersData[i].email + "</td>" + "<td>" + usersData[i].address.street + "</td>" + "<td>" + usersData[i].address.suite + "</td>" + "<td>" + usersData[i].address.city + "</td>" + "<td>" + usersData[i].address.zipcode + "</td>" + "<td>" + usersData[i].address.geo.lat + "</td>" + "<td>" + usersData[i].phone + "</td>" + "<td>" + usersData[i].website + "</td>" + "<td>" + usersData[i].company.name + "</td>" + "<td>" + usersData[i].company.catchPhrase + "</td>" + "<td>" + usersData[i].company.bs + "</td></tr>")
}
// finished loading, now sort by name
$(".sort.default").click();
});
Don't worry about this default class inside the jQuery selector, it's described down below :)
this is my approach to get it working:
1- I've marked the default th that you need to initially sort by with an additional class (named default)
2- I've then added a call to simulate the click action after the data is loaded (using a selector with the default class into account)
// finished loading, now sort by name
$(".sort.default").click();
and here is a link to the complete working fiddle: https://jsfiddle.net/hakeero/rfeh0q7v/1/
You should create a function sort(th) that you can call from anywhere so that you don't need to bother imitating click or hacks like that.
1.extract the sort statements from $('th.sort').click(), and put them in a function defined as follows:
function sort(th) {
var table = $(th).parents('table').eq(0)
var rows = table.find('tr:gt(0)').toArray().sort(comparer($(th).index()))
th.asc = !th.asc;
if (!th.asc){rows = rows.reverse()}
for (var i = 0; i < rows.length; i++){table.append(rows[i])}
}
2.sorting by name
$.getJSON(link, function (data) {
...
// sorting by name as the default action
sort($("#defaultSort"));
});
3.change $('th.sort').click() accordingly.
$('th.sort').click(function(){
sort(this);
})
for your convenience, live demo click here
Since you aren't using click event, you can just move the function away form the .click()
function clickHandler(){...}
.click(clickHandler)
then you can just call clickHandler() if you want that action

how to store array data in table?

I wanted the user to enter any alphabet in a text field, when he/she clicks on the Find! button, it will go through my php file and find a list of words that start with that alphabet (of course it's only a limited amount of words). And I want to output it to a table, with 5 columns, each cell containing one word.
Something like this:
in my HTML:
<label>
Enter any alphabet:
<input name="alphabet" type="text" id="alphabet"></label>
<input type="button" value="Find!" id="goFind">
<table border="1" id="output">
</table>
and Javascript:
$(document).ready(function () {
$.ajaxSetup({
cache: false
});
var bunchOfWords = function (data) {
var listOfWords = "";
if(!Array.isArray(data)) {
return false;
}
else {
for(i = 0; i < data.length; i = +5) {
listOfWords += "<tr><td>" + data[i] + "</td>" +
"<td>" + data[i] + "</td>" +
"<td>" + data[i] + "</td>" +
"<td>" + data[i] + "</td>" +
"<td>" + data[i] + "</td></tr>";
}
}
};
$("#goFind").click(function () {
var theWord = $("#alphabet").val();
$("#output").html("Loading..."); //gives the user an indication that it's loading
$.getJSON("wordslookup.php", "startswith=" + theWord, listOfWords);
});
});
Can't seem to figure out what's wrong.
listOfWords is out of scope in $.getJSON also its not a function, you should pass bunchOfWords to $.getJSON instead. To put the data in the table simply replace the current inner html, $("#output").html(listOfWords);

Refresh table after using jQuery .append()

The following code gets a JSON object and then spits its contents out into a <table>. The first time I do it I get my JSON content just fine. However, when I refresh, the refreshed data is stuck onto the bottom of my table. How do I refresh the data to show the new data only? I tried using .remove() but there was an obvious deleting and then a refresh of data.
$(function() {
$('#ReportedIssue').change(function() {
//$('.data').remove()
$.getJSON('/CurReport/GetUpdatedTableResults', function(json) {
for (var i = 0; i < json.GetDocumentResults.length; i++) {
$('#DocumentInfoTable').append(
"<tr class='data'>" +
"<td>" + json.GetDocumentResults[i].Document.DocumentId + "</td>" +
"<td>" + json.GetDocumentResults[i].Document.LanguageCode + "</td>" +
"<td>" + json.GetDocumentResults[i].ReportedIssue + "</td>" +
"<td>" + json.GetDocumentResults[i].PageNumber + "</td>" +
"</tr>"
);
};
});
});
});
Thank you,
Aaron
It will be more efficient to build the HTML as follows (and of course, solves the problem you're experiencing):
$(function() {
$('#ReportedIssue').change(function() {
//$('.data').remove()
$.getJSON('/CurReport/GetUpdatedTableResults', function(json) {
var str = '';
for (var i = 0; i < json.GetDocumentResults.length; i++) {
str += "<tr class='data'>" +
"<td>" + json.GetDocumentResults[i].Document.DocumentId + "</td>" +
"<td>" + json.GetDocumentResults[i].Document.LanguageCode + "</td>" +
"<td>" + json.GetDocumentResults[i].ReportedIssue + "</td>" +
"<td>" + json.GetDocumentResults[i].PageNumber + "</td>" +
"</tr>"
};
$('#DocumentInfoTable').html(str);
});
});
});

Categories

Resources