Solved

Passing array data to another page in Coldfusion

Posted on 2011-09-06
33
682 Views
Last Modified: 2012-05-12
Hello All,
Using Coldfusion...

IframeConsultant, (yes, IFRAME), contains

function to select a firm, after select a firm you may choose a consultant.
rather than store a consultant rate with the consultant information,
store the rate with the chosen consultant in an intersection (cross) table along with the orderid.

You can choose multiple consultants and assign each one a rate

Currently there's an array setup to grab the consultant id, already stored in tables and pass this info
to a function that updates the intersect table with orderid, consultantid.


All help appreciated - it's late so please ask questions I'm sure this sounds jumbled as it is.
I've added an input box to the looped array so there's a input field next to each new consultant selected for "rates".

as you choose a consultant a temparray is updated but nothing is "saved" to the table until you hit the save button.

The action on the save button is where I want to pass along my rates (in the looped array known as rate_#i#).

Problem:
I need to pass the rates data to the "save" action(method) which is a looping tempArray populated if another function finds a 
consultantid and since my "rates" data is not a part of the array, (ok... time for some psuedo-code)

--- CFC that sends data to the CFC that populates the cross table
--- This is the last function

<cfif arrayLen( tempArray )>
	<cfloop from="1" to="#arrayLen(tempArray)#" index="i">

		<cfset updateOrder(arguments.orderid.getID(), tempArray[i], rate) />
	</cfloop>
</cfif>
The form stores all data into request scope so I end up with rate_1, rate_2, rate_3
which corresponds to consultant1, consultant2, ...

until I submit the page. All form vars are converted to request vars.

but how to get the rate form data to the last function and in proper order so it updates the proper consultantid/orderid/rates
row in the table.

Open in new window

0
Comment
Question by:ecpeel
  • 15
  • 8
  • 4
  • +3
33 Comments
 
LVL 15

Expert Comment

by:Gurpreet Singh Randhawa
ID: 36495049
>> The form stores all data into request scope so I end up with rate_1, rate_2, rate_3  
which corresponds to consultant1, consultant2, ...  

I did not understood ur above line, can u elaborate
0
 
LVL 22

Expert Comment

by:plusone3055
ID: 36495124
0
 
LVL 39

Accepted Solution

by:
gdemaria earned 250 total points
ID: 36495703
I don't know if I followed you, but here's a guess.

You want to grab the value of Rate_1, Rate_2, Rate_3 as part of your CFLOOP to keep it in sync with tempArray's  array positions?

If I got it right, see the line added below...


<cfif arrayLen( tempArray )>
    <cfloop from="1" to="#arrayLen(tempArray)#" index="i">
        <cfset rate = form['rate_' & i]>
        <cfset updateOrder(arguments.orderid.getID(), tempArray[i], rate) />
     </cfloop>
</cfif>

Open in new window

0
 
LVL 15

Expert Comment

by:Gurpreet Singh Randhawa
ID: 36496789
yes, i agree with @gd, I think the same way, if you have some other logic or chage, Please elaborate here

0
 
LVL 52

Expert Comment

by:_agx_
ID: 36497310
>> which is a looping tempArray populated if another function finds a
>> consultantid and since my "rates" data is not a part of the array

I can't say I understand your form .. but that comment jumped out at me.  Are you saying the array and input fields are generated in 2 totally different steps .. ?
0
 

Author Comment

by:ecpeel
ID: 36498484
Hi All,
let me try to step through this better.
gdemaria's code is valid if the form vars which are converted explicitly to request vars exist.
what happens is that the form inside the Iframe submits for each change on the drop down for the counselor.
so this line: <input type="text" name="rate_#i#" value="" />      which holds the rates are always wiped because the value needs to be rate_#i#. value.

Perhaps because of this the Form/Request vars cease to exist beyond the Iframe.
Dumping the request vars prior to  <cfset rate = form['rate_' & i]> (and substituting form for rate) shows they don't exist.
0
 

Author Comment

by:ecpeel
ID: 36498569
additionally if i dump with the iframe via the onchange submit I can see the form vars and their values
0
 

Author Comment

by:ecpeel
ID: 36498710
excuse me: I should have said if I cfdump the request scope within the iframe
the request.rate_i var is present.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 36498812
>> Form/Request vars cease to exist beyond the Iframe.

Request variables only exist for the life of a single http request.  So they won't exist after the iframe is generated if that's what you mean.


0
 

Author Comment

by:ecpeel
ID: 36499684
quite right agx. there is a function that i need to pass the form/request data array into.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 36500064
Honestly I don't quite grok the structure ...  but it sounds like you're trying to perform some action when the form is submitted.  In which case you should be using FORM variables instead of REQUEST variables.  But we'd need to see more code to be of help ..

0
 
LVL 9

Expert Comment

by:digicidal
ID: 36500958
Either FORM variables or if you are using sessions you could store each update in the SESSION scope and then on the submission append whatever is currently available via FORM to whatever was previously created during the IFRAME activity...

This is what it seems like to me - but I'm pretty much as confused as everyone else around here I think one of two things:

Consider using two hidden fields to which you append the consultant and rate values via a javascript function.  (i.e. either via onBlur or onChange - not sure what that field is... text or select - your js function appends the current value of the calling field to the appropriate hidden field).  Then you can perform whatever you need to do on the back end by simply looking at the two values once submitted.

The other possibility is that you are actually doing form posts in the IFRAME but are then having the user post a form that exists in the main page (the parent of the IFRAME essentially).  I don't think this is the case from what you've said but if it is then you could have that form post to a function that simply appends the most recent values to two arrays stored in the SESSION scope and then upon the main page form's submission you hit those values for your backend operations.

_agx_ has already pointed out the most obvious problem in that the REQUEST scope is only going to hold values created during the live of the single request itself and not anything created later on via external functions.
0
 

Author Comment

by:ecpeel
ID: 36501197
All the form vars are converted to request vars throughout the application explicitly by function.

@digicidal
pretty sure I'm going to have to store in session scope.
using <input type="text" name="rate_#i#" value="" />
How can I store this and append this/these values in a session?
Psuedo...
create a session.myVar = arrayNew(1);
<cfset temp = arrayAppend(session.myVar, structNew())>
<cfset session.myVar[arrayLen(session.myVar)].rate = #Request.rate_i#>

I doubt that #request.rate_i# is going to yield the name of proper field though.
that is if I'm in the right ball park.
0
 
LVL 9

Assisted Solution

by:digicidal
digicidal earned 250 total points
ID: 36502469
All the form vars are converted to request vars throughout the application explicitly by function.

Is this because of some framework that you are operating within... it doesn't technically matter but I can't come up with a good reason for the unnecessary complexity in process... but that may be because it's 5AM now and I'm pretty bleary.

If you are using <input type="text" name="rate_#i#" value="" /> in your form then the ariving form variable will have the name itself - not the index variable.  For example if it's the third input from the form page the value will be passed in FORM.rate_3 (or after translation... REQUEST.rate_3).  However, regardless of whatever is causing you to perform that extra step I'll write the snippet to expect it.

Here's a shot at what it seems like you're looking for based on the information provided:
<cflock scope="session" type="exclusive" timeout="30">
	<!--- If this is a first run - create the structure to store our arrays in --->
	<cfif NOT IsDefined("SESSION.FormUpdateValues")>
    	<cfset SESSION.FormUpdateValues = structNew()>
        <cfset SESSION.FormUpdateValues.FieldsArray = arrayNew(1)>
        <cfset SESSION.FormUpdateValues.ValuesArray = arrayNew(1)>
         </cfif>
    <!--- Now parse the REQUEST scope for an appropriate value --->
    <cfloop collection="#REQUEST#" item="Key">
    	<!--- Check to see if the key is named like a rate input from the form --->
        <cfif Key CONTAINS 'rate_'>
        <!--- We have a passed rate value in this request - add it's name to our fields array --->
            <cfset temp=arrayAppend(SESSION.FormUpdateValues.FieldsArray,Key)>
            <!--- And the actual value of that field to the values array --->
            <cfset temp=arrayAppend(SESSION.FormUpdateValues.ValuesArray,REQUEST[Key])>
        </cfif>
    </cfloop>
</cflock>

Open in new window


Just remember that on your final post (the one where you 'save' the changes) you will want to write the changes to the database and then destroy the session structure which holds your arrays using <cfset structDelete(SESSION,"FormUpdateValues")> prior to passing the user on to wherever the destination is... otherwise if they went back to that same page again... the prior changes would be held in the arrays still and would be used on the "save" action page/function.  However, as long as you always wrote the values to the database one at a time... nothing would be apparent to the user as even if they changed a value they had previously changed... the subsequent entries would occur after the earlier ones had been repeated.

I'm still confused as to how the values are getting to the REQUEST scope however - there should only be one value passed if I understand you correctly - either that or they will all be passed because the whole form has been submitted.  How are you passing the values from the IFRAME to the page?  In other words - how are you updating these?  And is there a reason why you don't want to simply make the changes on the page via javascript and then pass everything at once?  Finally, even if you have a function that is writing the FORM scope into the REQUEST scope for whatever reason you have for doing that... unless you are explictly destroying it, it will still exist and be available for a much simpler process.  It seems like maybe you (or someone else if you are working with another programmers work) is making your application unnecessarily complex... I would recommend thinking long and hard about why you are moving scoped values around every request... it may cost you performance in the long run or limit the scalability of the application once deployed.  Just food for thought though!
0
 

Author Comment

by:ecpeel
ID: 36502566
yup, the formercoder created a custom framework some time ago thus the extra extras!

I'll be back in a bit with results thank you.
0
 

Author Comment

by:ecpeel
ID: 36502775
trying to clarify some of what is what...

the iFrame upon change submits to an intermediary cfc, that's where I'll set the session variables, all the other variables are written to a temp array.
but calls an entirely different cfc with another function to output this functions results to the database.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 39

Expert Comment

by:gdemaria
ID: 36503034
All, we're giving a lot of advice in the dark here... I don't think we should go down the session variable path unless really necessary.   That would take up server resources and very likely to cause bugs... keep in mind that multiple browser sessions can share session variables!

I think we need to see the code and really understand what is happening before we commit to any solutions... my 2 cents :)
0
 
