JavaScript: Building a HTML table from a nested JSON - javascript

I have a problem building a HTML table from the following JSON
[
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
},
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
},
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children":[
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
},
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
}
]
},
{
"size" : 167,
"price" : 453400,
"type" : "Neubau",
"children" : false
}
]
when fed into these functions
function getRowHTML(dataObject, type) {
cycles = dataObject.length;
var markup = '';
for (var i=0; i < cycles; i++) {
// different markup for each line
switch (type) {
case 'size':
markup += ' <td>' + dataObject[i].size + '</td>';
break;
case 'price':
markup += ' <td>' + addDots(dataObject[i].price) + '€ </td>';
break;
case 'type':
markup += ' <td>' + dataObject[i].type + '</td>';
break;
}
// Check if an object has children and insert children HTML as well
if (dataObject[i].children) {
markup += getRowHTML(dataObject[i].children,type);
}
}
return markup;
}
function getHTML(data) {
var markup = '<table>';
markup += '<tr class="odd">' + getRowHTML(data,'size') + '</tr>';
markup += '<tr class="even">' + getRowHTML(data,'price') + '</tr>';
markup += '<tr class="odd">' + getRowHTML(data,'type') + '</tr>';
markup += '</table>';
return markup;
}
Everything works fine until I add the check for children and the corresponding recursive function call.
Then the result are the first two objects and the children but the last one won't be in the table. Any ideas?

You have forgotten the var on the cycles variable, making it an accidental global. The inner call to getRowHTML overwrites the value of the global cycles in the outer call, making the outer loop end early.
Note you also have HTML-injection problems if any of the properties can contain HTML-special characters. You should HTML-escape any content being inserted into an HTML string. Or, to avoid having to think about that, use DOM methods to create the table instead. eg.
function fillRow(row, items, property) {
for (var i= 0, n= items.length; i<n; i++) {
var item= items[i];
var s= item[property];
if (property==='price')
s= addDots(s)+'\u20Ac'; // €
row.insertCell(-1).appendChild(document.createTextNode(s));
if (item.children)
fillRow(row, item.children, property);
}
}
function makeTable(data) {
var table= document.createElement('table');
var properties= ['size', 'price', 'type'];
for (var i= 0, n= properties.length; i<n; i++) {
var row= table.insertRow(-1);
row.className= i%2===0? 'odd' : 'even';
fillRow(row, data, properties[i]);
}
return table;
}

Related

DataTables - Export all columns in data, regardless of what's visible in the table

Using datatables jquery plugin, I've table that's been populated( created, actually ), upon success on ajax call. Here's sample code, where d is js variable with data:
if ( ! $.fn.DataTable.isDataTable( '#DataTables_Table_0' ) ) {
$('#DataTables_Table_0').DataTable ({
"data" : d,
"dom": "Blfrtip",
"searching": false,
"order": [],
"paging": false,
"columns" : [
{ "data" : "country" },
{ "data" : "round" },
{ "data" : "sector" },
{ "data" : "size" },
],
"columnDefs": [{
render: $.fn.dataTable.render.number(',', '.', 2)
}],
"buttons": [
{
extend: 'excelHtml5',
text: 'Excel',
customize: function( xlsx ) {
setSheetName(xlsx, 'Data');
addSheet(xlsx, '#DataTables_Table_1', 'Meta Data', 'Meta', '2');
}
},
"csv"
]
});
} else {
$('#DataTables_Table_0').dataTable().fnClearTable();
$('#DataTables_Table_0').dataTable().fnDestroy();
let tu = last_column_name;
$('#DataTables_Table_0').DataTable ({
"destroy": true,
"searching": false,
"order": [],
"paging": false,
"data" : current_table_data,
"dom": "Bfrtip",
"columns" : [
{ "data" : "country" },
{ "data" : "round" },
{ "data" : "sector" },
{ "data" : tu},
],
"buttons": [
{
extend: 'excelHtml5',
text: 'Excel',
customize: function( xlsx ) {
setSheetName(xlsx, 'Data');
addSheet(xlsx, '#DataTables_Table_1', 'Meta Data', 'Meta', '2');
}
},
"csv"
]
});
Aside from this, I'm also using buttons, to export my data to Excel and CSV. Everything works properly, I think, the only issue is that it only exports columns that are visible in the table, or actually defined.
What I want to do is to actually export all the columns that I passed along with data object, and not only those displayed in the table. Also, this was working until some time ago, until I changed the code. The problem is that I've changed much, and didn't really test export all that much, and when I did, didn't really think about columns in the exported doc.
If it changes anything, here's a tad more code, functions used in customize:
function getHeaderNames(table) {
// Gets header names.
//params:
// table: table ID.
//Returns:
// Array of column header names.
var header = $(table).DataTable().columns().header().toArray();
var names = [];
header.forEach(function(th) {
names.push($(th).html());
});
return names;
}
function buildCols(data) {
// Builds cols XML.
//To do: deifne widths for each column.
//Params:
// data: row data.
//Returns:
// String of XML formatted column widths.
var cols = '<cols>';
for ( var i=0; i<data.length; i++) {
var colNum = i + 1;
cols += '<col min="' + colNum + '" max="' + colNum + '" width="20" customWidth="1"/>';
}
cols += '</cols>';
return cols;
}
function buildRow(data, rowNum, styleNum) {
// Builds row XML.
//Params:
// data: Row data.
// rowNum: Excel row number.
// styleNum: style number or empty string for no style.
//Returns:
// String of XML formatted row.
var style = styleNum ? ' s="' + styleNum + '"' : '';
var row = '<row r="' + rowNum + '">';
if( rowNum > 2 ) {
data.shift();
}
for (var i=0; i<data.length; i++) {
var colNum = (i + 10).toString(36).toUpperCase(); // Convert to alpha
var cr = colNum + rowNum;
row += '<c t="inlineStr" r="' + cr + '"' + style + '>' +
'<is>' +
'<t>' + data[i] + '</t>' +
'</is>' +
'</c>';
}
row += '</row>';
return row;
}
function getTableData(table, title) {
// Processes Datatable row data to build sheet.
//Params:
// table: table ID.
// title: Title displayed at top of SS or empty str for no title.
//Returns:
// String of XML formatted worksheet.
var header = getHeaderNames(table);
var table = $(table).DataTable();
var rowNum = 1;
var mergeCells = '';
var ws = '';
ws += buildCols(header);
ws += '<sheetData>';
if (title.length > 0) {
ws += buildRow([title], rowNum, 51);
rowNum++;
var mergeCol = ((header.length - 1) + 10).toString(36).toUpperCase();
mergeCells = '<mergeCells count="1">'+
'<mergeCell ref="A1:' + mergeCol + '1"/>' +
'</mergeCells>';
}
ws += buildRow(header, rowNum, 2);
rowNum++;
// Loop through each row to append to sheet.
table.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
let secondtabledata = $('#DataTables_Table_1').DataTable();
var data = secondtabledata.data();
var tmp_arr = [];
$.each( data, function(k, v) {
tmp_arr.push( Object.values(v) );
});
// If data is object based then it needs to be converted
// to an array before sending to buildRow()
ws += buildRow(tmp_arr[rowNum-3], rowNum, '');
rowNum++;
} );
ws += '</sheetData>' + mergeCells;
return ws;
}
function setSheetName(xlsx, name) {
// Changes tab title for sheet.
//Params:
// xlsx: xlxs worksheet object.
// name: name for sheet.
if (name.length > 0) {
var source = xlsx.xl['workbook.xml'].getElementsByTagName('sheet')[0];
source.setAttribute('name', name);
}
}
function addSheet(xlsx, table, title, name, sheetId) {
//Clones sheet from Sheet1 to build new sheet.
//Params:
// xlsx: xlsx object.
// table: table ID.
// title: Title for top row or blank if no title.
// name: Name of new sheet.
// sheetId: string containing sheetId for new sheet.
//Returns:
// Updated sheet object.
//Add sheet2 to [Content_Types].xml => <Types>
//============================================
var source = xlsx['[Content_Types].xml'].getElementsByTagName('Override')[1];
var clone = source.cloneNode(true);
clone.setAttribute('PartName','/xl/worksheets/sheet2.xml');
xlsx['[Content_Types].xml'].getElementsByTagName('Types')[0].appendChild(clone);
//Add sheet relationship to xl/_rels/workbook.xml.rels => Relationships
//=====================================================================
var source = xlsx.xl._rels['workbook.xml.rels'].getElementsByTagName('Relationship')[0];
var clone = source.cloneNode(true);
clone.setAttribute('Id','rId3');
clone.setAttribute('Target','worksheets/sheet2.xml');
xlsx.xl._rels['workbook.xml.rels'].getElementsByTagName('Relationships')[0].appendChild(clone);
//Add second sheet to xl/workbook.xml => <workbook><sheets>
//=========================================================
var source = xlsx.xl['workbook.xml'].getElementsByTagName('sheet')[0];
var clone = source.cloneNode(true);
clone.setAttribute('name', name);
clone.setAttribute('sheetId', sheetId);
clone.setAttribute('r:id','rId3');
xlsx.xl['workbook.xml'].getElementsByTagName('sheets')[0].appendChild(clone);
//Add sheet2.xml to xl/worksheets
//===============================
var newSheet = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" mc:Ignorable="x14ac">'+
getTableData(table, title) +
'</worksheet>';
xlsx.xl.worksheets['sheet2.xml'] = $.parseXML(newSheet);
}
I couldn't really find an answer for this. Workable solution for this use-case is to actually add all the columns that exist in data object, and then just hide those I don't want displayed. This way, it's exporting the invisible columns, too.

Javascript object from string

I need to build an object string by string, and then use eval() to create the object.
I was successful doing this with an array of objects, but the next part, an object, is not working.
These three jsFiddles show the progression:
Chart with normal array (pieData) and object (pieOptions)
Chart with array formed of strings - works
Add object formed of strings - no work
There is considerable discussion about why I use eval(). The array and object used for data and options respectively are both formed bit-by-bit as strings, and then glomped together into an array and an object. This jsFiddle will demonstrate a (simpler) version of my problem:
http://jsfiddle.net/81fpdc44/3/
Please show me how to make s1...s5 into an array without using eval(). Am I missing something (not an uncommon situation...) ?
For Posterity: The code
Working (array):
<canvas id="pieChart" height="400" width="300"></canvas>
pieD = '{value:25, color:"red"},';
pieD += '{value:5, color:"blue"},';
pieD += '{value:25, color:"palegreen"},';
pieD += '{value:10, color:"darkcyan"},';
pieD += '{value:35, color:"wheat"}';
eval('pieData = ['+pieD+']');
var pieOptions = {
annotateDisplay : true,
segmentShowStroke : false,
segmentStrokeColor : "white",
segmentStrokeWidth : 1,
percentageInnerCutout : 0,
animation: false,
animationSteps : 100,
animationEasing : "easeOutQuart",
animateRotate : true,
animateScale : false,
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
var ctx = document.getElementById("pieChart").getContext("2d");
var myPieChart = new Chart(ctx).Pie(pieData,pieOptions);
Not working:
pieO = 'annotateDisplay : true,';
pieO += 'segmentShowStroke : false,';
pieO += 'segmentStrokeColor : "white",';
pieO += 'segmentStrokeWidth : 1,';
pieO += 'percentageInnerCutout : 0,';
pieO += 'animation: false,';
pieO += 'animationSteps : 100,';
pieO += 'animationEasing : "easeOutQuart",';
pieO += 'animateRotate : true,';
pieO += 'animateScale : false,';
pieO += 'legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"';
eval('pieOptions = {'+pieO+'}');
I have fixed this. The key was understanding that eval() must not ever be used, under any circumstances. (At my present skill level, at least)
Aside from the ajax injection, and JavaScript code being injected with it, here's what I was trying to do. I had these values in variables:
cu = 3;
py = 5;
fs = 7;
qz = 9;
ch = 11;
am = 13;
mi = 15;
mo = 17;
I had to create an array that was part text/part variable (I thought...). So, I tried this:
pDat = ['{value:'+cu+'}, {value:'+py+'}, {value:'+fs+'}, {value:'+qz+'}, {value:'+ch+'}, {value:'+am+'}, {value:'+mi+'}, {value:'+mo+'}'];
That didn't work. So I tried:
eval('pDat = [{value:'+cu+'}, {value:'+py+'}, {value:'+fs+'}, {value:'+qz+'}, {value:'+ch+'}, {value:'+am+'}, {value:'+mi+'}, {value:'+mo+'}']');
That worked for the array, but not for the object.
With the good advice from Vohuman, guest271314, epascarello and other good souls, I went back to the drawing board and refactored the code so that I could just do this:
(And it worked for everything - I was even able to add the variables with the color codes):
pDat = [{value:cu, color:CuCol}, {value:py, color:PyCol}, {value:fs, color:FsCol}, {value:qz, color:QzCol}, {value:ch, color:ChCol}, {value:am, color:AmCol}, {value:mi, color:MiCol}, {value:mo, color:MOCol}];
oOpt = {
annotateDisplay : true,
segmentShowStroke : false,
segmentStrokeColor : "white",
segmentStrokeWidth : 1,
percentageInnerCutout : 0,
animation: false,
animationSteps : 100,
animationEasing : "easeOutQuart",
animateRotate : true,
animateScale : false,
legendTemplate : '<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
};
var ctx = document.getElementById("pieChart").getContext("2d");
updateChart(ctx,pDat,pOpt,true,false);
Note:
FWIW, CuCol, PyCol etc are just vars that look like this:
CuCol = '#ffe382';
PyCol = '#1bb3a5';
etc
You are using eval for creating an array of objects:
s1 = '{value:25, color:"red"}';
s2 = '{value:5, color:"blue"}';
s3 = '{value:25, color:"palegreen"}';
s4 = '{value:10, color:"darkcyan"}';
s5 = '{value:35, color:"wheat"}';
var pieData = [ s1+s2+s3+s4+s5 ];
The above code snippet is a wrong way of doing this. Here you shouldn't create a string representation of an object (those are not valid JSON strings) when you need a real object. What you should do is:
var s1 = {value:25, color:"red"};
var s2 = {value:5, color:"blue"};
var s3 = {value:25, color:"palegreen"};
var s4 = {value:10, color:"darkcyan"};
var s5 = {value:35, color:"wheat"};
var pieData = [ s1, s2, s3, s4, s5 ];
Now pieData is an array of objects. Done!
Note, adjusted double quotes at <ul> string attributes to single quotes .
Try using String.prototype.split() , Array.prototype.map() , String.prototype.replace() with RegExp /(^[a-zA-Z]+)(?=\s|:)/g to match characters a-z case insensitive followed by space character or colon character ":" property of object string ; JSON.stringify() , JSON.parse()
pieO = 'annotateDisplay : true,';
pieO += 'segmentShowStroke : false,';
pieO += 'segmentStrokeColor : "white",';
pieO += 'segmentStrokeWidth : 1,';
pieO += 'percentageInnerCutout : 0,';
pieO += 'animation: false,';
pieO += 'animationSteps : 100,';
pieO += 'animationEasing : "easeOutQuart",';
pieO += 'animateRotate : true,';
pieO += 'animateScale : false,';
pieO += 'legendTemplate : "<ul class=\'<%=name.toLowerCase()%>-legend\'><% for (var i=0; i<segments.length; i++){%><li><span style=\'background-color:<%=segments[i].fillColor%>\'></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"'
pieO = pieO.split(",").map(function(val, index) {
val = val.replace(/(^[a-zA-Z]+)(?=\s|:)/g, function(match) {
return JSON.stringify(match)
});
return JSON.parse("{" + val + "}")
});
console.log(pieO)

DataTable with JS Source

I'm trying to generate some data with Sage Sdata using javascript and after that handle that data with datatables plugin but I'm getting error:
DataTables warning: table id=example - Requested unknown parameter '1' for row 0. For more information about this error, please see http://datatables.net/tn/4
if(aNode2)
{
resultTextData += '[';
resultTextData += "'" + aNode1.nodeValue + "'";
resultTextData += ',';
resultTextData += "'" + aNode2.nodeValue + "'";
resultTextData += ',';
resultTextData += "'" + aNode3.nodeValue + "'";
resultTextData += ']';
resultTextData += ',';
}
var dataSet = resultTextData ;
console.log(dataSet);
$('#example').dataTable({
"data": dataSet,
"aoColumns": [
{ "aDataSort": [ 0, 1 ] },
{ "aDataSort": [ 1, 0 ] },
{ "aDataSort": [ 2, 3 ] }
]
});
the data option doesn't not accept string inputs. See https://datatables.net/reference/option/data
DataTables support loading from json-encoded string.
Here is Example of converting XML result to array.
function FormatDataByIolist($data,$IOlist) {
$returnAray = array();
$RecordCount = count($data);
for($i = 0; $i < $RecordCount; $i++) {
$tmpSingleRow = array();
foreach($IOlist as $colName) {
$columVal = (string)$data[$i]->$colName;
$tmpSingleRow[$colName] = $columVal;
}
array_push($returnAray,$tmpSingleRow);
unset($tmpSingleRow);
}
return $returnAray;
}
After it you need to convert array to json_encoded string that DataTable can understand.
$formatted = '{ "data": '.json_encode($returnAray).'}';
After writing this in backend you need to add following row in your datatable definition
"ajax": "your.php?action=getJson"
your.php?action=getJson Method should be GET and should return formatted json-string ( as shown ).
I thnik, this repository will help you to work with SData. ( It is model for working with SData )
https://github.com/AramKocharyan/Sage-SData

Jquery TypeError: a is undefined when trying to dynamically create table

Im new to Jquery and have been trying to get some code working for dynamically creating a table. In doing so i have come up with an issue.
I have a web service that will respond in JSON the data looks like this (sample)
{
"aaData": [
1
],
"aaSorting": [
1,
"desc"
],
"aoColumns": {
"sTitle": "Title1"
}
}
The entire java script is bellow
`
$(document).ready
(
function()
{
$.getJSON
(
'http://intranet/testing/data/public.php', function(data)
{
var newTable = '<thead><tr>';
$.each
(
data[0], function(key, value)
{
newTable += "<th>" + key + "</th>";
}
);
newTable += "</tr></thead><tbody>";
$.each
(
data, function(key, row)
{
newTable += "<tr>";
$.each
(
row, function(key, fieldValue)
{
newTable += "<td>" + fieldValue + "</td>";
}
);
newTable += "</tr>";
}
);
newTable += '<tbody>';
$('#example').html(newTable);
}
);
$('#example').dataTable();
}
);
</script>`
Would appreciate some help in fixing this.

Create table with jQuery - append

I have on page div:
<div id="here_table"></div>
and in jquery:
for(i=0;i<3;i++){
$('#here_table').append( 'result' + i );
}
this generating for me:
<div id="here_table">
result1 result2 result3 etc
</div>
I would like receive this in table:
<div id="here_table">
<table>
<tr><td>result1</td></tr>
<tr><td>result2</td></tr>
<tr><td>result3</td></tr>
</table>
</div>
I doing:
$('#here_table').append( '<table>' );
for(i=0;i<3;i++){
$('#here_table').append( '<tr><td>' + 'result' + i + '</td></tr>' );
}
$('#here_table').append( '</table>' );
but this generate for me:
<div id="here_table">
<table> </table> !!!!!!!!!!
<tr><td>result1</td></tr>
<tr><td>result2</td></tr>
<tr><td>result3</td></tr>
</div>
Why? how can i make this correctly?
LIVE: http://jsfiddle.net/n7cyE/
This line:
$('#here_table').append( '<tr><td>' + 'result' + i + '</td></tr>' );
Appends to the div#here_table not the new table.
There are several approaches:
/* Note that the whole content variable is just a string */
var content = "<table>"
for(i=0; i<3; i++){
content += '<tr><td>' + 'result ' + i + '</td></tr>';
}
content += "</table>"
$('#here_table').append(content);
But, with the above approach it is less manageable to add styles and do stuff dynamically with <table>.
But how about this one, it does what you expect nearly great:
var table = $('<table>').addClass('foo');
for(i=0; i<3; i++){
var row = $('<tr>').addClass('bar').text('result ' + i);
table.append(row);
}
$('#here_table').append(table);
Hope this would help.
You need to append the tr inside the table so I updated your selector inside your loop and removed the closing table because it is not necessary.
$('#here_table').append( '<table />' );
for(i=0;i<3;i++){
$('#here_table table').append( '<tr><td>' + 'result' + i + '</td></tr>' );
}
The main problem was that you were appending the tr to the div here_table.
Edit: Here is a JavaScript version if performance is a concern. Using document fragment will not cause a reflow for every iteration of the loop
var doc = document;
var fragment = doc.createDocumentFragment();
for (i = 0; i < 3; i++) {
var tr = doc.createElement("tr");
var td = doc.createElement("td");
td.innerHTML = "content";
tr.appendChild(td);
//does not trigger reflow
fragment.appendChild(tr);
}
var table = doc.createElement("table");
table.appendChild(fragment);
doc.getElementById("here_table").appendChild(table);
When you use append, jQuery expects it to be well-formed HTML (plain text counts). append is not like doing +=.
You need to make the table first, then append it.
var $table = $('<table/>');
for(var i=0; i<3; i++){
$table.append( '<tr><td>' + 'result' + i + '</td></tr>' );
}
$('#here_table').append($table);
Or do it this way to use ALL jQuery. The each can loop through any data be it DOM elements or an array/object.
var data = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'];
var numCols = 1;
$.each(data, function(i) {
if(!(i%numCols)) tRow = $('<tr>');
tCell = $('<td>').html(data[i]);
$('table').append(tRow.append(tCell));
});
​
http://jsfiddle.net/n7cyE/93/
To add multiple columns and rows, we can also do a string concatenation. Not the best way, but it sure works.
var resultstring='<table>';
for(var j=0;j<arr.length;j++){
//array arr contains the field names in this case
resultstring+= '<th>'+ arr[j] + '</th>';
}
$(resultset).each(function(i, result) {
// resultset is in json format
resultstring+='<tr>';
for(var j=0;j<arr.length;j++){
resultstring+='<td>'+ result[arr[j]]+ '</td>';
}
resultstring+='</tr>';
});
resultstring+='</table>';
$('#resultdisplay').html(resultstring);
This also allows you to add rows and columns to the table dynamically, without hardcoding the fieldnames.
Here is what you can do: http://jsfiddle.net/n7cyE/4/
$('#here_table').append('<table></table>');
var table = $('#here_table').children();
for(i=0;i<3;i++){
table.append( '<tr><td>' + 'result' + i + '</td></tr>' );
}
Best regards!
Following is done for multiple file uploads using jquery:
File input button:
<div>
<input type="file" name="uploadFiles" id="uploadFiles" multiple="multiple" class="input-xlarge" onchange="getFileSizeandName(this);"/>
</div>
Displaying File name and File size in a table:
<div id="uploadMultipleFilediv">
<table id="uploadTable" class="table table-striped table-bordered table-condensed"></table></div>
Javascript for getting the file name and file size:
function getFileSizeandName(input)
{
var select = $('#uploadTable');
//select.empty();
var totalsizeOfUploadFiles = "";
for(var i =0; i<input.files.length; i++)
{
var filesizeInBytes = input.files[i].size; // file size in bytes
var filesizeInMB = (filesizeInBytes / (1024*1024)).toFixed(2); // convert the file size from bytes to mb
var filename = input.files[i].name;
select.append($('<tr><td>'+filename+'</td><td>'+filesizeInMB+'</td></tr>'));
totalsizeOfUploadFiles = totalsizeOfUploadFiles+filesizeInMB;
//alert("File name is : "+filename+" || size : "+filesizeInMB+" MB || size : "+filesizeInBytes+" Bytes");
}
}
Or static HTML without the loop for creating some links (or whatever). Place the <div id="menu"> on any page to reproduce the HTML.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML Masterpage</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript">
function nav() {
var menuHTML= '<ul><li>link 1</li></ul><ul><li>link 2</li></ul>';
$('#menu').append(menuHTML);
}
</script>
<style type="text/css">
</style>
</head>
<body onload="nav()">
<div id="menu"></div>
</body>
</html>
I wrote rather good function that can generate vertical and horizontal tables:
function generateTable(rowsData, titles, type, _class) {
var $table = $("<table>").addClass(_class);
var $tbody = $("<tbody>").appendTo($table);
if (type == 2) {//vertical table
if (rowsData.length !== titles.length) {
console.error('rows and data rows count doesent match');
return false;
}
titles.forEach(function (title, index) {
var $tr = $("<tr>");
$("<th>").html(title).appendTo($tr);
var rows = rowsData[index];
rows.forEach(function (html) {
$("<td>").html(html).appendTo($tr);
});
$tr.appendTo($tbody);
});
} else if (type == 1) {//horsantal table
var valid = true;
rowsData.forEach(function (row) {
if (!row) {
valid = false;
return;
}
if (row.length !== titles.length) {
valid = false;
return;
}
});
if (!valid) {
console.error('rows and data rows count doesent match');
return false;
}
var $tr = $("<tr>");
titles.forEach(function (title, index) {
$("<th>").html(title).appendTo($tr);
});
$tr.appendTo($tbody);
rowsData.forEach(function (row, index) {
var $tr = $("<tr>");
row.forEach(function (html) {
$("<td>").html(html).appendTo($tr);
});
$tr.appendTo($tbody);
});
}
return $table;
}
usage example:
var title = [
'مساحت موجود',
'مساحت باقیمانده',
'مساحت در طرح'
];
var rows = [
[number_format(data.source.area,2)],
[number_format(data.intersection.area,2)],
[number_format(data.deference.area,2)]
];
var $ft = generateTable(rows, title, 2,"table table-striped table-hover table-bordered");
$ft.appendTo( GroupAnalyse.$results );
var title = [
'جهت',
'اندازه قبلی',
'اندازه فعلی',
'وضعیت',
'میزان عقب نشینی',
];
var rows = data.edgesData.map(function (r) {
return [
r.directionText,
r.lineLength,
r.newLineLength,
r.stateText,
r.lineLengthDifference
];
});
var $et = generateTable(rows, title, 1,"table table-striped table-hover table-bordered");
$et.appendTo( GroupAnalyse.$results );
$('<hr/>').appendTo( GroupAnalyse.$results );
example result:
A working example using the method mentioned above and using JSON to represent the data. This is used in my project of dealing with ajax calls fetching data from server.
http://jsfiddle.net/vinocui/22mX6/1/
In your html:
< table id='here_table' >< /table >
JS code:
function feed_table(tableobj){
// data is a JSON object with
//{'id': 'table id',
// 'header':[{'a': 'Asset Tpe', 'b' : 'Description', 'c' : 'Assets Value', 'd':'Action'}],
// 'data': [{'a': 'Non Real Estate', 'b' :'Credit card', 'c' :'$5000' , 'd': 'Edit/Delete' },... ]}
$('#' + tableobj.id).html( '' );
$.each([tableobj.header, tableobj.data], function(_index, _obj){
$.each(_obj, function(index, row){
var line = "";
$.each(row, function(key, value){
if(0 === _index){
line += '<th>' + value + '</th>';
}else{
line += '<td>' + value + '</td>';
}
});
line = '<tr>' + line + '</tr>';
$('#' + tableobj.id).append(line);
});
});
}
// testing
$(function(){
var t = {
'id': 'here_table',
'header':[{'a': 'Asset Tpe', 'b' : 'Description', 'c' : 'Assets Value', 'd':'Action'}],
'data': [{'a': 'Non Real Estate', 'b' :'Credit card', 'c' :'$5000' , 'd': 'Edit/Delete' },
{'a': 'Real Estate', 'b' :'Property', 'c' :'$500000' , 'd': 'Edit/Delete' }
]};
feed_table(t);
});
As for me, this approach is prettier:
String.prototype.embraceWith = function(tag) {
return "<" + tag + ">" + this + "</" + tag + ">";
};
var results = [
{type:"Fiat", model:500, color:"white"},
{type:"Mercedes", model: "Benz", color:"black"},
{type:"BMV", model: "X6", color:"black"}
];
var tableHeader = ("Type".embraceWith("th") + "Model".embraceWith("th") + "Color".embraceWith("th")).embraceWith("tr");
var tableBody = results.map(function(item) {
return (item.type.embraceWith("td") + item.model.toString().embraceWith("td") + item.color.embraceWith("td")).embraceWith("tr")
}).join("");
var table = (tableHeader + tableBody).embraceWith("table");
$("#result-holder").append(table);
i prefer the most readable and extensible way using jquery.
Also, you can build fully dynamic content on the fly.
Since jquery version 1.4 you can pass attributes to elements which is, imho, a killer feature.
Also the code can be kept cleaner.
$(function(){
var tablerows = new Array();
$.each(['result1', 'result2', 'result3'], function( index, value ) {
tablerows.push('<tr><td>' + value + '</td></tr>');
});
var table = $('<table/>', {
html: tablerows
});
var div = $('<div/>', {
id: 'here_table',
html: table
});
$('body').append(div);
});
Addon: passing more than one "html" tag you've to use array notation like:
e.g.
var div = $('<div/>', {
id: 'here_table',
html: [ div1, div2, table ]
});
best Rgds.
Franz
<table id="game_table" border="1">
and Jquery
var i;
for (i = 0; ii < 10; i++)
{
var tr = $("<tr></tr>")
var ii;
for (ii = 0; ii < 10; ii++)
{
tr.append(`<th>Firstname</th>`)
}
$('#game_table').append(tr)
}
this is most better
html
<div id="here_table"> </div>
jQuery
$('#here_table').append( '<table>' );
for(i=0;i<3;i++)
{
$('#here_table').append( '<tr>' + 'result' + i + '</tr>' );
for(ii=0;ii<3;ii++)
{
$('#here_table').append( '<td>' + 'result' + i + '</tr>' );
}
}
$('#here_table').append( '</table>' );
It is important to note that you could use Emmet to achieve the same result. First, check what Emmet can do for you at https://emmet.io/
In a nutshell, with Emmet, you can expand a string into a complexe HTML markup as shown in the examples below:
Example #1
ul>li*5
... will produce
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
Example #2
div#header+div.page+div#footer.class1.class2.class3
... will produce
<div id="header"></div>
<div class="page"></div>
<div id="footer" class="class1 class2 class3"></div>
And list goes on. There are more examples at https://docs.emmet.io/abbreviations/syntax/
And there is a library for doing that using jQuery. It's called Emmet.js and available at https://github.com/christiansandor/Emmet.js
Here the below code helps to generate responsive html table
#javascript
(function($){
var data = [{
"head 1": "row1 col 1",
"head 2": "row1 col 2",
"head 3": "row1 col 3"
}, {
"head 1": "row2 col 1",
"head 2": "row2 col 2",
"head 3": "row2 col 3"
}, {
"head 1": "row3 col 1",
"head 2": "row3 col 2",
"head 3": "row3 col 3"
}];
for (var i = 0; i < data.length; i++) {
var accordianhtml = "<button class='accordion'>" + data[i][small_screen_heading] + "<span class='arrow rarrow'>→</span><span class='arrow darrow'>↓</span></button><div class='panel'><p><table class='accordian_table'>";
var table_row = null;
var table_header = null;
for (var key in data[i]) {
accordianhtml = accordianhtml + "<tr><th>" + key + "</th><td>" + data[i][key] + "</td></tr>";
if (i === 0 && true) {
table_header = table_header + "<th>" + key + "</th>";
}
table_row = table_row + "<td>" + data[i][key] + "</td>"
}
if (i === 0 && true) {
table_header = "<tr>" + table_header + "</tr>";
$(".mv_table #simple_table").append(table_header);
}
table_row = "<tr>" + table_row + "</tr>";
$(".mv_table #simple_table").append(table_row);
accordianhtml = accordianhtml + "</table></p></div>";
$(".mv_table .accordian_content").append(accordianhtml);
}
}(jquery)
Here we can see the demo responsive html table generator
let html = '';
html += '<table class="tblWay" border="0" cellpadding="5" cellspacing="0" width="100%">';
html += '<tbody>';
html += '<tr style="background-color:#EEEFF0">';
html += '<td width="80"> </td>';
html += '<td><b>Shipping Method</b></td>';
html += '<td><b>Shipping Cost</b></td>';
html += '<td><b>Transit Time</b></td>';
html += '</tr>';
html += '</tbody>';
html += '</table>';
$('.product-shipping-more').append(html);

Categories

Resources