PHP Array all possible combinations into SELECT OPTION form drop boxes.

wfninpa
wfninpa used Ask the Experts™
on
Goal: Output HTML drop boxes containing all possible combinations between two arrays values.

In my example arrays below I have a COLOR array and a SIZE array.  I would like the output to look something like this:

Color: Black  Size: S
Color: Black  Size: M
Color: Black  Size: L
Color: Black  Size: XL
Color: Cocoa  Size: S
Color: Cocoa  Size: M
Color: Cocoa  Size: L
Color: Cocoa  Size: XL

Where the above words of "Color:" and "Size:" are just select box labels and the values are just select boxes themselves.  And the "id=" attributes for the select/option tags should correspond to the "[id]" value shown.

For each row of color and size combination I only want the select boxes to have single values, not all available values.

In other words I want my output to look exactly as shown above.  I don't want my users to be able to change the select box values and I'm not interested in using a DISABLE or specifying a default SELECTED value.

Here is my COLOR array:

Array
(
    [0] => Array
        (
            [id] => 2
            [text] => Black
        )

    [1] => Array
        (
            [id] => 63
            [text] => Cocoa
        )
)

Here is my SIZE array:

Array
(
    [0] => Array
        (
            [id] => 2400
            [text] => S
        )

    [1] => Array
        (
            [id] => 878
            [text] => M
        )

    [2] => Array
        (
            [id] => 929
            [text] => L
        )

    [3] => Array
        (
            [id] => 58
            [text] => XL
        )

)

I would be very happy to have my solution today in PHP code of course.  Thanks.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
wfninpa:

Is this data stored in a database?  It would be much simpler and flexible to create what you want in the SQL query if it's in a database.

Aielloj

Author

Commented:
Yes it is but for the sake of not having to change the rest of the world to suit this particular instance as I said I've got two arrays so go with that please.

Thanks.
Freelancer
Top Expert 2010
Commented:
I suggest you to increase points> the code attached is not so simple as one can think ;-)... but it works

Cheers
<?php
echo "<pre>";
function generateCodes($arr) {
    global $returnArray, $tempArray, $pos;
    if(count($arr)) {
        for($i=0; $i<count($arr[0]); $i++) {
            $tmp = $arr;
            $tempArray[$pos] = $arr[0][$i];
            $tarr = array_shift($tmp);
            $pos++;
            generateCodes($tmp);
        }
    } else {
        $returnArray[] = strtoupper(join(" ", $tempArray));
    }
    $pos--;
}

$colors = array("Black", "Cocoa");
$sizes = array("S", "M", "L", "XL");
$values = array($colors, $sizes);
$returnArray = array();
$tempArray = array();
$pos = 0;
generateCodes($values);

foreach($returnArray as $item){
    $i = explode(" ", $item);
    echo "Color: ".$i[0]." Size: ". $i[1] ."<br>";
}

Open in new window

Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Author

Commented:
After the first post I did think that myself.  It's Sunday here so I just didn't feel like walking through and coding it myself. I will take a look at the code posted.  Thanks.
Most Valuable Expert 2011
Top Expert 2016

Commented:
Do you care about the use of the "id" fields in these arrays of arrays?  And regarding this, "I don't want my users to be able to change the select box values" - you should PLAN on having your users change the select box values.  The nice ones won't; the hackers will - it's just that simple.  That kind of planning is basic to application security, and is implemented in the data validation logic of the action script that processes your form input.
Most Valuable Expert 2011
Top Expert 2016

Commented:
Also, are you talking about an HTML drop-down select control or about checkboxes?  And do you need the "id" values submitted or just used to style the HTML?  Do you want single select only or multiple select?   Thanks, ~Ray
Most Valuable Expert 2011
Top Expert 2016

Commented:

<?php // RAY_temp_wfninpa.php
error_reporting(E_ALL);
echo "<pre>";

/* DESCRIPTION OF OUTPUT FROM THE POST AT EE
Color: Black  Size: S
Color: Black  Size: M
Color: Black  Size: L
Color: Black  Size: XL
Color: Cocoa  Size: S
Color: Cocoa  Size: M
Color: Cocoa  Size: L
Color: Cocoa  Size: XL
*/

// TEST DATA FROM THE POST AT EE
// COLOR ARRAY
$colors
= Array
(
    "0" => Array
        ( "id" => 2
        , "text" => "Black"
        )
        ,

    "1" => Array
        ( "id" => 63
        , "text" => "Cocoa"
        )
)
;

// SIZE ARRAY
$sizes
= Array
(
    "0" => Array
        ( "id" => 2400
        , "text" => "S"
        )
        ,
    "1" => Array
        ( "id" => 878
        , "text" => "M"
        )
        ,
    "2" => Array
        ( "id" => 929
        , "text" => "L"
        )
        ,

    "3" => Array
        ( "id" => 58
        , "text" => "XL"
        )

)
;

// DOES THE TEST DATA LOOK RIGHT? - CLOSE ENOUGH!
// print_r($colors);
// print_r($sizes);


// IF THE FORM HAS BEEN SUBMITTED
if (!empty($_POST["thing"]))
{
    // SET DEFAULT VALUES
    $chosen_color = 'UNKNOWN';
    $chosen_size  = 'UNKNOWN';

    // ISOLATE THE COMPONENTS OF THE POSTED DATA
    $arr = explode('-', $_POST["thing"]);
    $my_color = $arr[0];
    $my_size  = $arr[1];

    // LOOK UP THE INFORMATION IN OUR ARRAYS
    foreach ($colors as $key => $color_array)
    {
        if ($color_array["id"] == $my_color) $chosen_color = $color_array["text"];
    }
    foreach ($sizes as $key => $size_array)
    {
        if ($size_array["id"] == $my_size)   $chosen_size  = $size_array["text"];
    }

    // SHOW THE CHOICES
    echo PHP_EOL . "YOU CHOSE COLOR: $chosen_color AND SIZE: $chosen_size";
}

// CREATE THE FORM FROM THE ARRAYS
echo '<form method="post">' . PHP_EOL;
echo '<select name="thing">' . PHP_EOL;
foreach ($colors as $key => $color_array)
{
    foreach ($sizes as $key => $size_array)
    {
        $option
        = '<option value="'
        . $color_array['id']
        . '-'
        . $size_array['id']
        . '">'
        . 'COLOR: '
        . $color_array['text']
        . ' SIZE: '
        . $size_array['text']
        . '</option>'
        . PHP_EOL
        ;
        echo $option;
    }
}
echo '</select>' . PHP_EOL;
echo '<input type="submit" />' . PHP_EOL;
echo '</form>';

Open in new window

Author

Commented:
My apologies if my post was misleading.  I did not mean checkbox when I said select boxes.  No for the multiple select.  Thanks for looking out for me but processing is not a concern because that is locked down already and protected from all sorts of injection.

I do care about the use of the key "id" from the array as it will be the option value:

<select><option id="combo1_color" value="2">Black</option></select>
<select><option id="combo1_size" value="2400">S</option></select>
<input type="text" id="combo1_quantity" name="combo1_quantity" value="0" />

<select><option id="combo2_color" value="2">Black</option></select>
<select><option id="combo2_size" value="878">M</option></select>
<input type="text" id="combo2_quantity" name="combo2_quantity" value="0" />

etc....  Until all possible combinations are displayed.

I have a reason for all of this.  I guess all I really needed was how to get all of the possible combinations and also have access to the key "id" if I decided to use it for anything.  If you're curious I am modifying OSCommerce a little bit to integrate and provide further information regarding a particular products color and size combination with data provided from another table I've created within OSCommerce that is updated every 15 minutes from our CRM and inventory systems.  Basically I will be creating the combinations and then iterating through the loop of combinations with some MySQL SELECT statements inside the loop that will do various things for me.  It's a long and deep explanation as to why.

Anyway, I have been working on this today and have attached what I've come up with (using snippets here and there).

At this point I'm not concerned with code to create my form elements.

I think I've created what I need but possibly you can suggest some things here and there that would make it better.

Thanks.
<?php
    header('Content-Type: text/plain');

    function showCombinations($string, $traits, $i)
    {
        if ($i >= count($traits))
            echo trim($string) . "\n";
        else
        {
            foreach ($traits[$i] as $trait)
                showCombinations("$string $trait", $traits, $i + 1);
        }
    }
    
	// COLORS
	$colors = array
	(
	  array("id" => "72", "value" => "Black"),
	  array("id" => "54", "value" => "White"),
	  array("id" => "62", "value" => "Red"),
	  array("id" => "119", "value" => "Orange"),
	  array("id" => "23", "value" => "Navy"),
	  array("id" => "29", "value" => "Sparky Blue")
	);

	// SIZES
	$sizes = array
	(
	  array("id" => "22", "value" => "S"),
	  array("id" => "115", "value" => "M"),
	  array("id" => "85", "value" => "L"),
	  array("id" => "9", "value" => "XL"),
	  array("id" => "4", "value" => "XXL")
	);

$colorsArr = array();
for ( $row = 0; $row < sizeof($colors); $row++ )
{
 while ( list( $key, $value ) = each( $colors[$row] ) )
 {	
	if ($row2 == 0)
	{  	
	  $row2++;
	} else {
	  echo "$value";  // SCREEN OUTPUT - only display the 2nd index value which is KEY 'value'
	  $colorsArr[] = $value;  // put the value of KEY 'value' into new array
	  $row2 = 0;
	}
 }
 echo "\n";
}
$row = 0;  // reset variable to zero out because I'm paranoid
$row2 = 0;  // reset variable to zero out because I'm paranoid

$sizesArr = array();
for ( $row = 0; $row < sizeof($sizes); $row++ )
{
 while ( list( $key, $value ) = each( $sizes[$row] ) )
 {
	if ($row2 == 0)
	{  	
	  $row2++;
	} else {
	  echo "$value";  // SCREEN OUTPUT - only display the 2nd index value which is KEY 'value'
	  $sizesArr[] = $value;  // put the value of KEY 'value' into new array
	  $row2 = 0;
	}
 }
 echo "\n";
}
$row = 0;  // reset variable to zero out because I'm paranoid
$row2 = 0;  // reset variable to zero out because I'm paranoid

// SCREEN OUTPUT for testing
echo "\n";
echo "New Arrays (without 'id' key)";
echo "\n";
print_r($colorsArr);  // SCREEN OUTPUT of new COLORS only array
print_r($sizesArr);  // SCREEN OUTPUT of new SIZES only array

	// create multidimensional array
	$traits = array
    (
		$colorsArr,$sizesArr
    );
    
    showCombinations('', $traits, 0);
?>

Open in new window

Erdinç Güngör ÇorbacıPHP Development Team Leader

Commented:
Sorry if i got ya wrong ,but i think you want a chained select. I'm not on my production PC now so i can't suggest you a adapted code but this link will do the trick for you i guess.

http://www.yxscripts.com/cs/chainedselects.html

You can populate JS variables which will be injected into <option>

But maybe id deal make you confused. (a tip : you can use option values as joined 2 variables.  )
Most Valuable Expert 2011
Top Expert 2016

Commented:
Did you try the code I posted above?  You can install it and run it to see how the moving parts interoperate.

Regarding this:
<select><option id="combo1_color" value="2">Black</option></select>
<select><option id="combo1_size" value="2400">S</option></select>

You will want to have a SELECT control to wrap around these option tags.  The <select> will contain the name of the key to the POST array.

When it comes to things like this:
<input type="text" id="combo1_quantity" name="combo1_quantity" value="0" />
<input type="text" id="combo2_quantity" name="combo2_quantity" value="0" />

You may want to use an array structure instead of generating unique names.  The resulting code will be much easier to debug, modify and maintain if it is not dependent on variable names.

Here is the code from above, now using the new arrays of colors and sizes.  In the colors and sizes array, I changed the key name from "value" to "text" mainly because it is a "text" string and has no real computer-science meaning as a value - it just provides visual information.

HTH, ~Ray
<?php // RAY_temp_wfninpa.php
error_reporting(E_ALL);
echo "<pre>";

/* DESCRIPTION OF OUTPUT FROM THE POST AT EE
Color: Black  Size: S
Color: Black  Size: M
Color: Black  Size: L
Color: Black  Size: XL
Color: Cocoa  Size: S
Color: Cocoa  Size: M
Color: Cocoa  Size: L
Color: Cocoa  Size: XL
*/

// TEST DATA NEWLY COPIED FROM THE POST AT EE
	// COLORS
	$colors = array
	(
	  array("id" => "72",  "text" => "Black"),
	  array("id" => "54",  "text" => "White"),
	  array("id" => "62",  "text" => "Red"),
	  array("id" => "119", "text" => "Orange"),
	  array("id" => "23",  "text" => "Navy"),
	  array("id" => "29",  "text" => "Sparky Blue")
	);

	// SIZES
	$sizes = array
	(
	  array("id" => "22",  "text" => "S"),
	  array("id" => "115", "text" => "M"),
	  array("id" => "85",  "text" => "L"),
	  array("id" => "9",   "text" => "XL"),
	  array("id" => "4",   "text" => "XXL")
	);

// DOES THE TEST DATA LOOK RIGHT? - CLOSE ENOUGH!
// print_r($colors);
// print_r($sizes);


// IF THE FORM HAS BEEN SUBMITTED
if (!empty($_POST["thing"]))
{
    // SET DEFAULT VALUES
    $chosen_color = 'UNKNOWN';
    $chosen_size  = 'UNKNOWN';

    // ISOLATE THE COMPONENTS OF THE POSTED DATA
    $arr = explode('-', $_POST["thing"]);
    $my_color = $arr[0];
    $my_size  = $arr[1];

    // LOOK UP THE INFORMATION IN OUR ARRAYS
    foreach ($colors as $key => $color_array)
    {
        if ($color_array["id"] == $my_color) $chosen_color = $color_array["text"];
    }
    foreach ($sizes as $key => $size_array)
    {
        if ($size_array["id"] == $my_size)   $chosen_size  = $size_array["text"];
    }

    // SHOW THE CHOICES
    echo PHP_EOL . "YOU CHOSE COLOR: $chosen_color AND SIZE: $chosen_size";
}

// CREATE THE FORM FROM THE ARRAYS
echo '<form method="post">' . PHP_EOL;
echo '<select name="thing">' . PHP_EOL;
foreach ($colors as $key => $color_array)
{
    foreach ($sizes as $key => $size_array)
    {
        $option
        = '<option value="'
        . $color_array['id']
        . '-'
        . $size_array['id']
        . '">'
        . 'COLOR: '
        . $color_array['text']
        . ' SIZE: '
        . $size_array['text']
        . '</option>'
        . PHP_EOL
        ;
        echo $option;
    }
}
echo '</select>' . PHP_EOL;
echo '<input type="submit" />' . PHP_EOL;
echo '</form>';

Open in new window

Most Valuable Expert 2011
Top Expert 2016
Commented:
Now having said all that, a little real-world experience.  

As Aielloj wrote right at the top: Is this data stored in a database?

In real life you will almost certainly be getting this information from a data base, not out of arrays that are hardcoded into your program.  Real-world inventory is keyed by Stock-Keeping Unit Numbers ("Skus").  The Sku is the fungible commodity level.  A shoe that is red and size small will not have the same Sku as a shoe that is red and size medium.  Your inventory can be accurate in real time if you design the application correctly!  That would mean populating your dropdown select lists with only the colors and sizes that you had in uncommitted inventory.

You might want to use two select lists - one for color and one for size.  People tend to think of those as separate selections.  However your programming will need to take into account the possibility that a particular color or size may be depleted.  Here is an example with two select boxes.  You might add a little jQuery to the mix to check the availability of sizes after colors are selected, or vice versa.
<?php // RAY_temp_wfninpa.php
error_reporting(E_ALL);
echo "<pre>";

// TEST DATA COPIED FROM THE POST AT EE
	// COLORS
	$colors = array
	(
	  array("id" => "72",  "text" => "Black"),
	  array("id" => "54",  "text" => "White"),
	  array("id" => "62",  "text" => "Red"),
	  array("id" => "119", "text" => "Orange"),
	  array("id" => "23",  "text" => "Navy"),
	  array("id" => "29",  "text" => "Sparky Blue")
	);

	// SIZES
	$sizes = array
	(
	  array("id" => "22",  "text" => "S"),
	  array("id" => "115", "text" => "M"),
	  array("id" => "85",  "text" => "L"),
	  array("id" => "9",   "text" => "XL"),
	  array("id" => "4",   "text" => "XXL")
	);

// DOES THE TEST DATA LOOK RIGHT? - CLOSE ENOUGH!
// print_r($colors);
// print_r($sizes);


// IF THE FORM HAS BEEN SUBMITTED
if (!empty($_POST))
{
    // SET CHOSEN OR DEFAULT VALUES
    $chosen_color = 'UNKNOWN';
    $chosen_size  = 'UNKNOWN';

    // LOOK UP THE INFORMATION IN OUR ARRAYS
    foreach ($colors as $key => $color_array)
    {
        if ($color_array["id"] == $_POST["c"]) $chosen_color = $color_array["text"];
    }
    foreach ($sizes as $key => $size_array)
    {
        if ($size_array["id"] == $_POST["s"])  $chosen_size  = $size_array["text"];
    }

    // SHOW THE CHOICES
    echo PHP_EOL . "YOU CHOSE COLOR: $chosen_color AND SIZE: $chosen_size";
}

// CREATE THE FORM FROM THE ARRAYS
echo '<form method="post">' . PHP_EOL;