LVL 9

Expert Comment

by:digicidal
ID: 36511804
I agree gdmaria.  Based on the latest post...

"the iFrame upon change submits to an intermediary cfc, that's where I'll set the session variables, all the other variables are written to a temp array.
but calls an entirely different cfc with another function to output this functions results to the database."

ecpeel - what gets returned from that "intermediary cfc" if anything?  Are those "variables written to a temp array" what you are getting from the REQUEST scope, and if not where are you going to access them?  From the rough description you made in that post above it seems as if you already have the mechanism to pass back something from the cfc the IFRAME is posting to - in which case that would be the obvious place to update something on the actual content of the IFRAME to store the incremental changes for later posting as the update.

It would really help all of us if you could provide a more complete copy of the code you are working with - at least the content of the IFRAME and the method in the component it hits upon changes.  If you want to you can change variable names and replace any queries with something like "<My query here gets the current settings for populating the form fields Input_1, Input_2...> or something similar if you're concerned about privacy, etc.
0
 

Author Comment

by:ecpeel
ID: 36516502
Advice taken. I've attached the code with very few changes (names changed protecting the innocent).
Not bad advice  so far to be working in the dark :)

---- This is the iFrame that holds the form -------

<!--- form for updating existing outside counsel --->
<cfif Request.isEdit Or Request.isAdd>
	<form name="updateForm" method="post" action="index.cfm">		 
		<input type="hidden" name="actionMapping" value="updateOutsideCounselIFrame" />	
		<input type="hidden" name="isEdit" value="#Request.isEdit#" />
		<input type="hidden" name="isAdd" value="#Request.isAdd#" />
		<input type="hidden" name="isMatter" value="#Request.isMatter#" />
		<input type="hidden" name="isClaim" value="#Request.isClaim#" />
