PDA

View Full Version : Adding a div or table from a button



Humper
10-23-2008, 03:45 PM
I am creating a page that has a form for a customer to fill out. I need to allow the user to add comments one line at a time. What I cant figure out is how can I add a table (or div) by pressing on a button? I need to be able to add an unknown amount of tables and with in that table I need to be able to add rows by pressing on a button. So this is a two step process. I looked into AJAX but I am very new to javascript and I am completely lost. I just need a starting point. Can someone show me a simple example? or use my code to show me.

Here is what my form looks like so far:


<!-- Connect to the Database -->
<?php

include "common_vars.inc";

mysql_connect($HostName,$UserName, $Password) OR DIE ("Unable to connect to database! Please try again later.");
mysql_select_db($DBName);

$UserName= $_GET["UserName"];

?>

<form name="WDR" action="Add_WDR.php" method="post" >
<div id="container">
<table width="100%" border="0">
<tr>
<td colspan="2"> image goes here </td>
<td colspan="4" align="left"> <span class="heading">Weekly Direct Report</span><br /> </td>
</tr>
<tr>
<td colspan="6"><hr /></td>
</tr>
</table>
<div class="mainindexTable">
<table width="100%" border="0">
<tr>
<td width="21%">
<strong>UserName:</strong><br />
<input name="UserName" type="text" id="UserName" size="16" maxlength="16" disabled="disabled" value="<?php echo $UserName; ?>" />
</td>
<td width="13%">
<strong>Date:</strong><br />
<input name="ReportDate" type="text" id="ReportDate" size="8" maxlength="8"/>
</td>
<td width="17%">
<strong>Anticipated Travel:</strong><br />
<select name="AnticipatedTravel">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select> </td>
<td width="49%">
<strong>Anticipated Leave:</strong><br />
<select name="AnticipatedLeave">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select>
</td>
</tr>
<tr>
<td colspan="4">
<input type="button" name="AddDO" id="AddDO" value="Add Another DO" onclick="hide()" />
</td>
</tr>
</table>
</div>
<div id="Data" class="mainindexTableBG">
<table width="100%" border="0" style="display:block" id="Table">
<tr>
<td>
<strong>Select DO:</strong><br />
<select name="DO1">
<option value="#" selected="selected">Task Name</option>
<?php

$query = "SELECT DO, TaskName FROM DeliveryOrders ORDER BY TaskName";
$result = mysql_query($query);

while($row= mysql_fetch_array($result))
{
$DONum = $row["DO"];
$TaskName = $row["TaskName"];
$DO = $TaskName . " " . $DONum;
echo "<option value=\"$DO\">$DO</option>";
}
?>
</select>
</td>
<td width="9%">
<strong>Hours:</strong><br />
<input name="RegularHours" type="text" id="RegularHours" size="8" maxlength="8"/>
</td>
<td width="12%">
<strong>Travel on this DO:</strong><br />
<input type="checkbox" name="Travel" value="Yes" onclick="hide()"/>Yes</td>
<td width="13%" id="TravelExp" style="visibility:hidden">
<strong>Travel Expense:</strong><br />
$<input name="TravelExp" type="text" id="TravelExp" size="15" maxlength="15"/>
</td>
<td width="18%" id="TravelExpODC" style="visibility:hidden">
<strong>OCD Travel Expense:</strong><br />
$<input name="TravelExpODC" type="text" id="TravelExpODC" size="15" maxlength="15"/>
</td>
<td width="32%">
&nbsp;
</td>
</tr>
</table>
<table width="100%" border="0">
<tr>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td width="34%">
<span class="tableheadings"><?php echo $DO. "Highlights"; ?></span><br />
<input name="Highlights" type="text" id="Highlights" size="50" maxlength="100" />
</td>
<td width="34%">
<strong>Select Common Task:</strong><br />
<select name="CommonTask" id="CommonTask">
<option value="#" selected="selected">Common Tasks</option>
<?php
$query1 = "SELECT TaskDesc FROM CommonTasks ORDER BY TaskDesc";
$result1 = mysql_query($query1);

while($row1= mysql_fetch_array($result1))
{
$Task = $row1["TaskDesc"];

print "<option value=\"$Task\" > $Task </option>";
}
?>
</select>
</td>
<td width="32%">
<input type="button" value="Add another Highlight" />
</td>
</tr>
</table>
</div>
<div id="End" class="mainindexTable">
<table width="100%">
<tr>
<td height="46" colspan="6" align="left"><input name="Submit" type="submit" value="Submit WDR" /> </td>
</tr>
</table>
</div>
</div>
</form>




Here is a link to the page...
http://www.southernsinners.com/WDR/WDR.php

Jesdisciple
10-23-2008, 06:11 PM
Here's an example which adds X new rows to your table of highlights.

I've moved your HTML around a bit because you use strong tags in table cells to simulate table headers. This makes the headers be repeated for every copy of the cells, but headers only need to be at the table's top.
<html>
<head>
<title>Titled Document</title>
<style type="text/css">
th{
text-align: left;
}
</style>
</head>
<body>
<form name="WDR" action="Add_WDR.php" method="post" >
<div id="container">
<table width="100%" border="0">
<tr>
<td colspan="2"> image goes here </td>
<td colspan="4" align="left">
<span class="heading">Weekly Direct Report</span><br />
</td>
</tr>
<tr>
<td colspan="6"><hr /></td>
</tr>
</table>
<div class="mainindexTable">
<table width="100%" border="0">
<tr>
<td width="21%">
<strong>UserName:</strong><br />
<input name="UserName" type="text" id="UserName" size="16" maxlength="16" disabled="disabled" value="<?php echo $UserName; ?>" />
</td>
<td width="13%">
<strong>Date:</strong><br />
<input name="ReportDate" type="text" id="ReportDate" size="8" maxlength="8"/>
</td>
<td width="17%">
<strong>Anticipated Travel:</strong><br />
<select name="AnticipatedTravel">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select> </td>
<td width="49%">
<strong>Anticipated Leave:</strong><br />
<select name="AnticipatedLeave">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select>
</td>
</tr>
<tr>
<td colspan="4">
<input type="button" name="AddDO" id="AddDO" value="Add Another DO" onclick="hide()" />
</td>
</tr>
</table>
</div>
<div id="Data" class="mainindexTableBG">
<table width="100%" border="0" style="display:block" id="Table">
<tr>
<td>
<strong>Select DO:</strong><br />
<select name="DO1">
<option value="#" selected="selected">Task Name</option>
<?php
$query = "SELECT DO, TaskName FROM DeliveryOrders ORDER BY TaskName";
$result = mysql_query($query);