// COLOR
echo '<select name="c">' . PHP_EOL;
echo '<option value="" selected="selected">PLEASE CHOOSE COLOR</option>' . PHP_EOL;
foreach ($colors as $key => $color_array)
{
    $option
    = '<option value="'
    . $color_array['id']
    . '">'
    . 'COLOR: '
    . $color_array['text']
    . '</option>'
    . PHP_EOL
    ;
    echo $option;
}
echo '</select>' . PHP_EOL;

// SIZE
echo '<select name="s">' . PHP_EOL;
echo '<option value=""selected="selected">PLEASE CHOOSE SIZE</option>' . PHP_EOL;
foreach ($sizes as $key => $size_array)
{
    $option
    = '<option value="'
    . $size_array['id']
    . '">'
    . 'SIZE: '
    . $size_array['text']
    . '</option>'
    . PHP_EOL
    ;
    echo $option;
}
echo '</select>' . PHP_EOL;

echo '<input type="submit" />' . PHP_EOL;
echo '</form>';

Open in new window

Author

Commented:
Exact solution not provided.  
Most Valuable Expert 2011
Top Expert 2016

Commented:
If you have a question, EE is a good place to get answers, and you have gotten complete answers, and more, to this question.  

But it's been hanging around since October!  If you want an exact solution (one that works seamlessly in your servers) then you need to hire a professional developer to create your solution.  Volunteers here at EE cannot do that because we do not have access to your servers and data model.

Best of luck with your project, ~Ray

Author

Commented:
PLEASE CLOSE THIS.  THE QUESTION WAS NOT ANSWERED FULLY OR CORRECTLY AND I'M NO LONGER IN NEED OF THE ANSWER.
Most Valuable Expert 2011
Top Expert 2016

Commented:
Complete, correct and easy-to-understand answers were posted here.   These answers contained tested and working code snippets.  ID:34136499.  ID:34136839.  I do not know what you expected beyond these exact solutions.  All we had to work with are the examples you posted.  Can you please explain why you marked the grade down to the lowest possible grade you can give at EE?  And please tell us why anyone should try to help you next time?  Thanks. ~Ray
Commented:
Yes, the answers provided with the code snippets do work for you.  marqusG's snippet on 10/17 came the closest by outputing all possible combinations of colors and sizes but dropped the 'id' in the arrays.

You either overlooked or ignored the examples I provided and responses to the questions you asked me.

Most of your responses were suggestive that I do things a different way that would ultimately require changing other things (the way oscommerce builds/fills select options in the product_details.php page).  I did mention what I wanted to do and what I did not want to do in the initial post.

In the grand scheme of things I was building a multidimensional array with color and size options and al of their 'id' values.
With this multidimensional array I am looping through it and querying a table in the oscommerce database that is populated by an outside source (navision).  This table contains a style#, description, size, color, and other fields.
So if I have a match for style#, size, and color I will allow the combination to be displayed or not displayed and it could be out of stock, discontinued, back order, doesnt exist, or whatever I want it to be determined by 'other fields'.

Maybe I wasn't clear enough and if that is the case please accept my apologies.

I will see what can be done about the points and the grade.  The answers do deserve a better grade and others like marqusG deserve some points as well.


Author

Commented:
Everyone was helpful.  Thank you.
Erdinç Güngör ÇorbacıPHP Development Team Leader

Commented:
"And please tell us why anyone should try to help you next time? " .... is a very good question for all the people like this asker. None of these people needs your points, but expecting their work to be considered is everyone's right i think.

P & L  

Commented:
I concur with erdincgc.

Your comment "Most of your responses were suggestive that I do things a different way that would ultimately require changing other things (the way oscommerce builds/fills select options in the product_details.php page).  I did mention what I wanted to do and what I did not want to do in the initial post." was totally unappreciative of the efforts to help you with your project, thus I stopped assisting on this question.  I saw that response as a predictor of how the rest of your responses would be like.  Unfortunately I was correct in my assessement.  Most of the names of the experts that responded to you are very familiar to me, and I have a great respect for their opinions which was lacking in your responses.  There are certain people I don't bother to respond to their posts.  Unfortunately I'll be adding your name to that list.

This could have been done very simply with a SQL query and such was suggested.  It would have been the shortest and most reliable way to get this accomplished as opposed to the hand coded solution you insisted on.  We're not here to tell you what you want to hear, but to offer suggestions as to the best way to get things done.  Having customized many open source software packages, it's possible to do things efficiently, and in my opinion correctly, if you're open to some of the suggestions made.

AielloJ

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial