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?
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
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:
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.
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();
});