Wrox Programmer Forums
Go Back   Wrox Programmer Forums > PHP/MySQL > Beginning PHP
|
Beginning PHP Beginning-level PHP discussions. More advanced coders should post to the Pro PHP forum.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the Beginning PHP section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old December 28th, 2003, 07:52 PM
Registered User
 
Join Date: Dec 2003
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Default Arrays & Form Fields

Good Evening,
I have two separate arrays, one contains alpha-numeric information and the other is the names associated with the previous field. I would like to have the webpage auto refresh and populate the 2nd field with the name. I have been playing with the onChange that is with the "select" section of the form. So far I have been learning what does not work.
I have succeeded in getting the form to write the correct information to a new page. Is it possible to get the page to refresh with the info?

Thanks for the help.

 
Old December 29th, 2003, 06:14 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

You don't need to reload the page to get the second dropdown to work. You can change the contents of a dropdown on-the-fly with JavaScript.

The problem with your refresh approach is that your page will need the second dropdown populated in the HTML. You can do this with PHP.

I'll summarize both ways of doing it:

Completely client side -- one request:

PHP generates the javascript code to automatically change the options list of the second dropdown. PHP needs to know ahead of time what ALL the options are, so that it can generate the proper javascript code to populate the options arrays.

Once the page is loaded, and the user changes something from the first dropdown, the onChange event runs a javascript function that changes the options list of the second dropdown automatically. No further requests of the server are made.


[b]Client/Server -- multiple requests:

The OnChange event of the first dropdown submits a form with the value of the first dropdown. PHP gets this value and re-generates the HTML page, populating the second dropdown with the values corresponding to the submitted value.


I'll give a brief example of both versions. Suppose you had two lists, colors and fruits. The "Red" fruits are "Apple", "Tomato", and "Pomegranate". The "Green" fruits are "Kiwi" and "Grape". The only "Yellow" fruit is "Banana".

When the user selects a color from the first dropdown, the second dropdown is populated with the fruits corresponding to the color selected.


In the first model, you'd have PHP generate ALL the javascript code required to change the second dropdown without making any new requests of the server. Here is the javascript code that I'd use to do this.

// This is a handy function that empties a select dropdown's options
function clearOptions(selectObject)
{
    if(document.layers)
    {
        selectObject.options.length = 0;
    }
    else
    {
        selectObject.innerHTML = "";
    }
}

function opt(value, text)
{
    this.text = text;
    this.value = value;
}

var fruits = new Array();

fruits["Red"] = new Array();
fruits["Green"] = new Array();
fruits["Yellow"] = new Array();

fruits["Red"].push(new opt("Apple", "Apple"));
fruits["Red"].push(new opt("Tomato", "Tomato"));
fruits["Red"].push(new opt("Pomegranate", "Pomegranate"));
fruits["Green"].push(new opt("Kiwi", "Kiwi"));
fruits["Green"].push(new opt("Grape", "Grape"));
fruits["Yellow"].push(new opt("Banana", "Banana"));


// This is the function that will actually change the options list
// of the second dropdown based on the selected value of the first.
function sync_fruits(colorSelect, fruitSelect)
{
    var id = colorSelect[colorSelect.selectedIndex].value;
    var name = colorSelect[colorSelect.selectedIndex].text;

    clearOptions(fruitSelect);

    if (id == 0)
    {
        fruitSelect.options[0] = new Option('Select a color', 0);
        fruitSelect.disabled = true;
        fruitSelect.size = 1;
    }
    else
    {
        var colorFruits = fruits[id];
        for (var i in colorFruits)
        {
            fruitSelect.options[fruitSelect.options.length] = new Option(colorFruits[i].text, colorFruits[i].value);
        }
        fruitSelect.disabled = false;
    }
}


In your first <select> field, set the onChange to

onChange="javascript:sync_fruits(this, document.<form name>.<fruit select name>);"

