Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 05-29-2009, 04:43 PM   PM User | #1
Dan06
Regular Coder

 
Join Date: Sep 2008
Posts: 205
Thanks: 1
Thanked 0 Times in 0 Posts
Dan06 is an unknown quantity at this point
Question How to make a dynamic (variable # of rows) spreadsheet-like form?

I'm trying to create a spreadsheet style form, where the column headers are set, but the number of editable data rows vary. The idea I have is to create a table and make its table cells editable via contentEditable='true', and use javascript to add more rows when a user clicks a button (id="addRows" -- see below).

Thus far I've put together the html for the static component of the table and I'm putting together the javascript. At this point I have a couple of questions:

1. Is there a better way to accomplish my goal?
2. How can I retrieve the data from the editable cells and group them so when I send the data via ajax, the information can be saved properly - i.e. grouped according to row?

Below is my html:
Code:
<table class="registration" name="registration" border="1">
						<tr>
							<th>&nbsp;</th> <th>&nbsp;</th> <th>&nbsp;</th> <th>Date: {$date}</th>
						</tr>
						<tr>
							<th>&nbsp;</th> <th>&nbsp;</th> <th>&nbsp;</th> <th>Team Name: <span class="editable" contentEditable="true">&nbsp;</span></th>
						</tr>
						<tr>
							<th>&nbsp;</th> <th>&nbsp;</th> <th>&nbsp;</th> <th>&nbsp;</th>
						</tr>
						<tr>
							<th>Name</th> <th>D.O.B.</th> <th>Position</th> <th>Tel. #</th>
						</tr>
						<tr>
							<td><div class="editable" contentEditable="true">&nbsp;</div></td> <td><div class="editable" contentEditable="true">&nbsp;</div></td> <td><div class="editable" contentEditable="true">&nbsp;</div></td> <td><div class="editable" contentEditable="true">&nbsp;</div></td> 	 
						</tr>
					</table>
					<span id="addRows" class="submitBtn floatLeft">Add Rows</span>
					</div>
Dan06 is offline   Reply With Quote
Old 05-29-2009, 05:25 PM   PM User | #2
itsallkizza
Senior Coder

 
Join Date: Oct 2008
Location: Long Beach
Posts: 1,196
Thanks: 36
Thanked 164 Times in 164 Posts
itsallkizza will become famous soon enough
Take a step back and look at it from a different perspective. Let's say the "actual" rows and their data exist inside JS objects (each row) inside an array (of all rows) that is your table. Now the actual html will merely be a representation of your data, not the actual data itself. So you can use a JS object to manipulate your data (add/remove/sort rows, send off in json format via ajax, etc).

Something like this to help you get started:
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Test</title>
<script type="text/javascript">
// <![CDATA[

function MyTableData(table_ref)
	{
	this.table_ref = table_ref;
	this.thead = table_ref.getElementsByTagName("thead")[0];
	this.tbody = table_ref.getElementsByTagName("tbody")[0];
	this.headers = new Array();
	this.rows = new Array();
	this.__construct = function()
		{
		/* if data already exists in html, pull the data and insert it into JS table */
		var ths = this.thead.getElementsByTagName("th");
		for (var i=0;i<ths.length;i++) this.headers[i] = ths[i].innerHTML;
		var existing_trs = this.tbody.getElementsByTagName("tr");
		var rows_to_insert = new Array();
		for (var r=0;r<existing_trs.length;r++)
			{
			var tds = existing_trs[r].getElementsByTagName("td");
			var row_data = new Array();
			for (var c=0;c<tds.length;c++) row_data[c] = tds[c].innerHTML;
			rows_to_insert[r] = row_data;
			}
		for (var r=0;r<rows_to_insert.length;r++) this.addRow(rows_to_insert[r]);
		}
	this.refreshHTMLTable = function()
		{
		this.resfreshHTMLHeaders();
		this.refreshHTMLBody();
		}
	this.resfreshHTMLHeaders = function()
		{
		var new_html = "<tr>";
		for (var i=0;i<this.headers.length;i++)
			{
			new_html += "<th>";
			new_html += this.headers[i];
			new_html += "</th>";
			}
		new_html += "</tr>";
		this.thead.innerHTML = new_html;
		}
	this.refreshHTMLBody = function()
		{
		var new_html = "";
		for (var r=0;r<this.rows.length;r++)
			{
			new_html += "<tr>";
			for (var c=0;c<this.rows[r].length;c++)
				{
				new_html += "<td>";
				new_html += this.rows[r][c];
				new_html += "</td>";
				}
			new_html += "</tr>";
			}
		this.tbody.innerHTML = new_html;
		}
	this.addRow = function(row_data)
		{
		alert(row_data);
		var row = new Array();
		for (var i=0;i<row_data.length;i++) row[i] = row_data[i];
		this.rows.push(row);
		this.refreshHTMLBody();
		}
	this.removeRow = function(index)
		{
		//remove row code here
		}
	this.__construct();
	}

window.onload = function()
	{
	table1 = new MyTableData(document.getElementById("table_1"));
	table1.addRow(["Sarah","19","F"]);
	}

// ]]>
</script>
</head>
<body>

<table id="table_1">
	<thead>
		<tr>
			<th>Name</th>
			<th>Age</th>
			<th>Gender</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>Bob</td>
			<td>24</td>
			<td>M</td>
		</tr>
		<tr>
			<td>Cory</td>
			<td>21</td>
			<td>M</td>
		</tr>
	</tbody>
</table>

</body>
</html>
__________________
Feel free to e-mail me if I forget to respond ;)
ohsosexybrit@gmail.com
itsallkizza is offline   Reply With Quote
Old 06-01-2009, 09:23 PM   PM User | #3
Dan06
Regular Coder

 
Join Date: Sep 2008
Posts: 205
Thanks: 1
Thanked 0 Times in 0 Posts
Dan06 is an unknown quantity at this point
Thanks for the example, it was very helpful. I've almost got the spreadsheet to where I want. However, I'm having a bit of trouble with json - when I send the js array, php seems to be getting the same array twice.

