Link to home
Start Free TrialLog in
Avatar of Coast Line
Coast LineFlag for Canada

asked on

Coldfusion Subcategories and categories

I have successfully completed the funda of showing subcategories under subcategories with the help of some tutorials and help from here experts.

I have some issue with here that i am running into:

it cannot select the already chosen category while editing here is my code:

from start to end:


The below is the code for listing categories & subcategories:
 
<cffunction name="ListFromQueryTree" returntype="string" output="No">
        <cfargument name="Query" type="query" required="Yes">
        <cfargument name="TitleColumn" type="string" required="No" default="Name">
        <cfargument name="DepthColumn" type="string" required="No" default="TreeDepth">
        <cfargument name="IDColumn" type="string" required="No" default="ID">
        <cfargument name="selected" type="any" required="No" default="">
        <cfset var Ret="">
        <cfset var Q=Arguments.Query>
        <cfset var ThisDepth=0>
        <cfset Ret = "<select name='category' size='10'>">
        <cfloop query="Q">
                <cfset ThisDepth=Q[Arguments.DepthColumn][Q.CurrentRow]>
                <!--- create the initial Option tag --->
                 <cfif Q[arguments.IDColumn][Q.CurrentRow] EQ arguments.selected>
					<cfset Ret = Ret & "<option value='#Q[arguments.IDColumn][Q.CurrentRow]#' selected='selected'>">
				<cfelse>
					<cfset Ret = Ret & "<option value='#Q[arguments.IDColumn][Q.CurrentRow]#'>">
				</cfif>
                <!--- pad with hyphens or whatever to indicate depth --->
                <cfset Ret=Ret & RepeatString(" &raquo; ",ThisDepth)>
                <cfset Ret=Ret & HTMLEditFormat(Q[Arguments.TitleColumn][Q.CurrentRow]) & "</option>">
        </cfloop>
        <cfset Ret = Ret & "</select>">
        <cfreturn Ret>
</cffunction>
 
<cffunction name="QueryTreeSort" returntype="query" output="No">
  <cfargument name="Stuff" type="query" required="Yes">
  <cfargument name="ParentID" type="string" required="No" default="ParentID">
  <cfargument name="catID" type="string" required="No" default="catID">
  <cfargument name="BaseDepth" type="numeric" required="No" default="0">
  <cfargument name="DepthName" type="string" required="No" default="TreeDepth">
  <cfset var RowFromID=StructNew()>
  <cfset var ChildrenFromID=StructNew()>
  <cfset var RootItems=ArrayNew(1)>
  <cfset var Depth=ArrayNew(1)>
  <cfset var ThisID=0>
  <cfset var ThisDepth=0>
  <cfset var RowID=0>
  <cfset var ChildrenIDs="">
  <cfset var ColName="">
  <cfset var Ret=QueryNew(ListAppend(Stuff.ColumnList, Arguments.DepthName))>
  <!--- Set up all of our indexing --->
  <cfloop query="Stuff">
    <cfset RowFromID[Stuff[ Arguments.catID][Stuff.CurrentRow]]=CurrentRow>
    <cfif NOT StructKeyExists(ChildrenFromID, Stuff[Arguments.ParentID][Stuff.CurrentRow])>
      <cfset ChildrenFromID[Stuff[ Arguments.ParentID][Stuff.CurrentRow]]=ArrayNew(1)>
    </cfif>
    <cfset ArrayAppend(ChildrenFromID[Stuff[ Arguments.ParentID][Stuff.CurrentRow]], Stuff[Arguments.catID][Stuff.CurrentRow])>
  </cfloop>
  <!--- Find parents without rows --->
  <cfloop query="Stuff">
    <cfif NOT StructKeyExists(RowFromID, Stuff[Arguments.ParentID][Stuff.CurrentRow])>
      <cfset ArrayAppend(RootItems, Stuff[Arguments.catID][Stuff.CurrentRow])>
      <cfset ArrayAppend(Depth, Arguments.BaseDepth)>
    </cfif>
  </cfloop>
  <!--- Do the deed --->
  <cfloop condition="ArrayLen(RootItems) GT 0">
    <cfset ThisID=RootItems[1]>
    <cfset ArrayDeleteAt(RootItems, 1)>
    <cfset ThisDepth=Depth[1]>
    <cfset ArrayDeleteAt(Depth, 1)>
    <cfif StructKeyExists(RowFromID, ThisID)>
      <!--- Add this row to the query --->
      <cfset RowID=RowFromID[ThisID]>
      <cfset QueryAddRow(Ret)>
      <cfset QuerySetCell(Ret, Arguments.DepthName, ThisDepth)>
      <cfloop list="#Stuff.ColumnList#" index="ColName">
        <cfset QuerySetCell(Ret, ColName, Stuff[ColName][RowID])>
      </cfloop>
    </cfif>
    <cfif StructKeyExists(ChildrenFromID, ThisID)>
      <!--- Push children into the stack --->
      <cfset ChildrenIDs=ChildrenFromID[ThisID]>
      <cfloop from="#ArrayLen(ChildrenIDs)#" to="1" step="-1" index="i">
        <cfset ArrayPrepend(RootItems, ChildrenIDs[i])>
        <cfset ArrayPrepend(Depth, ThisDepth + 1)>
      </cfloop>
    </cfif>
  </cfloop>
  <cfreturn Ret>