where <form name> is the name of your form, and <fruit select name> is the name of your 2nd select input field. For example:

<form name="my_form" method="get" action="whatever.php">
Select a color:
<select name="color_field"
         onChange="javascript:sync_fruits(this, document.my_form.fruit_field);">
    <option value="0">Select a color</option>
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Yellow">Yellow</option>
</select>
Select a fruit:
<select name="fruit_field" disabled="true">
    <option value="NULL">Select a color first</option>
</select>
</form>



Remember -- the code above is what you'll output from PHP. For example:

<?php

// generate the javascript array initializations

$query = "SELECT color, fruit FROM fruit_table";
$result = mysql_query($query);

$fruits = array();
while($row = mysql_fetch_array($result))
{
    $fruits[$row['color']][] = $row['fruit'];
}

/* The above code will create a nested array of this form:
$fruits: Array
(
[Red] => Array
(
     [0] => Apple
     [1] => Tomato
     [2] => Pomegranate
)
[Green] => Array
(
     [0] => Kiwi
     [1] => Grape
)
[Yellow] => Array
(
     [0] => Banana
)
)

*/

echo "var fruits = new Array();\n";
echo "\n";

// output color declarations first
foreach($fruits as $color => $cfruits)
{
    echo "fruits[\"{$color}\"] = new Array();\n";
}

// now populate each fruit
foreach($fruits as $color => $cfruits)
{
echo "\n";
foreach($cfruits as $fruit)
{
     echo "fruits[\"{$color}\"].push(new opt(\"{$fruit}\", \"{$fruit}\"));\n";
}
}

?>



For the client-server model, you won't have any additional javascript code outside of your onChange event. The onChange event should just submit the form. The PHP page receiving the form must then determine what needs to happen next -- Is the form being submitted because the first dropdown selection changed, or is the form being submitted because the user filled out all the fields?

You can use a hidden form field to make things easier on the PHP side. The value of the hidden field will be something like "User Submit" by default. The onChange of a select dropdown can change this value to something to let the PHP script know that the form was submitted as the result of an onChange. In our example, we can set this value to be "Color Change".

<form name="my_form" method="post" action="my_form.php">
<input type="hidden" name="why_submit" value="User Submit" />
<select name="color_field"
         onChange="javascript:document.myform.why_submi t.value='Color Change';document.my_form.submit();">
    <option value="Red">Red</option>
    <option value="Green">Green</option>
    <option value="Yellow">Yellow</option>
</select>
<select name="fruit_field" disabled="true">
     <option value="0">Select a color first.</option>
</select>
</form>


The above HTML form would be generated by your PHP script. Your PHP script should check for the existence of $_POST so it can pre-populate the form fields with any data the user already submitted. If $_POST['color_field'] is set, then you can generate the appropriate selections for the fruit_field as well.

<?php

// Generate the fruit options for a specified color:
if (isset($_POST['color_field']))
{
    $query = "SELECT fruit FROM fruits WHERE color='{$_POST['color_field']}'";
    $result = mysql_query($query);

    while ($row = mysql_fetch_array($result))
    {
        echo " <option value=\"{$row['color']}\">{$row['color']}</option>\n";
    }
}



Keep in mind that none of this code was tested -- I typed it all into the reply textarea directly, so YMMV. Also, there's a lot of code missing from these examples, but that's intentional -- you should have enough code to start with and enough description to figure out the rest and fill in the blanks.

Figuring the rest out for yourself will be a lot more valuable to you than just getting a completely working solution.


Take care,

Nik
http://www.bigaction.org/
 
Old December 29th, 2003, 08:18 PM
Registered User
 
Join Date: Dec 2003
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Nik,
Oh fudge, here I thought that I would be able to get this done. This is a little more detailed than I thought it would be. I appreciate your comments and contribution. I do have the "Beginning Javascript" book and started reading it again when I had this issue. As a matter of fact I am reading it now.

Thanks,
Ron

 
Old December 29th, 2003, 09:00 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