while($row= mysql_fetch_array($result))
{
$DONum = $row["DO"];
$TaskName = $row["TaskName"];
$DO = $TaskName . " " . $DONum;
echo "<option value=\"$DO\">$DO</option>";
}
?>
</select>
</td>
<td width="9%">
<strong>Hours:</strong><br />
<input name="RegularHours" type="text" id="RegularHours" size="8" maxlength="8"/>
</td>
<td width="12%">
<strong>Travel on this DO:</strong><br />
<input type="checkbox" name="Travel" value="Yes" onclick="hide()"/>Yes</td>
<td width="13%" id="TravelExp" style="visibility:hidden">
<strong>Travel Expense:</strong><br />
$<input name="TravelExp" type="text" id="TravelExp" size="15" maxlength="15"/>
</td>
<td width="18%" id="TravelExpODC" style="visibility:hidden">
<strong>OCD Travel Expense:</strong><br />
$<input name="TravelExpODC" type="text" id="TravelExpODC" size="15" maxlength="15"/>
</td>
<td width="32%">
&nbsp;
</td>
</tr>
</table>
<table width="100%" border="0">
<tr>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<th align="left"><?php echo $DO. "Highlights"; ?></th>
<th align="left">Select Common Task:</th>
</tr>
<tr>
<td width="34%">
<input name="Highlights" type="text" id="Highlights" size="50" maxlength="100" />
</td>
<td width="34%">
<select name="CommonTask" id="CommonTask">
<option value="#" selected="selected">Common Tasks</option>
<?php
$query1 = "SELECT TaskDesc FROM CommonTasks ORDER BY TaskDesc";
$result1 = mysql_query($query1);

while($row1= mysql_fetch_array($result1))
{
$Task = $row1["TaskDesc"];

print "<option value=\"$Task\" > $Task </option>";
}
?>
</select>
</td>
<td width="32%">
<input type="button" value="Add another Highlight" id="AddHighlight" />
</td>
</tr>
</table>
</div>
<div id="End" class="mainindexTable">
<table width="100%">
<tr>
<td height="46" colspan="6" align="left"><input name="Submit" type="submit" value="Submit WDR" /> </td>
</tr>
</table>
</div>
</div>
</form>
<script type="text/javascript" src="Duplicator.js"></script>
</body>
</html>

Duplicator.js
//Change anything but this function.
function makeDuplicator(button, element, callback){
//If 'callback' was passed, pass the prototype through it.
var prototype = (callback || function(e){return e;})(element.cloneNode(true));
button.onclick = function(){
element.parentNode.appendChild(prototype.cloneNode(true));
};
}
var addHighlight = document.getElementById('AddHighlight');
var callback = function(prototype){
//Get rid of the button.
prototype.deleteCell(2);
//Blank the text input in case the page was refreshed.
prototype.cells[0].childNodes[1].value = '';
return prototype;
};
//The second argument is the row which contains the button.
makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, callback);

Humper
10-23-2008, 07:02 PM
Jesdisciple ----- Thank You!! That works great!

I do have a problem tho... I need to put this information into a database and it seems that this would only get the last highlight? How can I create a unique ID for each row(highlight) I add?

Another issue is how can I create a new instance of the entire gray section. I also need to add this information to a database... so it would also need to be able to create unique IDs.

Jesdisciple
10-23-2008, 07:09 PM
Append [] to each field's name attribute and access them all as an array without the [] in the name.
$Highlights = $_POST['Highlights'];
for($ = 0; $i < count($Highlights); $i++){
//Do something with '$Highlights[$i]'.
}
<td width="34%">
<input name="Highlights[]" type="text" id="Highlights" size="50" maxlength="100" />
</td>As for the id, I hope no script needs that, because it will only return the first one. Use getElementsByName('Highlights[]') instead.


Another issue is how can I create a new instance of the entire gray section.I don't understand... What gray section? EDIT: Oh, the username? And only that?

Humper
10-23-2008, 07:24 PM
Thanks that will work for my first question....

"What gray section? EDIT: Oh, the username? And only that? " ---- No

Sorry I didnt explain better.....I mean the whole <div id="Data" class="mainindexTableBG"> section...

check out the link in the first post.. the Add Another DO button needs to add another (gray)section and I need all those fields to also be able to be added to a database..

Hopfully that is a little clearer....

Jesdisciple
10-23-2008, 09:07 PM
Ooh... That complicates things a good bit because 1) the onclick handler won't get copied with its button, so the callbacks have to be nested and 2) the form data arrays I just described need to be two-dimensional (but only inside the "Highlights" table).

To accomplish #2, you'll have to end every name inside the "Highlights" table with [0][] instead of just []. Also, keep the id values of those same elements identical to the name values except without the [0][]. I'll increment the index so PHP will understand.


function makeDuplicator(button, element, callback, nestingCallback){
//If 'callback' was passed, pass the prototype through it.
var prototype = (callback || lazy)(element.cloneNode(true));
button.onclick = function(){
//If 'nestingCallback' was passed, pass the clone through it.
var clone = (nestingCallback || lazy)(prototype.cloneNode(true));
element.parentNode.appendChild(clone);
};
function lazy(e){
return e;
}
}
var nestedCallback = function(prototype){
//Get rid of the button.
prototype.deleteCell(2);
//Blank the text input in case the page was refreshed.
prototype.cells[0].childNodes[1].value = '';
return prototype;
};

//The callback (below) won't do this because it never sees the original DIV.
var addHighlight = document.getElementById('AddHighlight');
makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, nestedCallback);

var callback = function(clone){
var highlights = clone.childNodes[3].rows[2];

//Leave instructions for PHP or it will get confused.
callback.index++;
updateNameOf(highlights.cells[0].childNodes[1]);
updateNameOf(highlights.cells[1].childNodes[1]);
function updateNameOf(element){
element.name = element.id + '[' + callback.index + '][]';
}

var addHighlight = highlights.cells[2].childNodes[1];
makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, nestedCallback);
return clone;
};
callback.index = 0;

makeDuplicator(document.getElementById('AddDO'), document.getElementById('Data'), null, callback);

Humper
10-24-2008, 01:37 PM
OK... I had to do a little redesign on the form. I needed to capture data in a different way. I just broke one of the sections into two different <div> sections.

I am having issues getting the sections to duplicate. I am trying to understand the javascript you posted but I thought I would go ahead and ask if you could help me figure out what I am doing wrong...

http://www.southernsinners.com/WDR/WDR.php
From the above site.... I need the "Add Another DO" button to add a whole new gray section(<div id="DOandHours">) to the page... this is independent of anything else..... Then I also need the "Add Another Task" button to add a whole new blue section(<div id="TaskAndHighlights">) to the page.

Here is my code:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Weekly Direct Report for <?php echo $UserName; ?></title>
<link href="style.css" rel="stylesheet" type="text/css" />

<script type="text/javascript">

//function to unhide fields
function hide()
{
if(document["WDR"]["Travel"].checked)
{
document.getElementById("TravelExpTD").style.visibility="visible"
document.getElementById("TravelExpODCTD").style.visibility="visible"
}
else
{
document.getElementById("TravelExpTD").style.visibility="hidden"
document.getElementById("TravelExpODCTD").style.visibility="hidden"
}
}

</script>

</head>

<body>

<!-- Connect to the Database -->
<?php

//connection here

$UserName= $_GET["UserName"];

?>