Prior to submitting the array via ajax, I convert the array to a string using:
Code:
"&spreadsheet=" + JSON.stringify(spreadsheet.rows)
On the php side I use:
Code:
$spreadsheet = json_decode($_POST['spreadsheet']);
However, when I print the array via
Code:
echo print_r($spreadsheet);
I get:
Quote:
Array(
[0] => Array([0] => Gum [1] => 1 [2] => 1 [3] => 1 )
[1] => Array([0] => Candy[1] => 2 [2] => 2 [3] => 4)
)
Array(
[0] => Array ( [0] => Gum [1] => 1 [2] => 1 [3] => 1 )
[1] => Array ( [0] => Candy [1] => 2 [2] => 2 [3] => 4 )
)
Why is php receiving the array twice?

Last edited by Dan06; 06-01-2009 at 09:25 PM..
Dan06 is offline   Reply With Quote
Old 06-02-2009, 02:42 PM   PM User | #4
12 Pack Mack
Banned

 
Join Date: Mar 2009
Posts: 248
Thanks: 3
Thanked 68 Times in 66 Posts
12 Pack Mack is an unknown quantity at this point
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>None</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">	

	var nTableBody = "";
	
	function insertRow(){
		
		nTableBody = document.forms[0].getElementsByTagName('tbody')[0];
		var nRows = nTableBody.getElementsByTagName('tr');
		var nClone = nRows[0].cloneNode(true);	
		var nFloor = nRows[nRows.length - 1];
		nTableBody.insertBefore(nClone,nFloor);
		var nEditable = nRows[nRows.length - 2].getElementsByTagName('td');
		for (i=0; i<nEditable.length; i++)
			{
			 nEditable[i].getElementsByTagName('div')[0].innerHTML = "&nbsp;";
			}	
	}

	function removeRow(){

		var nRows = nTableBody.getElementsByTagName('tr');
		var lastRow = nRows[nRows.length - 2];
		if (nRows.length > 2)
			{
			 nTableBody.removeChild(lastRow);	
			}				
	}	
	
</script>
<style type="text/css">

	.floor {display: none;}

