?
Solved

Coldfusion - Loop Refinement

Posted on 2009-04-27
16
Medium Priority
?
339 Views
Last Modified: 2012-05-06
Hi.  I need to come up with a way to loop through a form.  I have to repeat the structure 15 times, then pass the data to db (passing the data really isn't part of this question...).  I have a really really basic loop and I need help coming up with a 'good' 'proper' 'intelligent' way of doing this.  I've posted the beginning of my idea below (I've commented it as best I can, and it should explain what I'm trying to accomplish).

Thanks for your help.  Sooner or later I will catch on.  I'm using CF7 still.

~ Wendi
<!---First, set variables.resourceNum.  For each loop this increases by 3 total. This whole loop will run 15 times --->
<cfset resourceNum = 325>
 
<!--- Set part one of naming convention. this is a constant for the whole 15 cycles--->
<cfset pgname=  "cpo_ess">
 
<!--- Set the increment of the naming convention; probably could handle this with loop index --->
<cfset numpos=1>
 
 
<cfloop from="1" to="15" index="x">
 
<!--- this set is comprised of 1 textarea, 7 checkboxes, 1 text box ~ thus loop in loop --->
<tr>
	<td class="inner_table"  valign="top" align="left">
      <!---Row Number--->1)
    </td>
    <td class="inner_table"  valign="top" align="left">
    
    <!--- Validating textarea --->
    <cftextarea 
    	validate="maxlength" 
        maxlength="400" 
        message="You've exceed the character limit for Action Item 1.  Please edit." 
        validateat="onSubmit" 
        name="CFADMIN#resourceNum#" 
        cols="70" 
        rows="5" 
        wrap="soft">
        <!---should use variables.ResourceNum instead of CFADMIN325 --->
        #trim(getform.CFADMIN325)#</cftextarea>
     
     </td>
 
<!--- Increase variables.resourceNum by 1 --->
<cfset resourceNum = resourceNum + 1>
 
<!--- Begin the check boxes.  Should be using resourceNum instead of CFADMIN326 (below) --->
<cfloop from="1" to="7" index="j">
	<cfif j LTE 4>
	<td class="inner_table"  valign="top" align="left">
        
        	
            <!--- Also of note, these checkboxes will also have the same letter associated with them --->
            <!--- Compose name attribute with variables.pgname (set above) and _B (or _IM, or _OR... etc...)
				  and then variables.numpos set above, incremented below (this could really be the loop index)--->
            <input <cfif ("#trim(ListGetAtIncNulls(getform.CFADMIN326, 1))#" EQ "1")>checked="checked"</cfif> 
             type="checkbox" name="#pgname#_B#numpos#" id="checkbox" value="1"/>B
             
            <input <cfif ("#trim(ListGetAtIncNulls(getform.CFADMIN326, 2))#" EQ "1")>checked="checked"</cfif> 
             type="checkbox" name="#pgname#_IM#numpos#" id="checkbox" value="1"/>IM
             
            <input <cfif ("#trim(ListGetAtIncNulls(getform.CFADMIN326, 3))#" EQ "1")>checked="checked"</cfif> 
             type="checkbox" name="#pgname#_OR#numpos#" id="checkbox" value="1"/>OR
             
            <input <cfif ("#trim(ListGetAtIncNulls(getform.CFADMIN326, 4))#" EQ "1")>checked="checked"</cfif> 
             type="checkbox" name="#pgname#_ST#numpos#" id="checkbox" value="1"/>ST
             
	</td>
    		<!--- Astetics; if we've hit four checkboxes, create a new cell --->
    <cfelse>
	<td class="inner_table"  valign="top" align="left">
    		<input <cfif ("#trim(ListGetAtIncNulls(getform.CFADMIN326, 5))#" EQ "1")>checked="checked"</cfif> 
             type="checkbox" name="#pgname#_SSS#numpos#" id="checkbox2" value="1"/>SSS
             
          	<input <cfif ("#trim(ListGetAtIncNulls(getform.CFADMIN326, 6))#" EQ "1")>checked="checked"</cfif> 
             type="checkbox" name="#pgname#_TECH#numpos#" id="checkbox2" value="1"/>TECH
             
          	<input <cfif ("#trim(ListGetAtIncNulls(getform.CFADMIN326, 7))#" EQ "1")>checked="checked"</cfif> 
             type="checkbox" name="#pgname#_T#numpos#" id="checkbox2" value="1"/>T
    </td>
    </cfif>
    