<form name="WDR" action="Add_WDR.php" method="post" >
<div id="container">
<table width="100%" border="0">
<tr>
<td colspan="2"> <!-- <img src="" alt="IMG" /> --> </td>
<td colspan="4" align="left"> <span class="heading">Weekly Direct Report</span><br /> </td>
</tr>
<tr>
<td colspan="6"><hr /></td>
</tr>
</table>
<div class="mainindexTable">
<table width="100%" border="0">
<tr>
<td width="21%">
<strong>UserName:</strong><br />
<input name="UserName" type="text" id="UserName" size="16" maxlength="16" disabled="disabled" value="<?php echo $UserName; ?>" />
</td>
<td width="13%">
<strong>Date:</strong><br />
<input name="ReportDate" type="text" id="ReportDate" size="8" maxlength="8"/>
</td>
<td width="17%">
<strong>Anticipated Travel:</strong><br />
<select name="AnticipatedTravel">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select> </td>
<td width="49%">
<strong>Anticipated Leave:</strong><br />
<select name="AnticipatedLeave">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select>
</td>
</tr>
<tr>
<td colspan="4">&nbsp;

</td>
</tr>
<!--<tr>
<td colspan="4">
<input type="button" name="AddDO" id="AddDO" value="Add Another DO" />
</td>
</tr> -->
</table>
</div>
<div id="DOandHours" class="mainindexTableBG">
<table width="100%" border="0" style="display:block" id="Table">
<tr>
<td width="16%">
<input type="button" name="AddDO" id="AddDO" value="Add Another DO" />
</td>
</tr>
<tr>
<td>
<strong>Select DO:</strong><br />
<select name="DO1">
<option value="#" selected="selected">Select DO</option>
<?php

//$query = "SELECT DO, TaskName FROM DeliveryOrders ORDER BY TaskName";
$query = "SELECT DO FROM DeliveryOrders ORDER BY DO DESC";
$result = mysql_query($query);

while($row= mysql_fetch_array($result))
{
$DONum = $row["DO"];
//$TaskName = $row["TaskName"];
//$DO = $TaskName . " " . $DONum;
//echo "<option name=\"DONum[]\" value=\"$DO\">$DO</option>";
echo "<option name=\"DONum[][]\" value=\"$DONum\">$DONum</option>";
}
?>
</select>
</td>
<td width="9%">
<strong>Hours:</strong><br />
<input name="RegularHours[][]" type="text" id="RegularHours" size="8" maxlength="8"/>
</td>
<td width="12%">
<strong>Travel on this DO:</strong><br />
<input type="checkbox" name="Travel" value="Yes" onclick="hide()"/>Yes</td>
<td width="15%" id="TravelExpTD" style="visibility:hidden">
<strong>Travel Expense:</strong><br />
$<input name="TravelExp[][]" type="text" id="TravelExp" size="15" maxlength="15"/>
</td>
<td width="18%" id="TravelExpODCTD" style="visibility:hidden">
<strong>OCD Travel Expense:</strong><br />
$<input name="TravelExpODC[][]" type="text" id="TravelExpODC" size="15" maxlength="15"/>
</td>
</tr>
</table>
</div>
<div id="TaskAndHighlights" class="mainindexTableTask">
<table width="100%" border="0">
<tr>
<td><input type="button" value="Add Another Task" id="AddTask" />
</td>
</tr>
<tr>
<th align="left">Task:</th>
</tr>
<tr>
<td><select name="WorkedTask">
<option value="#" selected="selected">Task Name</option>
<?php

$query = "SELECT TaskName FROM DeliveryOrders ORDER BY TaskName";
$result = mysql_query($query);

while($row= mysql_fetch_array($result))
{
$TaskName = $row["TaskName"];
echo "<option name=\"TaskName[][]\" value=\"$TaskName\">$TaskName</option>";
}
?>
</select>
</td>
</tr>
<tr>
<th align="left">Highlights:</th>
<th align="left">Select Common Task:</th>
</tr>
<tr>
<td width="34%"><input name="Highlights[][]" type="text" id="Highlights" size="50" maxlength="100" />
</td>
<td width="34%"><select name="CommonTask" id="CommonTask">
<option value="#" selected="selected">Common Tasks</option>
<?php
$query1 = "SELECT TaskDesc FROM CommonTasks ORDER BY TaskDesc";
$result1 = mysql_query($query1);

while($row1= mysql_fetch_array($result1))
{
$Task = $row1["TaskDesc"];

print "<option value=\"$Task\" > $Task </option>";
}
?>
</select>
</td>
<td width="32%"><input type="button" value="Add another Highlight" id="AddHighlight" />
</td>
</tr>
</table>
</div>
<div id="End" class="mainindexTable">
<table width="100%">
<tr>
<td height="46" colspan="6" align="left"><input name="Submit" type="submit" value="Submit WDR" /> </td>
</tr>
</table>
</div>
</div>
</form>
<script type="text/javascript" src="Duplicator.js"></script>

</body>
</html>



And here is the javascript code I am using:


function makeDuplicator(button, element, callback, nestingCallback){
//If 'callback' was passed, pass the prototype through it.
var prototype = (callback || lazy)(element.cloneNode(true));
button.onclick = function(){
//If 'nestingCallback' was passed, pass the clone through it.
var clone = (nestingCallback || lazy)(prototype.cloneNode(true));
element.parentNode.appendChild(clone);
};
function lazy(e){
return e;
}
}
var nestedCallback = function(prototype){
//Get rid of the button.
prototype.deleteCell(2);
//Blank the text input in case the page was refreshed.
prototype.cells[0].childNodes[1].value = '';
return prototype;
};

//The callback (below) won't do this because it never sees the original DIV.
var addHighlight = document.getElementById('AddHighlight');
makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, nestedCallback);

var callback = function(clone){
var highlights = clone.childNodes[3].rows[2];

//Leave instructions for PHP or it will get confused.
callback.index++;
updateNameOf(highlights.cells[0].childNodes[1]);
updateNameOf(highlights.cells[1].childNodes[1]);
function updateNameOf(element){
element.name = element.id + '[' + callback.index + '][]';
}

var addHighlight = highlights.cells[2].childNodes[1];
makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, nestedCallback);
return clone;
};
callback.index = 0;

makeDuplicator(document.getElementById('AddDO'), document.getElementById('DOandHours'), null, callback);

Jesdisciple
10-24-2008, 05:24 PM
Before I start on the JS, I want to clarify three points about the forms and let you respond while I look at the code.
In select menus, select elements have names and option elements have values, but options do not have names. You will get a nasty surprise if you try to code PHP like that.
That [][] suffix will not work (EDIT: at least not by itself, I don't know whether it would with help from JS), which is why I said to use [0][] and let me increment the first index. When PHP sees [] in either PHP code or form names, it appends an index to ("pushes" an element onto) the array named just before the brackets. When you use [][], PHP reads it as [$length][0], so the second dimension is entirely useless.
The second dimension is only appropriate for form elements inside an area which is duplicated by the JavaScript.

Also, completely unrelated to forms, your HTML violates its XHTML doctype several times over, and validating it would be a great way for you to help me get this done for you if you have any problems after this. Reasonable indentation would be an even better way.

Humper
10-24-2008, 06:04 PM
OK sorry about that.. I just went to w3schools and validated the code... it's all valid now.. or so it says... I also fixed the select statements to not have name in the option element.... I have good indention in Dreamweaver but when I copy and paste the code it gets messed up.. sorry I will try and format this better...



<form name="WDR" action="Add_WDR.php" method="post" >
<div id="container">
<table width="100%" border="0">
<tr>
<td colspan="2"> <!-- <img src="" alt="IMG" /> --> </td>
<td colspan="4" align="left"><span class="heading">Weekly Direct Report</span><br /></td>
</tr>
<tr>
<td colspan="6"><hr /></td>
</tr>
</table>
<div class="mainindexTable">
<table width="100%" border="0">
<tr>
<td width="21%">
<strong>UserName:</strong><br />
<input name="UserName" type="text" id="UserName" size="16" maxlength="16" disabled="disabled" value="<?php echo $UserName; ?>" />
</td>
<td width="13%">
<strong>Date:</strong><br />
<input name="ReportDate" type="text" id="ReportDate" size="8" maxlength="8"/>
</td>
<td width="17%">
<strong>Anticipated Travel:</strong><br />
<select name="AnticipatedTravel">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select>
</td>
<td width="49%">
<strong>Anticipated Leave:</strong><br />
<select name="AnticipatedLeave">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select>
</td>
</tr>
<tr>
<td colspan="4">&nbsp;</td>
</tr>
<!--<tr>
<td colspan="4">
<input type="button" name="AddDO" id="AddDO" value="Add Another DO" />
</td>
</tr> -->
</table>
</div>
<div id="DOandHours" class="mainindexTableBG">
<table width="100%" border="0" style="display:block" id="Table">
<tr>
<td width="16%">
<input type="button" name="AddDO" id="AddDO" value="Add Another DO" />
</td>
</tr>
<tr>
<td>
<strong>Select DO:</strong><br />
<select name="DO[0][]" id="DO">
<option value="#" selected="selected">Select DO</option>
<?php

//$query = "SELECT DO, TaskName FROM DeliveryOrders ORDER BY TaskName";
$query = "SELECT DO FROM DeliveryOrders ORDER BY DO DESC";
$result = mysql_query($query);

while($row= mysql_fetch_array($result))
{
$DONum = $row["DO"];
echo "<option value=\"$DONum\">$DONum</option>";
}
?>
</select>
</td>
<td width="9%">
<strong>Hours:</strong><br />
<input name="RegularHours[0][]" type="text" id="RegularHours" size="8" maxlength="8"/>
</td>
<td width="12%">
<strong>Travel on this DO:</strong><br />
<input type="checkbox" name="Travel" value="Yes" onclick="hide()"/>Yes
</td>
<td width="15%" id="TravelExpTD" style="visibility:hidden">
<strong>Travel Expense:</strong><br />
$<input name="TravelExp[0][]" type="text" id="TravelExp" size="15" maxlength="15"/>
</td>
<td width="18%" id="TravelExpODCTD" style="visibility:hidden">
<strong>OCD Travel Expense:</strong><br />
$<input name="TravelExpODC[0][]" type="text" id="TravelExpODC" size="15" maxlength="15"/>
</td>
</tr>
</table>
</div>
<div id="TaskAndHighlights" class="mainindexTableTask">
<table width="100%" border="0">
<tr>
<td><input type="button" value="Add Another Task" id="AddTask" /></td>
</tr>
<tr>
<th align="left">Task:</th>
</tr>
<tr>
<td>
<select name="WorkedTask[0][]" id="WorkedTask">
<option value="#" selected="selected">Task Name</option>
<?php

$query = "SELECT TaskName FROM DeliveryOrders ORDER BY TaskName";
$result = mysql_query($query);

while($row= mysql_fetch_array($result))
{
$TaskName = $row["TaskName"];
echo "<option value=\"$TaskName\">$TaskName</option>";
}
?>
</select>
</td>
</tr>
<tr>
<th align="left">Highlights:</th>
<th align="left">Select Common Task:</th>
</tr>
<tr>
<td width="34%"><input name="Highlights[0][]" type="text" id="Highlights" size="50" maxlength="100" /></td>
<td width="34%">
<select name="CommonTask" id="CommonTask">
<option value="#" selected="selected">Common Tasks</option>
<?php
$query1 = "SELECT TaskDesc FROM CommonTasks ORDER BY TaskDesc";
$result1 = mysql_query($query1);

while($row1= mysql_fetch_array($result1))
{
$Task = $row1["TaskDesc"];
print "<option value=\"$Task\" > $Task </option>";
}
?>
</select>
</td>
<td width="32%"><input type="button" value="Add another Highlight" id="AddHighlight" /></td>
<td>
<input type="button" value="Remove Highlight" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" /> <!-- This doesnt work correctly -->
</td>
</tr>
</table>
</div>
<div id="End" class="mainindexTable">
<table width="100%">
<tr>
<td height="46" colspan="6" align="left"><input name="Submit" type="submit" value="Submit WDR" /> </td>
</tr>
</table>
</div>
</div>
</form>
<script type="text/javascript" src="Duplicator.js"></script>



Hopefully that's formatted a little better!

Jesdisciple
10-24-2008, 07:13 PM
I don't mean to sound like a drill sergeant; it's sometimes hard for me to gauge how much force I'm putting into my statements (and how much others intended in theirs). Plus going through a lot of poorly formatted sources gets old fast - but the experience and ideas I get are easily worth it.

Just to check... Do you use Design View (or Mode, or whatever it is) in Dreamweaver? If so, please stop; the worst coder in the world is surely a WYSIWYG.

Also, I advise you to post this page in the HTML forum and ask what could be done better. Using a lot more CSS instead of all the styling HTML attributes is the first thing I would suggest. Not using tables so much might be the second; if not, using table headers would be.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>


<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Weekly Direct Report for </title>
<link href="index_files/style.css" rel="stylesheet" type="text/css" />

<script type="text/javascript">

//function to unhide fields
function hide(){
if(document["WDR"]["Travel"].checked)
{
document.getElementById("TravelExpTD").style.visibility="visible"
document.getElementById("TravelExpODCTD").style.visibility="visible"
}
else
{
document.getElementById("TravelExpTD").style.visibility="hidden"
document.getElementById("TravelExpODCTD").style.visibility="hidden"
}
}

</script>

</head>
<body>

<!-- Connect to the Database -->

<form name="WDR" action="Add_WDR.php" method="post">
<div id="container">
<table border="0" width="100%">
<tbody>
<tr>
<td colspan="2"><!-- <img src="" alt="IMG" /> --></td>
<td colspan="4" align="left">
<span class="heading">Weekly Direct Report</span><br />
</td>
</tr>
<tr>
<td colspan="6">
<hr />
</td>
</tr>
</tbody>
</table>
<div class="mainindexTable">
<table border="0" width="100%">
<tbody>
<tr>
<th align="left">UserName:</th>
<th align="left">Date:</th>
<th align="left">Anticipated Travel:</th>
<th align="left">Anticipated Leave:</th>
</tr>
<tr>
<td width="21%">
<input name="UserName" id="UserName" size="16" maxlength="16" disabled="disabled" value="" type="text" />
</td>
<td width="13%">
<input name="ReportDate" id="ReportDate" size="8" maxlength="8" type="text" />
</td>
<td width="17%">
<select name="AnticipatedTravel">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select>
</td>
<td width="49%">
<select name="AnticipatedLeave">
<option value="No" selected="selected">No</option>
<option value="Yes">Yes</option>
</select>
</td>
</tr>
<tr>
<td colspan="4">&nbsp;</td>
</tr>
<!--<tr>
<td colspan="4">
<input type="button" name="AddDO" id="AddDO" value="Add Another DO" />
</td>
</tr> -->
</tbody>
</table>
</div>
<div id="DOandHours" class="mainindexTableBG">
<table style="display: block;" id="Table" border="0" width="100%">
<tbody>
<tr>
<td width="16%">
<input name="AddDO" id="AddDO" value="Add Another DO" type="button" />
</td>
</tr>
<tr>
<th align="left">Select DO:</th>
<th align="left">Hours:</th>
<th align="left">Travel on this DO:</th>
<th align="left">Travel Expense:</th>
<th align="left">OCD Travel Expense:</th>
</tr>
<tr>
<td>
<select name="DO1">
<option value="#" selected="selected">Select DO</option>
<option name="DONum[][]" value="9987.99.01">9987.99.01</option>
<option name="DONum[][]" value="9032.90">9032.90</option>
<option name="DONum[][]" value="5993.02">5993.02</option>
<option name="DONum[][]" value="1234.56">1234.56</option>
</select>
</td>
<td width="9%">
<input name="RegularHours[][]" id="RegularHours" size="8" maxlength="8" type="text" />
</td>
<td width="12%">
<input name="Travel" value="Yes" onclick="hide()" type="checkbox" />Yes
</td>
<td id="TravelExpTD" style="visibility: hidden;" width="15%">
$<input name="TravelExp[][]" id="TravelExp" size="15" maxlength="15" type="text" />
</td>
<td id="TravelExpODCTD" style="visibility: hidden;" width="18%">
$<input name="TravelExpODC[][]" id="TravelExpODC" size="15" maxlength="15" type="text" />
</td>
</tr>
</tbody>
</table>
</div>
<div id="TaskAndHighlights" class="mainindexTableTask">
<table border="0" width="100%">
<tbody>
<tr>
<td><input value="Add Another Task" id="AddTask" type="button" /></td>
</tr>
<tr>
<th align="left">Task:</th>
</tr>
<tr>
<td>
<select name="WorkedTask[0][]" id="WorkedTask">
<option value="#" selected="selected">Task Name</option>
<option value="Hello World">Hello World</option>
<option value="Somthing Else">Something Else</option>
<option value="Training">Training</option>
<option value="Whatever">Whatever</option>
</select>
</td>
</tr>
<tr>
<th align="left">Highlights:</th>
<th align="left">Select Common Task:</th>
</tr>
<tr>
<td width="34%"><input name="Highlights[0][]" id="Highlights" size="50" maxlength="100" type="text" /></td>
<td width="34%">
<select name="CommonTask[0][]" id="CommonTask">
<option value="#" selected="selected">Common Tasks</option>
<option value="Security Meeting."> Security Meeting. </option>
<option value="SWWG Meeting"> SWWG Meeting </option>
</select>
</td>
<td width="32%"><input value="Add another Highlight" id="AddHighlight" type="button" /></td>
</tr>
</tbody>
</table>
</div>
<div id="End" class="mainindexTable">
<table width="100%">
<tbody>
<tr>
<td colspan="6" align="left" height="46"><input name="Submit" value="Submit WDR" type="submit" /></td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
<script type="text/javascript" src="Duplicator.js"></script>
</body>
</html>


function makeDuplicator(button, element, cb_dress, cb_append){
var prototype = element.cloneNode(true);
button.onclick = function(){
//Dress the clone.
var clone = (cb_dress || lazy)(prototype.cloneNode(true));
//Append the clone.
if(cb_append) //Native objects apparently don't like short-circuit operators.
cb_append(clone, element);
else
element.parentNode.appendChild(clone);
};
function lazy(e){
return e;
}
}
var element = document.getElementById('DOandHours').getElementsByTagName('table')[0].rows[1];
makeDuplicator(document.getElementById('AddDO'), element);

function dressHighlight(clone){
//Get rid of the button.
clone.deleteCell(2);
//Blank the text input in case the page was refreshed.
clone.cells[0].getElementsByTagName('input')[0].value = '';
return clone;
};

//The callback (below) won't do this because it never sees the original DIV.
var addHighlight = document.getElementById('AddHighlight');

makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, dressHighlight);


function dressTask(clone){
var table = clone.getElementsByTagName('table')[0];
var highlights = table.rows[4];

//Leave instructions for PHP or it will get confused.
dressTask.index++;
updateNameOf(table.rows[2].cells[0].getElementsByTagName('select')[0]);
updateNameOf(highlights.cells[0].getElementsByTagName('input')[0]);
updateNameOf(highlights.cells[1].getElementsByTagName('select')[0]);
function updateNameOf(element){
element.name = element.id + '[' + dressTask.index + '][]';
}

var addHighlight = highlights.cells[2].getElementsByTagName('input')[0];
makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, dressHighlight);
return clone;
};
dressTask.index = 0;

//This is a more complex appendage, so we'll handle it.
function appendTask(clone, element){
element.parentNode.insertBefore(clone, document.getElementById('End'));
}

makeDuplicator(document.getElementById('AddTask'), document.getElementById('TaskAndHighlights'), dressTask, appendTask);

Humper
10-24-2008, 07:51 PM
Just to check... Do you use Design View (or Mode, or whatever it is) in Dreamweaver? If so, please stop; the worst coder in the world is surely a WYSIWYG.

I use the code view to do the coding but I like to be able to switch to Design view to see where everything is.. I know I should probably already know but I am kinda new to this...

Thanks for the tips about how I should clear up my code.. I will defiantly look into that as soon as everything is working...

I updated the page and have found a few things that need to be fixed..
1) The Add Another Task button doesn't work after the first time it is created.
2) The hide() function is broke now...
3) Remove Highlight button doesn't work


Can you please look at #1.. I am trying to go through the code to see what it might be but I am still getting a grasp on what you did.... its over my head.. but I am trying...

BTW--- THANK YOU!!

Jesdisciple
10-24-2008, 09:00 PM
I use the code view to do the coding but I like to be able to switch to Design view to see where everything is.. I know I should probably already know but I am kinda new to this...That's not nearly as bad as using it to write the code, but I still worry that it might rewrite your code. I suggest using a full browser to view your code's effects; it doesn't take that long once you get the URL typed in the first time, and everything works - PHP, JS, CSS, everything.


I updated the page and have found a few things that need to be fixed..I went back to my own version and noticed that the headers were being appended instead of the fields in the DO section, but maybe that bug didn't make it into my post. It's fixed now on my end.

1) The Add Another Task button doesn't work after the first time it is created.This is interesting... What browser are you using? Do you have multiple browsers? IE is great for seeing what most users will, but Firefox and/or Opera is essential for debugging.

2) The hide() function is broke now...Apply it to the table headers as well as the cells; I had to separate them for the modified page to look right. If that doesn't solve the problem, do you get any error messages?

3) Remove Highlight button doesn't workWhat "Remove Highlight" button? EDIT: Just looked on your site, will add it to my copy.

Humper
10-27-2008, 03:38 PM
I wanted to understand the JS so I went through it and wrote what I thought it was doing.. Can you check it out and correct me if I am wrong

Here is the JS:


function makeDuplicator(button, element, cb_dress, cb_append)
{
var prototype = element.cloneNode(true);
button.onclick = function(){
//Dress the clone.
var clone = (cb_dress || lazy)(prototype.cloneNode(true));
//Append the clone.
if(cb_append) //Native objects apparently don't like short-circuit operators.
cb_append(clone, element);
else
element.parentNode.appendChild(clone);
};
function lazy(e)
{
return e;
}
}