</style>
</head>
	<body>
		<form action="" method="post">	  
			<table class="registration" name="registration" border="1">
				<thead>
					<tr>
						<th>&nbsp;</th> <th>&nbsp;</th> <th>&nbsp;</th> <th>Date: {$date}</th>
					</tr>
					<tr>
						<th>&nbsp;</th> <th>&nbsp;</th> <th>&nbsp;</th> <th>Team Name: <span class="editable" contentEditable="true">&nbsp;</span></th>
					</tr>
					<tr>
						<th>&nbsp;</th> <th>&nbsp;</th> <th>&nbsp;</th> <th>&nbsp;</th>
					</tr>
					<tr>
						<th>Name</th> <th>D.O.B.</th> <th>Position</th> <th>Tel. #</th>
					</tr>
				</thead>
				<tbody>
					<tr>
						<td>
							<div class="editable" contentEditable="true">&nbsp;</div>
						</td>
						<td>
							<div class="editable" contentEditable="true">&nbsp;</div>
						</td> 
						<td>
							<div class="editable" contentEditable="true">&nbsp;</div>
						</td> 
						<td>
							<div class="editable" contentEditable="true">&nbsp;</div>
						</td> 	 
					</tr>
					<tr class="floor"><td>empty</td></tr>
				</tbody>
			</table>

			<input type="button" value="Add" onclick="insertRow();" >
			<input type="button" value="Remove" onclick="removeRow();">					
		</form>
	</body>
</html>
12 Pack Mack is offline   Reply With Quote
Old 06-02-2009, 04:28 PM   PM User | #5
Dan06
Regular Coder

 
Join Date: Sep 2008
Posts: 205
Thanks: 1
Thanked 0 Times in 0 Posts
Dan06 is an unknown quantity at this point
12 Pack Mack,

thanks for the example on row insertion and removal. Unfortunately, however, I'm having trouble with sending the array in json format via ajax and processing the array in the php page.

I format the array using
Code:
JSON.stringify(spreadsheet.rows)
which gives:
Quote:
[["Gum","1","1","1"], ["Candy","2","2","4"]]
Then on the php side, I decode json with:
Code:
$spreadsheet = json_decode($_POST['spreadsheet']);
which gives ( when echo print_r($spreadsheet) ):
Quote:
Array(
[0] => Array([0] => Gum [1] => 1 [2] => 1 [3] => 1 )
[1] => Array([0] => Candy[1] => 2 [2] => 2 [3] => 4)
)
Array(
[0] => Array ( [0] => Gum [1] => 1 [2] => 1 [3] => 1 )
[1] => Array ( [0] => Candy [1] => 2 [2] => 2 [3] => 4 )
)
Why is the array duplicated? Am I encoding it incorrectly or decoding it incorrectly? Or is the error something else?

Last edited by Dan06; 06-02-2009 at 04:33 PM..
Dan06 is offline   Reply With Quote
Old 06-02-2009, 04:37 PM   PM User | #6
abink
New to the CF scene

 
Join Date: Jun 2009
Location: Lawrence, KS
Posts: 9
Thanks: 0
Thanked 2 Times in 2 Posts
abink is an unknown quantity at this point
you don't need to:
'echo print_r()'

Just:
print_r()
abink is offline   Reply With Quote
Old 06-02-2009, 04:57 PM   PM User | #7
Dan06
Regular Coder

 
Join Date: Sep 2008
Posts: 205
Thanks: 1
Thanked 0 Times in 0 Posts
Dan06 is an unknown quantity at this point
Quote:
Originally Posted by abink View Post
you don't need to:
'echo print_r()'

Just:
print_r()
Thanks for catching/pointing out the typo, I made that error while editing my post.
Dan06 is offline   Reply With Quote
Old 06-02-2009, 06:54 PM   PM User | #8
abink
New to the CF scene

 
Join Date: Jun 2009
Location: Lawrence, KS
Posts: 9
Thanks: 0
Thanked 2 Times in 2 Posts
abink is an unknown quantity at this point
Your encoding/decoding looks fine to me. I'd look next at where you're assigning the results of JSON.stringify() and send the AJAX request.

P.S. If you haven't looked into Javascript frameworks yet, you might want to. I personally have been using jQuery and it makes life a lot easier. For instance, the JS in your post could be rewritten in jQuery ala...
Code:
// rough and untested but 
$('input [type=button][value=Add]').click(function(){
    $('#registration > tbody').append('<tr><td></td></tr>');
});

$('input [type=button][value=Add]').click(function(){
    $('#registration > tbody > tr:last').remove();
});
... or something similar.
abink is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 11:32 PM.


Advertisement
Log in to turn off these ads.