...

View Full Version : How to make a dynamic (variable # of rows) spreadsheet-like form?



Dan06
05-29-2009, 04:43 PM
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:


<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>

itsallkizza
05-29-2009, 05:25 PM
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:


<!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>

Dan06
06-01-2009, 09:23 PM
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:

"&spreadsheet=" + JSON.stringify(spreadsheet.rows)

On the php side I use:

$spreadsheet = json_decode($_POST['spreadsheet']);
However, when I print the array via

echo print_r($spreadsheet);
I get:

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?

12 Pack Mack
06-02-2009, 02:42 PM
<!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>

Dan06
06-02-2009, 04:28 PM
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
JSON.stringify(spreadsheet.rows) which gives:

[["Gum","1","1","1"], ["Candy","2","2","4"]]

Then on the php side, I decode json with:

$spreadsheet = json_decode($_POST['spreadsheet']);
which gives ( when echo print_r($spreadsheet) ):

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?

abink
06-02-2009, 04:37 PM
you don't need to:
'echo print_r()'

Just:
print_r()

Dan06
06-02-2009, 04:57 PM
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.

abink
06-02-2009, 06:54 PM
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...


// 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.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum