Lasso Soft Inc. > Home

  • Articles

Adding Unlimited Rows

Using jQuery and JavaScript to add unlimited rows to a form, and Lasso to process the submission.

Introduction

We are often faced with the problem of building a form with an unknown number of rows for data. Thanks to AJAX it is posssible to dynamically add and remove rows from a form to meet the needs of user.

The following code is based on a post to LassoTalk by Jason Huck and adapted to meet the needs of a project. The code assumes that the latest version of jQuery is located in the path "/javascript/jquery/jquery_latest.js", and that two small graphics (plus.gif (+) and minus.gif (-)) are located in the directory "/graphics/".

The basic requirement is to have a form with some information to add to a database and the option of one or more sets of additional data that can be added to a separate related table at the time the form is submitted. This example is for adding Frequently Asked Questions with any associated links to external resources. We will call the main table 'FAQ' and the related table 'FAQlinks'. The two tables share the common keyfield FAQ_Ref.

<script type="text/javascript" src="/javascript/jquery/jquery_latest.js"></script>
<script type="text/javascript">
	$(function(){
	// start a counter for new row IDs
	// by setting it to the number
	// of existing rows
	var newRowNum = 0;
	
	// bind a click event to the "Add" link
	$('#addnew').click(function(){
	// increment the counter
	newRowNum += 1;
						
	// get the entire "Add" row --
	// "this" refers to the clicked element
	// and "parent" moves the selection up
	// to the parent node in the DOM
	var addRow = $(this).parent().parent();
			
	// copy the entire row from the DOM
	// with "clone"
	var newRow = addRow.clone();
				
	// set the values of the inputs
	// in the "Add" row to empty strings
	$('input', addRow).val('');
				
	// insert a remove link in the first cell
	$('td:first-child', newRow).html('<a href="" class="remove"><img alt="-" src="\/graphics\/minus.gif" class="linkbutton" \/><\/a>');
				
	// loop through the inputs in the new row
	// and update the ID and name attributes
	// adding the prefix 'r_' for identification
	// through the Lasso code
	$('input', newRow).each(function(i){
	var newID = 'r_' + newRowNum + '_' + i;
	$(this).attr('id',newID).attr('name',newID);
	});
				
	// insert the new row into the table
	// "before" the Add row
	addRow.before(newRow);
				
	// add the remove function to the new row
	$('a.remove', newRow).click(function(){
	$(this).parent().parent().remove();
	return false;				
	});
			
	// prevent the default click
	return false;
	});
	});
</script>

 

In the page body we place a form as normal and use a little JavaScript to conceal/reveal the option to add FAQlink records to the related table.

As the form is layed out in a table and we wanted to conceal the FAQlink related fields unless they are needed, we are setting the width of the tables and left hand "formprompts" colums with a Lasso variable.

<form name="FAQ" action="[Response_FilePath]" method="post" >
<input type="hidden" name="Action" value="Add" />

[Var:'Table_Width'='550']
[Var:'Prompts_Width'='85px']
         
<table border="0" cellpadding="4" cellspacing="0" id="mainform" class="formtable" width="[$Table_Witdh]">

<tr><td align="right" valign="top" class="formprompts" style="width: [$Prompts_Width]" >Category:</td>

<td align="left" valign="top" class="forminput"><input type="text" size="60" name="FAQ_Category" class="formfield" value="" /></td></tr>

<tr><td align="right" valign="top" class="formprompts" style="width: [$Prompts_Width]" >FAQ Title:</td>

<td align="left" valign="top" class="forminput"><input type="text" size="60" name="FAQ_Title" class="formfield" value="" /></td></tr>

<tr><td align="right" valign="top" class="formprompts" style="width: [$Prompts_Width]" >Question:</td>
<td align="left" valign="top" class="forminput" >
<textarea name="FAQ_Question" cols="60" rows="2" class="formfield" ></textarea><br /></td></tr>
			
<tr><td align="right" valign="top" class="formprompts" style="width: [$Prompts_Width]">Answer:</td>
<td align="left" valign="top" class="forminput"><textarea name="FAQ_Answer" cols="60" rows="4" class="formfield"></textarea></td></tr>
             
<tr><td class="formprompts" style="width: [$Prompts_Width]" valign="top</td><td class="forminput" valign="top">
<a href="javascript:;" onmousedown="if(document.getElementById('addLinks').style.display == 'none'){ document.getElementById('addLinks').style.display = 'block';  
document.getElementById('linkInfo').style.display = 'block';} else{ document.getElementById('addLinks').style.display = 'none';  document.getElementById('linkInfo').style.display = 'none'; }">FAQ Links</a><br />

<div id="linkInfo" style="display:none">
Click on the "plus sign" before pressing the "Next" button to add more link fields, if required.<br /><br />
The contents of the "Text" field will be displayed as the link in the FAQ (eg. Related Information).  The "URL" is the full address of the link. .<br />
The "Desc" field is provided for a description of the link (eg. Full details of all CF Office Space)
</div></td></tr>
</table>
             
<div id="addLinks" style="display:none">
<table border="0" cellpadding="4" cellspacing="0" id="linksform" class="formtable" width="[$Table_Width]">

<tr><td  class="formprompts" style="width: [$Prompts_Width]" valign="top" >Links:</td>
<td class="forminput" valign="top">
			 
