I'm kind of new to Javascript, and somebody helped me with this script, it works great on Chrome but it doesn't work in Firefox, and haven't tested it in IE yet but I want it to work in all browsers, and I don't really know that much on jQuery as to translate it
function displayTotal()
{
var tableRows = document.getElementById('budgetTable').getElementsByTagName('tr');
var totalDays = tableRows.length - 3; //Don't count the header rows and the Total rows
var totalPrice = 0;
var price = filterNum(document.getElementById( 'txtPrice' ).value);
var totalField = document.getElementById('txtTotal');
var tempHours = 0;
var tempTotal = 0;
for(var i = 0; i < totalDays; i++)
{
tempHours = document.getElementById("end" + i).value - document.getElementById("start" + i).value;
tempTotal = tempHours * price;
document.getElementById("total" + i).innerHTML = formatCurrency(tempTotal);
totalPrice += tempTotal;
console.log(i, "Start:" + document.getElementById("start" + i).value, "End:" + document.getElementById("end" + i).value, "Hours:" + tempHours, "Total:" + tempTotal);
}
totalField.value = formatCurrency(totalPrice);
}
function addRowToTable()
{
var tbl = document.getElementById('budgetTable');
var lastRow = tbl.rows.length - 2;
var iteration = lastRow;
var entry = iteration - 1; //because we started with day0, etc
var row = tbl.insertRow(lastRow);
// day cell
var cellDay = row.insertCell(0);
cellDay.appendChild(createInput('text','day' + entry, '', displayTotal));
// start cell
var cellStart = row.insertCell(1);
cellStart.appendChild(createInput('text','start' + entry, 0, displayTotal));
// end cell
var cellEnd = row.insertCell(2);
cellEnd.appendChild(createInput('text','end' + entry, 0, displayTotal));
// total cell
var cellTotal = row.insertCell(3);
cellTotal.id = 'total' + entry;
}
function createInput(type, id, value, action)
{
var el = document.createElement('input');
el.type = type;
el.id = id;
el.value = value;
el.onkeyup = action;
return el;
}
function filterNum(str)
{
re = /^\$|,/g;
// remove "$" and ","
return str.replace(re, "");
}
function formatCurrency(num)
{
num = isNaN(num) || num === '' || num === null ? 0.00 : num;
return parseFloat(num).toFixed(2);
}
Any help will be welcomed as I really don't know where I'm missing then point here.
EDIT: ok, this is weird, but on Firefox, when I enable firebug to try to debug it,... it works.
tempHours = document.getElementById("end" + i).value - document.getElementById("start" + i).value;
document.getElementById("total" + i).innerHTML
The output any element attribute (such as element.value and element.innerHTML) is always a string. You can only perform mathematical functions on numbers. If the string only contains 'number characters' you can use parseInt() or parseFloat to convert them
console.log(); // Is a Firebug function. Try commenting it out.
Related
I need to assign instances of my object as values in my array, but when I try to add let to my loop for collecting user input, I get an error stating that "[" is an unexpected token. This is a new technique to me so I'm not sure if this is even a practical method for making a table. Any help is appreciated.
<script>
function generateTable() {
var tblStart = "<table>";
//This is the header line for my table.
var tblMeat = "<tr> <td><b>Name</b></td> <td><b>Attendance</b></td> <td><b>Homework</b></td> <td><b>Midterm</b></td> <td><b>Final</b></td> <td><b>Course Grade</b></td> <td><b>Round Grade</b></td> <td><b>Letter Grade</b></td> </tr>";
var tblStop = "</table>";
//This determines the number of rows.
var rowCount = prompt("How many students are in the class?");
//I want to assign instances of Student to this array which will be used to fill the table cells.
var pupil = [NUMBER(rowCount)];
//This object should process user entries and use them to calculate the total grade, rounded grade, and letter grade.
function Student(name, attendance, homework, mGrade, fGrade) {
this.name = name;
this.attend = attendance;
this.homewrk = homework;
this.midter = mGrade;
this.fingrad = fGrade;
this.course = function () {
var attGrade = this.attend * 0.1;
var hwkGrade = this.homewrk * 0.2;
var midGrade = this.midter * 0.3;
var finGrade = this.fingrad * 0.4;
var combGrade = attGrade + hwkGrade + midGrade + finGrade;
return combGrade.toFixed(2);
};
this.round = Math.round(this.course);
this.letter = function() {
if(this.course < 60) {
return '<p style="color:red;">F</p>';
} else if(this.course >= 60 && this.course <= 69.9){
return "D";
} else if(this.course >= 70 && this.course <= 79.9) {
return "C";
} else if(this.course >= 80 && this.course <= 89.9) {
return "B";
} else if(this.course >= 90 && this.course <= 100) {
return "A";
};
};
}
/*This loop should collect user input based on the declared number of students, and assign input values to instances of
Student based on which execution of the loop is being run. I am getting an error stating "[" is unexpected for line 79.
*/
for (var r = 0; r < rowCount; r++) {
var studentN = prompt("Enter student name.");
var studentA = prompt("Enter student attendance.");
var studentH = prompt("Enter student homework grade.");
var studentM = prompt("Enter student midterm grade.");
var studentF = prompt("Enter student final grade.");
let pupil[r] = new Student(studentN, studentA, studentH, studentM, studentF);
}
for(var i = 0; i < rowCount; i++) {
tblMeat += "<tr>";
for(var j = 0; j < 8; j++) {
tblMeat += "<td>" + pupil[i].name + "</td><td>" + pupil[i].attend + "</td><td>" + pupil[i].homewrk + "</td><td>" + pupil[i].midter + "</td><td>" + pupil[i].fingrad + "</td><td>" + pupil[i].course() + "</td><td>" + pupil[i].round + "</td><td>" + pupil[i].letter() + "</td>";
}
tblMeat += "</tr>";
}
//This just puts it all together.
var completeTable = tblStart + tblMeat + tblStop;
document.getElementById("placetable").innerHTML = completeTable;
}
</script>
I ran your program through uglifyJS. It's actually for compressing javascript code, but when there is a lot of code to debug, it's a life changer.
The script told me:
Parse error: Unexpected token: punc ([)
Line 59, column 16
let pupil[r] = new Student(studentN, studentA, studentH, studentM, studentF);
You're trying to define an already existing variable. Remove "let".
A tiny advice for the future.
The problem is that when I create page number buttons at the bottom of the page the onclick only ever works with the last element created.
Here is what the page buttons look like:
for(var i = 0; i < numberOfPages; i++) {
if(Math.floor((((startIndex + 1) / 10) + 1)) == (i + 1)) {
var newElement = document.createElement("u");
document.getElementById("imagesNav").appendChild(newElement);
newElement.id = "imagesNavU";
var newElement = document.createElement("a");
document.getElementById("imagesNavU").appendChild(newElement);
var str = "page" + (i + 1);
newElement.innerHTML = i + 1;
newElement.onclick=function(){currentPageNumber(str);};
} else {
var newElement = document.createElement("a");
document.getElementById("imagesNav").appendChild(newElement);
var str = "page" + (i + 1);
newElement.innerHTML = i + 1;
newElement.onclick=function(){currentPageNumber(str);};
}
if(i + 1 != numberOfPages) {
document.getElementById("imagesNav").innerHTML += " ";
}
}
}
The first if statement just puts underline tags on if that element is the current page.
Edit: The problem has been solved. Thank you to everyone for their help!
The problem is with this part of the loop:
if(i + 1 != numberOfPages) {
document.getElementById("imagesNav").innerHTML += " ";
}
This is re-parsing all the HTML in the imagesNav element. This creates new <a> elements, which don't have the onclick bindings that the previous ones had.
Instead, you can append a <span> element containing the spaces.
var numberOfPages = 3;
var startIndex = 0;
for (var i = 0; i < numberOfPages; i++) {
if (Math.floor((((startIndex + 1) / 10) + 1)) == (i + 1)) {
var newElement = document.createElement("u");
document.getElementById("imagesNav").appendChild(newElement);
newElement.id = "imagesNavU";
var newElement = document.createElement("a");
document.getElementById("imagesNavU").appendChild(newElement);
var str = "page" + (i + 1);
newElement.innerHTML = i + 1;
newElement.onclick = function() {
currentPageNumber(str);
};
} else {
var newElement = document.createElement("a");
document.getElementById("imagesNav").appendChild(newElement);
var str = "page" + (i + 1);
newElement.innerHTML = i + 1;
newElement.onclick = function() {
currentPageNumber(str);
};
}
if (i + 1 != numberOfPages) {
var span = document.createElement('span');
span.innerHTML = ' ';
document.getElementById("imagesNav").appendChild(span);
}
}
function currentPageNumber(str) {
alert(str);
}
<div id="imagesNav">
</div>
Another way to do it is with insertAdjacentHTML, which adds HTML to an element without re-parsing what's already in it.
document.getElementById("imagesNav").insertAdjacentHTML('beforeend', ' ');
You should also see JavaScript closure inside loops – simple practical example because the way you're using the str variable, all the click handlers will use the value from the last iteration of the loop.
I need to display a date from an array and it needs to be incremented for each input by 1 day. The date should display as mm/dd/yyyy. I was able to get the date to display correctly with the code that is in the message but after each input the all the dates would increment. I need just the last input to increment a day and I thought putting it in an array would work but now nothing displays. Thanks for helping.
var lowTempArray = [];
var highTempArray = [];
var nowArray = [];
function process() {
'use strict';
//declare variables
var lowTemp = document.getElementById('lowTemp');
var highTemp = document.getElementById('highTemp');
var output = document.getElementById('output');
var date = new Date();
var message = ' ';
if (lowTemp.value) {
lowTempArray.push(lowTemp.value);
if (highTemp.value) {
highTempArray.push(highTemp.value);
message = '<table><th>Date </th><th> Low Temperatures</th><th> High Temperatures</th>';
for (var i = 0, count = lowTempArray.length; i < count; i++) {
for (var i = 0, count = highTempArray.length; i < count; i++) {
for (var i = 0, count = nowArray.length; i < count; i++) {
nowArray.push(new Date(date.getTime()));
date.setDate(date.getDate() + count);
message += '<tr><td>' + ((nowArray.getMonth() + 1) + '/' + (nowArray.getDate() + count) + '/' + nowArray.getFullYear()) + '</td><td> ' + lowTempArray[i] + '</td><td> ' + highTempArray[i] + '</td></tr>';
}
message += '</table>';
output.innerHTML = message;
}
}
}
}
return false;
}
function init() {
'use strict';
document.getElementById('theForm').onsubmit = process;
} // End of init() function.
window.onload = init;
The user should be able to enter in an integer and see the base, squared, and cubed result of that number. The base result should be listed under the "base" header, the squared result should be listed under the "squared" header and the cubed result should be listed under the "cubed" result. However, my output is listed all results under the "base" header. How can I make the results be listed under the related headers? This is what I have:
var $ = function (id) {
return document.getElementById(id);
}
var calculate = function () {
//Get the input from the user and assign it to the userInput variable
var integer = $("integer").value;
var header = "Base" + " " + "Square" + " " + "Cubed" + "\n";
var squared = "";
var cubed = "";
var base = "";
var displayOutput;
for (var i = 1; i <= integer; i++) {
base += i + "\n";
squared += i * i + "\n";
cubed += i * i * i + "\n";
displayOutput = base + squared + cubed;
}
$("output").value = header + displayOutput;
}
var form_reset = function () {
$("output").value = "";
$("integer").value = "";
}
//Assign event handlers to their events
window.onload = function () {
$("powers").onclick = calculate;
$("clear").onclick = form_reset;
}
It all depends on the output. Trying to stay as close as possible to your code, seems you are inserting your resulting displayOutput string into a textarea control. If you want to keep it that way, try tabs (\t) to separate your columns, and only a new line at the end (\n). Also, I noticed you were concatenating every column (base, square, and cubed) on every iteration, so I removed that. Here's the result:
var $ = function (id) {
return document.getElementById(id);
};
var calculate = function () {
//Get the input from the user and assign it to the userInput variable
var integer = $("integer").value;
var header = "Base" + " " + "Square" + " " + "Cubed" + "\n";
var squared = "";
var cubed = "";
var base = "";
var displayOutput = "";
for (var i = 1; i <= integer; i++) {
base = i + "\t";
squared = i * i + "\t";
cubed = i * i * i + "\n";
displayOutput += base + squared + cubed;
}
$("output").value = header + displayOutput;
};
var form_reset = function () {
$("output").value = "";
$("integer").value = "";
};
//Assign event handlers to their events
window.onload = function () {
$("powers").onclick = calculate;
$("clear").onclick = form_reset;
$("theform").onsubmit = function() { return false; };
};
My node.js code is below.
Basically I have a buffer called searchRes and first I get some values from it.
It is supposed to loop round "results - 1" times.
It is looping.
It prints the first 3 bits of information totally correctly and then after that (4th onwards) is always the same as the 3rd one.
I have no idea why.
results = 20;
var sSize = searchRes.slice(8,16);
sSize = parseInt(sSize,16);
lols = new Array();
while(num <= results -1 ){
var cur = num + 1;
var sres=0;
for(var i in lols) { sres += lols[i]; }
if (num == 0){
var clanRes = searchRes.slice(0, 128 + (sSize * 2));
var cLen = clanRes.slice(8,16);
cLen = parseInt(cLen,16);
var firstLen = clanRes.length;
var lastLen = clanRes.length;
}else{
var cLen = searchRes.slice(lastLen + 8, lastLen + 16);
cLen = parseInt(cLen,16);
var clanRes = searchRes.slice(
lastLen,
lastLen + 128 + (cLen * 2)
);
var abc = 1;
if (abc == 1){
var lastLen = firstLen + clanRes.length;
abc++;
}else{
var lastLen = lastLen + clanRes.length;
}
}
lols.push(cLen);
console.log('\n\nClan ' + cur + ' Details');
var clanID = clanRes.slice(0,8);
clanID = parseInt(clanID,16);
num ++;
}
I'm not sure at all about where the problem is. Is it when defining clanRes or is it in making the loop?
Thanks!
**
Updated code for #bergi
**
num = 0;
var sSize = searchRes.slice(8,16);
sSize = parseInt(sSize,16);
lols = new Array();
while(num <= 3){
var cur = num + 1;
var sres=0;
for(var i in lols) { sres += lols[i]; }
if (num == 0){
var clanRes = searchRes.slice(0, 128 + (sSize * 2));
var cLen = clanRes.slice(8,16);
cLen = parseInt(cLen,16);
var firstLen = clanRes.length;
var lastLen = clanRes.length;
}else{
var cLen = searchRes.slice(lastLen + 8, lastLen + 16);
cLen = parseInt(cLen,16);
var clanRes = searchRes.slice(
lastLen,
lastLen + 128 + (cLen * 2)
);
var abc = 1;
if (abc == 1){
var lastLen = firstLen + clanRes.length;
abc++;
}else{
var lastLen = lastLen + clanRes.length;
}
}
lols.push(cLen);
console.log('\n\nClan ' + cur + ' Details');
var clanID = clanRes.slice(0,8);
clanID = parseInt(clanID,16);
console.log(clanID);
num ++;
}
Here is a exmaple searchRes:
http://pastie.org/10075399
And an example sSize:
0000000e - hex
14 - int.
var abc = 1;
if (abc == 1){
abc is always 1 in that comparison (the value is assigned right in the line before), so it will never evaluate the else block. I assume you want to move the initialisation of the variable out of the looping.