It's not really that difficult, though I imagine my super-long post looks overwhelming.

Here's a fully-functional version of the script using method 1:

<?php // Auto-updating select boxes tutorial sample

// First, we create an array that holds all the data we're going to display
// in our select boxes. In this array, the first level of indexing represents
// the values that will be in the first select dropdown.
// The second level of nesting contains the items found in the second dropdown
// that correspond to the selected index of the first dropdown.
$fruits = array("Red" => array("Apple", "Tomato", "Pomegranate"),
                "Green" => array("Grape", "Kiwi", "Bell Pepper"),
                "Yellow" => array("Banana")
               );

?>
<html>
<head>
  <title>Select Box Prepopulating</title>
<script language="javascript">
<!-- Hide from old browsers

// This is a handy function that empties a select dropdown's options
function clearOptions(selectObject)
{
    if(document.layers)
    {
        selectObject.options.length = 0;
    }
    else
    {
        selectObject.innerHTML = "";
    }
}

function opt(value, text)
{
    this.text = text;
    this.value = value;
}


<?php

echo "var fruits = new Array();\n";

foreach ($fruits as $color => $fruits_of_that_color)
{
    echo "\n";
    echo "fruits[\"{$color}\"] = new Array();\n";
    foreach ($fruits_of_that_color as $fruit)
    {
        echo "fruits[\"{$color}\"].push(new opt(\"{$fruit}\", \"{$fruit}\"));\n";
    }
}

?>

// This is the function that will actually change the options list
// of the second dropdown based on the selected value of the first.
function sync_fruits(colorSelect, fruitSelect)
{
    var id = colorSelect[colorSelect.selectedIndex].value;
    var name = colorSelect[colorSelect.selectedIndex].text;

    clearOptions(fruitSelect);

    if (id == 0)
    {
        fruitSelect.options[0] = new Option('Select a color', 0);
        fruitSelect.disabled = true;
        fruitSelect.size = 1;
    }
    else
    {
        var colorFruits = fruits[id];
        for (var i in colorFruits)
        {
            fruitSelect.options[fruitSelect.options.length] = new Option(colorFruits[i].text, colorFruits[i].value);
        }
        fruitSelect.disabled = false;
    }
}



// -->
</script>
</head>
<body>

<form name="FruitForm" method="get" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Select a fruit color:
  <select name="color_field" onChange="javascript:sync_fruits(this, document.FruitForm.fruit_field);">
    <option value="0">Select a color</option>
<?php
foreach($fruits as $color => $fruits_of_that_color)
{
    echo " <option value=\"{$color}\">{$color}</option>\n";
}
?>
  </select>
  <br />
  Select a fruit of that color:
  <select name="fruit_field" disabled="true">
    <option value="0">Select a color first</option>
  </select>
</form>

</body>
</html>


It's not my favored style of coding -- I don't like jumping in and out of PHP and HTML blocks, but it's the best way to illustrate what role PHP plays in generating the javascript and HTML input fields, and what's not really dynamic about it.

You should compare the contents of the script with the output to get a better idea of what the script is doing (i.e. View Source).



Take care,

Nik
http://www.bigaction.org/
 
Old December 29th, 2003, 09:25 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Just for kicks, here's a fully-functional version using the other method (minimal javascript, multiple requests, and PHP logic):


<?php // Auto-updating select boxes tutorial sample

// First, we create an array that holds all the data we're going to display
// in our select boxes. In this array, the first level of indexing represents
// the values that will be in the first select dropdown.
// The second level of nesting contains the items found in the second dropdown
// that correspond to the selected index of the first dropdown.
$fruits = array("Red" => array("Apple", "Tomato", "Pomegranate"),
                "Green" => array("Grape", "Kiwi", "Bell Pepper"),
                "Yellow" => array("Banana")
               );

