trying to create a horizontal menu with struct data i have - coldfusion

I have the following type of structure
https://prnt.sc/wkerdv
in the above only the first one has childrens but the possibility is childrens can have childrens and so on, but i prefer to display only 3 levels deep as horizontal menu
i am struk the loop where i had to add the loop properly to create the menu bar, i am trying to create menu like this
https://prnt.sc/wket5s
so here is what i am trying
<cfoutput>
<ul>
<cfloop from="1" to="#arrayLen(data.item)#" index="i">
<cfset x = data.item[i]>
<cfloop collection="#x#" item="key">
<cfif Structkeyexists(key,'Item')>
<cfloop from="1" to="#arrayLen(data.item)#" index="i">
<cfset x = data.item[i]>
<cfelse>
</cfif>
<cfdump var="#key#">
<!--- <cfloop from="1" to="#arrayLen(key.item)#" index="d">
<cfset n = key.item[d]>
<!--- <li>#d#:#n[d]#</li> --->
<cfdump var="#n#">
</cfloop>
<li>#key#:#x[key]#</li>--->
</cfloop>
</cfloop>
</ul>
</cfoutput>
the html code behind the above second screen is like this
<ul class="menu-list">
<cfloop from="1" to="#ArrayLen(data.menu.item)#" index="toplevel">
<li>#toplevel#
</cfloop>
<li class="active">HOME
<ul class="menu-dropdown">
<li>Home One</li>
<li>Home Two</li>
<li>Home Three
<ul class="thirdlevel-menu">
<li>Thirdlevel</li>
<li>Thirdlevel</li>
<li>Thirdlevel</li>
</ul>
</li>
</ul>
</li>
<li>ABOUT</li>
<li>SHOP

Related

ColdFusion Options removed after selecting option

I'm having trouble with my ColdFusion code. I'm trying to create a simple HTML select form using cfloop to populate the options. it works, and when you select an option, it pulls that option from the db. but once you do that, the only option available is the option previously selected. What am I doing wrong?
<!--- Query the DataBase --->
<cfparam name="url.colors" default="">
<cfif structKeyExists(form, "colordb")>
<cfset url.colordb = form.colordb>
</cfif>
<cfquery datasource="bentest" name="colors">
SELECT *
FROM color_codes
<cfif structKeyExists(url,"colordb") and isNumeric(url.colordb)>
WHERE id=#url.colordb#
</cfif>
</cfquery>
<!--- Add Selector for user to select a color --->
<div class="selector">
<cfoutput>
<form action="?contentId=colorPickdb" name="clr" method="post" class="clr">
<select class="clr" name="colordb" onChange="submit();">
<option selected>Select A Color!</option>
<cfloop query="colors">
<option value="#colors.id#">#colors.color#</option>
</cfloop>
</select>
</form>
</cfoutput>
</div>
<div class="dump">
<!--- Output results of Query --->
<p><cfif structKeyExists(form, "colordb")>
<cfoutput query="colors">
#colors.color# <br>
#colors.hexvalue# <br><br>
</cfoutput>
</cfif>
<br>
</p>
</div>
You can use query of query here.
<!--- Query the DataBase --->
<cfparam name="url.colors" default="">
<cfquery datasource="bentest" name="colors">
SELECT *
FROM color_codes
</cfquery>
<!--- Add Selector for user to select a color --->
<div class="selector">
<cfoutput>
<form action="?contentId=colorPickdb" name="clr" method="post" class="clr">
<select class="clr" name="colordb" onChange="submit();">
<option selected>Select A Color!</option>
<cfloop query="colors">
<option value="#colors.id#">#colors.color#</option>
</cfloop>
</select>
</form>
</cfoutput>
</div>
<div class="dump">
<!--- Output results of Query --->
<p>
<cfif structKeyExists(form, "colordb")>
<cfquery dbtype="query" name="colorSelected">
SELECT *
FROM colors
WHERE id=#form.colordb#
</cfquery>
<cfoutput query="colorSelected">
#colorSelected.color# <br>
#colorSelected.hexvalue# <br><br>
</cfoutput>
</cfif>
<br>
</p>
</div>

ColdFusion cfloop skip row or change loop endRow

I am trying to display 2 images, and skip one if it matches the following criteria (<cfif myDir.name eq property_mainimage> which works fine, and then continue onto the next image and display the next image until I have a total of 2 images. But when the criteria image is say in row 5, the loop displays 3 images, when the criteria image is say row 1, it displays 2 images.
There doesn't seem to be a skip row in cfloop?
I have tried <cfif counter gt 3 > <cfabort> which works but it displays the 3 images still of the criteria image is in a row greater than 3. Below is what i'm working with...
<cfdirectory directory="C:\Domains\domain.com\wwwroot\uploads\images\#property_ID#\" filter="*.jpg" name="myDir" type="file" sort="datelastmodified">
<ul>
<cfset counter = 0>
<cfset endrowvalue = 3 >
<cfloop query="myDir" endRow="#endrowvalue#">
<cfset counter = counter +1 >
<li>
<cfif right(myDir.name,4) is ".jpg">
<cfif fileexists("C:\Domains\ domain.com\wwwroot\uploads\ images\#property_ID#\#left(mydir.name,len(myDir.name)-4)#.jpg")>
<cfif myDir.name eq property_mainimage>
DO NOT SHOW THIS IMAGE
<cfelse>
<cfset endrowvalue = 1 >
<cfset myDir.endRow = 1 >
test #endrowvalue#
test #counter# <img src="#request.root#uploads/images/#property_ID#/#myDir.name#" border="0" width="230px" style="margin-bottom:15px;" />
</cfif>
</cfif>
</cfif>
</li>
</cfloop>
</ul>
any help would be most appreciated.
I would use a counter to count when you show the image. Once you get to 2 images displayed break out of the loop.
<cfdirectory directory="C:\Domains\domain.com\wwwroot\uploads\images\#property_ID#\" filter="*.jpg" name="myDir" type="file" sort="datelastmodified">
<ul>
<cfset counter = 1>
<cfloop query="myDir">
<li>
<cfif right(myDir.name,4) is ".jpg">
<cfif fileexists("C:\Domains\ domain.com\wwwroot\uploads\ images\#property_ID#\#left(mydir.name,len(myDir.name)-4)#.jpg")>
<cfif myDir.name eq property_mainimage>
DO NOT SHOW THIS IMAGE
<cfelse>
<!--- image displayed increment coutner --->
<cfset counter++>
<img src="#request.root#uploads/images/#property_ID#/#myDir.name#" border="0" width="230px" style="margin-bottom:15px;" />
</cfif>
</cfif>
</cfif>
<cfif counter EQ 2>
<cfbreak>
</cfif>
</li>
</cfloop>
</ul>
This is a formatted comment. Your code has this:
<cfset endrowvalue = 3 >
<cfloop query="myDir" endRow="#endrowvalue#">
<cfif myDir.name eq property_mainimage>
DO NOT SHOW THIS IMAGE
<cfelse>
<cfset endrowvalue = 1 >
You would have to test it to be sure, but I suspect that the endRow attribute of your cfloop tag will continue to be 3, even if you change the value of the endrowvalue variable to 1.
This might not be the cause of your current problem, but, it my suspicians are correct, you will either have a problem elsewhere or you are running a pointless command.

Invalid tag nesting configuration in ColdFusion 10?

How do I get around this ColdFusion error?
I'm following this ColdFusion tutorial. When I tried to implement the code in ColdFusion 10 I got the following error:
Invalid tag nesting configuration. A query driven queryloop tag is
nested inside a queryloop tag that also has a query attribute. This is
not allowed. Nesting these tags implies that you want to use grouped
processing. However, only the top-level tag can specify the query that
drives the processing.
The error occurred in line 76
74 : </cfloop>
75 : </tr>
76 : <cfoutput query="data" startRow="2">
77 : <tr>
78 : <cfloop index="c" list="#colList
Here is the code:
<cfset showForm = true>
<cfif structKeyExists(form, "xlsfile") and len(form.xlsfile)>
<!--- Destination outside of web root --->
<cfset dest = getTempDirectory()>
<cffile action="upload" destination="#dest#" filefield="xlsfile" result="upload" nameconflict="makeunique">
<cfif upload.fileWasSaved>
<cfset theFile = upload.serverDirectory & "/" & upload.serverFile>
<cfif isSpreadsheetFile(theFile)>
<cfspreadsheet action="read" src="#theFile#" query="data" headerrow="1">
<cffile action="delete" file="#theFile#">
<cfset showForm = false>
<cfelse>
<cfset errors = "The file was not an Excel file.">
<cffile action="delete" file="#theFile#">
</cfif>
<cfelse>
<cfset errors = "The file was not properly uploaded.">
</cfif>
</cfif>
<cfif showForm>
<cfif structKeyExists(variables, "errors")>
<cfoutput>
<p>
<b>Error: #variables.errors#</b>
</p>
</cfoutput>
</cfif>
<form action="test.cfm" enctype="multipart/form-data" method="post">
<input type="file" name="xlsfile" required>
<input type="submit" value="Upload XLS File">
</form>
<cfelse>
<style>
.ssTable {
width: 100%;
border-style:solid;
border-width:thin;
}
.ssHeader { background-color: #ffff00; }
.ssTable td, .ssTable th {
padding: 10px;
border-style:solid;
border-width:thin;
}
</style>
<p>
Here is the data in your Excel sheet (assuming first row as headers):
</p>
<cfset metadata = getMetadata(data)>
<cfset colList = "">
<cfloop index="col" array="#metadata#">
<cfset colList = listAppend(colList, col.name)>
</cfloop>
<cfif data.recordCount is 1>
<p>
This spreadsheet appeared to have no data.
</p>
<cfelse>
<table class="ssTable">
<tr class="ssHeader">
<cfloop index="c" list="#colList#">
<cfoutput><th>#c#</th></cfoutput>
</cfloop>
</tr>
<cfoutput query="data" startRow="2">
<tr>
<cfloop index="c" list="#colList#">
<td>#data[c][currentRow]#</td>
</cfloop>
</tr>
</cfoutput>
</table>
</cfif>
</cfif>
Try this:
<cfoutput>
<cfloop query="data" startRow="2">
<tr>
<cfloop index="c" list="#colList#">
<td>#data[c][currentRow]#</td>
</cfloop>
</tr>
</cfloop>
</cfoutput>

Including or excluding range attribute in dynamically generate form field

I am using a query to dynamically create form fields, not all fields use the range attribute.
When using the cfif statement to include or exclude the range attribute I get an error:
See code below:
<cfoutput>
<input type="hidden" name="question_ids" id="question_ids" value="#valueList(rsQuestions.question_id)#">
</cfoutput>
<cfoutput query="rsQuestions" group="modid">
<table border="1" cellpadding="4" cellspacing="4" bgcolor="##0E777A" >
<tr>
<td colspan="2"><span class="style1">#rsQuestions.ModName#</span></td>
</tr>
<cfoutput>
<tr>
<td width="700" bgcolor="##FFFFFF">#rsQuestions.question#</td>
<td width="200" bgcolor="##FFFFFF">
<cfif rsQuestions.question_type_id eq 1>
<cfinput type="text" name="answer_#rsQuestions.question_id#"
message="#rsQuestions.Message#"
tooltip="#rsQuestions.Tooltip#"
validate="#rsQuestions.Validate#"
<cfif #rsQuestions.Range# neq "">
range = "#rsQuestions.Range#"
</cfif>
required="#rsQuestions.mandatory#"
size="#rsQuestions.Size#">
<cfelseif rsQuestions.question_type_id eq 2>
<cfquery name="rsOptions" datasource="dsTest">
SELECT option_id, [option], question_id
FROM questionnaire_question_options
WHERE (question_id = #rsQuestions.question_id#)
</cfquery>
<cfselect enabled="yes"
name="answer_#rsQuestions.question_id#"
multiple="no"
query="rsOptions"
value="option"
display="option">
</cfselect>
</cfif>
</td>
</tr>
</cfoutput>
</table>
</cfoutput>
How can I structure the above statement to include or exclude the 'range' attribute?
As user8675309 (Jenny?) mentioned, you cannot nest <cfif> tags inside another CF tag. So you need to separate those statements out. Here is one way you could do that:
....
<cfif rsQuestions.question_type_id eq 1>
<cfif rsQuestions.Range neq "">
<cfinput type="text" name="answer_#rsQuestions.question_id#"
message="#rsQuestions.Message#"
tooltip="#rsQuestions.Tooltip#"
validate="#rsQuestions.Validate#"
range="#rsQuestions.Range#"
required="#rsQuestions.mandatory#"
size="#rsQuestions.Size#">
<cfelse>
<cfinput type="text" name="answer_#rsQuestions.question_id#"
message="#rsQuestions.Message#"
tooltip="#rsQuestions.Tooltip#"
validate="#rsQuestions.Validate#"
required="#rsQuestions.mandatory#"
size="#rsQuestions.Size#">
</cfif>
<cfelseif rsQuestions.question_type_id eq 2>
....
As mentioned, you can't nest a cfif (or any CF tag) inside another CF tag.
One thing you can do if you really need dynamic attributes is to use the "attributeCollection" attribute.
(ColdFusion 8 or higher.)
Something like:
<cfset inputAttr=structNew()>
<cfset inputAttr.type="text">
<cfset inputAttr.name="answer_#rsQuestions.question_id#">
<cfset inputAttr.message="#rsQuestions.Message#">
<cfset inputAttr.tooltip="#rsQuestions.Tooltip#">
<cfset inputAttr.validate="#rsQuestions.Validate#">
<cfif rsQuestions.Range neq "">
<cfset inputAttr.range = "#rsQuestions.Range#">
</cfif>
<cfset inputAttr.required="#rsQuestions.mandatory#">
<cfset inputAttr.size="#rsQuestions.Size#">
<cfinput attributecollection="#inputAttr#">

Nesting queries in CF

I'm using this code to display a list of platforms. If a platformID was specified upon entering the page, I would like to create a list of genres underneath the specified platform.
browse.cfm was accessed via a link that specified a platformID of 1
browse.cfm will list all available platforms
browse.cfm will now list all available genres under platformID of 1.
<ul>
<li>Browse</li>
<cfoutput query="qGetPlatforms">
<li>
#qGetPlatforms.pName#
<cfif URL.platformID EQ qGetPlatforms.platformID>
<ul>
<cfoutput query="qGetGenres">
<li>#qGetGenres.gName#</li>
</cfoutput>
</ul>
</cfif>
</li>
</cfoutput>
</ul>
By using this approach, however, I'm getting an invalid nesting configuration. How do I fix this? Or is there another approach to achieve the same idea?
Thanks
MY queries:
<!---Get platforms--->
<cffunction
name="fGetPlatforms"
access="public"
returntype="query"
output="false"
hint="I get all the platforms">
<!---Local var--->
<cfset qGetPlatforms = "">
<!---Database query--->
<cfquery name="qGetPlatforms" datasource="#REQUEST.datasource#">
SELECT
platforms.platformID,
platforms.platformName AS pName
FROM
platforms
</cfquery>
<cfreturn qGetPlatforms>
</cffunction>
<!---Get genres--->
<cffunction
name="fGetGenres"
access="public"
returntype="query"
output="false"
hint="I get all the genres">
<!---Local var--->
<cfset qGetGenres = "">
<!---Database query--->
<cfquery name="qGetGenres" datasource="#REQUEST.datasource#">
SELECT
genres.genreID,
genres.genreName AS gName
FROM
genres
</cfquery>
<cfreturn qGetGenres>
</cffunction>
You can use <cfloop query="qGetGenres"></cfloop>, they can be nested.
IMO, using cfoutput for looping over the queries is old style and should be avoided. Use cfoutput for output, cfloop for looping and you'll have more readable code.
more food for thought is to use an inner join between the two tables, combine and retrieve everything in one query and then use cfoutput's group attribute to display the results:
<cfset URL.platformID = int(val(URL.platformID))>
<cfquery name="getPlatformsAndGenres" datasource="#REQUEST.datasource#">
SELECT
p.platformID AS platformID
,p.platformName AS pName
,g.genreID AS genreID
,g.genreName AS gName
FROM
platforms p
INNER JOIN genres g
ON p.platformID = g.platformID
WHERE
p.platformID = <cfqueryparam cfsqltype="cf_sql_integer" value="#URL.platformID#">
ORDER BY
pName
,genreName
</cfquery>
Once you have everything in one query, you can use <cfoutput query="getPlatformsAndGenres" group="pName">
to lessen your code:
<ul>
<li>Browse</li>
<cfoutput query="getPlatformsAndGenres" group="pName">
<li>
#pName#
<ul>
<cfoutput>
<li>#gName#</li>
</cfoutput>
</ul>
</cfif>
</li>
</cfoutput>
</ul>