Solved

Multiple (n) Entries on a Form...How to Handle?

Posted on 2004-08-02
12
200 Views
Last Modified: 2013-12-24
I have an employment application form in CF.  One section of the form is called "Employment History".  

In this section, the user needs to have the ability to enter "n" number of previous employers with corresponding details, not a predefined number of employer.  The details section is as follows:

Employment History

Employer 1:

Employer Name: txt_emp_name
Employer Phone: txt_emp_phone
Start Date: txt_emp_start_date
End Date: txt_emp_end_date

Employer 2:

Employer Name: txt_emp_name
Employer Phone: txt_emp_phone
Start Date: txt_emp_start_date
End Date: txt_emp_end_date
----
etc, etc.

Employer "n":

Employer Name: txt_emp_name
Employer Phone: txt_emp_phone
Start Date: txt_emp_start_date
End Date: txt_emp_end_date

How can I set up this section to allow the input of "n" number of employers by the user as well as the processing of these dynamic fields on submit (cfquery insert to db).  

I am looking for someone to provide me a code-based solution to this issue (form page and processing page).

My code for the relevant section of the form is as follows:

<table width="100%"  border="0" cellspacing="0" cellpadding="0">
          <tr>
            <td  > Employer: (Present or most recent)<br />
              <input name="job1Empl" id="job1Empl" size="40" maxlength="40" /></td>
            <td  > Address:<br />
              <input name="job1Addr" id="job1Addr" size="40" maxlength="40" /></td>

            <td  > Phone #:<br />
              <input name="job1Phone" id="job1Phone" size="20" maxlength="20" /></td>
          </tr>
          <tr>
            <td  > Job Title:<br />
              <input name="job1Title" id="job1Title" size="40" maxlength="40" /></td>
            <td  > Name and title of supervisor: <br />

              <input name="job1Sup" id="job1Sup" size="40" maxlength="40" /></td>
            <td  >No. supervised by you:<br />
              <input name="job1NumSupd" id="job1NumSupd" size="20" maxlength="20" /></td>
          </tr>
          <tr>
            <td  > Date Employed: <br />
              <input name="job1DateEmpl" type="text" id="job1DateEmpl" />

            </td>
            <td  > Starting Salary <br />
              <input name="job1StartAmt" id="job1StartAmt" value="" size="2" maxlength="2" />
per
<input name="job1StartTerm" id="job1StartTerm"
       value="" size="2" maxlength="2" /></td>
            <td  > Ending Salary <br />
              <input name="job1EndAmt" id="job1EndAmt" value="" size="2" maxlength="2" />
              per
              <input name="job1EndTerm" id="job1EndTerm"
       value="" size="2" maxlength="2" />

            </td>
          </tr>
          <tr>
            <td valign="top"  >Date Separated: <br />
              <input name="job1DateSep" id="job1DateSep" size="40" maxlength="40" /></td>
            <td colspan="2"  > Duties:<br />
              <textarea name="job1Duties" cols="71" rows="8" wrap="soft" id="job1Duties"></textarea></td>

          </tr>
          <tr>
            <td  >Full time for: Years Months <br />
              <input name="job1FTYrs" type="text" id="job1FTYrs" size="4" maxlength="4" />
              <input name="job1FTMos" type="text" id="job1FTMos" size="4" maxlength="4" /></td>
            <td colspan="2"  >&nbsp; <br />
            </td>
          </tr>

          <tr>
            <td  > Part time for: Years Months &nbsp; <br />
              <input name="job1PTYrs" type="text" id="job1PTYrs" size="4" maxlength="4" />
              <input name="job1PTMos" type="text" id="job1PTMos" size="4" maxlength="4" />
            </td>
            <td colspan="2"  >&nbsp;</td>
          </tr>

          <tr>
            <td colspan="3"  >If part-time, number of hrs. worked per week:<br />
              <input name="job1PTHrs" type="text" id="job1PTHrs" /></td>
          </tr>
          <tr>
            <td colspan="3"  > Reason for leaving<br />
              <input name="job1RsnLvg" id="job1RsnLvg" size="60" maxlength="50" />

&nbsp; </td>
        </tr>
      </table>
0
Comment
Question by:mjrogan
  • 7
  • 4
12 Comments
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
There are 2 solutions

1) Have the user specify on the first page the number of previous employers and then submit to the next page that generates the form

2) Dynamically allow the user to add/remove the number of previous employers at run time


Evaluation:

Method 1 Pros : User does not need javascript enabled - less and cleaner coding
Method 1 Cons : Not as dynamic - user has to hit back if they need an extra one, pae has to be submitted

method 2 Pros :  Completely dynamic addition/removal of rows of inputs
Method 2 cons : Requires javascript to be enabled - not compatible across as many browsers (although it is compatible across all newer browsers) - Some issues in older browsers with dynamica adding of rows if using SSL



In either case you access the form fields on the submission page as

#Form['fieldname_' & i]#

Where i is each numbered field.  Usually this is in a loop like :

<cfloop index="i" from="1" to="#Form.numfields#">
     #Form['fieldname_' & i]#
</cfloop>

Method 1 should be straightforward - just use a loop to generate the correct number of inputs after the user submits the first form
I will follow this post with an example of how to do method 2 (it is very long)
0
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
The following example is how to dymaically add rows to a table.  It is an example for a timesheet application


Step 1)  Create regular html table - Note if you have a header row or not.  This example below has a header row...  Be sure to give the table an id
===================================

<table id="timesheet_table" border="0">
<!--- Header row --->
  <tr>
     <td>TimeCode</td>
     <td>Sunday</td>
     <td>Monday</td>
     <td>Tuesday</td>
     <td>Wednesday</td>
     <td>Thursday</td>
     <td>Friday</td>
     <td>Saturday</td>
   </tr>
<!--- Now create first row of inputs --->
   <tr>
     <td>
         <select name="TimeCode_1">
              <option value=""></option>
              <option value="W">Worked</option>
              <option value="V">Vacation</option>
              <option value="S">Sick</option>
              <option value="J">Jury Duty</option>
         </select>
     </td>
     <td><input name="Sun_1" size="2" type="text"></td>
     <td><input name="Mon_1" size="2" type="text"></td>
     <td><input name="Tue_1" size="2" type="text"></td>
     <td><input name="Wed_1" size="2" type="text"></td>
     <td><input name="Thu_1" size="2" type="text"></td>
     <td><input name="Fri_1" size="2" type="text"></td>
     <td><input name="Sat_1" size="2" type="text"></td>
  </tr>
</table>

===================================



Step 2) Create Links above the table to add or delete a row

===================================

<a href="javascript:addCode();">Add TimeCode Row</a>
<a href="javascript:deleteCode();">Delete Last Row</a>

===================================



Step 3) Create an input (hidden) to keep track of how many rows you have - default to 1

===================================

<input type="hidden" name="CodeCount" value="1">

===================================




Step 4) Create the javascript functions to add and remove rows.  I personally would link to this as a separate file to help keep the code easier to manage.....

===================================

Step 4a) In the head of the document :

-----------------------------------------------------------------

<script type="text/javascript" language="JavaScript" src="/timesheet.js"></script>

-----------------------------------------------------------------

Step 4b) In the file timesheet.js:

-----------------------------------------------------------------

// Build array of the various timecodes allowed in the format Display, Value which looks like <option value="Value">Display</option> when turned into the select box
var TimeCodeArray = new Array('','','Worked','W','Vacation','V','Sick','S','Jury Duty','J');

// Include this function which will create a select box for you based on above array
function BuildSelectListBox(tempSelect, currentOptionArray)
{
     for(var i=0; i<(currentOptionArray.length); i+=2)
     {
          tempSelect.options[tempSelect.options.length] = new Option(currentOptionArray[i], currentOptionArray[i+1]);
     }
     tempSelect.options.length = currentOptionArray.length/2;
     return tempSelect;
}

// Include the function to delete a row - force them to have at least one row (i.e cannot delte only row)
function deleteCode()
{
     var tbody = document.getElementById('timesheet_table').getElementsByTagName("TBODY")[0];
     form = document.Timesheetform; // Timesheetform is the name of your form
     if(tbody.rows.length > 2) // +1 because we don't count header row
     {
          tbody.deleteRow(tbody.rows.length-1);
          // Decrement the number of Codes
          document.Timesheetform.CodeCount.value = parseInt(document.Timesheetform.CodeCount.value) - 1;
     }
     else
     {
          alert('You cannot delete this row.');
     }
}

// Include the function to add a row
function addCode()
{
     var tbody = document.getElementById('timesheet_table').getElementsByTagName("TBODY")[0];
     var row = document.createElement("TR"); // create a new table row
     var td = new Array(8); // counting the table we made there are 8 cells per table row
     var tempSelect;
     var tempInput;
     var rownum = tbody.rows.length; // not +1 because we have a header row
     
     // Create Code select box
     td[0] = document.createElement("TD"); // create a td element    
     tempSelect = document.createElement("SELECT"); // create a select box
     BuildSelectListBox(tempSelect, TimeCodeArray); // put the options into the select box using our function
     tempSelect.name = "TimeCode_" + rownum; // name the select box
     tempSelect.id = "TimeCode_" + rownum; // give an id to the select box
     td[0].appendChild(tempSelect); // add the select box to the table cell
     
     // Create Daily hour inputs
     td[1] = document.createElement("TD"); // create a table cell
     tempInput = document.createElement("INPUT"); //  create an input
     tempInput.name = "Sun_" + rownum; // name the input
     tempInput.id = "Sun_" + rownum; // give an id to the input
     tempInput.size = 2; // set the size of the input
     td[1].appendChild(tempInput); // add the input to the table cell
     
     td[2] = document.createElement("TD");
     tempInput = document.createElement("INPUT");
     tempInput.name = "Mon_" + rownum;
     tempInput.id = "Mon_" + rownum;
     tempInput.size = 2;
     td[2].appendChild(tempInput);
     
     td[3] = document.createElement("TD");
     tempInput = document.createElement("INPUT");
     tempInput.name = "Tue_" + rownum;
     tempInput.id = "Tue_" + rownum;
     tempInput.size = 2;
     td[3].appendChild(tempInput);
     
     td[4] = document.createElement("TD");
     tempInput = document.createElement("INPUT");
     tempInput.name = "Wed_" + rownum;
     tempInput.id = "Wed_" + rownum;
     tempInput.size = 2;
     td[4].appendChild(tempInput);
     
     td[5] = document.createElement("TD");
     tempInput = document.createElement("INPUT");
     tempInput.name = "Thu_" + rownum;
     tempInput.id = "Thu_" + rownum;
     tempInput.size = 2;
     td[5].appendChild(tempInput);
     
     td[6] = document.createElement("TD");
     tempInput = document.createElement("INPUT");
     tempInput.name = "Fri_" + rownum;
     tempInput.id = "Fri_" + rownum;
     tempInput.size = 2;
     td[6].appendChild(tempInput);
     
     td[7] = document.createElement("TD");
     tempInput = document.createElement("INPUT");
     tempInput.name = "Sat_" + rownum;
     tempInput.id = "Sat_" + rownum;
     tempInput.size = 2;
     td[7].appendChild(tempInput);
               
     // Append each cell to  the row we created row
     for(i=0; i<8; i++)
          row.appendChild(td[i]);
     // Append row to table so that it appears on screen
     tbody.appendChild(row);
     
     // Increment the number of Code rows
     document.Timesheetform.CodeCount.value = parseInt(document.Timesheetform.CodeCount.value) + 1;
}
0
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
The above can easily be modified to add objects (i.e. a previous employer may have inputs that are displayed in more than one table row) and different types of inputs.