var element = document.getElementById('DOandHours').getElementsByTagName('table')[0].rows[1]; //getting the <div id="DOandHours"> table.. start at row 1 of table

//call makeDuplicator() for adding another DO
makeDuplicator(document.getElementById('AddDO'), element); //copies the <div id="DOandHours"> table

function dressHighlight(clone)
{
clone.deleteCell(2); //Get rid of the Add Another Highlight button
clone.cells[0].getElementsByTagName('input')[0].value = ''; //Blank the text input in case the page was refreshed.
return clone;
};

//The callback (below) won't do this because it never sees the original DIV.
var addHighlight = document.getElementById('AddHighlight');

makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, dressHighlight);


function dressTask(clone)
{
var table = clone.getElementsByTagName('table')[0]; //get table and create a clone of it start at row 0 -- entire table is cloned
var highlights = table.rows[4]; //start at 4th row of table

//Leave instructions for PHP or it will get confused.
dressTask.index++; //incrementing counter
updateNameOf(table.rows[2].cells[0].getElementsByTagName('select')[0]); //WorkedTask[][]
updateNameOf(highlights.cells[0].getElementsByTagName('input')[0]); //Highlights[][]
updateNameOf(highlights.cells[1].getElementsByTagName('select')[0]); //CommonTask

function updateNameOf(element)
{
element.name = element.id + '[' + dressTask.index + '][]'; //Give the element a unique name so we can pull the data later
}

var addHighlight = highlights.cells[2].getElementsByTagName('input')[0]; //Add Another Hightlight button
makeDuplicator(addHighlight, addHighlight.parentNode.parentNode, dressHighlight); //Adds another input box for Highlights[][]
return clone;
}
dressTask.index = 0;

//This is a more complex appendage, so we'll handle it.
function appendTask(clone, element)
{
element.parentNode.insertBefore(clone, document.getElementById('End')); //insert clone before <div id="End">
}


//call makeDuplicator() for Adding another task
makeDuplicator(document.getElementById('AddTask'), document.getElementById('TaskAndHighlights'), dressTask, appendTask); //button = AddTask, element = <div id="TaskAndHighlights">, calling dressTask, calling appendTask



Here is the hide function:


function hide()
{
if(document["WDR"]["Travel[0][]"].checked)
{
document.getElementById("TravelExp").style.visibility="visible"
document.getElementById("TravelExpODC").style.visibility="visible"
}
else
{
document.getElementById("TravelExp").style.visibility="hidden"
document.getElementById("TravelExpODC").style.visibility="hidden"
}
}

</script>



The Hide function still does not work. I tried adding it to the table headers and still nothing..(well let me take that back... it works if you don't click "Add Another DO"... but as soon as you do it stops working) I am not getting any errors.

Also the "Add Another Task" button still doesn't work after the first instance of the button. Again I am not getting any errors.

I also found something new..... The "Add Another Highlight" button doesn't work in IE7.. But in FF its fine and I get no errors in FF. here is the error from IE.
Line:28
Char:3
Error:'cells.0' is null or not an object
code:0

Humper
10-27-2008, 06:07 PM
I also added this to the duplicator.js ... but its not working either.... I need to be able to save the info from the "DOandHours" <div> also.. so I thought this would work...



function dressDO(clone) //added this function
{
var table1 = clone.getElementsByTagName('table'[0]);

//Leave instructions for PHP or it will get confused.
dressD0.index++; //incrementing counter
updateNameOf(table1.rows[1].cells[0].getElementsByTagName('select')[0]); //DO[][]
updateNameOf(table1.rows[1].cells[1].getElementsByTagName('input')[0]); //RegularHours[][]
updateNameOf(table1.rows[1].cells[2].getElementsByTagName('select')[0]); //Travel[][]
updateNameOf(table1.rows[1].cells[3].getElementsByTagName('input')[0]); //TravelExp[][]
updateNameOf(table1.rows[1].cells[4].getElementsByTagName('input')[0]); //TravelExpODC[][]

function updateNameOf(element)
{
element.name = element.id + '[' + dressDO.index + '][]'; //Give the element a unique name so we can pull the data later
}
}
dressDO.index = 0;

function appendDO(clone, element)
{
element.parentNode.insertBefore(clone, document.getElementById('TaskAndHighlights')); //insert clone before <div id="TaskAndHighlights">
}

Jesdisciple
10-27-2008, 09:36 PM
First, I can tell that you're taking to heart my encouragement to try, and I appreciate that. But I need to gently remind you to also ask questions about stuff you don't quite get. Maybe you're not recognizing that you don't get it, but these lines don't mean what you think they do, and they're good examples of stuff you could ask about.

var table1 = clone.getElementsByTagName('table'[0]);Expressions are evaluated from the inside out. A string is actually (under the hood, anyway) an array of characters. If accessing an index of a JS string means anything (which it might not do in all browsers, in which case it would be the constant undefined), it will be another string containing only the character at that index. In Firefox, 'table'[0] returns 't', so you're actually getting all zero elements in the clone with name="t" (or, depending on the browser, triggering an error because you passed undefined, i.e. nothing, where a function required a string). Here's what you're wanting:
var table1 = clone.getElementsByTagName('table')[0];


element.parentNode.insertBefore(clone, document.getElementById('TaskAndHighlights'));See https://developer.mozilla.org/en/DOM/element.insertBefore and http://msdn.microsoft.com/en-us/library/ms536454(VS.85).aspx for this one. element.parentNode does not contain document.getElementById('TaskAndHighlights') (see the HTML), so this is gibberish to the JS parser. Here's what you're wanting:
element.parentNode.appendChild(clone);But that's the default behavior of makeDuplicator, so the appendDO function is unnecessary.

The updateNameOf function in dressDO is a more subtle mistake than the other two. We only need to use [0][] when an area A, which is being duplicated, contains another area B which is also being duplicated. Each A may contain multiple Bs, and each set of Bs must be unique. The ordinary [] can make each individual B unique, but it can't tell you which A contained that B or what other Bs were in the same A.

The DO section is not contained by a duplicated area, so it doesn't need [0][].



var table = clone.getElementsByTagName('table')[0]; //get table and create a clone of it start at row 0 -- entire table is clonedNope... clone is not a function but an ordinary variable (which we passed into the dressTask function). We find all table elements under the clone, take the first one (because we know there's only one), and assign it to the table variable. (I changed to using getElementsByTagName[0] everywhere because it's more predictable than the childNodes collection. Every time a browser sees a bunch of text between tags, even if it's just indentation, it makes a new node to hold that text.) The cloning has already occurred before we ever see the clone.


var highlights = table.rows[4]; //start at 4th row of tableThat's actually the 5th row because arrays and array-like objects are 0-based. 0 1 2 3 4 Also, I don't understand what you mean by "start" because we never proceed to another row.


makeDuplicator(document.getElementById('AddTask'), document.getElementById('TaskAndHighlights'), dressTask, appendTask); //button = AddTask, element = <div id="TaskAndHighlights">, calling dressTask, calling appendTaskdressTask and appendTask aren't getting called on this line, but they're being set up to be called every time someone presses the AddTask button. (I changed the callback setup because we would otherwise have needed 3 of them.)

I got the hide function fixed; the page in the attached archive works in Firefox.

For the IE problem, can you try debugging it? I don't have IE, so I can only help if you post debugging results. You could start by finding out what clone.innerHTML is in dressHighlight. Firebug Lite (http://getfirebug.com/lite.html)'s console.log function is one way to do this; IE's Developer Toolbar (http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en) might be another. (You could alert the value, but I don't know if IE lets you copy an alert box's contents.)

EDIT: I just realized that I forgot to do anything about the AddTask button. Would you rather remove all but the first button or have all the buttons work?

Humper
10-27-2008, 10:37 PM
EDIT: I just realized that I forgot to do anything about the AddTask button. Would you rather remove all but the first button or have all the buttons work?

I would rather just have one 'Add Another DO' button also can you see about adding a remove DO button too.. i totally forgot about that...

I think I need several 'Add Another Task' buttons since the page can get lengthy... I download the zip file you attached a few mins ago.. and nothing seemed to work... i see you just uploaded a new one so I will try the one out and see whats going on...

I will post back with question :)