</cfif>
<table>
	<tr>
		<th colspan="3">SW Outside Counsel</th>
	</tr>
	<!--- if there are existing outsideCounsel --->
	<cfif arrayLen( Request.outsideCounsel )>
		<!--- display existing outside counsel already added to matter/claim --->
		<!--- loop over all existing outsideCounsel --->
		<cfloop from="1" to="#arrayLen( Request.outsideCounsel )#" index="i">

			<tr>				
				<td class="data" colspan="3">
					<cfsavecontent variable="Variables.dropDownContent">
						<!--- loop over all outside counsel --->
						<cfloop query="Request.qOutsideCounsel">
							<cfif Request.outsideCounsel[i].getFirmId() eq Request.qOutsideCounsel.firmId>
								#Request.qOutsideCounsel.firmName#
								<cfbreak />
							</cfif>
						</cfloop>
					</cfsavecontent>
					#Trim(Variables.dropDownContent)#
					
					<cfif Request.outsideCounsel[i].getConflict() And Not Request.outsideCounsel[i].getConflictOverride() >
						<span class="counselConflict">Conflict</span>
					</cfif>
					
					<cfif Request.isEdit Or Request.isAdd>
						&nbsp;&nbsp;
						<cfset Variables.link = encLink("index.cfm", "actionMapping__removeOutsideCounselFromOutsideCounselIFrame__#i#" &
							   										 "&isEdit=#Request.isEdit#" &
																	 "&isAdd=#Request.isAdd#" &
																     "&isMatter=#Request.isMatter#" & 
																     "&isClaim=#Request.isClaim#") />
						<a href="#Variables.link#">Remove Firm</a>
					</cfif>
				</td>
			</tr>					
			<!--- show attorney if one's defined --->	
			<cfif ( Request.qOutsideCounselAttorneyArray[i].recordCount And (Request.isEdit Or Request.isAdd) )
				  Or
				  ( Len( Request.outsideCounsel[i].getPrimaryAttorney().getAttorneyId() ) )>
				<tr>				
					<td class="data">&nbsp;</td>
					<td class="dataHeaderForm">Primary&nbsp;Attorney:</td>
					<td class="data" colspan="1">
						<cfif Request.isEdit Or Request.isAdd>
							<select name="outsideCounselAttornyId_#i#" onchange="document.updateForm.submit();">
								<option value="">Select</option>
								<cfset Variables.tempQuery = Request.qOutsideCounselAttorneyArray[i] />
								<cfloop query="Variables.tempQuery">
									<option value="#Variables.tempQuery.attorneyId#" 
											<cfif Variables.tempQuery.attorneyId eq Request.outsideCounsel[i].getPrimaryAttorney().getAttorneyId()>
												selected="selected"
											</cfif>
										>
										#Variables.tempQuery.firstName# 
										#Variables.tempQuery.lastName#	
									</option>
								</cfloop>
							</select>
				<!--- exp152 Add the rate field here --->	
				Max: <input type="text" name="rate_#i#" value="" />	
						<cfelse>
							<cfset Variables.tempQuery = Request.qOutsideCounselAttorneyArray[i] />
							<cfloop query="Variables.tempQuery">
								<cfif Variables.tempQuery.attorneyId eq Request.outsideCounsel[i].getPrimaryAttorney().getAttorneyId()>
									<!--- exp152 show the attorney/timekeeper id info including rate --->
									#Variables.tempQuery.attorneyId# &nbsp;| &nbsp;
									#Variables.tempQuery.firstName# 
									#Variables.tempQuery.lastName#
								</cfif>
							</cfloop>
						</cfif>
					</td>
				</tr>
			</cfif>

