I'm working to a homework and I wrote the frontend in html, css, javascript. Till now when I press a button I get some data from backend and in javascript a parse the response. The response is an array of items. An item is a structure. What I want it's to build dynamically a list of those items. I didn't find on google a way of doing that with javascript. Some hints/help?
What I tried, you can see below, is to append some HTML to an HTML element - it didn't work.
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
source.value = "";
destination.value = "";
var array_rides = JSON.parse(this.responseText).results;
var rides_length = array_rides.length;
for (var i = 0;i < rides_length;i++) {
console.log(array_rides[i][DRIVER]);
console.log(array_rides[i][RIDERS]);
console.log(array_rides[i][SOURCE]);
console.log(array_rides[i][DESTINATION]);
console.log(array_rides[i][START]);
console.log(array_rides[i][SEATS_AVAILABLE]);
console.log(array_rides[i][SEATS_TOTAL]);
my_list.append('<span class="name">{0}</span>'.format(array_rides[i][DRIVER]));
}
}
};
So, I want a list which is dynamically populated.
Something like (table ish):
array_rides[0][DRIVER], array_rides[0][RIDERS], ...
array_rides[1][DRIVER], array_rides[1][RIDERS], ...
...
array_rides[n][DRIVER], array_rides[n][RIDERS], ...
which, of cours, to inherit some css.
I assume a list in the document, like a product table or something.
The easiest way to do this is by just looping through your list and inserting it into a table or something. An example could be this:
function somefunc() {
var table = document.getElementById('my_table');
var array_rides = ['cell1', 'cell2', 'cell3', 'cell4'];
var string;
string = "<table>";
for (var i = 0;i < array_rides.length;i++) {
//add table row
string += "<tr>";
//add all items in tabel cells
//you just have to replace the array_rides[i] with array_rides[i].DRIVER, array_rides[i].RIDERS... and so on
string += "<td>"+array_rides[i]+"</td>";
string += "<td>"+array_rides[i]+"</td>";
string += "<td>"+array_rides[i]+"</td>";
string += "<td>"+array_rides[i]+"</td>";
string += "<td>"+array_rides[i]+"</td>";
string += "<td>"+array_rides[i]+"</td>";
//close table row
string += "</tr>";
}
string += "</table>";
table.innerHTML = string;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Testpage</title>
</head>
<body onload="somefunc();">
<div id="my_table"></div>
</body>
</html>
basically what this does is take all the data from the array and append them to a table.
You could add some CSS too to make it look nicer
Related
This question already has answers here:
Google script - using template to build table
(1 answer)
Passing variable to HTML output and then into a scriptlet
(1 answer)
Closed 2 years ago.
I have data in a sheet in this format which has to be presented in a tabular form inside an HTML Page
I am using Google App Script for achieving the same. The below code is for trying out this option and if this works, I will fit the code into my original HTML Page.
All other things are working fine except the excel data is not coming into the HTML page. I am able to form the table equal to the length of the data but the information inside it is not coming. I have checked the javascript code independently and the data is being fetched to the code, but it is not appearing in the HTML Code.
I have written the following HTML code
<!DOCTYPE HTML>
<HTML>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
</style>
</head>
<body>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
</tr>
<? for (var i=0; i<defintion_s_no.length;i++) {?>
<tr>
<th><?defintion_s_no[i]; ?></th>
<th> 1 </th>
</tr>
<? }?>
</table>
</body>
</html>
and the following javascript code for the same
var url = 'https://docs.google.com/spreadsheets/d/1CGZVG6NGAy325wgCz-dS6ZjJ_it5ShzLshIdD-CCpqs/edit';
function doGet(e){
return definition();
}
function defintion() {
var ss = SpreadsheetApp.openByUrl(url);
var webAppSheet = ss.getSheetByName("Datafeed");
var defintion_s_no = data_till_lastrow_coulmn("Description");
var tmp = HtmlService.createTemplateFromFile('try');
tmp.defintion_s_no = defintion_s_no.map(function(r){ return r[0]; });
return tmp.evaluate().setTitle('Daily Task Updater');
}
function data_till_lastrow_coulmn(key) {
//get the data till the last row of a specified column using the key to find the header of the column
var ss = SpreadsheetApp.openByUrl(url);
var webAppSheet = ss.getSheetByName("Datafeed");
var last_row = webAppSheet.getLastRow();
var header_values = webAppSheet.getRange(1,1,1,15).getValues()[0];
var dropdown_column = 0;
//find the column of the "key" in the header row
for (var i=0; i<15; i++){
if(header_values[i]==key){
dropdown_column = i+1;
}
}
//finding the last row in the column containing key as the header
var workstream_Values = webAppSheet.getRange(2,dropdown_column,last_row,1).getValues();
var dropdown_lastrow = 0;
var blank = false;
for (var i=0;i<last_row;i++){
if(workstream_Values[i+1]==""&& !blank){
dropdown_lastrow = i+1;
blank = true;
break;
}
else if(workstream_Values[i] != ""){
blank = false;
}
}
return webAppSheet.getRange(2,dropdown_column,dropdown_lastrow,1).getValues();
}
I am unable to see the data here
A javascript array (jArray) has 5 elements.
I pass them into the HTML array (hArray).
Now, I want to drag elements out of hArray (let's say number 10) into the hFrame.
This last one is not working.
That is the problem is how we make draggable elements of an html variable
produced by an javascript array. The examples I have found regard a fixed number of elements, predefined in html. Here is about a sequence of words, of uknown length, produced by javascript.
Thank you all of you in advance.
<!-- THIS IS THE FRAME TO SEND THE DRAGGABLE ELEMENTS -->
<div id="hFrame";
style="text-align: left;
border:1px solid white;
width: 350px;
height: 200px;
padding: 10px";
ondrop= "drop(event)";
ondragover= "allowDrop(event)"></div>
<!-- THIS IS THE HTML VARIABLE hArray -->
<div id="hArray"></div>
<!-- THESE ARE THE FUNCTIONS FOR DRAGGING -->
<script>
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
function allowDrop(ev) {
ev.preventDefault();
}
</script>
<!-- THIS IS THE SCRIPT FOR PRODUCING THE jArray WHICH PASSES ITS ELEMENTS TO hArray -->
<script>
class Array {
constructor(){
this.length=0;
this.data={};
}
push(element){
this.data[this.length]=element;
this.length++;
return this.length
}
getElementAtIndex(index){
return this.data[index];
}
}
//pushing element
const jArray= new Array();
jArray.push(12);
jArray.push(13);
jArray.push(14);
jArray.push(10);
jArray.push(989);
for (var y=0; y< jArray.length; y++) {
document.getElementById("hArray").innerHTML += jArray.getElementAtIndex(y) + " ";
}
</script>
You need to add a few things:
Set ondragstart event for draggable item
Set attribute draggable as true
Define attribute id for draggable item
So, you loop should be like this:
for (var y=0; y< jArray.length; y++) {
document.getElementById("hArray").innerHTML += '<span draggable="true" ondragstart="drag(event)" id=' + y + '>' + jArray.getElementAtIndex(y) + "</span> " ;
}
See my full example in sandbox:
https://jsfiddle.net/denisstukalov/73zntmvd/29/#&togetherjs=tVJr9JjkUn
For a task I need to display a list of albums' titles and all the songs. But I'm stuck only getting the first song to display for each album. How do I display them all? I assume I need to change the index value but I'm not sure how to write it to get all the values. My code is below.
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
</style>
<script>
function loadDoc() {
// This function will load the xml file and connect it to the webpage
var xhttp = new XMLHttpRequest();
// This is used to exchange data with the server, allowing for parts of the page to change without reloading the page
xhttp.onreadystatechange = function() {
// This defines a function to be called when the readystate property changes
if (this.readyState == 4 && this.status == 200) {
// This states that if the request is finished (readystate == 4) and the status returned is ok (this.staus == 200)
extractSongs(this);
// This runs the function to display the data from the xml file
}
};
xhttp.open("GET", "CDLibrary.xml", true);
// This gets the xml file
xhttp.send();
// This sends a request to the server
}
function extractSongs(xml) {
// This function will extract and display data from the xml file
var i;
var xmlDoc = xml.responseXML;
// This returns the document containg a response to my request
var table="<tr><th>Artist</th><th>Title</th></tr>";
// This sets up the table
var CdList = xmlDoc.getElementsByTagName("CD");
// This creates an array of the data from the xml file
for (i = 0; i <CdList.length; i++) {
// This will loop through the array by the number of cds in the array
table += "<tr><td>" +
CdList[i].getElementsByTagName("title")[0].childNodes[0].nodeValue +
"</td><td>" +
CdList[i].getElementsByTagName("track")[0].childNodes[0].nodeValue +
"</td></td>" ;
// These display the elements by the tag name and generate them as table data
}
document.getElementById("CdCollection").innerHTML = table;
// This gets the table from the html and makes it equal to the table from the javascript
}
</script>
</head>
<body>
<h1>My CD Collection</h1>
<button type="button" onclick="loadDoc()">Get my collection</button>
<br><br>
<table id="CdCollection"></table>
</body>
I'm guessing you need a 2nd for loop for the for the title/track:-
for (i = 0; i < CdList.length; i++) {
var titleCount = CdList[i].getElementsByTagName("title").length;
for (j = 0; j < titleCount; j++){
// This will loop through the array by the number of cds in the array
table += "<tr><td>" +
CdList[i].getElementsByTagName("title")[j].childNodes[0].nodeValue +
"</td><td>" +
CdList[i].getElementsByTagName("track")[j].childNodes[0].nodeValue +
"</td></td>";
// These display the elements by the tag name and generate them as table data
}
}
I'm trying to create a table using javascript. The number of rows is inserted by the user using this form.I don't know how to output this table correctly.Tried this but i think i have a problem inside the javascript code.Can someone please show me how to output a table where the number of rows is inserted in this form?
Here is my code
<html>
<head>
<title>
</title>
</head>
<body>
<form name="table" id="hey">
Insert nr of rows <input type="text"/>
</form>
<script>
var nr=document.getElementById("hey");
var c=parseInt("nr");
for(int i=0;i<c;i++){
print("<table><tr><td></td></tr></table>");
}
</script>
</script>
</body>
</html>
You had an error in your for loop, you had:
for(int i=0;i<c;i++){
print("<table><tr><td></td></tr></table>");
}
This should be:
for(i=0;i<c;i++){
print("<table><tr><td></td></tr></table>");
}
As for your actual problem, you could try doing it like this:
HTML
Insert number of rows
<input type="text" id="hey" />
<input type="button" value="Generate table" id="btnShow">
<div id="container"></div>
CSS
#container {
height:50vh;
width:50vw;
background-color:#eee;
}
JavaScript
//Event listener for the button.
document.getElementById ("btnShow").addEventListener ("click", generateTable, false);
//Function generating the table.
function generateTable() {
//Get the value the user gave
var nr = document.getElementById("hey").value;
//Make it an Int
var c = parseInt(nr);
//Get the div containing the table
var div = document.getElementById("container");
//Write the table
div.innerHTML += "<table border='1' id='table'>";
for (i = 0; i < c; i++) {
//Write the rows and cells
document.getElementById('table').innerHTML += "<tr><td>One</td><td>Two</td></tr>"
}
}
JsFiddle
EDIT
I've updated the code to clear the div before adding rows a second time.
Updated fiddle
JavaSript
//Event listener for the button.
document.getElementById ("btnShow").addEventListener ("click", generateTable, false);
//Function generating the table.
function generateTable() {
//Get the value the user gave
var nr = document.getElementById("hey").value;
//Make it an Int
var c = parseInt(nr);
//Get the div containing the table
var div = document.getElementById("container");
//Clear the container div <----------- Note this
div.innerHTML = " ";
//Write the table
div.innerHTML += "<table border='1' id='table'>";
for (i = 0; i < c; i++) {
//Write the rows and cells
document.getElementById('table').innerHTML += "<tr><td>One</td><td>Two</td></tr>"
}
}
Hope this helps!
This is what a proper table should look like.
< table > /*this is the table that will contain all of the rows and table data */
< tr > /* this stands for table row */
< td > /* this stands for table data which is inside the row. You can think of these as columns */
< / td >
< td >
< / td >
< / tr >
< / table >
You do not need all of the extra coding unless you are trying to do something very specific.
Here i have an initial table which i have created using rcm.create() method.Then i have to create another in which rows will will be ordered according to the descending summation of the rows from first table.That means the row having higher sum will be placed first in second table.For creating the second table i have rcm.generateTab2() method .Which works as following;
1.call rcm.create() method to create the second table.
2.create the sum of each rows from first table and push it inside a rank array which contains an array of objects.
3.rank array is sorted according to descending value
now rank array contains object with three element.
first td value from each row.
sum of rows
and the complete row which will be used to insert rows in tbody of second table
4.tbody element from second table is deleted.
5.then created a new one and attempted to insert sorted rows form table 1 to table 2.
but all i am getting is table 2 is pushed above table 1 in browser and no rows are inserted.
full code : jsfiddle
main problem is inside rcm.generateTab2 method.So i am posting it here separately .
rcm.generateTab2 method:
generateTab2:function(){
var power=0;
this.create(machine,process); //create the second table
var tbody=document.getElementsByTagName('tbody')[0];
var trow=tbody.getElementsByTagName('tr');
for(i=0;i<trow.length;i++){ //get summation
var td=trow[i].getElementsByTagName('td');
var sum=0;
for(j=td.length-1;j>0;j--){
if(td[j].innerHTML==''){
sum+=0*Math.pow(2,power);
}else{
sum+=parseInt(td[j].innerHTML)*Math.pow(2,power);
}
power++;
}
var first=parseInt(td[0].innerHTML);
rank.push({rowNo:first,sum:sum,row:trow[i]}); //pushed to rank array
power=0;
}
rank.sort(function (a,b){ //rank array is sorted
if(a.sum>b.sum){
return -1;
}else if(a.sum<b.sum){
return 1;
}else{
return 0;
}
});
console.log(rank);
var parent=document.getElementsByTagName('table')[1];
parent.removeChild(parent.childNodes[1]);//delete existing tbody from second table
var newTbody=document.createElement('tbody'); //create a new tbody
parent.appendChild(newTbody); //append it to second table
for(i=0;i<rank.length;i++){
newTbody.appendChild(rank[i].row); //insert rows to tbody of second table
}
}
Not sure if I've understood the ranking math correctly.
Please have a look at the demo below and here at jsfiddle.
I've re-coded your js because I've thought that's easier. (But if you don't like using jQuery, I could have a look at your code and check if I can find the issue.)
I'm using these js libs:
jQuery for DOM manipulation
Underscore for array creation with _.range (could be also done with a for loop, so Underscore is not really needed)
Tinysort jQuery plugin for sorting the table
For the sorting I've added the sorting rank (sum of the row) as data attribute to each row so tinysort can use this to order the table.
The CSS here at SO is a bit different then at jsFiddle (not centered text) in table header. Not sure why.
The default values (3 & 2) in the form inputs is just for easier debugging. Just remove the value attribute from the inputs later.
Update 07.04.2015
I've found the issue with your code. The problem was that you've stored the reference to table1 inside your rank object. The tr elements in the object.
So you've overriden the table1 because of that reference.
You can fix this with using rank[i].row.cloneNode(true) to clone the contents of the row. Then you can append it to your new table with-out the problem.
See the updated fiddle here.
var ROC = {
init: function (element) {
this.$el = $(element);
this.$table1wrap = $('<div/>').attr('id', 'table1wrapper');
this.$table2wrap = $('<div/>').attr('id', 'table2wrapper');
this.$el.append([this.$table1wrap, this.$table2wrap]);
},
create: function (machine, process) {
var self = this,
$tableHeading = $('<tr/>'),
$table = $('<table/>').attr('id', 'mainTable');
this.$table1wrap.html($table.append($('<thead/>').html($tableHeading)));
this.processes = this.createCols(process);
this.machines = this.createRows(machine);
//var addRow = function() {
// this.$el.append($('tr').html(this.processes));
//this.$el.append($('<tr/>').html($('<td/>').text('test')));
$(this.machines).each(function (index, row) {
//console.log(index, $(row));
var $curRow = $(row);
//console.log($tableHeading.length);
$(self.processes).each(function (i, col) {
if (index == 0) {
var letter = String.fromCharCode(97 + i).toUpperCase();
if (i == 0) $tableHeading.append($('<th/>').text('~'));
$tableHeading.append($('<th/>').text(letter));
}
//console.log(i, $(col));
// self.$el.append(($(row).clone()).html($(col).clone()));
if (i == 0) $curRow.append($('<td/>')
.text(index + 1)
.addClass('rowIndex'));
$curRow.append($(col).attr('contentEditable', 'true'));
});
$table.append($curRow.clone());
});
//console.log(this.processes, this.machines);
},
createCols: function (cols) {
var rCols = _.range(cols).map(function (num, index) {
return $('<td/>').text(0);
}); // [td, td, ...];
return rCols;
},
createRows: function (rows) {
var rRows = _.range(rows).map(function (num, index) {
return $('<tr/>');
}); // [tr, tr, ...];
return rRows;
},
copy: function (sel) {
//console.log($(sel));
var $newTable = $(sel).clone().attr('id', 'copy');
var $sortedBody = $($newTable)
.find('tbody')
.html(this.calcRank($newTable));
//console.log($sortedBody, this.calcRank($newTable));
//console.log('sorted', $sortedTable);
$(this.$table2wrap).html($($newTable, 'tbody').append($sortedBody));
},
calcRank: function (newTable) {
var sum, $col;
newTable.find('tr').each(function (index, item) {
//console.log(index, $(item).children());
$col = $(item).children();
sum = 0;
if (index > 0) { // skip heading
$col.each(function (i, cell) {
if (i > 0) sum += parseInt($(cell).text()); // skip first col
});
$(item).attr('data-rank', sum);
}
//console.log(index, sum, $(item));
//$(item).attr('data-rank', sum);
});
//console.log($(newTable));
return tinysort($(newTable).find('tbody>tr'), {
attr: 'data-rank',
order: 'desc'
});
},
reset: function () {
this.$table1wrap.empty();
this.$table2wrap.empty();
}
};
ROC.init('#out');
$('#btnCreate').click(function () {
var proc = $('#process').val(),
machine = $('#machine').val();
ROC.create(machine, proc);
});
$('#btnCreate2').click(function () {
ROC.copy('#mainTable');
});
$('#btnRst').click(function () {
ROC.reset();
});
body {
padding: 1em;
}
input[type='number'] {
background:lightblue;
color:crimson;
margin-left:20px;
}
table {
border-collapse: initial !important;
border-spacing: 10px !important;
}
th {
background:black;
color:white;
width:40px;
height:40px;
border:1px solid white;
text-align:center;
box-shadow:0px 0px 7px black;
}
td {
box-shadow:0px 0px 7px black;
background:white;
width:40px;
height:40px;
border:1px solid black;
text-align:center;
}
td.rowIndex {
background: black;
color: white;
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.1.1/tinysort.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Rank Order Clustering</h1>
<fieldset>
<legend style='font-size:30px;background:lightblue;'>insert items</legend>
<label for='process'>process :</label>
<input type='number' id='process' placeholder='processes' value="3" />
<br/>
<label for='machine'>machines :</label>
<input type='number' id='machine' placeholder='machines' value="2" />
<br/>
<input type='button' value='create table' id='btnCreate' />
<input type='button' value=' reset' id='btnRst' />
<input type='button' value='generate table2' id='btnCreate2' />
</fieldset>
<div id="out"></div>