0 Replies Latest reply on Sep 21, 2007 6:46 AM by M_I_C_U_S

    Output with cfcs

    M_I_C_U_S
      I'll explain this the best I can. I am experimenting with the cf8 cfmenu and cfmenuitem tags. I use two tables in a database, one for menus and the other menu items. Each menu item has 3 key fields, menuID, itemID, and parentID. Obviously menuID is which menu the item belongs, itemID is just a unique indentifier for the specific item, and parentId is optional. The parentID field would hold the itemID of an item that the specific item belongs to. So think family tree. Ex:
      Grandpa(top level menu items) has son and daughter (menu items in the grandpa menuitem), daughter has two childer, child1 and child2 (menu items under daughter).
      Grandpa
      >Son (menuid = grandpa, and parentid is empty)
      >Daughter (menuid = grandpa, and parentid is empty)
      >Child1 (parentid = Daughter)
      >Child2 (parentid = Daughter)

      I use two functions in a cfc to build the navigation, buildNavBar and buildMenu. This is how it is suppose to work. The buildNavBar function queries the database for the main menus. It outputs the cfmenu tag, and the starts looping through the main menus record set and outputs the opening cfmenuitem tag for the menu. After the cfmenuitem tag I invoke the buildMenu function to build the specific menu. After the invoke I close the cfmenuitem tag. And after the loop the menu is closed (/cfmen).

      The buildMenu function essentially performs the same way. It has two arguments, mid and iid, mid for menuid and iid for item id. The query that is run can run two different ways. If no itemID is passed to the function. I query the menu items table for all items that have the menu id as their menu id along with an empty parent id (would grab the Son and Daughter values in the example above). If the result returned has a record count I start looping through it. I output the opening menu item tag, then self-call the buildMenu function passing the menu id and the item id of the current item. I then close the cfmenuitem tag. This function would keep calling itself to find any children for a specific item and keep going down until it finds no more children items.

      As I said that is how it is suppose to work, how ever that is not what is happening. I receive a "cfmenuitem must have parent cfmenu or cfmenuitem tag." error. If I modify the functions to build a string, dump the string to the screen, copy and create a new cfm page with the code in string, the menu is build correct. If I comment out the call to the buildMenu function in the buildNavBar function, the main menu items are build fine and the menu displays. The error occurs in the call to the buildMenu function from the buildNavBar function. The two functions are below. Any help/a direction to go would be greatly appreciated.
      <cffunction name="buildNavBar" access="public" returntype="void" output="yes">
      <cfinvoke component="components.queries" method="getMainMenus" returnvariable="mainmenus">
      </cfinvoke>
      <cfmenu name="navbar" type="horizontal">
      <cfoutput query="mainmenus">
      <cfmenuitem display="#mainmenus.menu_title#">
      <cfinvoke component="components.functions" method="buildMenu">
      <cfinvokeargument name="menuid" value="#mainmenus.menu_id#">
      </cfinvoke>
      </cfmenuitem>
      </cfoutput>
      </cfmenu>
      </cffunction>
      <!--- Build Menu --->
      <cffunction name="buildMenu" access="public" output="yes" returntype="void">
      <cfargument name="mid" type="string" required="yes">
      <cfargument name="iid" type="string" required="no" default="">
      <!--- Call get menu items function --->
      <cfinvoke component="components.queries" method="getItems" returnvariable="items">
      <cfinvokeargument name="mid" value="#arguments.mid#">
      <cfif trim(arguments.iid) is not "">
      <cfinvokeargument name="iid" value="#arguments.iid#">
      </cfif>
      </cfinvoke>
      <cfif items.RecordCount gt 0>
      <cfoutput query="items">
      <cfmenuitem display="#items.text#">
      <cfinvoke component="components.functions" method="buildMenu">
      <cfinvokeargument name="mid" value="#arguments.mid#">
      <cfinvokeargument name="iid" value="#items.iid#">
      </cfinvoke>
      </cfmenuitem>
      </cfoutput>
      </cfif>
      </cffunction>