p2p.wrox.com Forums

Need to download code?

View our list of code downloads.


  Return to Index  

beginning_php thread: Re: Arrays, Queries and Select-boxes


Message #1 by "Peter Simard" <peter@p...> on Wed, 1 May 2002 12:40:28
Hi all;

For a better idea of what I'm thinking, here's a link to the "semi"-
functinal upate utility:


http://www.mainstreetsrestaurantgroup.com/msc/ud.php

Regards,

Pete
Message #2 by "Nikolai Devereaux" <yomama@u...> on Wed, 1 May 2002 09:28:36 -0700
Hey Peter,

Sorry I haven't had the time to really look through the code yet.  =(

> http://www.mainstreetsrestaurantgroup.com/msc/ud.php

I did notice that the menu item links on this page go to http://$id/, not
$PHP_SELF?id=$id or whatever.

Good luck, I'll be in touch later today.


nik

Message #3 by Peter Simard <pasimard@v...> on Wed, 1 May 2002 12:33:46 -0400
No problem.

It's just up there for a visual at the moment.

Thanks Nik,

Pete


Message #4 by "Nikolai Devereaux" <yomama@u...> on Wed, 1 May 2002 10:53:02 -0700
Okay, since today's a new day, let me try to paraphrase the problem to see
if I understand it properly:

Let's say you have a recipe for a burger.  The burger has a bun, 8oz patty,
and 2ox lettuce.

The update page would have three dropdowns, one for each ingredient IN the
recipe.

Each dropdown would list ALL ingredients, but have one of the burger
ingredients selected.

 SELECT    TEXT  TEXT
 [bun ]    [1]  [each]
 [patty]   [8]  [ounces]
 [lettuce] [2]  [ounces]


A simple solution is to have the first item of the dropdown be the
"preselcted" choice, but then list ALL possible choices appear underneath
it, too.

You can also write a utility function to create your dropdown.  We discussed
this in early april in this thread:
  http://p2p.wrox.com/archive/beginning_php/2002-04/25.asp


Putting it all together for your app would be something like this:

  // create a dropdown combo box and preselect a default option
  function create_select($name, $options, $default = "")
  {
    $tags = "<SELECT name=\"$name\">\n";

    // http://www.php.net/foreach
    foreach($options as $value => $text)
    {
      $tags .= "  <OPTION value=\"$value\"";

      if($value == $default)
      {
        $tags .= ' SELECTED';
      }

      $tags .= ">$text</OPTION>\n";
    }

    $tags .= "</SELECT>\n";

    return $tags;
  }

// ingredients:
function getIngredients()
{
   $ret = array();

   $result = db_query("SELECT name, cost FROM ingredients");

   if(! $result)
      return $ret;

   while($row = db_fetch_array($result))
   {
      $ret[] = $row;
   }

   return $ret;
}


Okay, now we get to the good stuff.  Since the array we get from
getAllIngredients() is like this:

Array
{
   [0]  => Array
   {
       [name]  => patty
       [cost]  => 3.99
   }
   [1]  => Array
   {
       [name]  => lettuce
       [cost]  => 2.50
   }
}

we need to reorganize the array to match what we need for create_select().
Since you don't have an ingredient ID, just a name and cost, we'll have to
use the name for both the index into the array and the value at that index.

$ingreds = getIngredients();
$ing_sel_opts = array();
foreach($ingreds as $ingred)
{
    $ingred[name] = $ingred[name];
}


I'll leave it to you to create the array of ingredients in a recipe from the
DB.

$recipe_ings = Array
{
    [0] => patty
    [1] => bun
    [2] => lettuce
}


Now, each of your selects is created like this:

$selects[] = array(); // will hold the select dropdowns
$num_ings = count($recipe_ings);
for($i = 0; $i < $num_ings; ++$i)
{
    //                          name          options   default
    $selects[] = create_select("rec_ing[$i]", $ingreds, $recipe_ings[$i]);
}


$select = Array
{
   [0] = "<SELECT> ... </SELECT>" // with patty preselected
   [1] = "<SELECT> ... </SELECT>" // with bun preselected
   [2] = "<SELECT> ... </SELECT>" // with lettuce preselected
}


hope this helps...

nik

Message #5 by Peter Simard <pasimard@v...> on Wed, 1 May 2002 14:06:14 -0400
Well you paraphrased it correctly...

I'll get back to you...I'm sure!!

Thanks Nik


Message #6 by "Nikolai Devereaux" <yomama@u...> on Wed, 1 May 2002 11:15:05 -0700
Jake Cohen pointed a coupls bugs out to me.

The first is that I make reference to "getAllIngredients()" when the
function I defined is actually called "getIngredients()".

The second is more serious:

> $ingreds = getIngredients();
> $ing_sel_opts = array();
> foreach($ingreds as $ingred)
> {
>     $ingred[name] = $ingred[name];
> }

this is wrong .  The line in the foreach loop should look like this:

   $ing_sel_opts[$ingred['name']] = $ingred['name'];


What we're doing is creating an array where the index is the same as the
value.

Array
{
    [patty]       => patty
    [lettuce]     => lettuce
    [chx fingers] => chx fingers
    [chx toes]    => chx toes
}

It doesn't look like it makes much sense, but that's okay.  The reason why
we do this is because we pass an array of options to create_select().
create_select() assumes that each index in the array is the "value" of the
option, and the text between <OPTION> and </OPTION> tags is the value at
that index.

To illustrate:

Array
{
   [0]  =>  value of index 0
   [1]  =>  value of index 1
   [2]  =>  value of index 2
}

passing this array to create select would generate this:

<select name...>
  <option value="0">value of index 0</option>
  <option value="1">value of index 1</option>
  <option value="2">value of index 2</option>
</select>


Since your ingredients array doesn't have (to my knowledge) a unique
numerical index id column, we can't use that as the value of the option; so
we're stuck with using the name for both the option value and text.

<select name...>
  <option value="patty">patty</option>
  <option value="lettuce">lettuce</option>
  ...
</select>


nik

Message #7 by "Nikolai Devereaux" <yomama@u...> on Wed, 1 May 2002 11:29:44 -0700
> Jake Cohen pointed a coupls bugs out to me.

er... "couple".

it's going to be a long day.
=)
Message #8 by Peter Simard <pasimard@v...> on Wed, 1 May 2002 14:41:37 -0400
You're gonna have a long day?  Welcome to my world....one thing is,
I'm 3 hours closer to the finish of mine..

Got my bug-spray handy...and eyes are peeled...


Message #9 by Peter Simard <pasimard@v...> on Wed, 1 May 2002 15:48:23 -0400
OK, here's what we have so far:

Almost thre...see bottom

<?php
$recCode = "id3cc4ddb02";
function create_select($name, $options, $default = "")
  {
    $tags = "<SELECT name=\"$name\">\n";

    // http://www.php.net/foreach
    foreach($options as $value => $text)
    {
      $tags .= "  <OPTION value=\"$value\"";

      if($value == $default)
      {
        $tags .= ' SELECTED';
      }

      $tags .= ">$text</OPTION>\n";
    }

    $tags .= "</SELECT>\n";

    return $tags;
  }
//////////////////////////////////////////////////////////////
  function getIngredients2()
{
   $ret = array();

   $result = mysql_query("SELECT ingredient, gross_cost from ingredient") or die( mysql_error());

   if(! $result)
      return $ret;

   while($row = mysql_fetch_array($result))
   {
      $ret[] = $row;
   }

   return $ret;
}
///////////////////////////////////////////////////////////////////
$sql = "SELECT rec_ingredient FROM recipe_ingredient_data WHERE rec_code ='" . $recCode . "'";
$recResult = mysql_query( $sql );


while($ar = mysql_fetch_array( $recResult ))
{
$rec_ings[] = $ar;
}

