jQuery create tables from JSON and group in expandable rows - javascript

I want to create a nested table with data from JSON file. here I use an array of object to simulate the back end:
var response = [
{
"mezzo":"fiat punto",
"tipologia":"auto",
"id":"1"
},
{
"mezzo":"fiat punto",
"tipologia":"auto",
"id":"2"
},
{
"mezzo":"fiat punto",
"tipologia":"auto",
"id":"3"
},
{
"mezzo":"alfa giulia",
"tipologia":"auto",
"id":"1"
},
{
"mezzo":"alfa giulia",
"tipologia":"auto",
"id":"2"
},
{
"mezzo":"fiat punto",
"tipologia":"auto",
"id":"4"
},
{
"mezzo":"alfa giulia",
"tipologia":"auto",
"id":"3"
}
];
I want to group my result table using the "mezzo" field, so I try sorting the array:
response.sort(function(a,b){
var mezzoA = a.mezzo.toLowerCase();
var mezzoB = b.mezzo.toLowerCase();
if (mezzoA > mezzoB) {
return -1;
}
if (mezzoA < mezzoB) {
return 1;
}
return 0;
});
now the jQuery code: I try to create elements and append to the DOM using .each() loop. the commented code works with hardcoded demo, but by now I have to group the rows matching the "mezzo" field in a single expandable row:
$(function () {
var parentFrag = document.createDocumentFragment();
$.each(response, function(i, item) {
var parentTr = document.createElement('tr');
var parentTd = '<td>></td><td>' + item.mezzo + '</td><td>' + item.tipologia + '</td><td>' + item.id +'</td>';
parentTr.innerHTML = parentTd;
parentFrag.appendChild(parentTr);
})
var parentTable = $('.parent');
parentTable[0].appendChild(parentFrag);
// Expand-Collapse details table
// $('table table').hide();
// $('td > a').on('click', function (e) {
// e.preventDefault();
// $(this).closest('tr').next().find('table:first').toggle();
// });
});
This is my html file:
<table border="1">
<thead>
<tr>
<td></td>
<td>Mezzo</td>
<td>Tipologia</td>
<td>ID</td>
</tr>
</thead>
<tbody class="parent">
</tbody>
</table>

Related

$(#id).html(content) function to set content to the next column

This is my HTML code:
<div class="row margin-top-3">
<div class="col-sm-7">
<h2>NFTs</h2>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th id = "NFTID">NFT ID</th>
<th id = "NFTNAME">NFT Name</th>
<th id = "NFTCREATOR">Creator</th>
</tr>
</thead>
<tbody id="NFT-rows">
</tbody>
</table>
</div>
</div>
</div>
The following three functions populate the table by column.
The problem is that the third function overwrites the second column instead of the third column.
Also, adding a fourth function will again overwrite the second column.
So, how can I re-write the $(#id).html(content) part to make it populate the next column instead of the second?
setupNFTRows: function() {
console.log("setupNFTrows NFT Array = " + JSON.stringify(NFTs));
console.log("NFT = " + Object.keys(NFTs))
Object.keys(NFTs).forEach(function (NFT) {
console.log("inside setupNFTrows");
$("#NFT-rows").append("<tr><td>" + "NFT_ID_" + NFT + "</td><td id='" + NFTs[NFT] + "'></td></tr>");
});
},
populateNFTNames: function() {
console.log("inside populateNFTNames")
let NFTIDs = Object.keys(NFTs);
console.log("NFTIDs = " + NFTIDs)
for(var i=0; i < NFTIDs.length; i++) {
let nftid = NFTIDs[i];
NFTContract.deployed().then(function(contractInstance) {
contractInstance.getNFTname.call(nftid).then(function(v) {
$("#" + NFTs[nftid]).html(v.toString());
})
})
}
},
populateCreators: function() {
let NFTIDs = Object.keys(NFTs);
for(var i=0; i < NFTIDs.length; i++) {
let nftid = NFTIDs[i];
NFTContract.deployed().then(function(contractInstance) {
contractInstance.getCreator.call(nftid).then(function(v) {
$("#" + NFTs[nftid]).html(v.toString());
})
})
}
},
This is because data tables are populated a row at a time, not a column at a time. The best way to approach this would be to zip your data together into a cohesive set to fill the rows:
const getNFTNames = (id) => {
NFTContract.deployed().then(contractInstance => {
contractInstance.getNFTname.call(nftid).then(v => {
return v.toString();
});
});
};
const getCreators = (id) => {
NFTContract.deployed().then(contractInstance => {
contractInstance.getCreator.call(nftid).then(v => {
return v.toString();
});
});
};
const setupNFTRows = () => {
Object.keys(NFTs).forEach(id => {
$("#NFT-rows").append(
`<tr id='NFT_ID_${id}'>
<td>NFT_ID_${id}</td>
<td>${getNFTNames(id)}</td>
<td>${getCreators(id)}</td>
</tr>`);
});
};

How to get old value and new value in Javascript?

I have a table grid, which is editable using Javascript, when I click on that particular field. I can change the value and update the old value.
How can I get old value and also the new value for logging purposes?
<s:iterator var="posting" value="PostLookup">
<tr class="update-rel">
<td id="${post.Id}"><input type="checkbox" /></td>
<td class="alignleft">${post.coin}</td>
<td class="alignleft" >${post.rate}</td>
<td class="alignleft">${posting.trainCode}</td>
<td class="alignleft"><fmt:formatDate pattern="HH:mm" value="${posting.postTime}" /></td>
<td class="alignleft">${posting.payMode}</td>
<td class="alignleft">${posting.payModeSub}</td>
</tr>
</s:iterator>
JavaScript Making rows editable
function activateTableEditing() {
$(document).ready(function() {
var rowIndex;
var columnIndex;
// get dynamic values from the server through a json call to be displayed inside the drop down box
var jsonObject = getJSONObject('ajax/fetchpayMode.action', 'Pay Modes');
var payModes = jsonObject.payModes;
$('#tablePostLookup tbody td').on('click', function(e) {
rowIndex = $(this).parent().index('#tablePostLookup tbody tr');
columnIndex = $(this).index('#tablePostLookup tbody tr:eq(' + rowIndex + ') td');
//console.log('Row ' + rowIndex + ' and column ' + columnIndex + ' is clicked ...');
if (columnIndex == 2 || columnIndex == 3 || columnIndex == 4) {
editInputBox(e, $(this).parent(), rowIndex, columnIndex);
}
if (columnIndex == 5) {
editCombobox(e, $(this).parent(), rowIndex, columnIndex, payMode);
}
if (columnIndex == 6) {
var payModes = $(this).parent().children('td:eq(5)').text();
jsonObject = getJSONObject('ajax/fetchpayModeSub.action?payModeSub=' + payMode, 'paymode sub ');
var paymentModeSub = jsonObject.paymentModeSub;
editCombobox(e, $(this).parent(), rowIndex, columnIndex, paymentModeSub);
}
});
});
}
Getting current values - When update button is clicked.
function savePostLookup(e, action) {
var countRowSelected = 0;
$('#tablePostLookup tbody tr').each(function() {
var result = $(this).children('td').eq(0).children('input[type=checkbox]').eq(0).is(':checked');
if (result) {
++countRowSelected;
e.preventDefault();
var id = $(this).find('td:eq(0)').eq(0).attr('id');
var coin = $(this).find('td:eq(1)').text();
var rate = $(this).find('td:eq(2)').text();
var trainCode = $(this).find('td:eq(3)').text();
var postTime = $(this).find('td:eq(4)').text();
var payMode = $(this).find('td:eq(5)').text();
var payModeSub = $(this).find('td:eq(6)').text();
createJSONObject(id, coin, rate, trainCode, postTime, payMode, payModeSub);
}
});
This is what you could potentially do. Create an object with the following key values pair.
{
"td1": [
{
"oldVlaue": "old",
"newValue": "new"
}
],
"td2": [
{
"oldVlaue": "old1",
"newValue": "new1"
}
]
}
So each time you click on some a table value, you can get the value from the event.target and you can also get which table element is clicked. Just update the value in your JSON object with the values you get.
As I said, this could potenitally be a way to keep track of the old or new values. Feel free to try something different or better.

DataTable with dropdown Column

I need to make dropdown as column in DataTable jQuery it is lookinng like as below right now
And I want it like the below image
and the code which I use is
<table id="example" class="hover row-border dataTable" role="grid" width="100%">
<thead class="dataTableHeader">
<tr>
<th>Days</th>
<th>Start Time</th>
<th>End Time</th>
</tr>
</thead>
</table>
$(document).ready(function () {
$('#example').DataTable({
"aaData": OrganizationData.OrganizationPreference.ScheduleDaysCol,
"columns": [
{"data": "DayName"},
{"data": "StartDateHour"},
{"data": "EndDateHour"}
],
"paging": false,
"ordering": false,
"info": false,
"filter": false
});
});
Another way would be to use the render method:
"render": function(d,t,r){
var $select = $("<select></select>", {
"id": r[0]+"start",
"value": d
});
$.each(times, function(k,v){
var $option = $("<option></option>", {
"text": v,
"value": v
});
if(d === v){
$option.attr("selected", "selected")
}
$select.append($option);
});
return $select.prop("outerHTML");
}
Working example.
You can use this way then for the dropdown setting
"aaData": OrganizationData.OrganizationPreference.ScheduleDaysCol,
"columnDefs": [{ "targets": 0,"data": "DayName" },
{
"targets": 1,
"data": "StartDateTime",
"render": function (data, type, full, meta) {
var $select = $("<select></select>", {
});
$.each(times, function (k, v) {
var $option = $("<option></option>", {
"text": v,
"value": v
});
if (data === v) {
$option.attr("selected", "selected")
}
$select.append($option);
});
return $select.prop("outerHTML");
}
DataTables seem to have an editor for this type of thing as refrenced by Samyukta and others: https://editor.datatables.net/examples/inline-editing/simple
I would say that is the easiest answer. It is however, a commercial extension with a free trial only.
If you wanted some jquery code to simply change the static times to dropdown boxes, you could give this a shot:
//utility functions to get half-hour increment lists
function getTimeList(){
var iterations = 48;
var result = [];
for(int i = 0; i < iterations; i++){
var hour = Math.floor(i / 2);
var minute = (i % 2) > 0 ? '30' : '00';
result.push(hour + ':' + minute);
}
return result;
}
function getOptionTimeList(){
var raw = getTimeList();
var iterations = raw.length;
var result = '';
for(int i = 0; i < iterations; i++){
result = result + '<option>' + raw[i] + '</option>';
}
return result;
}
//I'm using the not selector to avoid changing the days into dropdown by accident
$('#example tbody tr td:not(#example tbody tr:first-child)').each(
function(index, element){
var value = element.innerHTML;
var optionList = getOptionTimeList();
var replacement = '<td><select>' + optionList + '</select></td>';
$(element).replaceWith(replacement)
}
);
This should get you the drop down boxes where you need them. I'll revise this if you have problems with it.
You can try to use this, this is what i'm using now.
https://github.com/ejbeaty/CellEdit
Look at this example:
"inputTypes": [
{
"column":0,
"type":"text",
"options":null
},
{
"column":1,
"type": "list",
"options":[
{ "value": "1", "display": "Beaty" },
{ "value": "2", "display": "Doe" },
{ "value": "3", "display": "Dirt" }
]
}
Hope it help someone.

table multiple word search in jquery

I have a jquery function that search a word in a table. e.g.
TABLE
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Band Name</th>
</tr>
<tr>
<td>John</td>
<td>Lennon</td>
<td>Beatles</td>
</tr>
<tr>
<td>Paul</td>
<td>McCartney</td>
<td>Beatles</td>
</tr>
<tr>
<td>George</td>
<td>Harrison</td>
<td>Beatles</td>
</tr>
<tr>
<td>Ringo</td>
<td>Starr</td>
<td>Beatles</td>
</tr>
now. i have an input text box that if you put any word in there based on the table e.g Paul
the result will be a table that has only paul mccartney . and all the other td elements will be hidden.
$(document).ready(function(){
if (!RegExp.escape) {
RegExp.escape = function (s) {
return s.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&")
};
}
///search this table
jQuery(function ($) {
///search this table
$(' #search ').click(function () {
var searchthis = new RegExp($(' #emp_search ').val().replace(/\s+/, '|'), 'i');
$("table").find("tr").slice(1).each(function (index) {
var text = $.trim($(this).text());
$(this).toggle(searchthis.test(text));
});
Now, what i want to happen is..
what if i input a text containg "Paul Harrison", the result should be paul mccartney and george harrison.. is that possible? like inputting a multiple words and displaying a possible result? Im just new in jquery. and the codes above is not mine.. thanks in advance. :)
here is the demo
http://jsfiddle.net/wind_chime18/D6nzC/7/
I think a regex based search will be the best fit for this
if (!RegExp.escape) {
RegExp.escape = function (s) {
return s.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&")
};
}
jQuery(function ($) {
var $table = $("table");
var bands = [];
$table.find('td:nth-child(3)').each(function () {
var text = $.trim($(this).text()).toLowerCase();
if ($.inArray(text, bands) == -1) {
bands.push(text);
}
}).get();
///search this table
$(' #search ').click(function () {
var parts = $(' #emp_search ').val().split(/\s+/);
var bns = [],
i = 0,
idx;
while (i < parts.length) {
idx = $.inArray(parts[i].toLowerCase(), bands);
if (idx >= 0) {
bns.push(parts.splice(i, 1)[0]);
} else {
i++;
}
}
var nameexp = parts.length ? new RegExp(parts.join('|'), 'im') : false;
var bnexp = bns.length ? new RegExp(bns.join('|'), 'im') : false;
$("table").find("tr").slice(1).each(function (index) {
var $this = $(this);
var name = $.trim($this.children().not(':nth-child(3)').text());
var band = $.trim($this.children(':nth-child(3)').text());
$(this).toggle((!nameexp || nameexp.test(name)) && (!bnexp || bnexp.test(band)));
});
});
});
Demo: Fiddle
You could first collapse all the rows, then split the searchthis string on space and finally add visible to rows that match one of the rows... something like this for example.
$(document).ready(function(){
///search this table
$('#search').click(function() {
var searchthis = $('#emp_search').val();
$("table").find("tr").each(function(index) {
if (index === 0) return;
$(this).css('visibility', 'collapse');
});
var searchArray = [searchthis];
if (searchthis.indexOf(' ') > -1) {
searchArray = searchthis.split(' ');
}
$("table").find("tr").each(function(index) {
if (index === 0) return;
var id = $(this).find("td").text().toLowerCase().trim();
for (var i = 0; i < searchArray.length; i++) {
var txt = searchArray[i].toLowerCase().trim();
if (id.indexOf(txt) !== -1) {
$(this).css('visibility', 'visible');
}
}
});
});
});

Jquery - Sum of each same class li value

Currently I'm Developing an Invoice app with php , mysql & jquery. I want to show some details with jquery. I have dynamically created tables with dynamic data.
<table class="report_table">
<tr>
<td class="items_id">
<ul>
<li class="KKTF0">KKTF0</li>
<li class="PEN01">PEN01</li>
</ul>
</td>
<td class="items_qty">
<ul>
<li class="KKTF0">1</li>
<li class="PEN01">2</li>
</ul>
</td>
</tr>
</table>
<table class="report_table">
<tr>
<td class="items_id">
<ul>
<li class="BKK01">BKK01</li>
<li class="KKTF0">KKTF0</li>
<li class="PEN01">PEN01</li>
</ul>
</td>
<td class="items_qty">
<ul>
<li class="BKK01">4</li>
<li class="KKTF0">2</li>
<li class="PEN01">3</li>
</ul>
</td>
</tr>
</table>
li classes are dynamically created. my jquery code
jQuery(document).ready(function() {
$('.report_table').each(function() {
$('.items_id ul li').each(function() {
$(this).addClass($(this).text());
var className = $(this).attr("class");
$(this).parents('tr').find('td.items_qty li').eq($(this).index()).addClass(className);
});
});
});
I want this result
<table>
<tr>
<th>Item Id</th>
<th>Sum of Item</th>
</tr>
<tr>
<td>KKTF0</td>
<td>3</td>
</tr>
<tr>
<td>PEN01</td>
<td>5</td>
</tr>
<tr>
<td>BKK01</td>
<td>4</td>
</tr>
</table>
I don't have any idea. please help me... Thanks.
Pretty short solution:
var data = {};
$('.report_table .items_qty li').each(function() {
data[this.className] = (data[this.className] || 0) + +$(this).text();
});
var table = '<table class="result"><tr><tr><th>Item Id</th><th>Sum of Item</th></tr>' +
$.map(data, function(qty, key) {
return '<td>' + key + '</td><td>' + qty + '</td>';
}).join('</tr><tr>') + '</tr></table>';
http://jsfiddle.net/VF7bz/
Brief explanation:
1). each collects the data into an object:
{"KKTF0":3,"PEN01":5,"BKK01":4}
2). map creates an array:
["<td>KKTF0</td><td>3</td>","<td>PEN01</td><td>5</td>","<td>BKK01</td><td>4</td>"]
3). array items are joined into a string using </tr><tr> as separator.
Create an array of "items" and increment the associated quantity of each as you loop through every li. Then output the table.
function sum() {
// This will hold each category and value
var sums = new Array();
$('li').each(function() {
var item = new Object();
// Get category
item.category = $(this).attr('class');
// Get count
if (isFinite($(this).html())) {
item.count = parseInt($(this).html());
}
else {
// Skip if not a number
return;
}
// Find matching category
var exists = false;
for (var i = 0; i < sums.length; i++) {
if (sums[i].category == item.category) {
exists = true;
break;
}
}
// Increment total count
if (exists) {
sums[i].count += item.count;
}
else {
// Add category if it doesn't exist yet
sums.push(item);
}
});
var table = '<table><tr><th>Item Id</th><th>Sum of Item</th></tr><tbody>';
// Add rows to table
for (var i = 0; i < sums.length; i++) {
table += '<tr><td>' + sums[i].category + '</td><td>'
+ sums[i].count + '</td></tr>';
}
// Close table
table += '</tbody></table>';
// Append table after the last table
$('table :last').after(table);
}
Please omit the jquery code that you have posted in your question and use the one below:
Complete Jquery Solution:
Tested and Working
$(document).ready(function() {
//Create table to fill with data after last report table
$('<table id="sumtable"><th>Item Id</th><th>Sum of Item</th></table>').insertAfter($('.report_table').last());
//Loop through each report table, fetch amount and update sum in '#sumtable'
$('.report_table').each(function(){
var currtable = $(this);
$(this).find('.items_id ul li').each(function(){
//cache obj for performance
var curritem = $(this);
var itemid = curritem.html();
var itemvalue = parseInt(currtable.find('.items_qty ul li:eq('+curritem.index()+')').html());
var sumrow = $('#sumtable tbody').find('tr.'+itemid);
if(sumrow.length == 0){
//no rows found for this item id in the sum table, let's insert it
$('#sumtable tbody').append('<tr class="'+itemid+'"><td>'+itemid+'</td><td>'+itemvalue+'</td></tr>');
} else {
//Row found, do sum of value
sumrow.find('td').eq(1).html(parseInt(sumrow.find('td').eq(1).html())+itemvalue);
console.log(sumrow.find('td').eq(1).html());
}
});
})
});
DEMO: http://jsfiddle.net/N3FdB/
I am using .each loop on all li and store the values in the Object variable as key-value pairs.
Then, looping over created object properties building the desired table.
var resultObj = {};
$('li').each(function (idx, item) {
var $item = $(item);
var prop = $item.attr('class');
if (!resultObj[prop]) {
resultObj[prop] = 0;
}
var parsedVal = parseInt($item.text(), 10);
resultObj[prop] += isNaN(parsedVal) ? 0 : parsedVal;
});
var $resultTable = $('<table />');
$resultTable.append('<tr><th>Item Id</th><th>Sum of Item</th></tr>');
for (var key in resultObj) {
var $row = $('<tr />');
$row.append($('<td />', {
text: key
}))
.append($('<td />', {
text: resultObj[key]
}));
$resultTable.append($row);
}
$('body').append($resultTable);
Have a look at this FIDDLE.

Categories

Resources