Open in new window

---- this is the method that the form posts to

<cffunction name="updateOutsideCounselIFrame" access="public" returntype="void" output="false">
		<!--- arguments are implicitly passed into function via Request scope --->

		<cfset var matterClaim = 0 />
		<cfset var outsideCounsel = arrayNew(1) />
		<cfset var i = 0 />

		<cfparam name="Request.isEdit" type="boolean" default="false" />
		<cfparam name="Request.isAdd" type="boolean" default="false" />
		<cfparam name="Request.isMatter" type="boolean" default="true" />
		<cfparam name="Request.isClaim" type="boolean" default="false" />

		<cflock scope="session" type="readonly" timeout="30">
			<cfset matterClaim = Session.matterClaim />
		</cflock>

		<!--- get existing outsideCounsel --->
		<cfset outsideCounsel = matterClaim.getOutsideCounsel() />

		<!--- update array elements --->
		<cfloop from="1" to="#arrayLen(outsideCounsel)#" index="i">

			<cfif structKeyExists( Request, "outsideCounselAttornyId_#i#" )>
				<cfset outsideCounsel[i].getPrimaryAttorney().setAttorneyId( Evaluate("Request.outsideCounselAttornyId_#i#") ) />
			</cfif>

			<!--- update counsel conflict --->
			<cfset updateCounselConflict( counsel = outsideCounsel[i], counselIndex = i ) />

		</cfloop>

		<!--- set outsideCounsel back into matterClaim --->
		<cfset matterClaim.setOutsideCounsel( outsideCounsel ) />

		<!--- set data back to session --->
		<cflock scope="session" type="exclusive" timeout="30">
			<cfset Session.matterClaim = matterClaim />
		</cflock>


		<cfset link = encLink("index.cfm", urlVars) />
		<cflocation url="#link#" addtoken="false" />

	</cffunction>

Open in new window

---- This is the update function where I need to pass the rate as a parameter in the function call addOutsideCounselToMatterOrClaim ----


	<cffunction name="updateOutsideCounsel" access="public" output="false" returntype="void">
		<cfargument name="claim" hint="Matter/Claim" type="com.applicationname.model.claim" required="true" />
		<cfargument name="eid" hint="EID" type="string" required="true" />
		
			
		<cfset var tempArray = 0 />
		<cfset var i = 0 />
		<cfset var idList = "" />

		<cftry>
			<!--- copy array to temp array to access via index --->
			<cfset tempArray = Arguments.claim.getOutsideCounsel() />
		
			<!--- remove all outsideCounsel for this matter --->
			<cfset Application.dao.outsideCounselDAO.removeOutsideCounselFromMatterOrClaim( Arguments.claim.getId(), true ) />
				
			<!--- if array has length, add each outsideCounsel to matter/Claim --->
			<cfif arrayLen( tempArray )>
				
				<cfloop from="1" to="#arrayLen(tempArray)#" index="i">
					<!--- add outsideCounsel-matter association --->
					<!--- The Rate needs to be the third parameter in this next cfset --->
					<cfset Application.dao.outsideCounselDAO.addOutsideCounselToMatterOrClaim( Arguments.claim.getId(), tempArray[i], rate) />
					
					
				</cfloop>
			</cfif>
			
			<cfreturn />

Open in new window

0
 
LVL 9

Expert Comment

by:digicidal
ID: 36519326
OK... it's going to take me a little time to digest, however the first thing I see is that you already have sessions in use so that is definitely a possibility for storing your array to later update - there are a lot of function calls that appear to be referrencing external data and/or code that I'm not sure about.  

The real question I guess is concerning the translation of FORM scoped variables to REQUEST scoped variables...  Does this mean that it's not simply performing a translation on 'expected' variables but all of them?  Let me clarify - if your page has a form with a input named "bob" then on the action page you will not have a FORM.bob value but you will always have a REQUEST.bob value?  Or does the translation only look for key FORM values like "isEdit" and "isAdd"?  If the latter is the case how do you handle any other form interactions?!?

If I'm correct in that the entire FORM scope is simply returned every time to the page via the REQUEST scope then why not simply create a secondary set of hidden fields on the page that contain your values in list form and then use ListToArray() and ArrayToList() to populate those hidden fields or convert their values into arrays for processing?

It appears from the code in your intermediate.cfc that you are currently storing some sort of object (most likely another CFC) in the SESSION scope currently:
<cfset matterClaim = Session.matterClaim />
...
<cfset matterClaim.setOutsideCounsel( outsideCounsel ) />

But you seemed to indicate that there wasn't any db interactions taking place during the iframe submissions - where does matterClaims's setOutsideCounsel method store it's data?  Would it not be possible to use this for storage of your array since you already have all of the overhead of holding that object in memory for every current session.

Maybe I'm less sophisticated as a programmer - but this seems to be an inordinately complex process for simply updating some tabular values.  Maybe someone else can see it more clearly but I can definitely say that I don't envy you your job!  I'll try some things and check back in a day or so when I have a little clearer thoughts.
0
 

Author Comment

by:ecpeel
ID: 36519604
@digital
"auto-magically" all form scoped variables are transformed into request vars and I have been seeking the function that makes this so for sometime.

If I'm correct in that the entire FORM scope is simply returned every time to the page via the REQUEST scope then why not simply create a secondary set of hidden fields on the page that contain your values in list form and then use ListToArray() and ArrayToList() to populate those hidden fields or convert their values into arrays for
processing?

- Sounds interesting.

But you seemed to indicate that there wasn't any db interactions taking place during the iframe submissions - where does matterClaims's setOutsideCounsel method store it's data?

-- there's a setter function that happens elsewhere (or so I think I've seen) in yet another set of arrays that
handles the matterClaims model... something not immediately clear.

Thanks for seeing it as I perceive it! there has to be a better way.
I'm leaning towards your session statements earlier. It might make it easier to return the rate vars to the form.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 36520361
    >> Maybe I'm less sophisticated as a programmer - but this seems to be an
     >> inordinately complex process for simply updating some tabular values.  


I don't think so.  It's possible I'm missing something, but it all seems overly complicated to me as well.  

For example, what's the purpose of copying the FORM scope into the REQUEST scope? Both are transient and disappear at the end of the request.  If you're trying to make the values accessible to different functions,  they should be passed into the function explicitly as ARGUMENTS.  Generally you don't want to access shared scopes directly (request, session, etc..) because it breaks encapsulation, which defeats the purpose of having a function.

  >> <cfset matterClaim = Session.matterClaim /> ...
        >> <cfset Session.matterClaim = matterClaim />