Let me know if you need more help after you have a chance to digest this.
0
 
LVL 15

Expert Comment

by:danrosenthal
Comment Utility
You could have a "Submit and add another Employer" button, so the user enters one at a time and show the previous one on the page as he builds the history.
0
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
Yes taht is true - with most of the same pros/cons of method 1 that I mentioned....
0
 

Author Comment

by:mjrogan
Comment Utility
Thanks for your replies and examples.  I am trying to rely on as little client-side code as possible, so I think that method 1 is preferable.

Since the user may not readily know their number of employers before entering the form, I also like the suggestion of having a "Submit and add another Employer" button.

Can you provide an example of how this method would be coded and I will give it a try?

Thanks again!
0
Scale it in WD Gold

With up to ten times the workload capacity of desktop drives, WD Gold hard drives employ advanced technology to deliver among the best in reliability, capacity, power efficiency and performance.

 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
Method 1a) Enter number up front

Page 1:
Please enter the number of employers <input type="textbox" name="numemployers">

Page 2:
<cfloop index="i" from="1" to="#Form.numemployers#">

 <tr>
            <td  > Employer: (Present or most recent)<br />
              <input name="job#i#Empl" id="job#i#Empl" size="40" maxlength="40" /></td>
            <td  > Address:<br />
              <input name="job#i#Addr" id="job#i#Addr" size="40" maxlength="40" /></td>

            <td  > Phone #:<br />
              <input name="job#i#Phone" id="job#I#Phone" size="20" maxlength="20" /></td>
          </tr>
          <tr>
            <td  > Job Title:<br />
              <input name="job#i#Title" id="job#I#Title" size="40" maxlength="40" /></td>
            <td  > Name and title of supervisor: <br />

              <input name="job#i#Sup" id="job#i#Sup" size="40" maxlength="40" /></td>
            <td  >No. supervised by you:<br />
              <input name="job#i#NumSupd" id="job#i#NumSupd" size="20" maxlength="20" /></td>
          </tr>
          <tr>
            <td  > Date Employed: <br />
              <input name="job#i#DateEmpl" type="text" id="job#i#DateEmpl" />

            </td>
            <td  > Starting Salary <br />
              <input name="job#i#StartAmt" id="job#i#StartAmt" value="" size="2" maxlength="2" />
per
<input name="job#i#StartTerm" id="job#i#StartTerm"
      value="" size="2" maxlength="2" /></td>
            <td  > Ending Salary <br />
              <input name="job#i#EndAmt" id="job#i#EndAmt" value="" size="2" maxlength="2" />
              per
              <input name="job#i#EndTerm" id="End#i#Term"
      value="" size="2" maxlength="2" />

            </td>
          </tr>

</cfloop>
<input type="hidden" name="numemplyers" value="#form.numemployers#">


Then you will end up with one row for each employer with the fields named
job1StartAmt, job1EndAmt, etc...
job2StartAmt, job2EndAmt, etc...
for each emplyer

Then on Page 3 where you process you can do :
<cfloop index="i" from="1" to="#Form.numemployers#">
#Form['job' & i & 'StartAmt']#
</cfloop>






Method 1B) Enter each as you go :

Page 1:


 <tr>
            <td  > Employer: (Present or most recent)<br />
              <input name="job1Empl" id="job1Empl" size="40" maxlength="40" /></td>
            <td  > Address:<br />
              <input name="job1Addr" id="job1Addr" size="40" maxlength="40" /></td>

            <td  > Phone #:<br />
              <input name="job1Phone" id="job1Phone" size="20" maxlength="20" /></td>
          </tr>
          <tr>
            <td  > Job Title:<br />
              <input name="job1Title" id="job1Title" size="40" maxlength="40" /></td>
            <td  > Name and title of supervisor: <br />

              <input name="job1Sup" id="job1Sup" size="40" maxlength="40" /></td>
            <td  >No. supervised by you:<br />
              <input name="job1NumSupd" id="job1NumSupd" size="20" maxlength="20" /></td>
          </tr>
          <tr>
            <td  > Date Employed: <br />
              <input name="job1DateEmpl" type="text" id="job1DateEmpl" />

            </td>
            <td  > Starting Salary <br />
              <input name="job1StartAmt" id="job1StartAmt" value="" size="2" maxlength="2" />