$ingreds = getIngredients2();
$ing_sel_opts = array();
foreach($ingreds as $ingred)
{
    $ingreds['ingredient'] = $ingred['ingredient'];//
}


$selects[] = array(); // will hold the select dropdowns
$num_ings = count($rec_ings);
for($i = 0; $i < $num_ings; ++$i)
{
    //                                                   name          options   default
    $selects[] = create_select("rec_ings[$i]", $ingreds[$i], $rec_ings[$i]);
        echo( $selects[$i] );
}




?>

******************* Yields this on View Source  ****************
Array<SELECT name="rec_ings[0]">
  <OPTION value="0">butter</OPTION>
  <OPTION value="ingredient">butter</OPTION>
  <OPTION value="1">1.75</OPTION>
  <OPTION value="gross_cost">1.75</OPTION>
</SELECT>
<SELECT name="rec_ings[1]">
  <OPTION value="0">diced carrots</OPTION>
  <OPTION value="ingredient">diced carrots</OPTION>
  <OPTION value="1">2.99</OPTION>
  <OPTION value="gross_cost">2.99</OPTION>
</SELECT>
<SELECT name="rec_ings[2]">
  <OPTION value="0">crumbled ritz crackers</OPTION>
  <OPTION value="ingredient">crumbled ritz crackers</OPTION>
  <OPTION value="1">3.25</OPTION>
  <OPTION value="gross_cost">3.25</OPTION>
</SELECT>
<SELECT name="rec_ings[3]">
  <OPTION value="0">salt</OPTION>
  <OPTION value="ingredient">salt</OPTION>
  <OPTION value="1">3.25</OPTION>
  <OPTION value="gross_cost">3.25</OPTION>
</SELECT>


Message #10 by "Nikolai Devereaux" <yomama@u...> on Wed, 1 May 2002 12:55:14 -0700
Looks like you forgot about the bug Jake noticed.  I didn't fix the whole
thing as I've been distracted here with my own load of work. =)


> $ingreds = getIngredients2();
> $ing_sel_opts = array();
> foreach($ingreds as $ingred)
> {
>     $ingreds['ingredient'] = $ingred['ingredient'];//
> }

The line in the foreach loop should be

$ing_sel_opts[$ingred['name']] = $ingred['name'];


Then below, we have to pass the right array to create_select()

> $selects[] = array(); // will hold the select dropdowns
> $num_ings = count($rec_ings);
> for($i = 0; $i < $num_ings; ++$i)
> {
>     //                       name
>      options   default
>     $selects[] = create_select("rec_ings[$i]", $ingreds[$i],
>                                 $rec_ings[$i]);
>         echo( $selects[$i] );
> }


The create_select line should be this:

  $selects[] = create_select("rec_ings[$i]", $ing_sel_opts, $rec_ings[$i]);

Try patching with these changes and tell me if it works.


Nik

Message #11 by Peter Simard <pasimard@v...> on Wed, 1 May 2002 16:57:45 -0400
latest results...getng rather close here, just not seeing any value
SELECTED unless i provide it as a string in function argument

<?php
include("../../include/phpClasses/MyConnect.php");
include("../../include/functions/functions.inc");//
new MyConnect();
/*
Created on:
Author:
Summary:
Classes;
Functions;

*/
$recCode = "id3cc4ddb02";

$sql = "SELECT rec_ingredient FROM recipe_ingredient_data WHERE rec_code ='" . $recCode . "'";
$recResult = mysql_query( $sql );


while($ar = mysql_fetch_array( $recResult ))
{
$rec_ings[] = $ar;
}

//print_r($rec_ings);
$ingreds = getIngredients2();//grabs cost and ingredient-name data
$ing_sel_opts = array();
foreach($ingreds as $ingred)
{
    $ing_sel_opts[$ingred['ingredient']] = $ingred['ingredient'];
}


$selects[] = array(); // will hold the select dropdowns
$num_ings = count($rec_ings);
for($i = 0; $i < $num_ings; ++$i)
{
    //                                                   name          options   default
        $selects[] = create_select("rec_ings[$i]", $ing_sel_opts, $rec_ings[$i]);
    
        echo( $selects[$i] );
}




?>
*****************************************************************


Sample out-put ( showing one drop-down of 4 )

Array<SELECT name="rec_ings[0]">
  <OPTION value="butter">butter</OPTION>
  <OPTION value="diced carrots">diced carrots</OPTION>
  <OPTION value="crumbled ritz crackers">crumbled ritz crackers</OPTION>
  <OPTION value="salt">salt</OPTION>
  <OPTION value="garlic">garlic</OPTION>
  <OPTION value="potatos">potatos</OPTION>
  <OPTION value="beef">beef</OPTION>
  <OPTION value="Salmon">Salmon</OPTION>
  <OPTION value="cream">cream</OPTION>
  <OPTION value="peanut butter">peanut butter</OPTION>
  <OPTION value="garlic powder">garlic powder</OPTION>
  <OPTION value="ketchup">ketchup</OPTION>
  <OPTION value="farfalle pasta">farfalle pasta</OPTION>
  <OPTION value="Grey Poupon Mustard">Grey Poupon Mustard</OPTION>
  <OPTION value="Worcesteshire Sauce">Worcesteshire Sauce</OPTION>
  <OPTION value="Black Pepper - ground">Black Pepper - ground</OPTION>
  <OPTION value="diced pineapple">diced pineapple</OPTION>
  <OPTION value="Chicken">Chicken</OPTION>
  <OPTION value="Penne Pasta">Penne Pasta</OPTION>
  <OPTION value="red pepper flakes">red pepper flakes</OPTION>
  <OPTION value="ground beef">ground beef</OPTION>
  <OPTION value="Tilapia">Tilapia</OPTION>
  <OPTION value="Olive oil - extra virgin">Olive oil - extra virgin</OPTION>
  <OPTION value="wild rice">wild rice</OPTION>
  <OPTION value="Polenta">Polenta</OPTION>
  <OPTION value="Angel hair pasta">Angel hair pasta</OPTION>
  <OPTION value="Tortellini - cheese filled">Tortellini - cheese filled</OPTION>
  <OPTION value="Caribou tenderloins">Caribou tenderloins</OPTION>
  <OPTION value="Red Deer">Red Deer</OPTION>
  <OPTION value="Mexican cheese mix">Mexican cheese mix</OPTION>
  <OPTION value="Caribbean Shrimp">Caribbean Shrimp</OPTION>
  <OPTION value="Buffalo meat">Buffalo meat</OPTION>
  <OPTION value="Jumbo Lump Crab meat">Jumbo Lump Crab meat</OPTION>
  <OPTION value="Mayonaise">Mayonaise</OPTION>
  <OPTION value="Rigatoni Pasta">Rigatoni Pasta</OPTION>
  <OPTION value="Veal Chops">Veal Chops</OPTION>
  <OPTION value="Pork Loin">Pork Loin</OPTION>
  <OPTION value="Chicken - breast">Chicken - breast</OPTION>
  <OPTION value="Turkey breast">Turkey breast</OPTION>
  <OPTION value="Ham - Virginia">Ham - Virginia</OPTION>
  <OPTION value="flour - bleached">flour - bleached</OPTION>
  <OPTION value="parmesan cheese">parmesan cheese</OPTION>
  <OPTION value="salsa">salsa</OPTION>
  <OPTION value="Human hair">Human hair</OPTION>
  <OPTION value="Dog Hair">Dog Hair</OPTION>
  <OPTION value="Cheese - cheddar">Cheese - cheddar</OPTION>
  <OPTION value="Cheese - monteray jack">Cheese - monteray jack</OPTION>
  <OPTION value="Cheese - swiss">Cheese - swiss</OPTION>
  <OPTION value="Portuguese Roll">Portuguese Roll</OPTION>
  <OPTION value="Lettuce - leaf">Lettuce - leaf</OPTION>
  <OPTION value="Lettuce - romaine">Lettuce - romaine</OPTION>
  <OPTION value="Tomato">Tomato</OPTION>
  <OPTION value="Pickle - spear">Pickle - spear</OPTION>
</SELECT>


Message #12 by "Nikolai Devereaux" <yomama@u...> on Wed, 1 May 2002 14:06:37 -0700
Ah crap, I know what's going on.

> $sql = "SELECT rec_ingredient FROM recipe_ingredient_data WHERE 
> rec_code ='" . $recCode . "'";
> $recResult = mysql_query( $sql );
> 
> 
> while($ar = mysql_fetch_array( $recResult ))
> {
>   $rec_ings[] = $ar;
> }

each item in $reg_ings is an array...  which you must've noticed here:

> //print_r($rec_ings);

So then when we do this:
> $selects[] = array(); // will hold the select dropdowns
> $num_ings = count($rec_ings);
> for($i = 0; $i < $num_ings; ++$i)
> {
>     //                                                   name     
>      options   default
>         $selects[] = create_select("rec_ings[$i]", $ing_sel_opts, 
> $rec_ings[$i]);
>     
>         echo( $selects[$i] );
> }

we really should specify the text value in the default field.

Try this:

$selects[] = create_select("rec_ings[$i]", $ing_sel_opts,
                           $rec_ings[$i]['rec_ingredient']);


nik
Message #13 by "Peter Simard" <peter@p...> on Wed, 1 May 2002 22:25:10
OK--that cleared that up.  one minor bug though:

This -->Array<-- Should be a drop down but as you can see by the output 
here it's being ouput before the first select box, so in this test I'm 
seeing 4 select boxes when i should see 5.

Array<SELECT name="rec_ings[0]">
  <OPTION value="butter">butter</OPTION>
  <OPTION value="diced carrots">diced car
Message #14 by "Nikolai Devereaux" <yomama@u...> on Wed, 1 May 2002 14:24:12 -0700
> OK--that cleared that up.  one minor bug though:
> 
> This -->Array<-- Should be a drop down but as you can see by the output 
> here it's being ouput before the first select box, so in this test I'm 
> seeing 4 select boxes when i should see 5.
> 
> Array<SELECT name="rec_ings[0]">
>   <OPTION value="butter">butter</OPTION>
>   <OPTION value="diced carrots">diced car

You're right -- that's another bug/typo.

Look for this line:

> $selects[] = array(); // will hold the select dropdowns

and change it to this:

$selects = array();

(notice the lack of square braces)



nik
Message #15 by Peter Simard <pasimard@v...> on Wed, 1 May 2002 17:26:35 -0400
Now this shows me the correct boxes and the correct data
pre-selected, however, it doesn't look too kosher.


for($i = 1; $i < $num_ings + 1; $i++)
{
    //                                                   name          options   default
$selects[] = create_select("rec_ings[$i]", $ing_sel_opts, $rec_ings[$i-1]['rec_ingredient']);
    
echo( $selects[$i] );
}


Message #16 by "Peter Simard" <peter@p...> on Wed, 1 May 2002 23:53:13
FYI;

Sample out-put

http://www.mainstreetsrestaurantgroup.com/msc/ud4.php

Message #17 by Peter Simard <pasimard@v...> on Wed, 1 May 2002 19:01:37 -0400
( abstracted functions are below at bottom )

$recCode = "id3cc4ddb02";

$sql = "SELECT rec_ingredient FROM recipe_ingredient_data WHERE rec_code ='" . $recCode . "'";
$recResult = mysql_query( $sql );


while($ar = mysql_fetch_array( $recResult ))
{
$rec_ings[] = $ar;
}

//print_r($rec_ings);
$ingreds = getIngredients2();//grabs cost and ingredient-name data
$ing_sel_opts = array();
foreach($ingreds as $ingred)
{
    $ing_sel_opts[$ingred['ingredient']] = $ingred['ingredient'];
}