</cffunction>
 
Now on my Page i am doing something like this:
 
<cfset NewQuery=QueryTreeSort(Stuff)>
 
<cfoutput>    		#ListFromQueryTree(Query=NewQuery,TitleColumn="catName",IDColumn="catID",selected="catID")#
</cfoutput>
 
so at the last of the above line , u see a selected tag with catID but it does select the default category.
 
really do not knowing what is happening

Open in new window

Avatar of duncancumming
duncancumming
Flag of United Kingdom of Great Britain and Northern Ireland image

You say
<cfif Q[arguments.IDColumn][Q.CurrentRow] EQ arguments.selected>

arguments.selected = "catID"

So in other words you're saying

<cfif Q[arguments.IDColumn][Q.CurrentRow] EQ "catID">

Does the value in the IDColumn equal the string "catID"?  I doubt it.  What is it you're trying to do?
Avatar of Coast Line

ASKER

sorry, i did not understood your point of view what you are asking me, can u elaborate please
What is it you're trying to achieve?  You want to make one of your options selected.... which one, when, why?  

Right now the code you've got will never work.

If I can get a better understanding of what it is you're trying to do, I may be able to suggest a change in your syntax to fix it.
Okay! I explain a bit:

I display the categories and subcategories under one select box.

they are displayed as:

category
  subcategory
      subsubcategory
nextcategory
    nextsub
         verynextsub

now initially when i did insert i chose one category say subsubcategory which have the CatID of 2.

Now i am trying to edit this record and i want that subsubcategory should be initially selected as its value is 2 as i picked it from database to edit.

but it picks the default value which is null.

so in my above code i am trying the catID with selected as one of the argument to pick the one which really belongs o the record i want to edit and it is not doing that way:

one thing i miss above u would like to ask about is STUFF:

i forgot to mention.

Stuff i had something like this:

<cffunction access="public" name="getCats" returntype="query">
        <cfset var myset = "">
        <cfquery datasource="#request.dsn#" username="#request.user#" password="#request.pass#" name="myset">
        SELECT categories.*
        FROM categories
        ORDER BY catID DESC
        </cfquery>
        <cfreturn myset>
    </cffunction>
i used the the above function as cfinvoke and returnvariable as stuff
ASKER CERTIFIED SOLUTION
Avatar of duncancumming
duncancumming
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Let's take it simple way.

we make select statement and then we can our select as:

<select name='b'>
    <option value='#catid#' <cfif #stuff.catID# eq #catID#>selected</cfif>>#catname#</option>
</select>

we often do something like above to get the one which is already in the database like i want edit record, which has a category of 2. i want that when i edit record, my editing record should automatically point to 2 no catID.

the procedure is bit same but some advanced funda where it is managing the select in a function.

i tried your code but is not working as
when i harcode value to 2,3,4 i get respective results

<cfoutput>
 #ListFromQueryTree(Query=NewQuery,TitleColumn="catName",IDColumn="catID",selected=stuff.catID)#
</cfoutput>

like

<cfoutput>
 #ListFromQueryTree(Query=NewQuery,TitleColumn="catName",IDColumn="catID",selected=2)#
</cfoutput>

it picks the right value
got it working, changed this:

<cfoutput>
 #ListFromQueryTree(Query=NewQuery,TitleColumn="catName",IDColumn="catID",selected=#catID#)#
</cfoutput>

but i am not sure this is the right way to do it or not

Thanks, Your Comments gave me some idea so i can try some hardcode value and it worked.