</cfloop>
 
<cfset resourceNum = resourceNum + 1>	
    <!--- Final text area. Should use variables.ResourceNum instead of CFADMING327 --->
	<td class="inner_table"  valign="top" align="left">
    		<input type="Text" name="CFADMIN327" value="#trim(getform.CFADMIN327)#" size="30">
    </td>
</tr>
<cfset resourceNum = resourceNum + 1>
<cfset numpos= numpos +1>
</cfloop>
 
<!--- Not important for the loop, but 
	  Now we take the 3 data sets which will look like this:  
	  Textarea entry ; 1,0,0,1,1,0,1 ;  Textbox entry  
	  and do a db update --->

Open in new window

0
Comment
Question by:wkolasa
  • 9
  • 4
  • 3
16 Comments
 
LVL 27

Accepted Solution

by:
azadisaryev earned 1000 total points
ID: 24241211
i am having a bit of trouble understanding exactly what you are trying to achieve to come up with a full working code for you, but i think this piece of advice can help you with the trouble of referencing your variables.resourceNum in your code:

use associative array notation, i.e.:

<cftextarea ...>#trim(getform['CFADMIN' & variables.resourceNum])#</cftextarea>

<cfif trim(ListGetAtIncNulls(getform['CFADMIN' & variables.resourceNum], 1)) EQ 1)>checked="checked"</cfif>

<input type="Text" name="CFADMIN#variables.resourceNum#" value="#trim(getform['CFADMIN' & variables.resourceNum])#" size="30">

Azadi
0
 
LVL 39

Assisted Solution

by:gdemaria
gdemaria earned 1000 total points
ID: 24241488
I agree with Azadi, you never really stated what you are trying to accomplish.

My observation is that you seem to be referencing a query "getform"  but you never loop through this query.   Every time you are using getform it seems you are showing the same record, the first one.

My suggested approach for this is to convert the query immediately to the form variable, and then use the form variable inside your loop instead of the query.  

<cfquery name="getform"....
  select * from theTable...
</cfquery>
<cfloop query="getform">
   <cfset "form.CFADMIN325_#getForm.currentRow#" = getForm.CFADMIN325>
   <cfset "form.CFADMIN326_#getForm.currentRow#" = getForm.CFADMIN326>
   <cfset "form.CFADMIN327_#getForm.currentRow#" = getForm.CFADMIN327>
</cfloop>

Now you have sort-of an array of form variables you can loop through in your <FORM>

