Dynamic checkboxes - creating checkbox submenu

Discussion in 'Programming' started by lespaul00, Dec 9, 2007.

  1. #1
    Hello,

    I have the following code:

    <cfquery name="getIngredients" datasource="mydatasource">
    SELECT it.Type, i.ingredient_id, i.ingredient
    FROM   TBLINGREDIENTS AS i INNER JOIN TBLINGREDIENTTYPES it
    	ON i.IngredientType_Id = it.IngredientType_Id
    ORDER BY it.Type, i.ingredient
    </cfquery>
    
    <form method="post" action="what_can_i_make_results.cfm">
    <table width="100%" border="0" cellspacing="0" cellpadding="0">
    <cfoutput query="getIngredients" group="type">
       <tr>
       	 <th colspan="3" align="left"><h2>&nbsp;</h2>
       	   <h2><span class="style5">#Type#</span></h2></th>
       </tr>
       <tr>
       <cfset typeRow = 1>
       <cfoutput>
          	  <td width="33%"><h5>
          	    <input type="checkbox" name="ingredient_id" value="#INGREDIENT_ID#" size="50"> 
          	    #Ingredient# </h5></td>
       	  <cfif typeRow mod 3 eq 0>
    	  	</tr><tr>
    	  </cfif>	
    	  <cfset typeRow = typeRow + 1 />
       </cfoutput>
       </tr>
    </cfoutput>
    </table>
      <input name="submit" type="submit" value="Find Recipes!" />
    </form> 
    Code (markup):
    So, all of my ingredients from my database are pulled and displayed on this page with checkboxes next to each. I've run into two problems/questions:

    1. One ingredient, I would like the default (when the page loads) to be checked. How can I do this? (only one of my ingredients)

    2. As I grow my database, i'm noticing there are some ingredients with different variations. So, Ingredient 1 may have 5 different brands. So this is what I want.... When a user checks this box (say, Ingredient1), then a submenu appears (either a pop-up or submenu below) that shows 5 more checkboxes with Ingredient1 - brand1, Ingredient1 - brand2, Ingredient1 - brand3, Ingredient1 - brand4, Ingredient1 - brand5. Note: The Ingredient1 checkbox will have its own value in the database, as well as each of the different brands for that ingredient.

    3. How can I create a "check all" checkbox that will check off all ingredients within a TYPE category?
    Thanks.
     
    lespaul00, Dec 9, 2007 IP
  2. unitedlocalbands

    unitedlocalbands Well-Known Member

    Messages:
    246
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    128
    #2
    Here is a javascript that I think will help you with the check all uncheck all function.

    http://www.shawnolson.net/a/639/select-all-checkboxes-in-a-form-with-javascript.html


    One way to check a box by default in to use this:
    
    <input type="checkbox" checked="checked" />
    
    Code (markup):
    But sense you are using <cfoutput> to dynamically create a list on check boxes I think this will cause all the boxes to be checked.

    I'll try and think of something creative.
     
    unitedlocalbands, Dec 9, 2007 IP
  3. unitedlocalbands

    unitedlocalbands Well-Known Member

    Messages:
    246
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    128
    #3
    Ok this will work but is not the most effcient way, So I wont be hurt if you dont use it...:)

    But one way you could do this is, add a column to your table called "checked"

    Set your datatype to bit or whatever you use for a boolean datatype.

    Then if you want one of the check boxes in your <cfoutput> list to be checked, you would set the "checked" column = 1. If you wanted them to be unchecked you would set them = 0.

    In the input tag you will have to add the checked attribute.
    Then set the checked attribute = "checked"

    You need a cfif statment as well. theres probly a way to do this without the cfif statment but.... here you go

    
    
    <cfquery name="getIngredients" datasource="mydatasource">
    SELECT it.Type, i.ingredient_id, i.ingredient, [B]CHECKED[/B]
    FROM   TBLINGREDIENTS AS i INNER JOIN TBLINGREDIENTTYPES it
    	ON i.IngredientType_Id = it.IngredientType_Id
    ORDER BY it.Type, i.ingredient
    </cfquery>
    
    
    
    
    <cfouput>
    <input [B]<cfif getIngredients.checked eq "1">
                 checked="checked" 
                 </cfif>[/B]
                 type="checkbox" 
                 name="ingredient_id" 
                 value="#INGREDIENT_ID#" 
                 size="50">
    </cfoutput>
    
    
    Code (markup):
     
    unitedlocalbands, Dec 9, 2007 IP
    lespaul00 likes this.
  4. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Awesome. That worked!

    How about the following?

    This seems like it will be a bit complex.
     
    lespaul00, Dec 9, 2007 IP
  5. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Unfortunately, this will not work. It will work for all checkboxes in form, but I have checkboxes in 8 different categories in my form. I'd want the feature to be able to work with each category.
     
    lespaul00, Dec 9, 2007 IP
  6. unitedlocalbands

    unitedlocalbands Well-Known Member

    Messages:
    246
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    128
    #6
    I asked this question on a different forum, when someone replies over there I will get back to you. I think I know what that are going to say.

    I think they will just say "Why dont you use a Chained Select List?"

    If you can use a chained select list you can get one here:

    http://www.dynamicdrive.com/dynamicindex16/chainedselects/index.htm

    I think I will have a better answer in about 15 minutes.
     
    unitedlocalbands, Dec 9, 2007 IP
  7. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #7
    Thanks for the reply. However, this is Java script. I'd like to strictly implement it via coldfusion.
     
    lespaul00, Dec 9, 2007 IP
  8. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #8
    Here is my code again:

    <cfquery name="getIngredients" datasource="mydatasource">
    SELECT it.Type, i.ingredient_id, i.ingredient
    FROM   TBLINGREDIENTS AS i INNER JOIN TBLINGREDIENTTYPES it
    	ON i.IngredientType_Id = it.IngredientType_Id
    ORDER BY it.Type, i.ingredient
    </cfquery>
    
    <form method="post" action="what_can_i_make_results.cfm">
    <table width="100%" border="0" cellspacing="0" cellpadding="0">
    <cfoutput query="getIngredients" group="type">
       <tr>
       	 <th colspan="3" align="left"><h2>&nbsp;</h2>
       	   <h2><span class="style5">#Type#</span></h2></th>
       </tr>
       <tr>
       <cfset typeRow = 1>
       <cfoutput>
          	  <td width="33%"><h5>
          	    <input type="checkbox" name="ingredient_id" value="#INGREDIENT_ID#" size="50"> 
          	    #Ingredient# </h5></td>
       	  <cfif typeRow mod 3 eq 0>
    	  	</tr><tr>
    	  </cfif>	
    	  <cfset typeRow = typeRow + 1 />
       </cfoutput>
       </tr>
    </cfoutput>
    </table>
      <input name="submit" type="submit" value="Find Recipes!" />
    </form>
    Code (markup):
    I'm thinking of creating another field in my TBLINGREDIENTS table. I can name it BRAND_ID. Then, for these ingredients with many brands, I can have these brands display if the ingredient's checkbox is checked.

    So,...

    <cfquery name="getIngredients" datasource="mydatasource">
    SELECT it.Type, i.ingredient_id, i.ingredient
    FROM   TBLINGREDIENTS AS i INNER JOIN TBLINGREDIENTTYPES it
    	ON i.IngredientType_Id = it.IngredientType_Id
    ORDER BY it.Type, i.ingredient
    </cfquery>
    
    <form method="post" action="what_can_i_make_results.cfm">
    <table width="100%" border="0" cellspacing="0" cellpadding="0">
    <cfoutput query="getIngredients" group="type">
       <tr>
       	 <th colspan="3" align="left"><h2>&nbsp;</h2>
       	   <h2><span class="style5">#Type#</span></h2></th>
       </tr>
       <tr>
       <cfset typeRow = 1>
       <cfoutput>
          	  <td width="33%"><h5>
          	    <input type="checkbox" name="ingredient_id" value="#INGREDIENT_ID#" size="50"> 
          	    #Ingredient# </h5>
    [COLOR="Red"][B]<cfif ingredient_id = checked>
    <cfquery name="brands" datasource="mydatabase">
    SELECT INGREDIENT, INGREDIENT_ID
    FROM TBLINGREDIENTS
    WHERE BRAND_ID = 2
    </cfquery>
    <cfoutput query= "brands" datasource="mydatabase">
    <tr>input type="checkbox" name="ingredient_id" value="#brands.INGREDIENT_ID#" size="50"> #brands.Ingredient# </h5>
    </tr>
    </cfif>[/B][/COLOR]
    </td>
       	  <cfif typeRow mod 3 eq 0>
    	  	</tr><tr>
    	  </cfif>	
    	  <cfset typeRow = typeRow + 1 />
       </cfoutput>
       </tr>
    </cfoutput>
    </table>
      <input name="submit" type="submit" value="Find Recipes!" />
    </form>
    Code (markup):
    Could something like this work? When Ingredient23 is checked, the different brands of Ingredient23 (with brand_id = 2) are shown below Ingredient 23 (rows within Ingredient23's cell)?
     
    lespaul00, Dec 10, 2007 IP
  9. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #9
    I found the following code. This is similar to what I'd like to occur:

    <head>
    <script type="text/javascript">
    function EnableSelectMenu()
        {
        if (document.getElementById('Checkbox').checked)
        {document.getElementById('SelectMenu').disabled=false}
        else
        {document.getElementById('SelectMenu').disabled=true}
    }
    </script>
    
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Untitled Document</title>
    </head>
    
    <body>
    <form action="" method="get">
      <p>
        <input type="checkbox" name="Checkbox" id="Checkbox" value="checkbox" onClick="EnableSelectMenu();">
    Check To Enable Select Menu </p>
      <p>
        <select name="SelectMenu" id="SelectMenu" disabled="disabled">
          <option value="SelectionA">Selection A</option>
          <option value="SelectionB">Selection B</option>
          <option value="SelectionC">Selection C</option>
        </select></p>
      </form>
    </body>
    </html>
    Code (markup):

    My problem is that the checkboxes are created dynamically from my TBLINGREDIENTS table. So, there's no way for me to pinpoint the recipes that would need this feature.

    For instance again, if INGREDIENT_ID = 23 is checked, then I want to show 5 more checkboxes of ingredients below it (That would be Ingredient23 - Brand1, etc.)
     
    lespaul00, Dec 10, 2007 IP
  10. cfStarlight

    cfStarlight Peon

    Messages:
    398
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #10
    It certainly sounds like it could be done with some javascript. (You would have to use javascript to toggle the visibility of the checkboxes) But I'm having a little trouble visualizing this one.

    Something seems to be missing here. How are you connecting Ingredient1 to brand1, brand2, brand3, ... brand5 if each brand is an ingredient ID ... or am I misreading that ?

    Also isn't there a possibility of duplicates here? What values are you trying to send to the action page: list of ingredient ids checked plus a list of brand ids checked .. or something else?
     
    cfStarlight, Dec 10, 2007 IP
  11. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #11
    Sorry for the confusion.

    For simplicity (even though it may not sound as such), I would like each brand as an individual ingredient as well.

    Each brand will be shown in the TBLINGREDIENTS table as INGREDIENT-BRAND1, and have unique INGREDIENT_IDs.

    No. Certain recipes REQUIRE a specific brand, while others do not. By doing this, it allows for all recipes that can use any brand to show, and those that include a brand you have available to show.

    My main intent is that the page is getting filled up with Ingredients as I populate my database. A lot of ingredients are listed as INGREDIENT5 - Brand1, etc. right now. If the user doesn't even have INGREDIENT5, I don't want all the INGREDIENT5s of the different brands to show too.

    Does that make it seem a little more clear?

    I was thinking of using the code in my previous post. But, I need some help with the code. I can create another field in my TBLINGREDIENTS and assign numbers to those brands for a specific INGREDIENT. So, as such:

    TBLINGREDIENTS:

    INGREDIENT_ID.....INGREDIENT...................BRAND_ID
    ...

    23.....................INGREDIENT23.....................0.......
    24.....................INGREDIENT23-BRAND1.........23......
    25.....................INGREDIENT23-BRAND2.........23......
    26.....................INGREDIENT23-BRAND3.........23......
    27.....................INGREDIENT23-BRAND4.........23......

    ...

    Now, with the code in the other post, I can somehow place code that does something like "when INGREDIENT 23 checkbox is checked, display 4 checkboxes below it of INGREDIENT WHERE BRAND_ID = 23.
     
    lespaul00, Dec 11, 2007 IP
  12. cfStarlight

    cfStarlight Peon

    Messages:
    398
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #12
    The one thing that bothers me about this is that the duplication of data could introduce inconsistencies. Say you needed to change #23 to

    23.....................OOPS THIS SHOULD BE BBQ SAUCE.....................0.......

    Now records #24 through #27 are out of synch with the generic record. That said, you could probably work around that.

    One possibility might be to pull all the information in one query, using an additional left join. This is not a tested query, but I'm thinking of something like this

    
    <cfquery name="getIngredients" datasource="mydatasource">
    SELECT it.Type, i.ingredient_id, i.ingredient,
           ib.IngredientBrand
    FROM   ( 
            TBLINGREDIENTTYPES it 
               INNER JOIN TBLINGREDIENTS AS i     
    	   ON i.IngredientType_Id = it.IngredientType_Id
           )
           LEFT JOIN TBLINGREDIENTS AS ib 
               ON i.Ingredient_Id = ib.BRAND_ID
    ORDER BY it.Type, i.ingredient, ib.ingredient
    </cfquery>
    
    Code (markup):
    Then use cfoutput's "group" attribute to generate all 5 of the checkboxes. But keep the 4 brand checkboxes hidden until the INGREDIENT #23 box is checked. Then make the checkboxes visible with javascript. But the query might have its own performance issues if the final resultset is very large.

    One thing is still unclear to me. What values do you want to pass to the action page? Let's say I check INGREDIENT #23. The page instantly displays the 4 brand checkboxes beneath it. I then check the BRAND-3 box

    23.....................INGREDIENT23.....................[checked]
    26.....................INGREDIENT23-BRAND3.........[checked]

    Since I've checked both boxes INGREDIENT23 and INGREDIENT23-BRAND3 will be sent to the action page. I'm not certain that is what you want.
     
    cfStarlight, Dec 11, 2007 IP
  13. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #13
    Some ingredients require a specific brand ingredient. Others do not. By doing it this way, you're covered regardless what the user checks.

    But how can I incorporate this into my code, such that the hidden fields do not take up space, but when they do appear, the table expands to accomodate these additional checkboxes? I'm thinking of the new checkboxes appearing either as a pop-up, or just creating a new table row beneath the ingredient's cell.
     
    lespaul00, Dec 11, 2007 IP
  14. cfStarlight

    cfStarlight Peon

    Messages:
    398
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #14
    Use CSS to make the element(s) basically invisible. For example you can set some elements' style to display:none. So its basically invisible and doesn't take up any extra space. You could then make it visible by using "block" or "inline". Here's a quick and ugly example using <div> tags

    
    <script type="text/javascript">
    	function toggleBrands(parentId, makeVisible) {
    		var divElement = document.getElementById('ingredientBrands_'+ parentId);
    		if (divElement) {
    			divElement.style.display = ( makeVisible ? 'block' : 'none')
    		}
    	}
    </script>
    <form>
    	<input type="checkbox" value="23" onClick="toggleBrands(this.value, this.checked);"> INGREDIENT23
    	<div id='ingredientBrands_23' style="display: none; background-color: #ffff00;">
    		<input type="checkbox" value="24"> INGREDIENT23-BRAND1
    		<input type="checkbox" value="25"> INGREDIENT23-BRAND2
    		<input type="checkbox" value="26"> INGREDIENT23-BRAND3
    		<input type="checkbox" value="27"> INGREDIENT23-BRAND4
    	</div>
    	<input type="checkbox" value="28" onClick="toggleBrands(this.value, this.checked);"> INGREDIENT28
    	<div id='ingredientBrands_28' style="display: none;  background-color: #ffff00;">
    		<input type="checkbox" value="29"> INGREDIENT28-BRAND1
    		<input type="checkbox" value="30"> INGREDIENT28-BRAND2
    		<input type="checkbox" value="31"> INGREDIENT28-BRAND3
    	</div>
    </form>
    
    Code (markup):
    How the elements displays and how much space they occupies depends on which you value you use. There are different possibilities

    http://www.w3schools.com/css/pr_class_display.asp
    http://www.w3.org/TR/REC-CSS2/visuren.html

    Keep in mind the display properties for a <tr> are different than for say a <div>. IIRC there may also be some subtle differences between how IE and FF handle them.

    http://snook.ca/archives/html_and_css/dynamically_sho/
     
    cfStarlight, Dec 11, 2007 IP
  15. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #15
    I'm sitting here trying to write out a different code... so maybe disregard my last post
     
    lespaul00, Dec 12, 2007 IP
  16. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #16
    OK, I was fooling around on paper, and this is what I came up with:

    TBLINGREDIENTS:

    INGREDIENT_ID.........INGREDIENT...............BRAND_ID
    1............................COFFEE............................0
    2............................COFFEE-STARBUCKS...........1
    3............................COFFEE-SEATLE'S BEST.......1
    4............................COFFEE-FOLGERS................1
    5............................BANANA............................0
    6............................APPLE...............................0
    7............................APPLE - RED.......................6
    8............................APPLE - GREEN....................6

    
    [COLOR="DarkOrange"]<!---this query will only pull ingredients that are not labeled as brands – AKA parent ingredients>[/COLOR]
    <cfquery name="getIngredients" datasource="mydatabase">
    SELECT it.Type, i.INGREDIENT_ID, i.INGREDIENT, i.BRAND_ID
    FROM TBLINGREDIENTS AS i INNER JOIN TBLINGREDIENTTYPES it
         ON i.INGREDIENTTYPE_ID = it.INGREDIENTTYPE_ID
    [COLOR="Red"]WHERE BRAND_ID = 0[/COLOR]
    ORDER BY it.TYPE, i.INGREDIENT
    </cfquery>
    
    [COLOR="darkorange"]<!---this query will pull the brands (which are actually independent ingredient records in the database themselves) per for each parent ingredient>[/COLOR]
    [COLOR="red"]
    <cfquery name="getbrands" datasource="mydatabase">
    SELECT i.INGREDIENT_ID, i.INGREDIENT, i.BRAND_ID
    FROM TBLINGREDIENTS AS i 
    [COLOR="DarkOrange"]<!---Left join below will take ALL ingredient_ids from TBLINGREDIENTS and their respective BRAND_IDs where available>[/COLOR]
             LEFT JOIN TBLINGREDIENTS i
                     ON i.INGREDIENT_ID = i.BRAND_ID
    [COLOR="darkorange"]<!---We can keep these results in order as the same order of the Ingredient IDs in query getIngredients… or is this true?  Would we have to group by type first too to keep them in the same order?>[/COLOR]
    ORDER BY i.INGREDIENT_ID, i.BRAND_ID
    </cfquery>[/COLOR]
    
    
    <form method="post" action="what_can_i_make_results.cfm">
    <table width="100%" cellspacing="0" cellpadding="0" border="0">
    <cfoutput query="getIngredients" group="type">
       <tr>
            <th colspan="3" align="left">#type#</th>
       </tr>
    
       <tr>
            <cfset typeRow = 1>
            <cfoutput>
                   <td width="33%">
                   <input type="checkbox" name="INGREDIENT_ID" value="#INGREDIENT_ID# size="50" [COLOR="red"]onClick="toggleBrands(this.value,this.checked[/COLOR]);">#INGREDIENT#
                   </td>
                   
                         [COLOR="red"] <cfoutput query="getbrands" group="INGREDIENT_ID">
                               <tr style="display:none">
                                    <input type="checkbox" name="INGREDIENT_ID" value="#INGREDIENT_ID#" size="50">#INGREDIENT#</tr>
                          </cfoutput>[/COLOR]
    
                   <cfif typeRow mod 3 eq 0>
                   </tr> <tr>
                   </cfif>
    
            <cfset typeRow = typeRow + 1 />
            </cfoutput>
       </tr>
    </cfoutput>
    </table>
       <input name="submit" type="submit" value="Find Recipes!" />
    </form>
    
    Code (markup):
    Would this work? Or more importantly, do you see my logic?

    Would the red above create rows of the brands within the table cell of their respective parent Ingredient?

    i.e. Assuming this is a portion of the output table (O is checkbox):

    ______________________________________________________________________
    O...COFFEE..........................|........O...INGREDIENT............|......O...INGREDIENT|
    --------------------------------------------------------------------------------

    When COFFEE is checked:
    ______________________________________________________________________
    X...COFFEE..........................|........O...INGREDIENT............|......O...INGREDIENT|
    O...COFFEE-STARBUCKS.........|.........................................|..........................|
    O...COFFEE-SEATTLE'S BEST...|.........................................|..........................|
    O..COFFEE-FOLGERS.............|.........................................|...........................|
    --------------------------------------------------------------------------------
     
    lespaul00, Dec 12, 2007 IP
  17. cfStarlight

    cfStarlight Peon

    Messages:
    398
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #17
    Yes, a demo is worth a 1000 words of explanation ;-)


    I didn't test the query, so I'm almost certain you'll need to tweak it. But the idea was to pull both the ingredients and brands in the same query. But ib.IngredientBrand should have been ib.Ingredient AS IngredientBrand. You have to give that column an alias because you don't want two columns in the query to have the same name.

    The way I see it you have two options:
    1) Pull everything (ingredients and brands) in one query. Then use cfoutput and (2) "group" options to generate the hidden divs.

    Advantage: simpler code
    Disadvantage: may result in more records

    2) Retrieve all ingredients in one query and all brands in another. Then use QoQ inside your cfoutput loop to retrieve the brands for each ingredient and generate the hidden divs.

    Advantage: may result in less records (total)
    Disadvantage: slightly more complex and more code

    Which do you prefer?
     
    cfStarlight, Dec 12, 2007 IP
  18. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #18
    Haha. Hmm, I guess which is easier! But, does my new posted code seem like it's on track with option #2?

    If not, I can try your code you just posted, and pursue option #1.
     
    lespaul00, Dec 12, 2007 IP
  19. cfStarlight

    cfStarlight Peon

    Messages:
    398
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #19
    Warning - this is all psuedo code

    Yes, it is kind of online with #2. But the second will need to change, so it only pull brands. You might even be able to get away with just this

    
    <cfquery name="getbrands" datasource="mydatabase">
    SELECT INGREDIENT_ID, INGREDIENT, BRAND_ID
    FROM TBLINGREDIENTS
    <!--- its a brand if the id > 0 --->
    WHERE  BRAND_ID > 0
    ORDER BY INGREDIENT_ID, BRAND_ID
    </cfquery>
    
    Code (markup):
    But you can't just output the brand query in the inner loop. You have a use QoQ to connect it to the current ingredient in the outer loop. That's what I meant about it being more code.

    Forgetting about tables and the "type" for a moment, it would be something like this.

    
    <cfoutput query="theIngredientsQuery" ...>
        the current ingredient is #theIngredientsQuery.Ingredient#<br>
        <!--- get the brands for this ingredient --->
        <cfquery name="getIngredientBrands" dbtype="query">
                SELECT  INGREDIENT_ID, INGREDIENT 
                FROM    getbrands
                WHERE   BRAND_ID = #theIngredientsQuery.INGREDIENT_ID#
        </cfquery>
    
        <cfif getIngredientBrands.recordCount GT 0>
              <div style="display: hidden" ...>
               <cfloop query="getIngredientBrands">
                     ... create a checkbox for each brand here
               </cfloop>
         </cfif>
    </cfoutput>
    
    Code (markup):

    The code for #1 would be simpler, but its not just about that. Consider how big your tables are going to get. Option #1 will likely result in a larger query size, so you may decide option #2 is more efficient in terms of performance.
     
    cfStarlight, Dec 12, 2007 IP
  20. lespaul00

    lespaul00 Peon

    Messages:
    283
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #20
    Thank you for the post.

    I modified my page code as such:

    <body>
    <!---this query will only pull ingredients that are not labeled as brands – AKA parent ingredients--->
    <cfquery name="getIngredients" datasource="mydatabase">
    SELECT it.Type, i.ingredient_id, i.ingredient, i.checked, i.BRAND_ID
    FROM   TBLINGREDIENTS AS i INNER JOIN TBLINGREDIENTTYPES it
    	ON i.IngredientType_Id = it.IngredientType_Id
    WHERE BRAND_ID = 0
    ORDER BY it.Type, i.ingredient
    </cfquery>
    <!---this query will pull the brands (which are actually independent ingredient records in the database themselves) per for each parent ingredient--->
    
    <cfquery name="getbrands" datasource="mydatabase">
    SELECT INGREDIENT_ID, INGREDIENT, BRAND_ID
    FROM TBLINGREDIENTS
    WHERE BRAND_ID > 0
    ORDER BY INGREDIENT_ID, BRAND_ID
    </cfquery>
    
    
    
    <form method="post" action="what_can_i_make_results.cfm">
    <table width="100%" cellspacing="0" cellpadding="0" border="0">
    <cfoutput query="getIngredients" group="type">
       <tr>
            <th colspan="3" align="left">#Type#</th>
       </tr>
    
       <tr>
            <cfset typeRow = 1>
            <cfoutput>
                   <td width="33%">
                   <input type="checkbox" 
    					   <cfif getIngredients.checked eq "1">
    						checked="checked" 
    						</cfif>
    			 name="ingredient_id" value="#getIngredients.INGREDIENT_ID# size="50" onClick="toggleBrands(this.value,this.checked);">#getIngredients.INGREDIENT#
                   </td>
    			   		<cfoutput>
                   		<tr>
    						<cfif getbrands.recordCount GT 0>
    						<div style="display: hidden">
    						<cfloop query="getbrands">
    							<input type="checkbox" name="INGREDIENT_ID" value="#getbrands.INGREDIENT_ID#" size="50">#getbrands.INGREDIENT#
    						</cfloop>
    						</div>
    						</cfif>
    					</tr>
    					</cfoutput>
                   <cfif typeRow mod 3 eq 0>
       </tr> 
       <tr>
                   </cfif>
    
            <cfset typeRow = typeRow + 1 />
            </cfoutput>
       </tr>
    </cfoutput>
    </table>
       <input name="submit" type="submit" value="Find Recipes!" />
    </form>
    
    
    </body>
    Code (markup):
    I ran this, and there were probably 300 duplicate rows of the brands from my database listed. After these rows, The normal ingredients (with BRAND_ID = 0) were listed under their respective TYPE category (but no longer in a 3 column list).

    What is wrong with my code? Is the loop not stopping?

    After some investigating, I removed the following portion of code, and it works as it did before:

    
    <cfoutput>
       <tr>
    	<cfif getbrands.recordCount GT 0>
    		<div style="display: hidden">
    		<cfloop query="getbrands">
    		<input type="checkbox" name="INGREDIENT_ID" value="#getbrands.INGREDIENT_ID#" size="50">#getbrands.INGREDIENT#
    		</cfloop>
    		</div>
    	</cfif>
       </tr>
    </cfoutput>
    
    Code (markup):
    It seems that this code fails by:

    1. Not being able to display the brands only once.
    2. Fails to place the brands ingredients under their respective parent ingredient.
     
    lespaul00, Dec 12, 2007 IP