Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 8 of 8
  1. #1
    Regular Coder
    Join Date
    Sep 2008
    Posts
    205
    Thanks
    1
    Thanked 0 Times in 0 Posts

    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>

  • #2
    Senior Coder
    Join Date
    Oct 2008
    Location
    Long Beach
    Posts
    1,196
    Thanks
    36
    Thanked 164 Times in 164 Posts
    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

  • #3
    Regular Coder
    Join Date
    Sep 2008
    Posts
    205
    Thanks
    1
    Thanked 0 Times in 0 Posts
    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:
    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.

  • #4
    Banned
    Join Date
    Mar 2009
    Posts
    248
    Thanks
    3
    Thanked 68 Times in 66 Posts
    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>

  • #5
    Regular Coder
    Join Date
    Sep 2008
    Posts
    205
    Thanks
    1
    Thanked 0 Times in 0 Posts
    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:
    [["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) ):
    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.

  • #6
    New to the CF scene
    Join Date
    Jun 2009
    Location
    Lawrence, KS
    Posts
    9
    Thanks
    0
    Thanked 2 Times in 2 Posts
    you don't need to:
    'echo print_r()'

    Just:
    print_r()

  • #7
    Regular Coder
    Join Date
    Sep 2008
    Posts
    205
    Thanks
    1
    Thanked 0 Times in 0 Posts
    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.

  • #8
    New to the CF scene
    Join Date
    Jun 2009
    Location
    Lawrence, KS
    Posts
    9
    Thanks
    0
    Thanked 2 Times in 2 Posts
    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.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •