Solved

Working with Objects, Object Hierarchies and Nodes

Posted on 2009-05-02
29
871 Views
Last Modified: 2012-05-06
I'm working on a case for a course I'm taking which involves making a website with certain tools.  The site should allow one to add new contributions to a contribution table and also allow one to remove rows in the table.  I've tried debugging and firebug doesn't come up with any errors but it's obvious that my functions are not functioning.  The code in the html and js function docs is posted below.  I've added the course's instructions in case they were of any help in referencing what I've tried to do with what the course has asked for.  I'm sure there are some syntax problems as I'm quite new to this.  
<html>

<head>

<!-- 

   New Perspectives on JavaScript

   Tutorial 10

   Case Problem 3
 

   The Lighthouse
 
 

   Filename:         clist.htm

   Supporting files: data.js, lhouse.css, logo.jpg, newdata.js
 

-->

<title>The Lighthouse</title>

<link href="lhouse.css" rel="stylesheet" type="text/css" />

<script type="text/javascript" src="data.js"></script>

<script type="text/javascript" src="newdata.js"></script>
 

</head>
 

<body onLoad="makeTable();">

<form name="donations" id="donations" action="">

<div id="title">

   <img src="logo.jpg" alt="The Lighthouse" />

   The Lighthouse<br />

   543 Oak Street<br />

   Delphi, KY &nbsp;&nbsp;89011<br/>

   (542) 555-7511

</div>
 

<div id="data_entry">

   <table>

   <tr>

      <td>Contributors</td>

      <td id="totalContr"></td>

   </tr>

   <tr>

      <td>Total</td>

      <td id="totalAmt"></td>

   </tr>

   </table>
 

   <table>

   <tr><td colspan="2"><h3>Enter a New Contributor</h3></td></tr>

   <tr>

      <td>First Name</td><td><input name="fname" id="fname" /></td>

   </tr>

   <tr>

      <td>Last Name</td><td><input name="lname" id="lname" /></td>

   </tr>

   <tr>

      <td>Street</td><td><input name="street" id="street" /></td>

   </tr>

   <tr>

      <td>City</td><td><input name="city" id="city" /></td>

   </tr>

   <tr>

      <td>State</td>

      <td><select name="state" id="state">

      <option>AL</option><option>AK</option><option>AZ</option><option>AR</option>

      <option>CA</option><option>CO</option><option>CT</option><option>DE</option>

      <option>DC</option><option>FL</option><option>GA</option><option>HI</option>

      <option>ID</option><option>IL</option><option>IN</option><option>IA</option>

      <option>KS</option><option>KY</option><option>LA</option><option>ME</option>

      <option>MD</option><option>MA</option><option>MI</option><option>MN</option>

      <option>MS</option><option>MO</option><option>MT</option><option>NE</option>

      <option>NV</option><option>NH</option><option>NJ</option><option>NM</option>

      <option>NY</option><option>NC</option><option>ND</option><option>OH</option>

      <option>OK</option><option>OR</option><option>PA</option><option>RI</option>

      <option>SC</option><option>SD</option><option>TN</option><option>TX</option>

      <option>UT</option><option>VT</option><option>VA</option><option>WA</option>

      <option>WV</option><option>WI</option><option>WY</option>

      </select>

      </td>

   </tr>

   <tr>

      <td>Zip</td><td><input name="zip" id="zip" /></td>

   </tr>

   <tr>

      <td>Amount</td><td><input name="amount" id="amount" /></td>

   </tr>

   <tr>

      <td>Date</td><td><input name="date" id="date" /></td>

   </tr>

   <tr>

      <td colspan="2" id="buttoncell1">

         <input type="button" onclick="addRecord()"  value="Add Contributor" />

		 

      </td>

   </tr>

   </table>

</div>
 

<div id="report">

   <p><input value="Remove Checked Items" onclick="removeRecords()" type="button" /></p>
 

   <table id="ctable">

   <tr><th colspan="5">Contributor List</th>

   </tr>

   <tr id="titleRow">

      <th>Remove</th>

      <th>Date</th>

      <th>Name</th>

      <th>Address</th>

      <th>Amount</th>

   </tr><tr id="emptyRow"><td class="rc"><input type="checkbox" /></td><td></td><td></td><td></td><td class="ac"></td></tr>

   </table>

</div>
 

</form>

</body>

</html>
 
 
 
 
 
 
 

/*

   

   New Perspectives on JavaScript

   Tutorial 10

   Case Problem 3
 

   Filename: newdata.js
 
 

   Function List:

   updateTotals(phrase, pnum)

      Updates contents of the table cells "totalContr" and "totalAmt" displaying 

      the total number of contributors and the total contributions
 

   makeTable()

      Populates the contributors table with the entries of the 8 data arrays by

      calling the addRow() function for each item in the arrays.
 

   addRow(i)

      Adds a row to the contributors using data from the 8 data arrays who index

      value equals "i".
 

   addRecord()

      Adds a new record to the end of the 8 data arrays and then calls the addRow() function

      to add a new row to the contributors table and the updateTotals() function to

      update the tables cells displaying the total number of contributors and

      contributions.
 

    removeRecord(index)

       Removes a record from the eight data arrays whose index value equals index.
 

    removeNode(node)

       Removes a node from a node tree, and returns a reference to the node's previous sibling.
 

    removeRecords()

       Loops through the rows in the contributors table checking whether the remove

       checkbox has been selected. For each selected checkbox, the table row is removed

       and the corresponding entries in the 8 data arrays are removed. The updateTotals()

       function is then called.
 

*/
 
 

/*  Within the totalContr table cell, display the length of the amount array. 
 

Create a variable named totalContributions and set its initial value to 0.
 

Create a for loop that loops through each entry in the amount array. Each time through the loop increases the value of the totalContributions variable by the amount in the current entry in thr amount array.
 

Within the totalAmt table cell, display the value of the totalContributions variable     */
 

function updateTotals() {

document.getElementById("totalContr").value = amount.length;

var totalContributions = 0;

   for (i=0; i < amount.length; i++) {

     totalContributions = totalContributions + amount[i];};

document.getElementById("totalAmt").value = totalContributions;

}
 

/*  Create a variable named headingRow that references the table row with the id "titleRow".  This row contains the titles from the contributors table.  Create a second variable named blankRow that references the table row with the id "emptyRow".
 

Use the cloneNode() method to clone the blankRow node.  Set the value of the deep variable to true in order to copy the entire node tree.  Store this document fragment in a variable named dataRow.
 

Create a for loop that loops through the entries in the amount array.  For each entry call the addRow() function using the value of the counter variable in the for loop as the parameter value in the addRow() function.
 

Call the updateTotals() function      */
 

function makeTable() {

var headingRow = document.getElementById("titleRow"); 

var blankRow = document.getElementById("emptyRow"); 

dataRow = blankRow.cloneNode(true);

for ( i = 0; i <amount.length; i++) { addRow(i) ;};

updateTotals();

}
 

/*  Use the cloneNode() method to clone the dataRow document fragment you created in the makeTable() function.  Set the value of the deep parameter to true.  Store this documentfragment in the variable newRow.
 

Change the content of newRow's second child node to the value of the date array using the current index. Change the content of newRow's third child node to the ntex string "lastName, firstName" where lastName and firstName are the values of the lastName and firstName arrays using the current index. Change the content of newRow's fourth child node to the text string "street<br />city, state, zip" where street, city, state, and zip are the current values from the street, city, state, and zip arrays. Change the content of newRow's fifth child node to the value of the amount array.
 

 If the value of the index variable equals 0, meaning that this is the first row being added to the contributor table, then use the replaceChild() method to replace the blankRow node with newRow.  (Hint: Apply the replaceChild() method to the blankRow.parentNode node)  If the index variable is not equal to 0, then insert the newRow node before the next sibling of the headingRow node. (Hint: Apply the insertBefore() method to the headingRow.parentNode node)    */
 

function addRow(i) {

var newRow;

newRow = dataRow.cloneNode(true);

newRow.childNodes[1].nodeValue = date[i];

newRow.childNodes[2].nodeValue = lastName[i] + ", " + firstName[i];

newRow.childNodes[3].nodeValue = street[i] + "<br>" + city[i] + ", " + state[i] + zip[i];

newRow.childNodes[4].nodeValue = amount.length;

if (n = 0) { blankRow.parentNode.replaceChild(newRow, blankRow) };

if (n != 0) { headingRow.parentNode.insertBefore(newRow, headingRow.nextSibling)  };

}
 

/*  Create a variable named recordNum equal to the length of the amount array.
 

Set the value of first[recordNum] to the value of the fname field from the donations Web form.  Set the value of last[recordNum] to the value of the lname field.  Set the value of the street array item to the value of the street field and the value of the city array item to the value of the city field.  Determine which state option has been selected by the user and store the text of the selected option in the state arry item. Set the value of the zip, amount, and date array items to the values of the zip, amount, and date fields in the donations Web form.  
 

Call the addRow() function using the value of the recordNum variable as the parameter value.
 

Call the updateTotals() function.     */
 

function addRecord() {

var recordNum = amount.length;

data_entry.document.getElementById("fname").nodeValue = first[recordNum];

data_entry.document.getElementById("lname").nodeValue = last[recordNum];

data_entry.document.getElementById("street").nodeValue = street;

data_entry.document.getElementById("city").nodeValue = city;

data_entry.document.getElementById("state").nodeValue = state;

data_entry.document.getElementById("zip").nodeValue = zip;

data_entry.document.getElementById("amount").nodeValue = amount;

data_entry.document.getElementById("date").nodeValue = date;

addRow(recordNum);

updateTotals();

}
 

/*  Use the splice() method to remove the item from the firstName array whose index value equals the value of the index parameter.  Remove only one array item.
 

Repeat step for the lastName, street, city, state, zip, amount, and date arrays.    */
 

function removeRecord(index) {

firstName.splice(index,1);

lastName.splice(index,1);

street.splice(index,1);

city.splice(index,1);

state.splice(index,1);

zip.splice(index,1);

amount.splice(index,1);

date.splice(index,1);

}
 

/*  Create a variable named prevNode referencing the node's previous sibling.  
 

Use the removeChild() method to remove the node.  (Hint: Apply the removeChild() method to the node's parent node.)
 

Return the prevNode variable from the function.      */
 

function removeNode(node) {

var prevNode = node.previousSibling;

prevNode.parentNode.removeChild(prevNode);

return prevNode;

}
 

/*  Create a variable named headerRow referencing the row with the id "titleRow".  
 

Create a variable named recordNum equal to the length of the amount array.
 

Create a for loop that uses familial references, starting with the node variable, n, equal to the first sibling of the headerRow node and proceeding to the next sibling (the next table row) until there is no next sibling.  Within the for loop, decrease the value of the recordNum varialbe by 1.  Then, insert an if condition that tests whether the name of the current node is "TR" (a table row).  If it is, insert a second if condition that tests whether the check box within the first table cell of the current row has been selected.  (Hint: Reference the check box using the reference n.firstChild.firstChild.)  If the check box has been checked, then: (1) Call the removeRecord() function using the recordNum as the parameter value, and (2) Let the node counter, n, be equal to the value returned by the removeNode() function using the n as the parameter value.
 

After the for loop has finished, call the updateTotals() function to update the contribution totals in the Web page.     */
 

function removeRecords() {

var headerRow;

ctable.document.getElementById("titleRow") = headerRow;

var recordNum = amount.length;

for ( n = 0; n < headerRow.childNodes.length; n++) {

recordNum = recordNum - 1;

if (headerRow.childNodes[n].name = "TR") {

  if (n.firstChild.firstChild != "") {

    removeRecord(recordNum);

	n = removeNode(n)};

	};

updateTotals(); }

}
 
 
 
 

/*

   New Perspectives on JavaScript

   Tutorial 10

   Case Problem 3

   Filename: lhouse.css
 

   This file contains styles used in the clist.htm file
 

*/
 
 

h1, h2, h3, th, #data_entry, #title {font-family: Arial, Helvetica, sans-serif}
 

h3 {width: 100%; background-color: rgb(135,206,255); text-align:center; margin: 0px}
 

td {vertical-align: top}
 

#title {width: 680px; text-align:right; color: rgb(192,142,90); border-bottom: 1px solid rgb(232,182,130); 

        margin-bottom:9px; font-size:10pt; height: 100px}

#title img {float: left}
 

#data_entry {width:230px; font-size: 9pt; float:left; margin-right: 10px}

#data_entry table {margin: 0px; width: 100%; border: 2px solid rgb(232,182,130); margin-bottom: 10px}

#data_entry td {font-size:9pt}

#data_entry input {font-size:9pt}

#data_entry select {font-size: 8pt}
 

#totalContr, #totalAmt {text-align: right; border: 1px solid black}

#first, #last, #street, #city {width: 150px}

#zip, #date {width: 80px}

#amount {width: 50px}

#buttoncell1 {text-align: center; border-top: 2px solid rgb(232,182,130); padding: 10px 0px}
 

#report {width:440px; float: left}

#report p {text-align: center; padding: 0px; margin: 15px 0px 20px 0px}
 

#report table {width: 100%; font-size: 8pt; margin-bottom: 10px; border: solid 2px rgb(232,182,130)}
 

#report #total {background-color:white; text-align:right; font-weight:normal}
 

#report th {background-color: rgb(255,230,153); border: 1px solid rgb(232,182,130)}

#report td {background-color:ivory; border: 1px solid black}
 

.rc {text-align: center}

.ac {text-align: right}
 
 
 

/*

   New Perspectives on JavaScript

   Tutorial 10

   Case Problem 3
 

   Filename: data.js
 

   Variable List:
 

   firstName: Contains the first name of the contributors.

   lastName:  Contains the last name of the contributors.

   street:    Contains the contributor's street address

   city:      Contains the contributor's city of residence

   state:     Contains the contributor's state of residence

   zip:       Contains the contributor's zip code.

   amount:    Contains the amount of the contribution.

   date:      Contains the date of the contribution.
 

*/
 
 

firstName = new Array();

lastName = new Array();

street = new Array();

city = new Array();

state= new Array();

zip = new Array();

amount = new Array();

date = new Array()
 
 

firstName[0]="Steve";

lastName[0]="Bones";

street[0]="900 Lawton Street";

city[0]="Wheaton";

state[0]="KY";

zip[0]="89211";

amount[0]=50;

date[0]="2007-08-25";
 
 

firstName[1]="Jeri";

lastName[1]="White";

street[1]="Hawkes Lane";

city[1]="Delphi";

state[1]="KY";

zip[1]="89211";

amount[1]=150;

date[1]="2007-08-25";
 
 

firstName[2]="Tom";

lastName[2]="Thomas";

street[2]="Rigel Avenue";

city[2]="Drake";

state[2]="KY";

zip[2]="89411";

amount[2]=100;

date[2]="2007-08-27";
 
 

firstName[3]="Hugh";

lastName[3]="Warren";

street[3]="585 Lindon Court";

city[3]="Wheaton";

state[3]="KY";

zip[3]="88877";

amount[3]=50;

date[3]="2007-08-28";
 
 

firstName[4]="Lynwood";

lastName[4]="Ingersoll";

street[4]="723 Jackson Avenue";

city[4]="Delphi";

state[4]="KY";

zip[4]="88802";

amount[4]=500;

date[4]="2007-08-30";
 
 

firstName[5]="Petronila";

lastName[5]="Damico";

street[5]="44 Stewart Street";

city[5]="Drake";

state[5]="KY";

zip[5]="88604";

amount[5]=250;

date[5]="2007-08-30";
 
 

firstName[6]="Livia";

lastName[6]="Mckinnon";

street[6]="557 Ivy Avenue";

city[6]="Jasper";

state[6]="KY";

zip[6]="88960";

amount[6]=50;

date[6]="2007-08-31";
 
 

firstName[7]="Kris";

lastName[7]="Levesque";

street[7]="542 Upton Avenue";

city[7]="Delphi";

state[7]="KY";

zip[7]="88793";

amount[7]=100;

date[7]="2007-08-31";
 
 

firstName[8]="Basilia";

lastName[8]="Lu";

street[8]="851 Flad Court";

city[8]="Jasper";

state[8]="KY";

zip[8]="88633";

amount[8]=500;

date[8]="2007-09-02";
 
 

firstName[9]="Ginny";

lastName[9]="Rainey";

street[9]="657 Dawson Lane";

city[9]="Youngston";

state[9]="KY";

zip[9]="88873";

amount[9]=50;

date[9]="2007-09-03";

Open in new window

0
Comment
Question by:inisrael
  • 16
  • 11
  • 2
29 Comments
 

Author Comment

by:inisrael
Comment Utility
Maybe I shouldn't have posted everything; it may make it more daunting.  The newdata.js file that comes after the clist.htm file is what I really need help on.  I thought the other parts might be helpful.  Let me know if you think I should put up just the specific troubling js parts of the project on other posts or if the supporting files help.  
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Search in newdata.js for "first", and you will see that the variable is never defined.

So, how can line 103 try to access first[recordNum] ?
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Might you, by any chance, mean firstName?
Which is defined, and initialized in data.js?

The same is true for line 104 (in newdata.ja), where you refer to last[recordNum]...
0
 

Author Comment

by:inisrael
Comment Utility
That function is trying to add a new record based on the information that the viewer inputs to add a new record.  The recordNum variable is n in the array sequence for the new item in the sequence being added; as in lastName[n].  I think the question must have gotten this wrong.  I believe you're right, it's lastName and firstName; recordNum should also be added to the other variables, I think.  I corrected the code below.  Perhaps I should be putting the equation the other way around?  such as:
firstName[recordNum] = data_entry.document.getElementById("fname").nodeValue
(I'm not sure about this.)
function addRecord() {

var recordNum = amount.length;

data_entry.document.getElementById("fname").nodeValue = firstName[recordNum];

data_entry.document.getElementById("lname").nodeValue = lastName[recordNum];

data_entry.document.getElementById("street").nodeValue = street[recordNum];

data_entry.document.getElementById("city").nodeValue = city[recordNum];

data_entry.document.getElementById("state").nodeValue = state[recordNum];

data_entry.document.getElementById("zip").nodeValue = zip[recordNum];

data_entry.document.getElementById("amount").nodeValue = amount[recordNum];

data_entry.document.getElementById("date").nodeValue = date[recordNum];

addRow(recordNum);

updateTotals();

}

Open in new window

0
 

Author Comment

by:inisrael
Comment Utility
I was doing some debugging and I found that in the function addRow(i) the:
newRow.childNodes[1].nodeValue    Had a null value.  I'm trying to use this method:
node.cloneNode(deep) more than once in the use of both the makeTable() and addRow(i) functions.  I've set the Boolean parameter deep as true so that the dataRow variable extends to blankRow's entire node tree, and likewise with newRow and dataRow in the following function.  I must not being developing the relationships between these values properly.  
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Right.

  When you've made your changes, show us, and we'll keep helping you.


0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
From this, and your other question http://www.experts-exchange.com/Q_24375458.html, it is clear that you are just learning JavaScript programming.

How much "hand holding" do you want/need in these questions?

Do you know what I mean by that phrase?
0
 

Author Comment

by:inisrael
Comment Utility
I think most people that learn Javascript have a teacher available fairly often.  I don't.  I would like to know the obvious places where I'm going wrong.  If you can see the code and know immediately that a certain syntax is wrong, it would really help if you were to let me know.  I can make the changes myself.  I'm looking for a few suggestions.  
I made the changes to the updateTotals() function.  I'm working on debugging makeTable() and addRow(i) right now.  Again, if anything is obvious to you, it would be really helpful if you would let me know.  
/*

   New Perspectives on JavaScript

   Tutorial 10

   Case Problem 3
 

   Author: Dustin Shaver

   Date:   April 1, 2009
 

   Filename: newdata.js
 
 

   Function List:

   updateTotals(phrase, pnum)

      Updates contents of the table cells "totalContr" and "totalAmt" displaying 

      the total number of contributors and the total contributions
 

   makeTable()

      Populates the contributors table with the entries of the 8 data arrays by

      calling the addRow() function for each item in the arrays.
 

   addRow(i)

      Adds a row to the contributors using data from the 8 data arrays who index

      value equals "i".
 

   addRecord()

      Adds a new record to the end of the 8 data arrays and then calls the addRow() function

      to add a new row to the contributors table and the updateTotals() function to

      update the tables cells displaying the total number of contributors and

      contributions.
 

    removeRecord(index)

       Removes a record from the eight data arrays whose index value equals index.
 

    removeNode(node)

       Removes a node from a node tree, and returns a reference to the node's previous sibling.
 

    removeRecords()

       Loops through the rows in the contributors table checking whether the remove

       checkbox has been selected. For each selected checkbox, the table row is removed

       and the corresponding entries in the 8 data arrays are removed. The updateTotals()

       function is then called.
 

*/
 
 

/*  Within the totalContr table cell, display the length of the amount array. 
 

Create a variable named totalContributions and set its initial value to 0.
 

Create a for loop that loops through each entry in the amount array. Each time through the loop increases the value of the totalContributions variable by the amount in the current entry in thr amount array.
 

Within the totalAmt table cell, display the value of the totalContributions variable     */
 

function updateTotals() {

document.getElementById("totalContr").value = amount.length;

var totalContributions = 0;

   for (i=0; i < amount.length; i++) {

     totalContributions = totalContributions + amount[i];};

document.getElementById("totalAmt").value = totalContributions;

}
 

/*  Create a variable named headingRow that references the table row with the id "titleRow".  This row contains the titles from the contributors table.  Create a second variable named blankRow that references the table row with the id "emptyRow".
 

Use the cloneNode() method to clone the blankRow node.  Set the value of the deep variable to true in order to copy the entire node tree.  Store this document fragment in a variable named dataRow.
 

Create a for loop that loops through the entries in the amount array.  For each entry call the addRow() function using the value of the counter variable in the for loop as the parameter value in the addRow() function.
 

Call the updateTotals() function      */
 

function makeTable() {

var headingRow = document.getElementById("titleRow"); 

var blankRow = document.getElementById("emptyRow"); 

dataRow = blankRow.cloneNode(true);

for ( i = 0; i <amount.length; i++) { addRow(i) ;};

updateTotals();

}
 

/*  Use the cloneNode() method to clone the dataRow document fragment you created in the makeTable() function.  Set the value of the deep parameter to true.  Store this documentfragment in the variable newRow.
 

Change the content of newRow's second child node to the value of the date array using the current index. Change the content of newRow's third child node to the ntex string "lastName, firstName" where lastName and firstName are the values of the lastName and firstName arrays using the current index. Change the content of newRow's fourth child node to the text string "street<br />city, state, zip" where street, city, state, and zip are the current values from the street, city, state, and zip arrays. Change the content of newRow's fifth child node to the value of the amount array.
 

 If the value of the index variable equals 0, meaning that this is the first row being added to the contributor table, then use the replaceChild() method to replace the blankRow node with newRow.  (Hint: Apply the replaceChild() method to the blankRow.parentNode node)  If the index variable is not equal to 0, then insert the newRow node before the next sibling of the headingRow node. (Hint: Apply the insertBefore() method to the headingRow.parentNode node)    */
 

function addRow(i) {

var newRow;

newRow = dataRow.cloneNode(true);

newRow.childNodes[1].nodeValue = date[i];

newRow.childNodes[2].nodeValue = lastName[i] + ", " + firstName[i];

newRow.childNodes[3].nodeValue = street[i] + "<br>" + city[i] + ", " + state[i] + zip[i];

newRow.childNodes[4].nodeValue = amount.length;

if (n = 0) { blankRow.parentNode.replaceChild(newRow, blankRow) };

if (n != 0) { headingRow.parentNode.insertBefore(newRow, headingRow.nextSibling)  };

}
 

/*  Create a variable named recordNum equal to the length of the amount array.
 

Set the value of first[recordNum] to the value of the fname field from the donations Web form.  Set the value of last[recordNum] to the value of the lname field.  Set the value of the street array item to the value of the street field and the value of the city array item to the value of the city field.  Determine which state option has been selected by the user and store the text of the selected option in the state arry item. Set the value of the zip, amount, and date array items to the values of the zip, amount, and date fields in the donations Web form.  
 

Call the addRow() function using the value of the recordNum variable as the parameter value.
 

Call the updateTotals() function.     */
 

function addRecord() {

var recordNum = amount.length;

firstName[recordNum] = data_entry.document.getElementById("fname").nodeValue;

lastName[recordNum] = data_entry.document.getElementById("lname").nodeValue;

street[recordNum] = data_entry.document.getElementById("street").nodeValue;

city[recordNum] = data_entry.document.getElementById("city").nodeValue;

state[recordNum] = data_entry.document.getElementById("state").nodeValue;

zip[recordNum] = data_entry.document.getElementById("zip").nodeValue;

amount[recordNum] = data_entry.document.getElementById("amount").nodeValue;

date[recordNum] = data_entry.document.getElementById("date").nodeValue;

addRow(recordNum);

updateTotals();

}
 

/*  Use the splice() method to remove the item from the firstName array whose index value equals the value of the index parameter.  Remove only one array item.
 

Repeat step for the lastName, street, city, state, zip, amount, and date arrays.    */
 

function removeRecord(index) {

firstName.splice(index,1);

lastName.splice(index,1);

street.splice(index,1);

city.splice(index,1);

state.splice(index,1);

zip.splice(index,1);

amount.splice(index,1);

date.splice(index,1);

}
 

/*  Create a variable named prevNode referencing the node's previous sibling.  
 

Use the removeChild() method to remove the node.  (Hint: Apply the removeChild() method to the node's parent node.)
 

Return the prevNode variable from the function.      */
 

function removeNode(node) {

var prevNode = node.previousSibling;

prevNode.parentNode.removeChild(prevNode);

return prevNode;

}
 

/*  Create a variable named headerRow referencing the row with the id "titleRow".  
 

Create a variable named recordNum equal to the length of the amount array.
 

Create a for loop that uses familial references, starting with the node variable, n, equal to the first sibling of the headerRow node and proceeding to the next sibling (the next table row) until there is no next sibling.  Within the for loop, decrease the value of the recordNum varialbe by 1.  Then, insert an if condition that tests whether the name of the current node is "TR" (a table row).  If it is, insert a second if condition that tests whether the check box within the first table cell of the current row has been selected.  (Hint: Reference the check box using the reference n.firstChild.firstChild.)  If the check box has been checked, then: (1) Call the removeRecord() function using the recordNum as the parameter value, and (2) Let the node counter, n, be equal to the value returned by the removeNode() function using the n as the parameter value.
 

After the for loop has finished, call the updateTotals() function to update the contribution totals in the Web page.     */
 

function removeRecords() {

var headerRow;

ctable.document.getElementById("titleRow") = headerRow;

var recordNum = amount.length;

for ( n = 0; n < headerRow.childNodes.length; n++) {

recordNum = recordNum - 1;

if (headerRow.childNodes[n].name = "TR") {

  if (n.firstChild.firstChild != "") {

    removeRecord(recordNum);

	n = removeNode(n)};

	};

updateTotals(); }

}

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Those that don't have a teacher "handy" tend to want it more... :-)

There are also "style" errors.  By this, I mean that they way the code looks on the script may not make it easy for the human reader to understand.  For example, let's take a look at the "updateTotals()" routine, which you have written like this:

----------------------------------------------------------------------
function updateTotals() {
document.getElementById("totalContr").value = amount.length;
var totalContributions = 0;
   for (i=0; i < amount.length; i++) {
     totalContributions = totalContributions + amount[i];};
document.getElementById("totalAmt").value = totalContributions;
}
----------------------------------------------------------------------

The problems that I see with this routine include:
1. The function body should be indented to show the statements that are part of the routine.   "Correcting" that, gets us to:

----------------------------------------------------------------------
function updateTotals() {
  document.getElementById("totalContr").value = amount.length;
  var totalContributions = 0;
  for (i=0; i < amount.length; i++) {
     totalContributions = totalContributions + amount[i];
  };
  document.getElementById("totalAmt").value = totalContributions;
}
----------------------------------------------------------------------

2. The way that the code is written "requires" the specified document elements to exist.  If they aren't, the user isn't warned about the problem, and the execution of the script stops abruptly.  So, it is always a good idea to verify that document elements exist.  How do we fix this?  One way would be to have a separate routine to do the lookup for the element, and let us know if it doesn't exist.  For example, something like:

----------------------------------------------------------------------
function field( id ) {
  var ele = document.getElementById( id )
  if ( !ele ) {
    alert( 'Specified document element not found. id="' + id + '"' )
  }
  return ele
}
----------------------------------------------------------------------

3. Now that this utility function exists, we can then investigate the routine for which we might be able to use it.  Returning to "updateTotals()", we see that the first occurrence of document.getElementById() is used to locate the "totalContr" element on the page.  ok, but what kind of element is this?  Looking at the HTML, we find:

----------------------------------------------------------------------
<td id="totalContr"></td>
----------------------------------------------------------------------

  Let's use something to make referring to this document element a little easier.  Say we have the following code:

----------------------------------------------------------------------
  var totalContr = field ( 'totalContr' )
----------------------------------------------------------------------

  After executing this statement, the totalContr variable can be used to reference the table cell (i.e., 'td') element having the specified id.

Remember though, that table cell elements don't have a value attribute!

Does this help?
0
 

Author Comment

by:inisrael
Comment Utility
ha!  i want to get this assignment done... that's what I want.  but it was a good joke.  

I know I have to work on my syntax.  Part of me wants to only make it clear enough for me to read, but you're right; I should make it easier for everyone else to read.  The statements used for debugging were great.

It's good that you reminded me that cell elements don't have a value attribute.  That was an obvious mistake and I'll fix that.  
However, for the input boxes I'm trying to extract what the viewers are inputting by using this:

---------------------------------------------------------------------
firstName[recordNum] = data_entry.document.getElementById("fname").nodeValue;
---------------------------------------------------------------------

in the addRecord() function; this id refers to the input field here:

---------------------------------------------------------------------
      <table>
   <tr><td colspan="2"><h3>Enter a New Contributor</h3></td></tr>
   <tr>
      <td>First Name</td><td><input name="fname" id="fname" /></td>
   </tr>
 ---------------------------------------------------------------------

This will work right?  
I'm going to do some work on building my code with these alert statements in place.
0
 

Author Comment

by:inisrael
Comment Utility
How do you assign a value to a table cell if they don't have a value?  I'm trying to put text strings in so many table cells.  This has got to be possible some way.  
For example:
-------------------------------------------------------
newRow.childNodes[2].nodeValue = lastName[i] + ", " + firstName[i];  
-------------------------------------------------------
I'm trying to make this childNode of the newRow (table cell) equal this text string.  That has got to be doable in some fairly easy way.  Hence the instructions:
"Change the content of newRow's second child node to the value of the date array using the current index. Change the content of newRow's third child node to the ntex string "lastName, firstName" where lastName and firstName are the values of the lastName and firstName arrays using the current index."  etc.

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
>> ... for the input boxes I'm trying to extract what the viewers are inputting by using this:

---------------------------------------------------------------------
firstName[recordNum] = data_entry.document.getElementById("fname").nodeValue;
---------------------------------------------------------------------

Correct.  However, remember that id Attributes need to be unique.
If you have a table, with the 2nd column as "Name", then the 1st data row might have:

<td><input name="fname" id="fname" />

But the next row, if you want to access it by it's id attribute, must have a different id attribute value.  Frequently, people have the row number as a suffix.  So for the first row, they might use either this:

<td><input name="fname" id="fname1" />

or this:

<td><input name="fname" id="fname01" />

Does that make sense?

>> How do you assign a value to a table cell if they don't have a value?

Well, that corresponds to this HTML syntax:

<td>Some data here</td>

Which gets translated by the browser into 2 document elements:
- 1 for the "td", and the "child" node element which is of type "#text", which is a text element.

Try this:


<html>

<body>
 

<table border='1'>

  <tr>

    <td id='here'>Some data</td>

  </tr>

</table>
 

<script type="text/javascript">
 

var td = document.getElementById( 'here' )

alert( td.firstChild.nodeName )
 

</script>
 

</body>

</html>

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Take a look at this.  It might help...
<html>

<body>
 

<table border='1'>

  <tbody>

    <tr>

      <th>Date</th>

      <th>Name</th>

      <th>Address</th>

      <th>Amount</th>

    </tr>

    <tr id='empty'>

      <td>01/02/2003</td>

      <td>Name</td>

      <td>Address</td>

      <td>Amount</td>

    </tr>

  </tbody>

</table>
 

<script type="text/javascript">
 

var tr = document.getElementById( 'empty' )

var tds = tr.getElementsByTagName( 'TD' )

tds[ 1 ].firstChild.nodeValue = 'Elmer Bimbo'

</script>
 

</body>

</html>

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Technically, I think that this is more correct table syntax though.
<table border='1'>

  <thead>

    <tr>

      <th>Date</th>

      <th>Name</th>

      <th>Address</th>

      <th>Amount</th>

    </tr>

  </thead>

  <tbody>

    <tr id='empty'>

      <td>01/02/2003</td>

      <td>Name</td>

      <td>Address</td>

      <td>Amount</td>

    </tr>

  </tbody>

</table>

Open in new window

0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Though personally, I don't like the way that Chrome renders it...
0
 

Author Comment

by:inisrael
Comment Utility
I've been using this script that you sent me; I really appreciate it.  I'm trying to figure out how to change the content of the table cell and I've pasted what I have so far below.  What I'm doing is obviously not working.  Any suggestions?
<html>

<body>

 

<table border='1'>

  <tr>

    <td id='here'>Some data</td>

  </tr>

<html>

<head>

<title>Untitled Document</title>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

</head>
 
 

<body>

 

<table border='1'>

  <tr>

    <td id='here'>Some data</td>

  </tr>

</table>

 

<script type="text/javascript">

  function updateTotals() {

document.getElementById( 'here' ).value = "I want to change this text";

}

 

 updateTotals();

var td = document.getElementById( 'here' )
 

alert( td.firstChild.nodeValue )

 
 

</script>

 

</body>

</html>
 

</html>

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Does this help?
<html>

<head>

<title>Untitled Document</title>

<script type="text/javascript">

  function updateTotals() {

    var here = document.getElementById( 'here' )

    if ( here ) {

      alert( 'here -> ' + here.nodeName )

      var child = here.firstChild

      alert( 'child -> ' + child.nodeName )

      child.nodeValue = "I want to change this text"

    } else {

      alert( '"here" not found.' )

    }

}

</script>
 

</head>

<body onload='updateTotals()'>

 

<table border='1'>

  <tr>

    <td id='here'>Some data</td>

  </tr>

</table>
 

</body>

</html>

 

</html>

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
If you really are, In Israel, it's like 5am... Have you been going at this all night?
0
 

Author Comment

by:inisrael
Comment Utility
lol, No, I was in Israel last summer but no I'm not in Israel right now. It's a play on my name.  
What you sent does work like a charm.  I ended up making this in the process and it works too.
Now I just have to apply it!
<body>

 

<table border='1'>

  <tr>

    <td id='here'>Some Text</td>

  </tr>

</table>

 

<script type="text/javascript">
 
 

var td = document.getElementById( 'here' );

td.innerHTML="I want to change this text";

alert( td.firstChild.nodeValue );

 
 

</script>

 

</body>

Open in new window

0
 
LVL 41

Accepted Solution

by:
HonorGod earned 500 total points
Comment Utility
Do you understand it though?
When a browser is processing the HTML, it build a hierarchy of document objects to represent the HTML.

So, when you do something like:

var td = document.getElementById( 'here' );

It puts into the variable named "td" a reference to the document element that has the id attribute value of "here" (if one exists).

The relationship between a TD element, and its contents, i.e., the text in this case of "Some Text" is that the text element is considered a child of the TD element.  The attribute of a TD element that is used to refer to the first child is named firstChild.

So, when we use:

td.firstChild

That is, in fact, referring to the the text node (in this specific, and particular instance).

Each node in the hierarchy has a "nodeName" attribute that tell what kind of element it is.

In this case, if you output the value of td.firstChild.nodeName, you will get "#text" which identifies it as a "text" node.

And the actual data, or text, within this node element, is found in the nodeValue attribute.

That's why changing it changes what is seen on the screen.

Does that help?
0
 

Author Comment

by:inisrael
Comment Utility
OK, from what I can see, the following code should now work for the updateTotals() function.  
If you don't think it will, please let me know.  
Thanks for your help with that function by the way.
function updateTotals() {

var contributors = document.getElementById( 'totalContr' );

contributors.innerHTML= amount.length;

var totalContributions = 0;

   for (i=0; i < amount.length; i++) {

     totalContributions = totalContributions + amount[i];}

var totalAmount = document.getElementById( 'totalAmt' );

totalAmount.innerHTML= totalContributions;

}

Open in new window

0
 

Author Comment

by:inisrael
Comment Utility
Yeah, that makes sense.  Thanks for explaining that.  So, why do we have to assign a variable to an element of the html document before we can change it's value and access the nodeName?  why can't we just say first child of the row element of the table element and start accessing its value and name?
0
 

Author Comment

by:inisrael
Comment Utility
I guess I could have done the following:
function updateTotals() {

document.getElementById( 'totalContr' ).innerHTML = amount.length;

var totalContributions = 0;

   for (i=0; i < amount.length; i++) {

     totalContributions = totalContributions + amount[i];}

document.getElementById( 'totalAmt' ).innerHTML = totalContributions;

}

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
>> So, why do we have to assign a variable to an element of the html document before we can change it's value?

Because if you don't verify that the element exists, and we try to use the result of document.getElementById() for a non-existent element, the result of which is null, then most JavaScript engines stop running (processing the code) when an error like this occurs....

For example, this this, and see if it does what you expect
<html>

<body>
 

<input id='here' value='Something'>
 

<script type="text/javascript">
 

document.getElementById( 'Here' ).value = 'testing'

alert( 'done' )
 

</script>
 

</body>

</html>

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Your indentation, or lack thereof, and your style are going to cause you, and anyone who reads your code, headaches.

Which is easier to follow, http://#a24292289, or this?
function updateTotals() {

  var totalContr = document.getElementById( 'totalContr' )

  if ( totalContr ) {

    totalContr.innerHTML = amount.length;

    var totalContributions = 0;

    for ( var i=0; i < amount.length; i++ ) {

      totalContributions += amount[ i ];

    }

    var totalAmt = document.getElementById( 'totalAmt' )

    if ( totalAmt ) {

      totalAmt.innerHTML = totalContributions;

    }

  }

}

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Thanks for the grade & points.

Good luck & have a great day.
0
 

Expert Comment

by:digiby
Comment Utility
Hi,

I have been following this thread to try to understand the same problem that I am currently working on. It may be a bit late to ask now, since i have to submit this in 6 hours, but I got everything to work except the removing of the records. I pasted my code below, any help will be greatly appreciated. The instructions are the same with inisrael.
function removeRecord(index) {
    firstName.splice(index, 1);
	lastName.splice(index, 1);
	street.splice(index, 1);
	city.splice(index, 1);
	state.splice(index, 1);
	zip.splice(index, 1);
	amount.splice(index, 1);
	date.splice(index,1);		
}
function removeNode(node) {
	prevNode = node.previousSibling;
	prevNode.parentNode.removeChild(prevNode);
	return prevNode;
}
function removeRecords() {
    headerRow = document.getElementById("titleRow");
    recordNum = amount.length;
    for (var n = headerRow.parentNode.firstChild; n < headerRow.parentNode.childNodes.length;
	     n=n.nextSibling) {
          recordNum += - 1;
		  if (n.name == "TR") {
              if (n.firstChild.firstChild != "") {
                  removeRecord(recordNum);
	              n = removeNode(n);
			  }
	      }
    updateTotals(); 
	}
}

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
;-(

Having functions access, use, and modify global variable should really be discouraged.

Does that make sense?

Go ahead and open a new (related) question.  That way more people are likely to see it, and comment on it.
0
 

Expert Comment

by:digiby
Comment Utility
No, I'm not sure i understand what you mean. I opened a new related topic question.

Related Question
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction HTML checkboxes provide the perfect way for a web developer to receive client input when the client's options might be none, one or many.  But the PHP code for processing the checkboxes can be confusing at first.  What if a checkbox is…
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now