I'm working on a php form with some validation rules.
If some of the fields are left blank that are require the form will report and error message and ask the user to complete the field.
The form currently keeps the values of the $_POST data so that if errors occur the data which is in the field remains.
I am having a problem with two fields(drop down lists) which are populated with data from a database.
If I complete these fields but there is a error elsewhere the form displays with the values in the drop down list but when I correct the errors and try submit the form it tells me that the drop down list fields are empty.
Here is the code for them
<! Drop Down Menu to get student names from database !>
<SELECT NAME=studentName >
<OPTION VALUE=0 selected="selected" >
<?php if(isset($_POST['studentName'])) echo $_POST['studentName'];?>
<?php echo $options1?>
</SELECT>
Any idea's why this is happening?
For starters, <option value=0 selected="selected"> means that option 0 will always be selected.
You could do something like the following, excuse me if this snippet has bugs, but it should give you a general idea of how you could achieve what you want to:
<?php
$myOptions = array(
'0' => ' --- nothing selected ---',
'1' => 'Apples',
'2' => 'Bananas',
// ...
);
?>
<select name="studentName">
<? php
foreach($myOptions as $key => $value ) {
$selected = isset($_POST['theOption']) && $_POST['theOption'] == $key ? 'selected="selected"' : "";
echo '<option value="' . $key . '" '. $selected . '>' . $value . "</option>";
}
?>
</select>
You can cleanup the above a bit using the alternative PHP syntax:
http://php.net/manual/en/control-structures.alternative-syntax.php
This isn't part of your bug, but just a good practice consideration, some of your HTML tags and their attributes are uppercase, and it's common nowadays to use lowercase. It's more standard this way.
You shouldn't echo $_POST['studentName']; you should check it against the value of each of your options (which should be an array in PHP, which you convert to a list of <option>s in a foreach loop), and set the selected attribute if it matches.
On a sidenote, your HTML is invalid; some attributes are not quoted, and a comment should be in <!-- ... -->, not <! ... !>.
Related
An option value is taken from the database and included in a select box along with other options. How can I set the value taken from the database as selected?
The value from the database is set as $row['value'] and equals s. In HTML the options look like so...
<select name="select">
<option value='xxs'>Extra, Extra small</option>
<option value='xs'>Extra small</option>
<option value='s'>Small</option>
<option value='m'>Medium</option>
<option value='l'>Large</option>
<option value='xl'>Extra Large</option>
<option value='xxl'>Extra, Extra small</option>
</select>
What I want is the $row['value'] (Small) option to be displayed on page load... Is this possible?
The good news is, this is possible and in PHP is quite simple really. First we put all of our options and their respective values in an array like so:
<?php
$options=array('Extra, Extra small'=>'xxs','Extra small'=>'xs','Small'=>'s','Medium'=>'m','Large'=>'l','Extra Large'=>'xl','Extra, Extra Large'=>'xxl');
Follow this by opening the select box and calling upon the options array in a foreach loop...
echo '<select>';
foreach($options as $view=>$value){
As you may have noticed the array contains fields that look like 'Large'=>'l' and the for each loop is calling upon the options as $view=>$value. $view represents the name field, in this case 'Large' and $value represents the value field 'l'. This is important if you expect the user to see different options in the select box than what the values are set at.
Next we create the variable $selected which is going to be used to determine if there is a match between $row['value'] and $value...
$selected=($row['value'] == $value)? "selected" : "";
This is the same as using an if and else statement to set the variable, but shorter. The first section after the variable is asking if $row['value'] is equal to $value, if it does then $selected="selected" else (:) $selected is set to blank.
Next we include the options. Because it is in the foreach loop, we only need one line to insert all of the options...
echo '<option '.$selected.' value="'.$value.'">'.$view.'</option>';
Remember the $selected variable in the last step? Each time the foreach loop goes through a section of the options array set at the beginning, it checks to see if $row['value'] equals $value. If it does then $selected will be set as selected and that particular option will be the one that is shown on page load. It continues through the rest of the array until all views and values have been scanned and returns their respective options.
Finally we close the foreach loop and the select box...
}
echo '</select>';
And there you have it, an automatic way to make a select box option set as selected. A similar pattern can be used for check-boxes, radio selectors, tabs and more.
The full code...
<?php
$options=array('Extra, Extra small'=>'xxs','Extra small'=>'xs','Small'=>'s','Medium'=>'m','Large'=>'l','Extra Large'=>'xl','Extra, Extra Large'=>'xxl');
echo '<select>';
foreach($options as $view=>$value){
$selected=($row['value'] == $value)? "selected" : "";
echo '<option '.$selected.' value="'.$value.'">'.$view.'</option>';
}
echo '</select>';
Given this array, and this value to be the selected value...
$options = array(
'Extra, Extra small' => 'xxs',
'Extra small' => 'xs',
'Small' => 's',
'Medium' => 'm',
'Large' => 'l',
'Extra Large' => 'xl',
'Extra, Extra Large' => 'xxl'
);
$selected = 'm'; // $selected can be swapped for $row['value'] as in the OP
There are several ways to dynamically construct the option tags inside of a <select> and set the selected attribute on one of them.
First the one-liner inside a foreach loop:
echo "<select name=\"select\">";
foreach($options as $text=>$value){
echo "<option value=\"$value\"" , ($selected == $value ? " selected" : "") , ">$text</option>";
}
echo "</select>";
This code block uses a ternary conditional operator aka conditional operator aka shorthand if/else aka inline conditon. Go here for further reading and examples.
By using double quotes " you avoid having to toggle back and forth between literal strings and variables. *You will have to escape double quotes that are nested inside of the string by prepending \. *Variables can be wrapped in curly brackets to isolate their variable name from the surround text. *Single quotes will not echo the value of the variable.) For continued read about quoting: reference
By using , (commas) instead of . (dots) to concatenate the string, performance is increased. one benchmark
By only adding a space before the selected attribute in the true condition (versus adding the space outside the condition on every iteration), you avoid creating unnecessary spaces inside your tag.
By using an inline condition statement, you avoid unnecessarily declaring a variable into the global scope. If you declare the selected string as a variable, as #independent.guru does, it will be declared/overwritten and used only once on every iteration; this can only decrease performance.
Each programmer will have their own preferences about "readability", "brevity", "consistency", and "performance" and may elect to construct their html using any mixture of the above techniques.
As a general rule, I don't bother to declare a variable that I will only use once. In my personal preference hierarchy, brevity, consistency, and performance always come before readability.
Some of the above points may seem like micro-optimizations, but for a canonical question, it is reasonable to include discussion on performance as any of the listed methods may be copy-pasted directly into projects.
If the first code block was too compact, here are two other versions that spread out the method over multiple lines without generating any extra variables:
Separated shorthand if/else syntax:
echo "<select name=\"select\">";
foreach($options as $text => $value){
echo "<option value=\"$value\"";
echo $selected == $value ? " selected" : "";
echo ">$text</option>";
}
echo "</select>";
Standard if conditional:
echo "<select name=\"select\">";
foreach($options as $text => $value){
echo "<option value=\"$value\"";
if($selected == $value){
echo " selected";
}
echo ">$text</option>";
}
echo "</select>";
All of the above versions of the same method will create this rendered html:
When the page is loaded:
When the select element is opened:
The source code will look like this:
<select name="select"><option value="xxs">Extra, Extra small</option><option value="xs">Extra small</option><option value="s">Small</option><option value="m" selected>Medium</option><option value="l">Large</option><option value="xl">Extra Large</option><option value="xxl">Extra, Extra Large</option></select>
This is the source code tabbed out for easier reading:
<select name="select">
<option value="xxs">Extra, Extra small</option>
<option value="xs">Extra small</option>
<option value="s">Small</option>
<option value="m" selected>Medium</option>
<option value="l">Large</option>
<option value="xl">Extra Large</option>
<option value="xxl">Extra, Extra Large</option>
</select>
Let's say I have a photo upload system where the user have to set a category for each album to get the basics for a nice and clean search functionality. But if an user is changing now a value like this:
<select>
<option value="">Choose a Category</option>
<option value="Holiday">Holiday</option>
</select>
to this:
<select>
<option value="">Choose a Category</option>
<option value="Holiday">Something Stupid</option>
</select>
is "something stupid" entered into the database.
That's why I have to do a server side check. But I don't know how to get all the correct values of the option fields to compare it with the posted value.
So my first considerations were the following:
PHP:
// Get all values of the option fields
// Push all the values into an array
if (in_array('foo', $array)) {
// foo is in the array
}
Thank you for helping.
Ok, so I think I guessed what you tried to tell.
You should not have the tags hardcoded in your list.php file, but instead have an array there. That way, you can use it both for generating the select field, but also for the verification. However, generally a database table with the categories would be preferable.
path/list.php
return array(
'1' => 'Name of Ctg 1',
'2' => 'Name of Ctg 2'
);
Here you generate the select
<select name="whatever">
<?php
$options = include('path/list.php');
foreach($options as $id => $name) {
echo '<option value="' . $id . '">' . $name . '</option>';
}
?>
</select>
And how to verify it then in the "target" page
$options = include('path/list.php');
if(!array_key_exists( $valueFromUser, $options ) ) {
// invalid option
}
When the data is posted from the page containing the select tag, it will be in the $_REQUEST array, if you run this php in catcher php page:
foreach ($_REQUEST AS $key => $value) echo "$key = $value <br>";
you will see the results from your list.php.
I'm having a bit of a confusing question but hopefully you'll get what I mean:
In my website I'm trying to implement a select box which is updated based on the value from a previous select box. For that I'm using a javascript that takes the values. For example an option from the select box looks like this:
<option value="22"> Apple </option>
I need the value in order to filter the select boxes but in my PHP script I need to get that 'Apple' text. Is there a way to do that?
Sorry for the noob question but web development is new for me.
Edit:
This is the java script I'm using for filtering the second select box:
$("#select1").change(function() {
if ($(this).data('options') == undefined) {
/*Taking an array of all options-2 and kind of embedding it on the select1*/
$(this).data('options', $('#select2 option').clone());
}
var id = $(this).val();
var options = $(this).data('options').filter('[value=' + id + ']');
$('#select2').html(options);
});
If I try to change this 'value' in the filter function to some other attribute it doesn't work for some reason. I don't know JavaScript at all.
Try this
var pName = document.getElementById('selectname');
var name = pName.options[pName.selectedIndex].text;
Send the name value to your php script by hidden form field or ajax request,
It will contain the text of the option
try this
function getSelectedText(elementId) {
var elt = document.getElementById(elementId);
if (elt.selectedIndex == -1)
return null;
return elt.options[elt.selectedIndex].text;
}
var text = getSelectedText('test');
or
this.options[this.selectedIndex].innerHTML
fruits_array.php
<?php
$fruits= array(
22 => 'apple' ,
23 => 'orange'
);
form_handler.php
if( isset($_POST['chosen_fruit']) && (int)$_POST['chosen_fruit'] > 0 ){
include 'fruits_array.php';
echo you chose ' . $fruits[$_POST['chosen_fruit'];
}
pick_your_fruit.php
<form action='form_handler.php' method= POST>
<select name='chosen_fruit'>
<?php
include 'fruits_array.php';
foreach($fruits as $key=$fruit)
echo '<option value=' . $key . '>' . $fruit .'</option>' . PHP_EOL ;
?>
<input type=submit />
</form>
Give this a try. Maintain an array of fruit in one place. Include it where you need it. If necessary that array could be from a database.
Use the array to
generate the form elements
generate the message
But, essentially, transferring the number of the key between the form and the form handler eases the thorny question of validating the incoming data.
DRY. Dont Repeat Yourself. Now if you have 99 fruit, and you add another, you only add it in one place.
(the main thing missing is the handling of a fruit number which does not exist, which probably means someone is tampering with you input form, leave that for another question, eh?)
Try like this
<form method="post" action="getvalue.php">
<select name="fruit">
<option value="">select the option</option>
<option value="1">Apple</option>
<option value="2">Banana</option>
<option value="3">Mango</option>
</select>
</form>
<?php
$option = array('1'=>'Apple','2'=>'Banana','3'=>'Mango');
echo $option[$_POST['fruit']];
?>
The Apple is not passed to the server, only your value, in this case 23. You can see that when you change your formular method to GET, it will look like script.php?some_select=23.
Two solutions to solve it:
The first one (the easy one) would be:
<option value="Apple" data-filterid="22"> Apple </option>
And in your js:
var options = $(this).data('options').filter('[data-filterid=' + id + ']');
So you get Apple in your php script instead of 22. You could then filter it in javascript by accessing data-filterid instead of value.
The second solution would be to store an associative dictionary which maps the value to the number, e.g.:
<?php
$mapped = array(22 => "Apple", 23=>"Orange");
$value = $mapped[$_GET['option_name']];
here I have stupid question, hope you can help me.
I create a menu using Select element and option like this:
<option selected="selected">Select type...</option>
<option value="1">Doctor</option>
<option value="2">Patient</option>
and every time I need to pick one value from this menu and use the submit button next to it to transfer data.
But every time the page refreshed, this menu will reveal: Select type...
I want it to reveal the value I chose last time, but don't know how.
Many thanks in advance!!
You'll want to move that selected="selected" onto the selected option.
Doing so in PHP isn't too rough. Just check the $_POST or $_GET (however you sent the form) value for your select box, such as $_POST["selectBox"] for each value down the list. When you find a match, echo out the selected="selected" string there. If the value was empty, output it on your default value.
The easiest way to achieve this is to populate the <select> options in an array, then loop through it to display the <option> list and mark them as selected is the $_POST variable matches the correct value:
<?php $myselect = array(1=>'Doctor', 2=>'Patient'); ?>
<select name="myselect">
<option>Select type...</option>
<?php foreach ($myselect as $value => $label): ?>
<option value="<?php echo $value; ?>"<?php if (isset($_POST['myselect']) && $_POST['myselect'] == $value) echo ' selected'; ?>>
<?php echo $label; ?>
</option>
<?php endforeach; ?>
</select>
<select name="myselect">
<?php
$myselect = array('Select type...','Doctor','Patient');
for($i=0; $i<=2; $i++){
echo "<option value=\"{myselect[$i]}\"";
if (isset($_POST['myselect']) && $_POST['myselect'] == $myselect[$i]){
echo 'selected=\"selected\"';
}
echo ">{$myselect[$i]}</option>";
}
?>
</select>
You have to use the server-side language of you choice to store the selected value in a database, xml or text file.
Edit : I think I may have misunderstood your question.
There are a few ways to do this.
On submit you can save that value as a $_SESSION value and use that to set the select on page load.
Using Javascript you can either set a cookie on change or alter the url to add a parameter (url?selecttype=1) and set that on page load using PHP.
There's a good use of cookies in JS on quirksmode: http://www.quirksmode.org/js/cookies.html
You need to change which one is selected to match the request....
function create_select($properties, $opts)
{
$out="<select ";
foreach ($properties as $propname=>$propval) {
$out.=" $propname='$propval'";
}
$out.=">\n";
foreach ($opts as $val=>$caption) {
$out.="<option value='$value'";
if ($_REQUEST[$properties['name']]==$val) $out.=" SELECTED";
$out.=">$caption</option>\n";
}
$out.="</select>";
return $out;
}
print create_select(array('name'=>'direction',
'id'=>'direction',
'class'=>'colourful',
'onChange'=>''),
array('N'=>'North',
'S'=>'South',
'E'=>'East',
'W'=>'West'));
I have the following dropdown box
<form name="myform" method="POST" ACTION="songs.php">
Select Category: <select id="sel" name="categories" onchange="document.myform.submit()">
And all the options follow after. When the user makes a selection, the category is brought up below using PHP and MYSQl based on the selection containing a list of songs etc.
However, the dropdown box always defaults back to the first value in the list of options. How do I make so that the dropdown box will set the selected option to the last submitted value? Thanks in advance!
You can't do that with JS as it has no direct access to POST request parameters. Rather let the server side language (which is in your case PHP) print the selected attribute on the <option> element whenever the submitted value matches the option value.
E.g.
foreach ($options as $value => $label) {
echo '<option value="' . $value . '"' . ($selected == $value ? ' selected' : '') . '>' . $label . '</option>';
}