• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

dynamic return from a function based on an argument

Community Beginner ,
Aug 28, 2007 Aug 28, 2007

Copy link to clipboard

Copied

I have a function that I am using to output a nested list of child/parent relationships

the function works wonderfully except that i want to be able to change the way the list is displayed depending on an argument being passed

i want the list to be displayed twice on the same page, one with output in a table, and one with output in a drop down box
i thought the easiest way would be to create an argument that can be used in IF statements

look at my code below

quote:

<!--- establish default values --->
<cfparam name="output" default="">
<cfparam name="catNameOutput" default="">
<cfparam name="indent" default="">

<cffunction name="GenerateCategories" access="public" returntype="string">
<!--- this holds the outermost parent value being passed to the function --->
<cfargument name="GenCatParent" type="uuid" required="yes" default=0 >

<!--- this holds the nested level we are on --->
<cfargument name="level" type="numeric" required="yes" default=0 >

<!--- this holds the output_type we need for display purposes --->
<cfargument name="output_type" type="numeric" required="yes" default=0 >

<!--- grab the children of the received category --->
<cfquery name="rsCategoryChildren" datasource="webdsn">
SELECT * FROM dbo.BlogCategories
WHERE catParent = '#GenCatParent#'
ORDER BY catName ASC
</cfquery>
<cfloop query="rsCategoryChildren">
<!--- keep track of the indentation needed depending on which level we are at --->
<cfloop from="0" to="#arguments.level#" index="i">
<cfset indent = indent & "  ">
</cfloop>

<!--- if the nest is being used in the dropdown on the category manage page, we need to use option tags --->
<cfif arguments.output_type EQ 1>
<cfset catNameOutput = "<option value='" & catPK & "'>" & indent & Trim(catName) & "</option>">
</cfif>

<!--- if the nest is being used in the table on the category manage page, we need to use table row tags --->
<cfif arguments.output_type EQ 2>
<cfset catNameOutput = "<tr> <td>edit</td> <td>delete</td> <td>" & indent & Trim(catName) & "</td> </tr>">
</cfif>

<cfset output = output & catNameOutput>

<!--- reset the indentation --->
<cfset indent = "">

<!--- check for children of this child --->
<cfquery name="checkForKids" datasource="webdsn">
SELECT * FROM dbo.BlogCategories
WHERE catParent = '#rsCategoryChildren.catPK#'
ORDER BY catName ASC
</cfquery>
<!--- if there are any, call this function recursively --->
<cfif checkForKids.recordcount GT 0>
<cfset GenerateCategories(genCatParent=catPK, level = level +1, output_type = arguments.output_type)>
</cfif>
</cfloop>

<cfreturn output>

</cffunction>

<cfquery name="rsCategoryParents" datasource="webdsn">
SELECT * FROM dbo.BlogCategories
WHERE catParent IS NULL
ORDER BY catName ASC
</cfquery>



and here is how i am calling the function for each situation (the table and the dropdown):

quote:


<table width="100%" class="managementtable">
<tr bgcolor="#F6F6F6">
<td> </td>
<td> </td>
<td>Category Name</td>
</tr>

<cfloop query="rsCategoryParents">
<cfoutput><tr> <td>edit</td> <td>delete</td> <td>#Trim(catName)#</td> </tr></cfoutput>
<cfset recursivecats = GenerateCategories(genCatParent=catPK,level=0,output_type=2)>
<cfoutput>#recursivecats#</cfoutput>
</cfloop>

</table>
<!---------------------------------------------------------------------------->
<select name="select">
<option>None</option>

<cfoutput query="rsCategoryParents">
<option value="#catPK#">#Trim(catName)#</option>
<cfset recursivecats = GenerateCategories(genCatParent=catPK,level=0,output_type=1)>
#recursivecats#
</cfoutput>

</select>



calling the function for the table and the dropdown on the same page does not work
if the function is first called with the argument for table, it tries to also output the table formatted code when the function is called again (even if it is called again with the argument for dropdown)

is there another way i can have the same function output two different sets of data based on an argument? what am i doing wrong

thanks for your time
TOPICS
Advanced techniques

Views

486

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 28, 2007 Aug 28, 2007

Copy link to clipboard

Copied

Check out the returntype="any" attribute in the CFFUNCTION tag.

I would recommend against using this because I'm more of a proponent of "scrict typing", but coldfusion allows it.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 28, 2007 Aug 28, 2007

Copy link to clipboard

Copied

hello, thanks for the fast reply
but the returntype is not my issue

the variable being returned is called output
output is set to different strings as a result of an argument being 1 or 2

for some reason, whenever i call the function on a page twice, output gets set to whatever the first argument is, that is being requested

for example

<function name='test'>
<if type = 1><set output = "Joe"></if>
<if type = 2><set output = "Bob"></if>
<return output>
</function>

Now I call the function twice on the same page:
test(type=1)
<br />
test(type=2)

The output SHOULD look like this:
Joe
Bob

Instead the output comes out looking like this:
Joe
Joe

The IF statements are done correctly, and the function is receiving the argument correctly, but my dynamic output is not working

my full code of the function is in the first post

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 28, 2007 Aug 28, 2007

Copy link to clipboard

Copied

Try getting rid of the cfparam name="output" line. It seems the scope of this variable is getting lost so that every instance of the ouput variable is global possible. I've found a few scope problems in the past.
In your cffunction where it's doing the cfset on the output variable, do a debugging cfoutput or cfdump to show that the cfif logic is working correctly. Even try outputing the output variable at that time after you set it to make sure it's alright then also dump the output variable as it's returned from the function.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 29, 2007 Aug 29, 2007

Copy link to clipboard

Copied

i was able to fix my problem by creating a different cfreturn based on the argument

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 29, 2007 Aug 29, 2007

Copy link to clipboard

Copied

I didn't read the code thoroughly, but personally I wouldn't mix the db and html code that way. IMO it complicates the code and makes it harder to follow. But whatever option you choose, you should always VAR variables that are only used inside a function. When you don't use "var" unscoped variables are placed in the shared VARIABLES scope, which is likely to cause more scope problems in the future.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 29, 2007 Aug 29, 2007

Copy link to clipboard

Copied

sjlsam2,

Yeah, I think the main problem you had was a scoping one. For the second function call, the output variable already contained all of the output code from the first function call. In fact, I wouldn't be surprised to find that the output string for the second function call contained the output of the first plus the output of the second, and that it didn't render correctly on screen. A View Source would have determined that.

Anyhow, I suggest that you VAR your output variable as cf_dev2 suggests, and delete the three CFParam lines at the top. Further, your recursive call would therefore need to return it's result to the output variable, thus completing the recursive loop. See below:

...
<!--- this holds the output_type we need for display purposes --->
<cfargument name="output_type" type="numeric" required="yes" default=0 >

<CFSet Var Output = "">
<CFSet Var catNameOutput = "">
<CFSet Var indent= RepeatString("  ", Arguments.Level)>

<!--- grab the children of the received category --->
<cfquery name="rsCategoryChildren" datasource="webdsn">
SELECT * FROM dbo.BlogCategories
...


and


...
<!--- if there are any, call this function recursively --->
<cfif checkForKids.recordcount GT 0>
<cfset Output = Output & GenerateCategories(genCatParent=catPK, level = level +1, output_type = arguments.output_type)>
</cfif>
</cfloop>


This is what I suggest with your code. HTH :)
Swift

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 29, 2007 Aug 29, 2007

Copy link to clipboard

Copied

LATEST
>Further, your recursive call would therefore need to return it's result to the output >variable, thus completing the recursive loop.

Good point.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation