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
Related
I create table with print out data from database like this:
here the JS and HTML.
JS
function initDataTableSaldoRek1() {
showLoadingCss()
$.ajax({
url: baseUrl + "api_dashboard/get_ivest",
dataType: 'JSON',
type: "GET",
success: function (res) {
var data = res.return;
$("#date").html(data[0].TANGGAL);
$('#table-invest tbody').empty();
$.each(data, function (key, val) {
var html = "<tr>" +
"<td>" + val.DATE + "</td>" +
"<td>" + val.TYPE + "</td>" +
"<td align='right'>" + accounting.formatNumber(val.USD,2,".",",") + "</td>" +
"<td align='right' >" + accounting.formatNumber(val.EUR,2,".",",") + "</td>" +
"</tr>";
$('#table-invest tbody').append(html);
});
hideLoadingCss()
},
});
}
HTML
<div class="view-table" >
<table id="table-invest" class="table table-bordered">
<thead>
<tr>
<th style="background-color: #67a2d8" width="12.5%">DATE</th>
<th style="background: #67a2d8" width="12.5%">TYPE OF PAYMENT</th>
<th style="background: #67a2d8" width="12.5%">EUR</th>
<th style="background: #67a2d8" width="12.5%">USD</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
and i want add a row every 3 rows that sum column 2 & 3 as below .
Everybody in here have ever experience to create table as below before in JavaScript?
Thank you..
Just make a check on each third row, since the $.each callback provides an index value.
function initDataTableSaldoRek1() {
showLoadingCss()
$.ajax({
url: baseUrl + "api_dashboard/get_ivest",
dataType: 'JSON',
type: "GET",
success: function (res) {
var data = res.return;
$("#date").html(data[0].TANGGAL);
let html = "<tr>" +
"<td>" + val.DATE + "</td>" +
"<td>" + val.TYPE + "</td>" +
"<td align='right'>" + accounting.formatNumber(val.USD, 2, ".", ",") + "</td>" +
"<td align='right' >" + accounting.formatNumber(val.EUR, 2, ".", ",") + "</td>" +
"</tr>";
$('#table-invest tbody').append(html);
$('#table-invest tbody').empty();
$.each(data, function (key, val) {
if ((key+1) % 3 === 0 ){
html = `<tr><td>TOTAL</td></tr> ${html}`;
}else{
return html;
}
});
hideLoadingCss()
},
});
}
You can simply use a counter, when this counter reaches the amount of rows you want, add the "total" row and reset the counter.
Also, keep track of the total value (I don't know which total you want to calculate, so it is up to you this part), inside the if to check the counter, reset this total too.
Something like this:
let counter = 0;
let sumTotal = 0;
$.each(data, function(key, val) {
var html = "<tr>" +
"<td>" + val.DATE + "</td>" +
"<td>" + val.TYPE + "</td>" +
"<td align='right'>" + accounting.formatNumber(val.USD, 2, ".", ",") + "</td>" +
"<td align='right' >" + accounting.formatNumber(val.EUR, 2, ".", ",") + "</td>" +
"</tr>";
sumTotal = 0;//USE YOUR LOGIC TO CALCULATE AND INCREASE TOTAL
$('#table-invest tbody').append(html);
counter++;
//check if it is the moment to add the new row total
if (counter == 3){
let newRow = "<tr>" +
"<td>Total: " + sumTotal + "</td>" +
"</tr>";
$('#table-invest tbody').append(newRow);
counter = 0;
sumTotal = 0;
}
});
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
I am trying to populate an html table of JSON data. I was provided the JSON data and cannot determine why it isn't populating but suspect the JSON may not be formatted properly. When I use other sample data it works, then when I sub in the JSON I was provided it doesn't work. I've tried copying the JSON into a file on my direct server, linking to what I was provided (here: https://boiling-fortress-75456.herokuapp.com/) and inserting it on myjson.com and reformatting the JSON data.
Here is my code:
<script>
$(function() {
var entries = [];
var dmJSON = "https://api.myjson.com/bins/6sjud?callback=?";
$.getJSON(dmJSON, function(data) {
$.each(data.entries, function(i, f) {
var tblRow = "<tr>" + "<td>" + f.rank + "</td>" + "<td>" + f.name + "</td>" + "<td>" + f.march_rank + "</td>" + "<td> " + f.april_rank + "</td>" + "<td>" + f.may_rank + "</td>" + f.personal_volume + "</td>" + f.team_volume + "</td>" + "</tr>"
$(tblRow).appendTo("#incentive tbody");
});
});
});
</script>
<div class="wrapper">
<div class="profile">
<table id= "incentive" border="1">
<thead>
<th>Rank</th>
<th>Name</th>
<th>March</th>
<th>April</th>
<th>May</th>
<th>Highest Rank</th>
<th>Personal Volume</th>
<th>Team Volume</th>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
You need to get the objects from affiliate
$.each(data.affiliate, function(i, f) {
var tblRow = "<tr>" + "<td>" + f.rank + "</td>" + "<td>" + f.name + "</td>" + "<td>" + f.march_rank + "</td>" + "<td> " + f.april_rank + "</td>" + "<td>" + f.may_rank + "</td>" + f.personal_volume + "</td>" + f.team_volume + "</td>" + "</tr>"
$(tblRow).appendTo("#incentive tbody");
});
Response from service
{
"affiliate":[{
"rank":1,"name":"Sally","march_rank":"Gold","april_rank":"Silver","may_rank":"Silver","highest_rank":"Silver","team_volume":12345
},{
"rank":2,"name":"Zelda","march_rank":"Gold","april_rank":"Bronze","may_rank":"Silver","highest_rank":"Gold","team_volume":12345
}
]
}
I am creating a Jquery Mobile page which includes a table. The table will display users. Table rows include checkboxes in the first cell, followed by the users information. At the bottom of the table there is a button (Edit). When this button is clicked I want the rows which have their check boxes ticked to be highlighted and the cells in the row editable.
I want to highlight/make editable rows on the click of the edit button, when
a) the rows checkbox is ticked.
The table has been created using a JavaScript loop (function is loaded on page load).
var UsersHTML = "<table class='full_width_table info_table_style ui-body-d ui-shadow table-stripe ui-responsive'>" +
"<thead>" +
"<tr class='ui-bar-b schedule_row'>" +
"<th></th>" +
"<th>UserID</th>" +
"<th>First Name</th>" +
"<th>Surname</th>" +
"<th>Home Location</th>" +
"</tr>" +
"</thead>" +
"<tbody>";
for (s = 0; s < 15; s++) {
//contenteditable='true'
UsersHTML += "<tr class='schedule_row'>" +
"<td class='user_check_cell'>" +"<input type='checkbox'>" + "</td>" +
"<td> " + + "</td>" +
"<td>" + + "</td>" +
"<td>" + + "</td>" +
"<td>" + + "</td>" +
"<td>" + + "</td>" +
"<td align='right'";
UsersHTML += "</td></tr>";
}
UsersHTML += "</tbody></table>";
$("#usersContent").html(UsersHTML);
I have used a div to display the table on the page:
<div id="usersContent">
</div>
Any help would be great!
You can use event delegation.
$('#userContent').on('click', '.user_check_cell input[type=checkbox]', function () {
var $input = $(this);
$input.closest('tr').toggleClass('highlighted', $input.prop('checked'));
});
This adds the event listener to #userContent and listens for events on that and if the element that triggered that click event matches the selector in on it goes though with the event.
The toggleClass just adds the class "highlighted" when the input that was clicked is checked.
Try this:
html
<div id="usersContent">
</div>
js:
var UsersHTML = "<table class='full_width_table info_table_style ui-body-d ui-shadow table-stripe ui-responsive'>" +
"<thead>" +
"<tr class='ui-bar-b schedule_row'>" +
"<th></th>" +
"<th>UserID</th>" +
"<th>First Name</th>" +
"<th>Surname</th>" +
"<th>Home Location</th>" +
"</tr>" +
"</thead>" +
"<tbody>";
for (s = 0; s < 15; s++) {
//contenteditable='true'
UsersHTML += "<tr class='schedule_row' id='testTr_"+s+"'>" +
"<td class='user_check_cell'>" +"<input type='checkbox' id='chk_"+s+"' specId='"+s+"' class='hightlight' onclick='changeHight(this);'>" + "</td>" +
"<td> " + + "</td>" +
"<td>" + + "</td>" +
"<td>" + + "</td>" +
"<td>" + + "</td>" +
"<td>" + + "</td>" +
"<td align='right'";
UsersHTML += "</td></tr>";
}
UsersHTML += "</tbody></table>";
$("#usersContent").html(UsersHTML);
window.changeHight = function(obj){
var specTr = $(obj).attr("specId");
if($(obj).prop("checked"))
$("#testTr_"+specTr).addClass("highlight");
else
$("#testTr_"+specTr).removeClass("highlight");
}
css:
.highlight{
background: green;
}
fiddle
First, I would encourage you to look into some sort of framework to make this easier. jsRender, Knockout.js and Angular.js would all make this cleaner and easier.
Without going down any of those roads, I would do something like this...
Add a couple classes to help us out....
.display input {
border: none;
color: #000;
}
.hightlight {
background-color: #ffffbb;
}
If you want to make the cells editable, you need to wrap them in an input. Disable the input and remove the border when in "display mode"...
$('#userTable').on('click', 'input[type="checkbox"]', function() {
var row = $(this).closest('tr');
row.removeClass('display');
row.addClass('hightlight');
row.find('input').removeAttr('disabled');
})
I also changed your code a bit to add an array of users and add the user data to the table...
for (
s = 0; s < 15; s++) {
//contenteditable='true'
UsersHTML += "<tr class='schedule_row display'>" +
"<td class='user_check_cell'>" +"<input type='checkbox'>" + "</td>" +
"<td> " + s + "</td>" +
"<td><input disabled='disabled' value='" + users[s].firstName + "'></input></td>" +
"<td>" + users[s].lastName + "</td>" +
"<td>" + users[s].location + "</td>";
UsersHTML += "</tr>";
}
Working fiddle here... http://jsfiddle.net/gRFD8/1/
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);
});
});
});