<cfloop index="aRow" from=1 to="#getForm.recordCount#">

 <!---- an example... ---->
 <input <cfif val(ListGetAtIncNulls(form["CFADMIN326_" & kk))>checked="checked"</cfif>
       type="checkbox" name="#pgname#_B#numpos#" id="checkbox" value="1">


</cfloop>


It's unclear to me why your checkbox name doesn't match the form/column name.  If it did, you would be able to submit this form and if there were any errors, you could redraw the form with all the user's input intact, but not saved.  Thus allowing them to correct any errors and resubmit without having to type everything in again.




   
0
 

Author Comment

by:wkolasa
ID: 24241499
Hi.  I'll clean up what I'm trying to accomplish and send very soon (I'll take a screenshot too).
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:wkolasa
ID: 24241560
First, yes, I do a basic query to get the "getForm" stuff.  

<cfquery name="getform" datasource="#application.dsn#">
      Select      *
      from       MISC.SIP_2009
      where      scid = '#session.scid#'
</cfquery>

It returns the getform.CFADMIN326 field, and this field contains the following type of data 1,0,0,1,1,0,1 .  I use this when building the checkboxes, test for position (ex:  for 3rd checkbox, check position 3 of getform.CFADMIN326... if it's a 1, then check, if it's a 0 or Null, leave unchecked.)

Now, the entire order of variables goes like this:

textarea = CFADMIN325

Checkboxes = CFADMIN326

text box = CFADMIN327
0
 
LVL 39

Expert Comment

by:gdemaria
ID: 24241622
I am guessing the database design is already set and it's too late to change, but if not, I think you should have every one of those data items in a separate field  1,0,0,1,1,0,1 would not be merged together in one field, but rather in 7 separate fields.   Or, if too many to create a separate field for, then have a field called "Name" and another called "Value" and enter the name and the value in these fields.

 TheName   TheValue
 isGreen      True
 isOversize  False
 isInStock    True

0
 

Author Comment

by:wkolasa
ID: 24241749
The db, and this monster of an app. were already built.  I can't get around it.  The db, just as a side note, is probably the worst design I've ever seen.  982 columns.  It's not relational, utilizing no naming structure, no anything that would make logical sense.  I can't dump it b/c it's been in existence for a while and it has data.
0
 
LVL 39

Expert Comment

by:gdemaria
ID: 24241790
Yea, the names look like a nightmare too.  Someday when you're bored and your company feels rich suggest a rebuild :)   You can always convert the data over, either way, I'm sure it's torture.


So, is the idea, you want to show X number of rows of data from getForms, allow the user to change the form and then update it back to the database?


0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 24242150
hmm... it all sounds like a royal PITA of a system to work with!

anyway, if getform is a query, then any associative array notation to its columns MUST include row reference, i.e.:

<cftextarea ...>#trim(getform['CFADMIN' & variables.resourceNum][1])#</cftextarea>

awaiting your posting of more explanations and possible screenshots...

Azadi
0
 

Author Comment

by:wkolasa
ID: 24242276
Hi, screenshot below:


example.gif
0
 
LVL 39

Expert Comment

by:gdemaria
ID: 24242350
Ok, so Azadi and I are giving you similar advice, but a bit different.  Choose your route.   My suggestion is to copy the data from your query directly into form variables and use those form variables when displaying the FORM.  This has the benefit of being able to redisplay to the user their inputted values if there is an error (for example, they left a required field blank).  

I believe Azadi is helping you move forward with the form as it's originally structured, using the query as the VALUE="" of your input tags.   This is perfectly fine too, just different for handling any errors.  

So, wkolasa, make some changes to your form in either direction and we will help guide you along.  Post your updated code and the current error or uncertainty...

0
 

Author Comment

by:wkolasa
ID: 24242398
Thanks GdeMaria, I'm implementing now.  I'll have a post soon.  Again, thank you both.
0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 24247199
@wkolasa:
what exactly does your getForm query return?
if you post a dump of the query, we can probably give you more detailed assistance with your loops...

Azadi
0
 

Author Comment

by:wkolasa
ID: 24251810
The dataDump of getForm would look like this (just a slice... there are hundreds of the cfadmin fields... again, I didn't build this):


 CFADMIN325      CFADMIN326      CFADMIN327
 -------------   -------------   -------------
 Textarea stuff  0,0,0,0,0,0,0   text box stuff

Open in new window

0
 

Author Comment

by:wkolasa
ID: 24252312
I'm a bit more focused.  In order to make the loop work I need help with the following:
 
1) I need to use replace the letters  B,IM,OR,ST,SSS,TECH,T  
2) with a the first position of this <cfset resourceModeChars =("B,IM,OR,ST,SSS,TECH,T") >
3) and then delete the first position -- something like this:  ListDeleteAt(resourceModeChars, x)

I've almost got it working... I've place the before and after below.  I need to break it into a second cell on the 5th cycle of the loop.
ORIGINAL
----------------------------------
<cfset resourceNum = resourceNum + 1>
<cfset pgname=  "cpo_ess">
<cfset numpos=1>
<cfset getFormList = "#trim(ListGetAtIncNulls(getform.CFADMIN326))#">
 
<!--- Begin the check boxes.  Loop.  --->
<cfloop from="1" to="1" index="j">
		<td class="inner_table"  valign="top" align="left">
			<input <cfif (ListGetAtIncNulls(getFormList, 1)) EQ "1">checked="checked"</cfif> 
             type="checkbox" name="#pgname#_B#numpos#" id="checkbox" value="1"/>B
             
            <input <cfif (ListGetAtIncNulls(getFormList, 2)) EQ "1">checked="checked"</cfif> 
             type="checkbox" name="#pgname#_IM#numpos#" id="checkbox" value="1"/>IM
             
            <input <cfif (ListGetAtIncNulls(getFormList, 3)) EQ "1">checked="checked"</cfif> 
             type="checkbox" name="#pgname#_OR#numpos#" id="checkbox" value="1"/>OR
             
            <input <cfif (ListGetAtIncNulls(getFormList, 4)) EQ "1">checked="checked"</cfif> 
             type="checkbox" name="#pgname#_ST#numpos#" id="checkbox" value="1"/>ST</td>
 
		<td class="inner_table"  valign="top" align="left">
    		<input <cfif (ListGetAtIncNulls(getFormList, 5)) EQ "1">checked="checked"</cfif> 
             type="checkbox" name="#pgname#_SSS#numpos#" id="checkbox2" value="1"/>SSS
             
          	<input <cfif (ListGetAtIncNulls(getFormList, 6)) EQ "1">checked="checked"</cfif> 
             type="checkbox" name="#pgname#_TECH#numpos#" id="checkbox2" value="1"/>TECH
             
          	<input <cfif (ListGetAtIncNulls(getFormList, 7)) EQ "1">checked="checked"</cfif> 
             type="checkbox" name="#pgname#_T#numpos#" id="checkbox2" value="1"/>T
    	</td>
</cfloop>
 
 
SIMPLIFIED LOOP
----------------------------------
<cfset resourceNum = resourceNum + 1>
<cfset pgname=  "cpo_ess">
<cfset getFormList = "#trim(getform.CFADMIN326)#">
<cfset resourceModeChars = ("B,IM,OR,ST,SSS,TECH,T") >
<cfset numpos=1>
 
<td class="inner_table"  valign="top" align="left">
<cfloop from="1" to="#ListLen(resourceModeChars)#" index="j">
	<input <cfif (ListGetAtIncNulls(getFormList, #j#)) EQ "1">checked="checked"</cfif> 
      type="checkbox" name="#pgname##(ListGetAt(resourceModeChars, j))##numpos#" id="checkbox" 
	  value="1"/>#(ListGetAt(resourceModeChars, j))#
</cfloop>
</td>

Open in new window

0
 

Author Comment

by:wkolasa
ID: 24252336
I tossed this in which makes the cell break work (don't know why I didn't think of it earlier):

<cfif j EQ 5></td><td></cfif>
0
 

Author Comment

by:wkolasa
ID: 24252523
I have it working pretty well now.  Thanks for everyone's help.  If I need further help with this I'll post a new question.

Thanks again!
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article  is about submitting  form through  ColdFusion.Ajax.submitForm to the action page and send a response back in JSON format which later can be decoded using ColdFusion.JSON.decode. By this way you can avoid the usual page refresh for subm…
Recently while working on a project I got a very annoying cfdocument has no body error message. I had never seen this error before. So I checked the code. The code was pretty simple; it was Just showing me the cfdocumnt tag and inside that tag a …
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Loops Section Overview
Suggested Courses
Course of the Month13 days, 8 hours left to enroll

749 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