$selects[] = array(); // will hold the select dropdowns
$num_ings = count($rec_ings);
for($i = 0; $i < $num_ings ; ++$i)
{
    //                                                   name          options   default
        $selects[] = create_select("$rec_ings[$i]", $ing_sel_opts, $rec_ings[$i]['rec_ingredient']);
    
        print( $selects[$i] );
}

//    functions   *****************
 function getIngredients2()
{
   $ret = array();

   $result = mysql_query("SELECT ingredient, gross_cost from ingredient") or die( mysql_error());

   if(! $result)
      return $ret;

   while($row = mysql_fetch_array($result))
   {
      $ret[] = $row;
   }

   return $ret;
}
//*************************************************
function create_select($name, $options, $default = "")
  {
    $tags = "<SELECT name=\"$name\">\n";

    // http://www.php.net/foreach
    foreach($options as $value => $text)
    {
      $tags .= "  <OPTION value=\"$value\"";

      if($value == $default)
      {
        $tags .= ' SELECTED';
      }

      $tags .= ">$text</OPTION>\n";
    }

    $tags .= "</SELECT>\n";

    return $tags;
  }


Message #18 by "Nikolai Devereaux" <yomama@u...> on Wed, 1 May 2002 16:57:36 -0700

Yeeep, as I thought.  This line is still wrong:

> $selects[] = array(); // will hold the select dropdowns

remove the square brackets:

$selects = array();


lemme know if that doesn't work.

nik
Message #19 by Peter Simard <pasimard@v...> on Wed, 1 May 2002 22:26:53 -0400
That did the trick.  Bravo.  That completely slipped by me.

For clarity sake:
$var = array()//  declares $var to be an array

$var[] = array() //sets this element of an array $var to another
array....?...in this case one that is empty.


The Devil's in the details...

Muchas Gracias


Message #20 by "Peter Simard" <peter@p...> on Thu, 2 May 2002 18:13:41
Nik;

If I change our foreach() loop to:

foreach($ingreds as $ingred)   
{
    $ing_sel_opts[$ingred['ingredient']] = ($ingred['ingredient'] . ":" . 
$ingred['gross_cost']);    
	
}

and tweak create_selects() to this:

 foreach($options as $value => $text)
    {
      $tags .= "  <OPTION value=\"$text\""; //<--- changed to $text from 
$value

So I get this ( sample )
<OPTION value="Cheese - swiss:8.99">Cheese - swiss:8.99</OPTION>
  <OPTION value="Portuguese Roll:0.25">Portuguese Roll:0.25</OPTION>
  <OPTION value="Lettuce - leaf:2.29" SELECTED>Lettuce - 
leaf:2.29</OPTION>


Do you foresee any potential problems?  

This is essntially what I am after here..

Pete  
Message #21 by "Nikolai Devereaux" <yomama@u...> on Thu, 2 May 2002 10:24:49 -0700
Well, a couple things.

"I still think the best solution" would be to have an integer ID field in
your ingredients column, and use that ID as the value of the options.

<SELECT...>
  <OPTION value="0">Swiss Cheese:5.99</OPTION>
  <OPTION value="1">Chicken breasts:2.50</OPTION>
  <OPTION value="2" SELECTED>Human Hair:.01</OPTION>
  ...
</SELECT>


Anyway, you don't need to change "create_select()" at all because that will
limit how useful it is for any other select dropdowns you'd want to create
later.  You control the options array you pass to create_select, if you want
your output to be different, change that options array, not the function!

> If I change our foreach() loop to:
>
> foreach($ingreds as $ingred)
> {
>     $ing_sel_opts[$ingred['ingredient']] = ($ingred['ingredient'] . ":" .
> $ingred['gross_cost']);
>
> }

foreach($ingreds as $ingred)
{
  $both = $ingred['ingredient'] . ':' . $ingred['gross_cost'];
  $ing_sel_opts[$both] = $both;
}


Nik


  Return to Index