per
<input name="job1StartTerm" id="job1StartTerm"
      value="" size="2" maxlength="2" /></td>
            <td  > Ending Salary <br />
              <input name="job1EndAmt" id="job1EndAmt" value="" size="2" maxlength="2" />
              per
              <input name="job1EndTerm" id="job1EndTerm"
      value="" size="2" maxlength="2" />

            </td>
          </tr>

<input type="submit" name="moreemployers" value="Add another employer">


Page 2:
Add the submitted employer to database or session
Send back to previous page so they can enter next one.....

0
 

Author Comment

by:mjrogan
Comment Utility
Thanks...in method 1B, I would still use the variable "i", right?  Would it just be set to 1 initially and then incremented?  How would that be done?  Something like:

Initial value:
<cfset session.jobapp.numemployers = 1>
<cfset i = session.jobapp.numemployers>

Future values:
<cfif IsDefined("FORM.moreemployers")>
     <cfset i = i + 1>
</cfif>
<cfset session.jobapp.numemployers = i>

???

Also, the processing of methods 1A and 1B would be the same, right?
0
 
LVL 35

Expert Comment

by:mrichmon
Comment Utility
No.

In Method 1A it works like this logically

Ask the user how many employers they will enter --> User says 3
On next page create 3 sets of inputs each labeled uniquley
User fills all 3 out
On the processing page look at each one using a loop and store to database


In Method 1B it works like this logically

User is presented with input form for 1st employer
User fills out 1st employer and submits
You store to database and present user with form again
User repeats.
Each time user repeats you do not know what number they are on so the fields (inputs) all are the same name
The processing is identical to if they were only submitting one.

0
 

Author Comment

by:mjrogan
Comment Utility
I would like to use method 1B and understand how it would work as you are describing it (with query execution on submit and reusing the same form), but in my case I am not doing an immediate insert query following each employment history entry.  

Employment history is, for example, step 4 of 7 in the entire application process, with each step on its own page.  As each step/page is completed, and the user clicks "next", the form fields are validated.  If valid, they are added to a session struct.  

In the case of employment history, each time the user clicks "enter another employer", the form fields for that entry need to be validated and then added to the session struct.  I need to be able to maintain them individually in order to display the details on the final confirmation page at the end of the application and then run the insert query for each of the employment entries on the "final" submit of the application.

I can see how this would work using method 1A.  How can I handle this using 1B?
0
 
LVL 35

Accepted Solution

by:
mrichmon earned 250 total points
Comment Utility
In method 1B what I would do is keep a count of number of employers in the session struct
Then each time the "add employer" page is submitted, increment the number in the session struct and replace the above "save to database" step with saving to the struct with the number as a suffix.  For example

<cfset session.employernum = 0> <!--- on step 1 of entire form --->


<!--- after each employer is submitted --->
<cfset session['EmpStartAmt' & employernum] = Form.EmpStartAmt>
....


So that when you process the entire thing to add to the database after step 7 you then do :

<cfloop index="i" from="1" to="#session.employernum#">
    Access each employer field in here such as :
   #Session['EmpStartAmt' & i]#
</cfloop>
0
 

Author Comment

by:mjrogan
Comment Utility
Thanks!  This looks like it will do exactly what I need!  
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Most ColdFusion developers get confused between the CFSet, Duplicate, and Structcopy methods of copying a Structure, especially which one to use when. This Article will explain the differences in the approaches with examples; therefore, after readin…
Periodically we have to update or add SSL certificates for customers. Depending upon your hosting plan you may be responsible for the installation and/or key generation. In the wake of Heartbleed many sites were forced to re-key. We will concen…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now