Description of program:
-My program uses a javascript for loop to place the data from an external javascript array named "arrays.js" into an HTML table. This program is suposed to place the correct data under the "Date Name Address Amount" table headings.
Problem:
-The data in the array is overstepping its boundarys or I should say lack of boundaries set within the table headers "Date Name Address Amount" Its not creating a new record after the "Amount" header, its simply adding the new record to the same line.I would like it to wrap back around to the next record row starting under "Date" table header. so that the dates value in the arrya will be under the "date" header, name value under the "Name" header...etc example bellow....
Example: I have 4 headers (Date, Name, Address, Amount) I would like the start of the next date under the next array to be placed under the "Date" table header.It placing the next date value of the array on the same row its not wraping around to a new record row. Code is bellow.
Date Name Address Amount
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Winch - Lab 10</title>
<script src="arrays.js" type="text/javascript"></script>
<script type="text/javascript">
function totalContributions()
{
var totalAmount = 0;
for (var i = 0; i < amount.length; i++)
totalAmount = totalAmount + amount[i];
return totalAmount;
}
</script>
</head>
<body>
<table id="donations">
<tr>
<th>Date</th>
<th>Name</th>
<th>Address</th>
<th>Amount</th>
</tr>
<script>
for (var x=0; x < amount.length; x++){
if (x%2==0){
document.write("<tr>");
} else {
document.write("<tr class='stripe'>");
}
document.write("<td>"+date[x]+"</td>");
document.write("<td>"+firstName[x]+" "+lastName[x]+"</td>");
document.write("<td>"+street[x]+"<br>"+city[x]+","+state[x]+" "+zip[x]);
document.write("<td class='amt'>$"+amount[x]+"</td>");
document.write("</tr)");
}
</script>
</table>
</body>
</html>
**arrays.js**
street = new Array();
city = new Array();
state= new Array();
zip = new Array();
amount = new Array();
date = new Array();
firstName[0]="Ron";
lastName[0]="Burgundy";
street[0]="88 Regal Lane";
city[0]="Williamsburg";
state[0]="KY";
zip[0]="40769";
amount[0]=625;
date[0]="2015-07-18";
firstName[1]="Ricky";
lastName[1]="Bobby";
street[1]="407 Easy Street";
city[1]="London";
state[1]="KY";
zip[1]="40744";
amount[1]=75;
date[1]="2015-07-18";
firstName[2]="Veronica";
lastName[2]="Corningstone";
street[2]="743 Stawlings Drive";
city[2]="Danville";
state[2]="KY";
zip[2]="40423";
amount[2]=50;
date[2]="2015-07-16";
firstName[3]="Brick";
lastName[3]="Tamland";
street[3]="102 Maple Lane";
city[3]="Danville";
state[3]="KY";
zip[3]="40423";
amount[3]=150;
date[3]="2015-07-15";
1) You forgot to define firstName and lastName variables in arrays.js file.
2) Inside for-loop the tr tag is not closed, changed document.write("</tr)"); to document.write("</tr>");.
Working Code:
Html Code:
`
Winch - Lab 10
function totalContributions()
{
var totalAmount = 0;
for (var i = 0; i < amount.length; i++)
totalAmount = totalAmount + amount[i];
return totalAmount;
}
</script>
</head>
<body>
<table id="donations" style="width:100%;" border="1">
<tr>
<th>Date</th>
<th>Name</th>
<th>Address</th>
<th>Amount</th>
</tr>
<script>
for (var x=0; x < amount.length; x++){
if (x%2==0){
document.write("<tr>");
} else {
document.write("<tr class='stripe'>");
}
document.write("<td>"+date[x]+"</td>");
document.write("<td>"+firstName[x]+" "+lastName[x]+"</td>");
document.write("<td>"+street[x]+"<br>"+city[x]+","+state[x]+" "+zip[x]);
document.write("<td class='amt'>$"+amount[x]+"</td>");
document.write("</tr>");
}
</script>
</table>
</body>
</html>
arrays.js
street = new Array();
city = new Array();
state= new Array();
zip = new Array();
amount = new Array();
date = new Array();
firstName = new Array();
lastName = new Array();
firstName[0]="Ron";
lastName[0]="Burgundy";
street[0]="88 Regal Lane";
city[0]="Williamsburg";
state[0]="KY";
zip[0]="40769";
amount[0]=625;
date[0]="2015-07-18";
firstName[1]="Ricky";
lastName[1]="Bobby";
street[1]="407 Easy Street";
city[1]="London";
state[1]="KY";
zip[1]="40744";
amount[1]=75;
date[1]="2015-07-18";
firstName[2]="Veronica";
lastName[2]="Corningstone";
street[2]="743 Stawlings Drive";
city[2]="Danville";
state[2]="KY";
zip[2]="40423";
amount[2]=50;
date[2]="2015-07-16";
firstName[3]="Brick";
lastName[3]="Tamland";
street[3]="102 Maple Lane";
city[3]="Danville";
state[3]="KY";
zip[3]="40423";
amount[3]=150;
date[3]="2015-07-15";
The world is moving to Angular, and I would recommend you to do same.
In Angular way, you can do this using either the angular-data-table or using the angular-material-data-table.
angular-data-table works fine with 1.5.8 but will not be supported in
angular2
angular material-data-table (md-data-table) works with 1.5.8
and will be supported in angular2 too.
Below is an example of md-data-table
<mdt-table table-card="{visible: true, title: 'Donations'}" paginated-rows = "true">
<mdt-header-row>
<mdt-column align-rule="left"><b>Name</b></mdt-column>
<mdt-column align-rule="left"><b>Description</b></mdt-column>
<mdt-column align-rule="left"><b>Since Year</b></mdt-column>
</mdt-header-row>
<mdt-row ng-repeat="item in donations">
<mdt-cell>{{item.name}}</mdt-cell>
<mdt-cell>{{item.description}}</mdt-cell>
<mdt-cell>{{item.since_yr}}</mdt-cell>
</mdt-row>
</mdt-table>
The above code also does pagination for you. Awesome!
The above code can also be used to make rows selectable by putting in :
selectable-rows="true" in
What u have to do is:-
write a angular module using ng-app and that can be included in ur body tag or create a parent tag on top of above code.
write a controller to move ur logic into the controller.
Below is an example.
angular.module('testModule',[])
.controller('testController', function($scope){
$scope.donations = function (){
//Your logic for donations goes here.
};
});
Related
I have a FireBase realtime DB with some data that I would like to display in HTML grid. Structure of the DB is pretty simple:
What I want to do is to have "id", "First column", "Second column", "Third column" as a column headers and data from DB to be displayed under each respective header.
This is my HTML part:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<!--Firebase SDK code below-->
<script src="/__/firebase/8.2.6/firebase-app.js"></script>
<script src="/__/firebase/8.2.6/firebase-analytics.js"></script>
<script src="/__/firebase/8.2.6/firebase-database.js"></script>
<!-- Initialize Firebase -->
<script src="/__/firebase/init.js"></script>
<script src="firebase.js"></script>
<button onClick="readData()">Load data from FB</button>
<table class="table table-striped" id="table">
<thead>
<tr>
<th>ID</th>
<th>First column</th>
<th>Second column</th>
<th>Third column</th>
</tr>
</thead>
<tbody>
</body>
</html>
JS here:
// Firebase reference
var database = firebase.database();
rootRef = database.ref('/');
itemsRef = database.ref('/Items/');
// Other vars
var pushLabels = ["id", "First column", "Second column", "Third column"];
function readData() {
itemsRef.once('value', function (snapshot) {
var arrayLen = pushLabels.length;
var childKeyArr = [];
var table = document.querySelector('#table tbody');
snapshot.forEach(function (childSnapshot) {
var childKey = childSnapshot.key;
childKeyArr.push(childKey);
});
for (var i = 0; i < childKeyArr.length; i++) {
var row = table.insertRow(-1);
for (var j = 0; j < arrayLen; j++) {
cell = row.insertCell(-1);
};
};
for (var i = 0; i < childKeyArr.length + 1; i++) {
database.ref('/Items/' + i).once('value', function (snapshot) {
snapshot.forEach(function (childSnapshot) {
var noha = childSnapshot.val();
for (var i = 0; i < pushLabels.length; i++) {
cell.innerHTML = noha;
};
});
});
}
});
}
I think it's quite "overcomplex". I was able to create rows based on number of parent items in the DB (1,2,3 as shown on the DB hierarchy screenshots) and for each of the nodes I was able to retrieve the data into snapshot but I don’t know how to project it to the grid so each value is correctly displayed to it’s relevant column.
The part where I put something into cell is obviously wrong in my code - I was just testing different ways.
Any help will be appreciated! Also if there is any better solution, some library that can do that in easier way, I would be happy if you can recommend.
Thanks!!
Is there a fixed number of columns expected, or do you want to to create columns dynamically?
Are your column headers already in the html file or are you looking to make them from the keys in the database? There's column headers in your html file, yet you also have an array storing the same. They also match the keys of each child Item so it looks a little confusing.
Here's a quick example of how you could get the table body, create a new row, create the cells, add the values from the database and then add the row to the table body.
var itemsRef = firebase.database().ref().child("Items");
var tableBody = document.querySelector('#table tbody');
function readData() {
itemsRef.once('value', function (snapshot) {
snapshot.forEach(function (item_snapshot) {
//Create html elements, TRs, TD,s etc.
var row = document.createElement("tr");
var col1 = document.createElement("td");
var col2 = document.createElement("td");
var col3 = document.createElement("td");
var col4 = document.createElement("td");
//Add data to the new elements.
col1.innerText = item_snapshot.key;
col2.innerText = item_snapshot.child("First column").val();
col3.innerText = item_snapshot.child("Second_column").val();
col4.innerText = item_snapshot.child("Third_column").val();
//Append the cells into the row and the row into the table body.
row.appendChild(col1);
row.appendChild(col2);
row.appendChild(col3);
row.appendChild(col4);
tableBody.appendChild(row);
});
});
}
It sounds kinda like you want to have the keys of each child Item to be the column headers if I'm not misunderstanding you, but keep in mind that each child might not have the same nodes within it and you only want to load the headers once, rather than from each child Item.
Currently the page is accessed using a link, for instance help.html?show=charInPw.
The table is written in the following manner:
<table>
...
<tbody class="table-body">
<tr class="pwLen"><td colspan="5" class="subheading">Password Length</td></tr>
<tr class="pwLen"><td class="first">Minimum length</td><td>Y</td><td> </td><td>Y</td><td>Y</td></tr>
<tr class="pwLen"><td class="first">Maximum length</td><td>Y</td><td> </td><td>Y</td><td>Y</td></tr>
<tr class="charInPw"><td colspan="5" class="subheading">Characters in Password</td></tr>
<tr class="charInPw"><td class="first">Minimum numeric characters</td><td>Y</td><td> </td><td>Y</td><td>Y</td></tr>
<tr class="charInPw"><td class="first">Minimum alphabetic characters</td><td>Y</td><td> </td><td>Y</td><td>Y</td></tr>
...
The CSS is as follows:
table tbody tr{
text-align: center;
display: none;
}
(There are also trs in thead and they are always shown by default.)
Then I have some Javascript code as follows (jQuery is not an option):
<script>
var url = new URL(window.location.href);
var c = url.searchParams.get("show");
for (i = 0; i < document.getElementsByClassName(c); i++)
document.getElementsByClassName(c)[i].style.display='table-row';
</script>
However I am not able to get my rows to show.
How should I change the code on the page to show only the rows referenced by the show parameter?
Edit #1: As a test I did the following hard-coding but it didn't work too!
<script>
var url = new URL(window.location.href);
var c = url.searchParams.get("show");
var trs = document.getElementsByClassName('pwLen');
for (i = 0; i < trs.length; i++)
trs[i].style.display='table-row';
</script>
Edit #2: I have combined two solutions below into one - please see https://jsfiddle.net/tea45p2o/. The demo output shown is what I want, however I am not able to see that when I save the file and open the page in my browser. What is going on?
With much help from BJohn and MrJ, I have come up with my solution as follows:
<script>
function show() {
var url = new URL(window.location.href);
var c = '.' + url.searchParams.get("show");
for (let el of document.querySelectorAll(c)) el.style.display = 'table-row';
}
</script>
Then, I changed my <body> to
<body onLoad="show();">
Use below code:
for (let el of document.querySelectorAll(c)) el.style.display = 'table-row';
You also need to append dot (.) with class name, which you are getting from the URL.
Please find the fiddle here
ŷou are missing to place .length
for (i = 0; i < document.getElementsByClassName(c).length; i++)
But I think it would be more readable on this way
for(let TR_x of [... document.getElementsByClassName(c) ]) {
TR_x.style.display='table-row';
}
but I definitely prefer
document.querySelectorAll('.'+c).forEach(trX=>{ trX.style.display='table-row' })
I want the user to input both 'part ID' and 'quantity' through prompt and have those values added to a table; which I've managed so far. After that, I want to add another row below the first one using the same method resulting in 2 rows with different values etc.
<html>
<head>
</head>
<!--CREATE AND POPULATE TABLE -->
<body onload="partID(); qty()">
<table id="resultsTable" border=".5px" class="results">
<tr><th>Part ID</th><th>Quantity</th>
<tr>
<td id="partID">Part ID</td>
<td id="qty">Quantity</td>
</tr>
</table>
<br>
<!-- I want this f('createTable') to bring the prompt back and append to existing table onclick, if that makes sense -->
<button onclick="createTable()">Add Another Part</button>
</body>
<!-- LOCAL SCRIPTS -->
<script>
function partID(){
var partID = prompt("Enter part ID:");
var x = document.getElementById('partID');
x.innerHTML = partID;
}
function qty(){
var qty = prompt("Enter Quantity:");
var y = document.getElementById('qty');
y.innerHTML = qty;
}
</script>
</html>
I can get it to work once around but I'm not sure how to repeat it for a new row and without losing previous data.
What you want to do is append data to the table, right now you are setting the values of individual cells instead of just appending them to the already existing ones.
JavaScript has a neat little shortcut for appending (just like many other languages) which is +=, basically var myVar = 'Foo'; myVar += 'Bar'; is equal to var myVar = 'Foo'; myVar = myVar + 'Bar';
function add() {
//prompt the user with boxes for the ID and quantity
var partID = prompt("Enter part ID:");
var qty = prompt("Enter Quantity:");
//generate the HTML for a new table row and insert the given values
var table_html = "<tr><td>" + partID + "</td><td>" + qty + "</td></tr>";
//append the HTML to the already existing HTML in the table
document.getElementById('resultsTable').innerHTML += table_html;
}
/*I dont like default buttons*/
button {
background-color: lightgrey;
color: black;
padding: 8px;
border: 0px;
}
button:hover {
background-color: grey;
}
<html>
<head>
</head>
<body onload="add();">
<!-- instead of onload use a button so the user can repeat the action multiple times -->
<button onclick="add();">Add part</button>
<hr>
<table id="resultsTable" border=".5px" class="results">
<tr>
<th>Part ID</th>
<th>Quantity</th>
</tr>
</table>
<br>
</body>
</html>
I hope this helps, if you need further explanation about the code just leave a comment.
Good luck.
From what I understand, you want to be able to add a new row to the <table>. For this, you probably want to use a button.
<button onclick="addRow()">Add row</button>
Then you can add a row using insertAdjacentHTML :
function addRow() {
var table = document.getElementById('resultsTable');
var partID = prompt("Enter part ID:");
var qty = prompt("Enter Quantity:");
table.insertAdjacentHTML('beforeend', "<tr><td>" + partID + "</td><td>" + qty + "</td></tr>")
}
Using insertAdjacentHTML is safer and more efficient than replacing the whole table innerHTML.
I've been debugging for some time, trying to get the value of a column in a table. I think once I've done this, it should be easy to pass the value in the next column out of my JS function.
My HTML table is:
<table id="country_LE_table" style = "display:none">
<tr>
<td>Japan</td>
<td>83.7</td>
</tr>
<tr>
<td>Switzerland</td>
<td>83.4</td>
</tr>
</table>
My Javascript is:
<script type="text/javascript">
function getLifeExpectancy() {
var Country = "<?php echo $Country ?>";
document.write(Country); // this gets read OK
var table = document.getElementById("country_LE_table");
var tr = table.getElementsByTagName("tr");
document.write(tr.length); document.write("<br>"); // works as expected
for (var i = 0; i < tr.length; i++) {
document.write(tr[i].innerHTML); document.write("<br>"); // works well up to here
// the following doesn't work
var td = tr[i].getElementsByTagName("td")[0];
if (td = Country) { //need td.fullHTML/value/fullText?
return tr[i].getElementsByTagName("td")[1]; // return the number
}
document.getElementById("demo").innerHTML = getLifeExpectancy();
</script>
If I do document.write(td), I get "[object HTMLTableCellElement]" on my page.
If I do document.write(td.fullHTML) I get "undefined" on my page.
When I explore other methods than td.innerHTML, I get this - it looks like I can't use functions based around text.
Use this instead. you have used assignment operator instead of comparison operator "=="
if (td.innerHTML == Country)
{
}
I have one client side application which is rendering maps on browser(IE). In that application I have one HTML form which will capture some text contents and then the application will be generating one Word document, which will have all the fields submitted by the user in a tabular form. I am able to do that, but i have to insert one image from the browser(the screenshot of the map).
I divided the problem into two parts:
1) write some table contents in tabular form using javascript--- I am able to do that.
2) take screenshot of map and insert it into that word document.--- couldn't take screenshot, but tried with one dummy image from local machine and insert it into word doc.
The problem is, I want that image in fourth row and first column. But the "word.Selection"
points to first cell in table.
itable.columns(1).cells(5).Range.Text="some text"; cant we use something like this to insert text or place "word.Selection" in a particular cell.
the below page serves my form request.
<!DOCTYPE html>
<html>
<head>
<script src="jquery-1.11.0.js"></script>
<script type="text/javascript">
function myFunction()
{
var table = document.getElementById("myTable");
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
cell1.innerHTML = getFieldValue("FirstName");
cell2.innerHTML = getFieldValue("lastName");
}
var JPEGName = "C:\\all data\\MyBT\\tasks\\dp manifold.jpg";
function saveAsWord() {
word = new ActiveXObject("Word.Application");
word.visible=false;
word.Documents.Add();
word.Application.Visible = true;
word.ActiveDocument.PageSetup.LineNumbering.Active=false;
word.ActiveDocument.PageSetup.TopMargin=30;
word.ActiveDocument.PageSetup.BottomMargin = 30;
word.ActiveDocument.PageSetup.LeftMargin = 35;
word.ActiveDocument.PageSetup.RightMargin = 30;
word.ActiveDocument.PageSetup.Gutter = 0.0;
word.Selection.Font.Bold = true;
word.Selection.Font.Size = 14;
word.Selection.ParagraphFormat.Alignment = 1;
word.Selection.TypeText("form details");
word.Selection.Font.Size = 12;
var itable=word.ActiveDocument.Tables.Add(word.ActiveDocument.Application.Selection.Range, 16, 4);
//itable.AutoFormat(16);
word.ActiveDocument.Tables(1).Range.ParagraphFormat.Alignment = 0;
itable.columns(2).cells(1).Range.ParagraphFormat.Alignment =1;
itable.columns(2).cells(1).Range.Text="Exchange Area"
itable.columns(3).cells(1).Range.ParagraphFormat.Alignment =0;
itable.columns(1).cells(2).Range.Text="CSS Job No ";
itable.columns(3).cells(2).Range.Text="Sr. No. : ";
itable.columns(1).cells(3).Range.Text="Customer Details : "+getFieldValue("firstName");
itable.columns(1).cells(4).Range.Text="Engineers Details : "+getFieldValue("lastName");
itable.columns(3).cells(4).Range.ParagraphFormat.Alignment =0;
itable.columns(3).cells(4).Range.Text="Date : ";
//itable.columns(3).cells(4).Range.Content.InlineShapes.AddPicture(JPEGName);
itable.columns(1).cells(5).Range.Text="Requirement : ";
itable.columns(3).cells(5).Range.ParagraphFormat.Alignment =0;
itable.columns(3).cells(5).Range.Text="Survey Reqd : ";
itable.columns(1).cells(6).Range.Text="Visiting Date : ";
itable.columns(2).cells(6).Range.ParagraphFormat.Alignment =1;
itable.columns(2).cells(6).Range.Text="Visit Time : ";
itable.columns(1).cells(5).Range.Text="Whom To Meet : ";
itable.columns(3).cells(5).Range.ParagraphFormat.Alignment =0;
itable.columns(3).cells(5).Range.Text="Underground Cable : ";
itable.columns(1).cells(6).Range.Text="Visiting Date : ";
itable.columns(2).cells(6).Range.ParagraphFormat.Alignment =1;
itable.columns(2).cells(6).Range.Text="Overhead Work : ";
itable.columns(3).cells(6).Range.Text="Underground Civil : ";
itable.columns(1).cells(7).Range.Text="Location: ";
itable.columns(1).cells(8).Range.Text="Map Ref: ";
itable.columns(1).cells(10).Range.ParagraphFormat.Alignment =1;
itable.columns(1).cells(10).Range.Text="Title: EXPOSE BURIED JOINT";
itable.columns(3).cells(10).Range.ParagraphFormat.Alignment =1;
itable.columns(3).cells(10).Range.Text="Job Summary";
itable.columns(1).cells(12).Range.ParagraphFormat.Alignment =1;
itable.columns(1).cells(12).Range.Text="Sig. of Security Supervisior";
itable.columns(3).cells(12).Range.ParagraphFormat.Alignment =1;
itable.columns(3).cells(12).Range.Text="Sig. of Meeting Person";
itable.Cell(3, 1).Merge(itable.Cell(3, 2));
itable.Cell(4, 2).Split(1, 2);
itable.Cell(4, 1).Merge(itable.Cell(4, 2));
itable.Cell(4, 2).Merge(itable.Cell(4, 3));
itable.Cell(5, 2).Split(1, 2);
itable.Cell(5, 1).Merge(itable.Cell(5, 2));
itable.Cell(5, 2).Merge(itable.Cell(5, 3));
itable.Cell(7, 1).Merge(itable.Cell(7, 3));
itable.Cell(8, 1).Merge(itable.Cell(8, 3));
itable.Cell(9, 1).Merge(itable.Cell(9, 3));
itable.Cell(11, 1).Merge(itable.Cell(11, 3));
itable.Cell(13, 1).Merge(itable.Cell(13, 3));
itable.Cell(14, 1).Merge(itable.Cell(14, 3));
itable.Cell(15, 1).Merge(itable.Cell(15, 3));
itable.Cell(16, 1).Merge(itable.Cell(16, 3));
//word.Application.PrintOut(true);
//setTimeout("appexit()",10000);
word.Selection.TypeParagraph();
word.Selection.InlineShapes.AddPicture(JPEGName);
}
</script>
</head>
<body>
<table id="myTable" style="border:1px solid black">
<tr>
<td>First Name</td>
<td>Last Name</td><td>SSN</td>
</tr>
</tr>
</table><br><br><br>
Your Social security number is <script type="text/javascript">
document.write(getFieldValue("ssn"))
</script>.<br>
You entered "<script type="text/javascript">
document.write(getFieldValue("FirstName"))
</script>" as your First Name.<br>
You entered "<script type="text/javascript">
document.write(getFieldValue("lastName"))
</script>" as your Last Name.<br>
<button id="foo" onclick="myFunction()">Try it</button>
<input type="button" value="print slip" onclick="saveAsWord()"/>
</body>
</html>
I am new to writing script for generating MS document.
I have found out the code where I was doing wrong. Instead of using "word.Selection" it would be good to use "itable.cell(row,column).range" for inserting.
itable.cell(5,1).range.InlineShapes.AddPicture(JPEGName );