<table id="tabdata">
<tbody><tr><td><a id="addnew" href=""><img alt="+" src="/graphics/plus.gif" class="linkbutton" /></a></td>

<td>Text:&nbsp;<input id="r_0_0" name="r_0_0" type="text" size="25" class="formfield" value="" /><br />

URL:&nbsp;&nbsp;<input id="r_0_1" name="r_0_1" type="text" size="50" class="formfield" value="" /><br />

Desc:<input id="r_0_2" name="r_0_2" type="text" size="55" class="formfield" value="" />
<hr /></td>
<td></td></tr>
</tbody>
</table>			
</td></tr>
</table>

 

The Lasso code to add the base FAQ record is extremely basic and we will assume that a variable "FAQ_Ref" has been generated as unique identifier as part of creating the main FAQ record. It is also assumed that a variable "Success" has been set to the value of "1" with the successful addition of the FAQ record to the main FAQ table.

The following code identifies the parameters submitted via the form that carry the prefix 'r_' and groups them to be added into the FAQlinks table.

[ 
// Set the matching fields to the IDs from the form
// This represents the order in which they appear
// on the page in the form.  Additional fields can be
// easily added to the form and included in the Map
Local:'Field_Map'=(Map);
#Field_Map ->(Insert:'0'='URL_Text');
#Field_Map ->(Insert:'1'='URL');
#Field_Map ->(Insert:'2'='URL_Description');

//Set the total number of expected fields
Local:'Total_Fields'= #Field_Map ->Size;
		
// Set the prefix to identify the parameters
Local:'Prefix' = 'r_';
Local:'Prefix_Size'= (#Prefix->Length);
		
Local:'Elements'=(Action_Params); // the data from the form
		
Local:'Ungrouped_Elements'=(Array);  
Local:'Temp_Array'=(Array); 
		
Local:'Output_Array'=(Array); 
		
// variables for managing rows and fields
Local:'Last_Row'=0;
Local:'Row_ID'=0;
Local:'Field_ID'=0;
Local:'Field_Data'='';
Local:'Field_Name'='';
Local:'This_Row'=0;
Local:'Field_Count'=0;
Local:'Submitted_Data'=0; 		
			
Loop: -loopfrom=(#Elements->size), -loopto=1, -loopincrement=(-1);

Var: ((#Elements)->(Get:Loop_Count)->First)=((#Elements)->(Get: Loop_Count)->Second);

Local: 'Temp_Element'=#Elements->Get:Loop_Count->First;
Local: 'Temp_Data'=#Elements->Get:Loop_Count->Second;
				
// remove any HTML C/- LassoSoft coding challenge
#Temp_Data = (string_replaceregexp: #Temp_Data,-Find='<[^>]+>',-Replace='');
				
If:#Temp_Element->(BeginsWith:#Prefix);

#Temp_Element=(String_Remove: #Temp_Element, -StartPosition=1, -EndPosition=#Prefix_Size);

#Row_ID = (Integer:(#Temp_Element->(Split:'_'))->(Get:1));

// determine the number of records being added
#Row_ID > #Last_Row ? #Last_Row = #Row_ID;
					
#Field_ID = #Temp_Element->(Split:'_')->(Get:2);
#Field_Name = #Field_Map->(Find:(#Temp_Element->(Split:'_')->(Get:2)));

// determine if there is any data in these rows 
#Temp_Data !='' ? #Submitted_Data += 1;
#Ungrouped_Elements->(Insert:#Row_ID+'_'+#Field_Name = #Temp_Data);
				
/If;
/Loop;

	
If:#Submitted_Data != 0;
While: #This_Row <= #Last_Row;
Iterate:#Ungrouped_Elements,$i;
#Row_ID = (Integer:(($i->First)->(Split:'_'))->(Get:1));
#Field_Name = (String_Remove: ($i->First), -StartPosition=1, -EndPosition=#Prefix_Size);
#Field_Data = $i->Second;
				
If:#Row_ID == #This_Row;
If:#Field_Count == #Total_Fields;
	#Field_Count = 0;
	#This_Row += 1;
	#Output_Array->(Insert:#Temp_Array);
	#Temp_Array = (Array);
Else;
	#Field_Data != '' ? #Temp_Array ->(Insert:#Field_Name = #Field_Data);
	#Field_Count += 1;
/If;
/If;
/Iterate;
/While;
	
/If;

// code to generate FAQ_Ref and insert main FAQ Record	
	
If:$Success == '1' && #Submitted_Data != 0;
Iterate:#Output_Array,(Var:'i');
$Submit_Elements->Merge:$i;
$Submit_Elements -> (Insert:'FAQ_Ref'=$FAQ_Ref);

Inline:
	$Database_Elements,
	$Submit_Elements,
	-Table='faqlinks',
	-Add;
	// error handling and logging here
	
/Inline;
$Submit_Elements = (Array);

/Iterate;
/If;
]

Author: Rick Draper
Created: 13 Apr 2008
Last Modified: 3 Mar 2011

Comments

No comments found
You must be logged in to comment.

Please note that periodically LassoSoft will go through the notes and may incorporate information from them into the documentation. Any submission here gives LassoSoft a non-exclusive license and will be made available in various formats to the Lasso community.

LassoSoft Inc. > Home

 

 

©LassoSoft Inc 2015 | Web Development by Treefrog Inc | PrivacyLegal terms and Shipping | Contact LassoSoft