Jesdisciple
10-27-2008, 10:42 PM
Yeah, I had a debugging call to console.log still in there. If you don't have Firebug (or Firebug Lite) installed, that will cause an "undefined" error.

Humper
11-12-2008, 07:39 PM
OK Im back.......

I am having some issues.... a lot of the script doesnt seem to work.... I created a removeElement function to delete the Highlights.

Here is the code


function removeElement(parentDiv, childDiv)
{
if (childDiv == parentDiv) {
alert("The parent cannot be removed.");
}
else if (document.getElementById(childDiv)) {
var child = document.getElementById(childDiv);
document.write(childDiv); //delete this line.....
document.write("<br \>") //delete this line.....
var parent = document.getElementById(parentDiv);
document.write(parentDiv); //delete this line........
parent.removeChild(child);
}
else {
alert("Child has already been removed or does not exist.");
return false;
}
}



and here is the page where it is calling it....


<div id="TaskAndHighlights" class="mainindexTableTask">
<table id="TAH" width="100%" border="0">
<tr>
<td><input type="button" value="Add Another Task" id="AddTask"/></td>
<td><input type="button" value="Remove Task" id="RemoveTask" onclick="Remove()" /></td>
</tr>
<tr>
<th align="left">Task:</th>
</tr>
<tr>
<td>
<select name="WorkedTask[0][]" id="WorkedTask">
<option value="#" selected="selected">Task Name</option>
<?php

$query = "SELECT TaskName FROM DeliveryOrders ORDER BY TaskName";
$result = mysql_query($query);

while($row= mysql_fetch_array($result))
{
$TaskName = $row["TaskName"];
echo "<option value=\"$TaskName\">$TaskName</option>";
}
?>
</select> </td>
</tr>
<tr>
<th align="left">Highlights:</th>
<th align="left">Select Common Task:</th>
</tr>
<tr id="HL">
<td width="34%"><input name="Highlights[0][]" type="text" id="Highlights" size="50" maxlength="100" /></td>
<td width="34%">
<select name="CommonTask" id="CommonTask">
<option value="#" selected="selected">Common Tasks</option>
<?php
$query1 = "SELECT TaskDesc FROM CommonTasks ORDER BY TaskDesc";
$result1 = mysql_query($query1);

while($row1= mysql_fetch_array($result1))
{
$Task = $row1["TaskDesc"];
print "<option value=\"$Task\" > $Task </option>";
}
?>
</select>
</td>
<td width="32%"><input type="button" value="Add another Highlight" id="AddHighlight" /></td>
<td>
<input type="button" value="Remove Highlight" onclick="removeElement('TAH', 'HL')" /> <!-- This doesnt work correctly -->
</td>
</tr>
</table>
</div>



I guess I am not in the correct parent node since I am getting 'parent is null' error.... what am I doing wrong?

Jesdisciple
11-13-2008, 02:41 AM
Let's back up for a sec... Why do you need removeElement? What's going wrong with this function?
function dressHighlight(clone){
//Recycle the button.
var button = clone.cells[2].getElementsByTagName('input')[0];
button.value = 'Remove Highlight';
button.onclick = function(){
clone.parentNode.removeChild(clone);
};
//Blank the text input in case the page was refreshed.
clone.cells[0].getElementsByTagName('input')[0].value = '';
return clone;
};

BTW, removeElement isn't working because the element with id "HL" doesn't exist. But it's much simpler and easier to just use the element before we're done with it the first time.

Humper
11-13-2008, 08:54 PM
OK so I was using the wrong java script file...I am able to get the remove highlights button to work but now I need one to be able to remve a DO, and to remove a task. I have attached my files in a zip. I changed the layout of the WDR.php page so I think that my be what Im having some issues with but everything seems to work but the new 'Remove DO' and 'Remove Task' buttons.

again you can see the live page here (http://www.southernsinners.com/WDR/WDR.php)

Jesdisciple
11-15-2008, 04:21 PM
var element = document.getElementById('DOandHours').getElementsByTagName('table')[0].rows[0];
makeDuplicator(document.getElementById('AddDO'), element, dressDO);
function dressDO(clone) //added this function
{
...
var table1 = clone.getElementsByTagName('table')[0];
...
}
You're passing element (a table row) to makeDuplicator for cloning. Then when you begin to dress the clone, you find the first table in the row so you can later access its first row. In the HTML source, the row doesn't contain any tables, so table1 is null.

Then when we get to the updateNameOf calls, you try to find the select element in the third cell. Travel[] is an <input type="checkbox">, so this fails.

Finally, you don't return the clone from dressDO, and that chokes makeDuplicator. I admit that's hard to remember, so here's an alternative makeDuplicator which doesn't require that the clone be returned.
function makeDuplicator(button, element, cb_dress, cb_append){
var prototype = element.cloneNode(true);
button.onclick = function(){
var clone = prototype.cloneNode(true);

//Dress the clone.
cb_dress(clone);

//Append the clone.
if(cb_append) //Native objects apparently don't like short-circuit operators.
cb_append(clone, element);
else
element.parentNode.appendChild(clone);
};
}

That's all I can respond to for now, and I won't be available again until Sunday or Monday.

Jesdisciple
11-17-2008, 04:52 PM
function dressTask(clone)
{
var buttons = clone.cells[1].getElementsByTagName('input')[0];
buttons.onclick = function(){
clone.parentNode.removeChild(clone);
};

var table = clone.getElementsByTagName('table')[0]
...
}
makeDuplicator(document.getElementById('AddTask'), document.getElementById('TaskAndHighlights'), dressTask, appendTask);In this section, clone is a div element because document.getElementById('TaskAndHighlights') is a div element. So it doesn't have a cells property like a table does, but this is a fairly simple problem.
function dressTask(clone)
{
var table = clone.getElementsByTagName('table')[0]

var buttons = table.cells[1].getElementsByTagName('input')[0];
buttons.onclick = function(){
clone.parentNode.removeChild(clone);
};

...
}

All the buttons now work for me. EDIT: Well, except for the top ones. But we could make them initially the adding buttons then change them to the removing buttons like with the highlights.

Humper
11-24-2008, 09:18 PM
Thanks for explaining that I was really getting frustrated with that. I fixed most of the issues but there are still some things that need fixed.

Here are the things I still need to fix:
Remove DO button
The hide() function
Add Another Task button doesn't work after the first button.
Remove Task button -- could we make them initially the adding buttons then change them to the removing buttons like with the highlights.
fix table layout for the DO section - the boxes are not under the correct headings for some reason


I tried to fix the hide function but I cant seem to get it to work correctly. Here is my latest attempt. I zipped up the files so you can review them. I think that it maybe easier that way.

MJH
11-24-2008, 09:32 PM
Take a look at the attached. I think it will help.

Jesdisciple
11-25-2008, 01:21 AM
I'm surprised those buttons don't work for you, but I haven't re-tested them yet. The hide() function is something I had noticed was broken, but I don't yet understand why (and I haven't re-tested it, either). I'll see how you like MJH's solution and go from there.

Humper
12-01-2008, 05:53 PM
Thanks MJH for the reply

I just dont want to spend any more time on redesigning what I already have and I kinda like the idea of having a button to add a new section.


Jesdisciple-

Have you gotten a chance to look at the issues I stated in my last message. I am still working on fixing theses


Here are the things I still need to fix:
Remove DO button
The hide() function
Add Another Task button doesn't work after the first button.
Remove Task button -- could we make them initially the adding buttons then change them to the removing buttons like with the highlights.
fix table layout for the DO section - the boxes are not under the correct headings for some reason

I will hopefully have time this week to work on this so any help would be appreciated.

Jesdisciple
12-02-2008, 12:21 AM
You had the hide function set up for its old version - the one in the HTML. The one in the JS, which uses this instead of finding the element again, is required for multiple checkboxes. But when hide is called from the event listener instead of being assigned as the event listener, this === window, which defeats the purpose of using this at all. When you use an HTML listener, the function is called rather than assigned (not to mention that it clutters the HTML).

I don't recall why (and I've now edited over the reason), but the function that was supposed to remove the tasks wasn't getting called.

I had to restructure the index management system. It was just keeping track of how many clones there were and permanently assigning them indexes based on the current count (at the time of their creation). This broke when elements were removed, so I made the indexes be reassigned to fill the holes.

You were specifying the indexes of the DOs, but this is unnecessary because they aren't nested in another duplication. And it actually makes things harder, because those indexes must be managed just like the others. I think I already mentioned that, so maybe you fixed it on your end after uploading (or maybe I was using an old upload).

Humper
12-02-2008, 02:22 PM
Jesdisciple ---- Your awesome!!!! That fixed almost all the issues I was having!!!! Thanks a ton!

I am still working on this so if I run into any problems I will let you know..


Thanks again!

Jesdisciple
12-02-2008, 05:34 PM
I just noticed that the HTML onclick handler snuck its way into my upload because of some issues I'm having with my test server not working. It won't harm the operation (because the JS overwrites it), but it should be removed anyway.

Humper
12-02-2008, 06:25 PM
Deleted ----- Thanks

Humper
12-04-2008, 01:34 PM
Jesdisciple--

Is there a way to copy the common task to the Highlights field if they select a common task?

Jesdisciple
12-04-2008, 07:01 PM
Yes... How would you accomplish that with the single task? And what would be necessary to apply that solution to all tasks?

FYI, this is a pop quiz... I hate 'em too, but I think we're getting into a rut of made-to-order JS. I find it fun and all, but I don't think you learn as much if you don't produce original ideas.

Humper
12-04-2008, 08:24 PM
well I know it can be done with an onchange event on the 'common task' drop down but what I am having issues with is getting it to function properly since the name of the highlights field changes. I think the below code should work -- well some what


heres the Java Script


function update(value)
{
document.WDR.Highlights[0][].value = value;
}


and heres where I input the onchange event in the html


<select name="CommonTask" id="CommonTask" onchange="update(this.value);">

Jesdisciple
12-04-2008, 11:54 PM
Since you're still using HTML event-handlers, I have to ask: Do you understand the standard objection to them? Do you agree with it?

Although each highlight's relation (as an element with a certain name) to the global document object varies and therefore the process for finding it also does, its relations to the corresponding dropdown menu remain constant. So if we have the dropdown menu we can find the highlight, and vice versa.

The only variable is which relation we want to use to find the highlight. There are two that I know of: a DOM relation (the one I've been using for other problems) and the identical index part of their names. Which would you prefer to use? (To find the identical index, you must use a regex based on the known element's name.)

Humper
12-05-2008, 03:54 PM
Since you're still using HTML event-handlers, I have to ask: Do you understand the standard objection to them? Do you agree with it?


As I am still learning I don't know how to do this without using a HTML event-handler.... and I didn't know people were trying to stay away from using them?? I will have to research this more.



Although each highlight's relation (as an element with a certain name) to the global document object varies and therefore the process for finding it also does, its relations to the corresponding dropdown menu remain constant. So if we have the dropdown menu we can find the highlight, and vice versa.


Are you saying that because they are going to be populated at the same time each time that their renaming would remain constant?
Like below:
Highlights[i][] --> CommonTask[i][]

This would consist of renaming the CommonTask field in the HTML and updating the name with the js?




The only variable is which relation we want to use to find the highlight. There are two that I know of: a DOM relation (the one I've been using for other problems) and the identical index part of their names. Which would you prefer to use? (To find the identical index, you must use a regex based on the known element's name.)

Wouldn't the DOM relation be the easier of the two to implement? Sorry I am trying to talk this out in my head.

Jesdisciple
12-05-2008, 08:37 PM
See http://www.quirksmode.org/js/events_early.html for an explanation of why HTML event-handlers are bad. I know of only one case which justifies their use: The img tag's onload can only be set in HTML. Click through to the related pages (via links at the pages' bottoms) for the alternatives.


Are you saying that because they are going to be populated at the same time each time that their renaming would remain constant?
Like below:
Highlights[i][] --> CommonTask[i][]Yes, that's the relation between the names.


This would consist of renaming the CommonTask field in the HTML and updating the name with the js?Sort of... We rename the fields via the DOM, and that does directly affect the HTML as the browser "thinks" of it. Yet the convention (I think) is to reserve "HTML" for literal chunks of it, like the server's response to a page request or the value of innerHTML.


Wouldn't the DOM relation be the easier of the two to implement?Maybe... They're probably about even in complexity, but the DOM spreads it out over several lines while a regex packs it all into one value. Plus JavaScript's regex support is a little weird. But I think I know both well enough, so pick the one you'd rather learn about.


Sorry I am trying to talk this out in my head.No problem. :) Discussion is always good.

Humper
12-05-2008, 09:18 PM
I think since we have been using DOM that this would be the logical choice. I will probably be able to grasp that implementation a little easier.

Jesdisciple
12-06-2008, 03:19 AM
Okay... Are you waiting on some code from me? 'Cause I'm waiting on it from you. :p

Humper
12-12-2008, 03:53 PM
Sorry Im not waiting on code from you I have just been busy with other things at work and havent had a chance to get back to this issue yet. Maybe next week I can get back to this.

Thanks for the help tho

Humper
12-18-2008, 09:07 PM
OK so I did some more on the site just not on the js side.....

Jesdisciple- You have been very helpful so can you please take a look at the issue I am having now HERE (http://www.dynamicdrive.com/forums/showthread.php?p=175992#post175992)

Thanks