// This function will return the previously-submitted value of the current
// form field if it was submitted, or an empty string otherwise.
function getFieldValue($fieldName)
{
    return isset($_GET[$fieldName])? $_GET[$fieldName] : "";
}


echo "<html>\n";
echo "<head>\n";
echo " <title>Select Box Prepopulating</title>\n";
echo "<script language=\"javascript\">\n";
echo "<!-- Hide from old browsers\n";
echo "\n";
echo "function submit_form(hidden_value)\n";
echo "{\n";
echo " document.FruitForm.why_submit.value = hidden_value;\n";
echo " document.FruitForm.submit();\n";
echo "}\n";
echo "\n";
echo "// -->\n";
echo "</script>\n";
echo "</head>\n";
echo "<body>\n";


if (isset($_GET['why_submit']) && ($_GET['why_submit'] == "User Submit"))
{
    echo "Thanks for submitting the form!\n";
    echo "You selected a {$_GET['color_field']} fruit.\n";
    echo "You selected: {$_GET['fruit_field']}.\n";
}
else // need to regenerate form
{
    $color_val = getFieldValue("color_field");

    echo "<form name=\"FruitForm\" method=\"get\" action=\"{$_SERVER['PHP_SELF']}\">\n";

    // Need the hidden form field:
    echo " <input type=\"hidden\" name=\"why_submit\" value=\"User Submit\" />\n";
    echo" Select a fruit color:\n";

    // Color dropdown:
    echo " <select name=\"color_field\" onChange=\"javascript:submit_form('Color Change');\">\n";
    echo " <option value=\"0\">Select a color</option>\n";

    foreach($fruits as $color => $fruits_of_that_color)
    {
        $selected = ($color_val == $color)? " selected=\"true\"" : "";
        echo " <option value=\"{$color}\"{$selected}>{$color}</option>\n";
    }

    echo " </select>\n";

    echo " <br />\n";

    // Fruit dropdown:
    echo " Select a fruit of that color:\n";

    if (($color_val == "") || ($color_val == "0")) // no color selected, output empty list
    {
        echo " <select name=\"fruit_field\" disabled=\"true\">\n";
        echo " <option value=\"0\">Select a color first</option>\n";
    }
    else // color selected, populate dropdown with appropriate fruits:
    {
        echo " <select name=\"fruit_field\">\n";
        foreach ($fruits[$color_val] as $fruit)
        {
            echo " <option value=\"{$fruit}\">$fruit</option>\n";
        }
    }
    echo " </select>\n";
    echo " <br />\n";
    echo " <input type=\"submit\" name=\"submit_field\" value=\"Submit\" />\n";
    echo "</form>\n";
}
echo "</body>\n";
echo "</html>\n";
?>


Take care,

Nik
http://www.bigaction.org/
 
Old October 12th, 2006, 11:12 PM
Registered User
 
Join Date: Oct 2006
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Sorry to drag this forum topic back up but I found it perfect for solving an issue I was having.
I have a can-it-be-done question that goes like this:
Is it possible to populate the options value field in each select box with an ID number drawn from the database while keeping the display for each option at something more useful to the user like the name? form output:
Code:
<option value="0">Select a fruit</option>
<option value="9005">apple</option>
<option value="9006">cherry</option>
This would be useful when posting to the database. I'm not very good at arrays and I think paired values might make it impossible? Any help is much appreciated.





Similar Threads
Thread Thread Starter Forum Replies Last Post
copy fields from Form to new form - openargs justabeginner Access VBA 1 February 4th, 2007 01:28 PM
CSS & Form Fields kwilliams CSS Cascading Style Sheets 2 May 17th, 2006 09:06 AM
Arrays & Variables? ldoodle Classic ASP Basics 0 February 5th, 2006 05:28 PM
How many control arrays can be placed in a form ramk_1978 Beginning VB 6 3 February 21st, 2005 07:57 AM
Arrays in Database fields JeffMM Classic ASP Databases 2 March 26th, 2004 07:27 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.