In another example, that code isn't doing anything.  Most complex objects in CF are passed by reference. So #matterClaim# and #Session.matterClaim# may be 2 different variables, but they're pointing to the exact same object.  So any changes to #matterClaim# are reflected in #Session.matterClaim#.  So this

        <cfset Session.matterClaim = matterClaim>

... is the same as saying:

         <cfset Session.matterClaim = Session.matterClaim >


      >> <cfset outsideCounsel[ii].getPrimaryAttorney().setAttorneyId(  
             Evaluate("Request.outsideCounselAttornyId_#i#") ) />

Matching disparate pieces of information on an index position alone always makes me uneasy.  Because they are so fragile. It's easy for things to get out of synch.  Especially when session variables are involved because they can be modified by multiple threads.  One small change to the array elements and you might end up matching the completely wrong id's.   May not be an issue in your app. But it's always something to take care with when matching on position alone ...  Just my $0.02
0
 

Author Comment

by:ecpeel
ID: 36520783
@agx & digicidal:
This application is a prime example of doing things simply because you can. The beauty of ColdFusion was making difficult tasks manageable and even fun at times. This application is several years old. It contains a custom xml based framework and while trying to utilize an interpretation of the  MVC it's managed to confuse the heck out of me and a few others as well. Maybe just too  many programming concepts under one roof. Or a stress test for CF itself. Every tag but CFHTTP seems to be in some part of it. It often has complex functions just to retrieve a single column from the database.

Simple and elegant it ain't!
0
 
LVL 9

Expert Comment

by:digicidal
ID: 36527001
Yeah I would have to admit to making an overly complex MVC structured application that became more work to maintain than it ever saved in organization - but at least it didn't obfuscate scoped variables or and did still maintain component encapsulation.  In any case - this is the beast you're left with so that's what we have to work with...

You ARE getting REQUEST.Rate_1, REQUEST.Rate_2, etc... on your final form submission page (at least I think that's the case, right?)  So let's just try to figure out why the code snipped from gdemaria didn't work for you or what's happening in between.  What do you get when you change that code:

 
<!--- GDEMARIA SUGGESTED --->
<cfif arrayLen( tempArray )>
    <cfloop from="1" to="#arrayLen(tempArray)#" index="i">
        <cfset rate = form['rate_' & i]>
        <cfset updateOrder(arguments.orderid.getID(), tempArray[i], rate) />
     </cfloop>
</cfif>

<!--- BUT YOU WOULD USE THIS INSTEAD --->
<cfif arrayLen( tempArray )>
    <cfloop from="1" to="#arrayLen(tempArray)#" index="i">
        <cfset rate = request['rate_' & i]>
        <cfset updateOrder(arguments.orderid.getID(), tempArray[i], rate) />
     </cfloop>
</cfif>

Open in new window


Since you SHOULD still be able to access the entire set of 'Rate_n' values from within the REQUEST scope even though the FORM scope doesn't exist.  It might help all of us (me especially) to see what is available to you via the REQUEST scope upon final submission to the final method.  I think there really shouldn't be a reason to do anything in the intermediate CFC because you aren't writing anything to the database, and you should have the array of outsideCounsel visible within REQUEST in both the IFRAME as well as in the final function via Arguments.claim.getOutsideCounsel().

If this is correct, as I see it at least, you already have everything you need arriving where you want to work with it... the issue is simply organizing it correctly - which is what the code from gdemaria should do.  Is there another lookup that is missing?  Do we need to do something with a Consultant ID value?  It seems like all of that is already present in the array, but I'm still a little confused.
0
 

Author Comment

by:ecpeel
ID: 36533517
Sorry for delay... car/plane travels.

gdemaria's code should work... except the component that holds the code has been purged of vars
0
 

Author Comment

by:ecpeel
ID: 36533596
well here are my thoughts again:
in the intermediate cfc I'm thinking of setting the session vars...

 		<cfloop from="1" to="#arrayLen(outsideCounsel)#" index="i">

			<cfif structKeyExists( Request, "outsideCounselAttornyId_#i#" )>
				<cfset outsideCounsel[i].getPrimaryAttorney().setAttorneyId( Evaluate("Request.outsideCounselAttornyId_#i#") ) />
			</cfif>

			<!--- update counsel conflict --->
			<cfset updateCounselConflict( counsel = outsideCounsel[i], counselIndex = i ) />
			
			<cflock scope="session" type="exclusive" timeout="30">
				<!--- If this is a first run - create the structure to store our arrays in --->
				<cfif NOT IsDefined("SESSION.FormUpdateValues")>
			    	<cfset SESSION.FormUpdateValues = structNew()>
			        <cfset SESSION.FormUpdateValues.FieldsArray = arrayNew(1)>
			        <cfset SESSION.FormUpdateValues.ValuesArray = arrayNew(1)>
			    </cfif>
			    <!--- Now parse the REQUEST scope for an appropriate value --->
			    <cfloop collection="#REQUEST#" item="Key">
			    	<!--- Check to see if the key is named like a rate input from the form --->
			        <cfif Key CONTAINS 'rate_'>
			        <!--- We have a passed rate value in this request - add it's name to our fields array --->
			            <cfset temp=arrayAppend(SESSION.FormUpdateValues.FieldsArray,Key)>
			            <!--- And the actual value of that field to the values array --->
			            <cfset temp=arrayAppend(SESSION.FormUpdateValues.ValuesArray,REQUEST[Key])>
			        </cfif>
			    </cfloop>
			</cflock>

		</cfloop>

Open in new window


and for the update to the database calling cfc:(not working yet but!)

 	<!--- if array has length, add each outsideCounsel to matter/Claim --->
			<cfif arrayLen( tempArray )>
				
				<!--- <cfdump var="#Session#" expand="false"><br>***********************************<cfabort> --->
				
				<cfloop from="1" to="#arrayLen(tempArray)#" index="i">
					<!--- <cfset rate = 450> --->
					<cfloop collection="#SESSION#" item="Key">
						<cfset rate = SESSION.FormUpdateValues.ValuesArray[key]>
					<!--- add outsideCounsel-matter association --->
					<!--- The Rate needs to be the third parameter in this next cfset --->
					<cfset Application.dao.outsideCounselDAO.addOutsideCounselToMatterOrClaim( Arguments.claim.getId(), tempArray[i], rate) />
					
					</cfloop>
				</cfloop>
			</cfif>
				<cfset temp = structDelete(Session,"FormUpdateValues")>

Open in new window




0
 
LVL 39

Expert Comment

by:gdemaria
ID: 36533719
>  the code has been purged of vars

what does that mean?
0
 
LVL 9

Expert Comment

by:digicidal
ID: 36533765
Looks pretty good, there are a couple of things I notice that may or may not be a factor for you - in the setting area (the code for creating and/or populating the arrays in the intermediate CFC) I wrote the code based on the belief that you might not be able to expect the same data in the same locations - hence the two arrays.  It seems from the discussions since that time that you should only need the one array as the value of Rate_1 should always be stored in ValuesArray[1] and Rate_2 in ValuesArray[2] - so if there's no reason to determine what the name of the field was for value one - you wouldn't need to worry about having a FieldsArray at all.  However it might be useful for testing until you are confident that it is definitely never necessary.

The other thing is in your final CFC - you are looping through the entire SESSION scope as the collection but this will add unnecessary overhead and won't work as expected.  You only need to loop through your actual array, not the SESSION scope as a structure.  The reason we did that with REQUEST in the intermediate CFC is because we have no way of knowing how many (if any at all) 'rate_n' keys may exist in the structure - in the case of the final method we already know the array we're looking for should be in SESSION.FormUpdateValues.ValuesArray. :)

Although as mentioned in the first paragraph of this response - if you determined that you didn't need two arrays at all and could simply be storing the values, you could simply create the ValuesArray in the SESSION scope and access it directly.
0
 
LVL 9

Expert Comment

by:digicidal
ID: 36533769
gdemaria - he means that by the time the framework he's operating under gets him to the final method (after posting the entire form) that he has access to neither the FORM scope, nor does he even have the values of the FORM scope reproduced in the REQUEST scope... so basically the entire form has disappeared as far as that component is concerned - hence the need to store those somewhere that isn't getting 'automagically' overwritten by a component that he has yet to be able to even find in the application! :S
0
 

Author Comment

by:ecpeel
ID: 36544078
digicidal take a look at this: (yeah I'm still working on this)! Inside the intermediate CFC:

		<!--- get existing outsideCounsel --->
		<cfset outsideCounsel = matterClaim.getOutsideCounsel() />

		<!--- create new outsideCounsel --->
		<cfset newOutsideCounsel = createObject("component", "model.outsideCounsel").init( argumentCollection = Request ) />

		<!--- set conflict --->
		<cfset newOutsideCounsel.setConflict( performCounselConflictCheck( firmId = newOutsideCounsel.getFirmId(),  isOutsideCounsel = true ) ) />

		<!--- append new outsideCounsel to array --->
		<cfset arrayAppend( outsideCounsel, newOutsideCounsel ) />

		<!--- sort by firmId (since thats the only data we have) to keep all like firms together --->
		<cfloop from="1" to="#arrayLen(outsideCounsel)#" index="i">
			<cfloop from="1" to="#arrayLen(outsideCounsel) - i#" index="j">
				<cfif Compare( outsideCounsel[j+1].getFirmId(), outsideCounsel[j].getFirmId() ) eq 1>
					<cfset arraySwap( outsideCounsel, j, j+1 ) />
				</cfif>
			</cfloop>
		</cfloop>
<cfset newOutsideCounsel.setConflict( performCounselConflictCheck( firmId = newOutsideCounsel.getFirmId(),   isOutsideCounsel = true ) ) />

		<!--- append new outsideCounsel to array --->
		[b]<cfset arrayAppend( outsideCounsel, newOutsideCounsel ) />[/b]

		<!--- set outsideCounsel back into matterClaim --->
		<cfset matterClaim.setOutsideCounsel( outsideCounsel ) />

Open in new window

There's a model outsideCounsel - in order to retrieve the data from the database for the record I had to create a getter and while I was at it I create a setter.

This got me thinking that I should be able to use the setRate function I created to set values in the temp array the way that it sets the counselid or setConflict

		<!--- append new outsideCounsel to array --->
		<cfset arrayAppend( outsideCounsel, newOutsideCounsel ) />

Open in new window


The arrayAppend to outsideCounsel is already populated with the newOutsideCounsel argument.
so I'm thinking I can either create a new array to append here (overhead!) or append something like..

<cfset newRate = setRate()> and then...
<cfset arrayAppend( outsideCounsel, newOutsideCounsel ) />
<cfset arrayAppend( outsideCounsel, newRate) />

Open in new window


whatcha think? Array swap not withstanding...



0
 
LVL 9

Expert Comment

by:digicidal
ID: 36547180
Well, there are some aspects that are not directly visible - but I can't see any reason why that wouldn't work just fine.  If you already have an array that can simply have a new element appended then that would certainly make more sense than creating a separate array to store values that you would then have to reexamine to make sure that you had a 1:1 correlation to your outsideCounsel set.  It seems like you have everything in place... give it a shot and let us know if there are any problems that present themselves.
0
 

Author Comment

by:ecpeel
ID: 36552026
Here's what ended up working for me:
In the object Model
1. created a rate cfproperty with cfargument both set to string data types
2. created setter and getter functions

For the record the responses by digicidal and gdemaria were excellent.
Both led me to look at the current array structure and see where I could identify similar functionality.

The session var solution did work ( i didn't implement a deleteArrayAt) but I gut-felt that I was taking the wrong path for an application that was already going in a lot of directions.

I had to study the application more closely to recognize that an object model(s) were being called. I would have provided that info but it was already too long winded.

So many thanks I can't express.

ecpeel
<cfif structKeyExists( Request, "outsideCounselAttornyId_#i#" )>
				<cfset outsideCounsel[i].getPrimaryAttorney().setAttorneyId( Evaluate("Request.outsideCounselAttornyId_#i#") ) />
<!--- exp152 set/get rate --->
<cfif structKeyExists( Request, "rate_#i#" )>
					<cfset outsideCounsel[i].setRate(Evaluate("Request.rate_#i#"))/>
				</cfif>
			</cfif>

Open in new window

0
 

Author Closing Comment

by:ecpeel
ID: 36552074
In the end my solution looked more like the code provided by gdemaria combined with digicidal's code they form a complete solution for this type of problem for a variety of situations.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

CFGRID Custom Functionality Series -  Part 1 Hi Guys, I was once asked how it is possible to to add a hyperlink in the cfgrid and open the window to show the data. Now this is quite simple, I have to use the EXT JS library for this and I achiev…
Hi. There are several upload tutorials using jquery and coldfusion. I found a very interesting one here Upload Your Files using Jquery & ColdFusion and Preview them (http://www.randhawaworld.com/) . I did keep the main js functions but made sever…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

746 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