Dynamic select array in PHP - php

I have a standard form array in PHP like this. I need to account for up to 10 hours of labor in 15 minute increments with 10 as a value for every 15 min or 40 per hour. Is it possible to automate this into some sort of array with PHP instead of hardcoding each of these values? It just seems like there should be a better way and I have no idea how to start?
<select size="1" name="labor" id="labor">
<option value="80">2 Hours</option>
<option value="70">1 Hour 45 min.</option>
<option value="60">1 Hour 30 min.</option>
<option value="50">1 Hour 15 min.</option>
<option value="40">1 Hour</option>
<option value="30">45 Minutes</option>
<option value="20">30 Minutes</option>
<option value="10">15 Minutes</option>
</select>

Probably easiest to hardcode the solution. I think this is one of those situations where it is OK as #Wrikken mentioned, as it makes the code very clean and easy to maintain (Imagine coming back to this in a year or two). In addition this situation can also be handled very well with a database table.
First use an array to store you values and descriptions:
$list = array();
$list['10'] = '15 Minutes';
....
Then loop through the entire array to generate your dropdown:
<select size="1" name="labor" id="labor">
<?php
foreach($list as $value => $desc){
$option = "<option value=$value>" . $desc . "</option>";
echo $option;
}
?>
</select>

You need two values, the 10-units increment and the user-displayed value. Run a for loop over $i (or some other variable) from 1 to 40 and calculate your values inside the loop:
10-increment is easy, just multiply $i by ten.
For the displayed value, multiply by 15 to get the total amount of minutes. Then transform that into hours and minutes using the modulo operator (which gives you the minutes) and standard divison (to get the hours).

This should do it. Change the start number of $i to how many total minutes the dropdown should contain. It´s now set to 750 minutes.
echo '<select>';
for ($i = 750; $i >= 15; $i -= 15) {
$hours = $i / 60;
$min = $i % 60;
echo '<option>';
if ($hours >= 1)
echo floor($hours)." Hours ";
if ($min > 1)
echo $min." Minutes";
echo '</option>';
}
echo '</select>';
NOTE: This code is not perfect, the start number needs to be evenly divided with 15 to generate your desired result, (however, it works).

Something like:
<select size="1" name="labor" id="labor">
<?php
for ($x = 1; $x < 11; $x++) {
echo '<option value="';
echo $x*10;
echo '">';
echo $x*15;
echo " Minutes</option>";
}
?>
</select>
Throw in an if statement there to seperate it so that once (x/10*15)>60 it starts carrying over into hours instead of having 75/90/105/120 minutes.

Related

PHP Form Select Array Increments by Value Threshold?

I was able to opt to out of a hard coded select of form values from 50,000 to 75,000,000 in increments of 100000.
<select name="<?php echo $search_parameter; ?>" id="<?php echo $search_parameter; ?>" class="form-control">
<option value=""><?php echo __( $search_labels[$i], 'tt' ); ?></option>
<?php for( $j = 50000; $j <= 75000000; $j += 50000 ) : ?>
<option value="<?php echo $j; ?>"><?php echo number_format( $j ); ?></option>
<?php endfor; ?>
</select>
This saved alot of time. I'd like to further customize this but really have no where to start outside of hard-coding this which seems like a step backwards?
How would I have PHP automate different incrementals based on value of $j thresholds? Is this even possible or am I asking too much?
50000 - 500000 - 50k increments
500001 - 1000000 - 100k increments
1000001 - 5000000 - 500k increments
5000001 - 10000000 - 1 million increments
10m+ 10 million increments
This is a very simple approach, that nevertheless should fit for you:
<?php
$inc = 50000;
for( $j = 50000; $j <= 75000000; $j += $inc) : ?>
<option value="<?php echo $j; ?>"><?php echo number_format( $j ); ?></option>
<?php
if ($j>10000000) {$inc=10000000;}
elseif ($j>5000000) {$inc=1000000;}
elseif //and so on...
endfor; ?>
Note that we're comparing "from the top", so that only a small number of comparisons/assignments should be needed.
Another possibility would be to define the thresholds and increments in an additional array and evaluate them in each loop.
Edit: Added two missing ;s.

Making a simple for loop with decimals

for ($x = 0.01;
$x <= 0.99;
$x++) {?>
<option value="<?php echo $x;?>"><?php echo $x;?></option>
<?php
} ?>
This does not work.
I am trying to get a decimal loop from .01 to .99
The amount of time I have spent on this I could have just typed it out manually :)
You just have to change this:
$x++ //Increments the value by 1
to this:
$x = $x + 0.01 //Increments the value by 0.01
Modify your code this way,
for ($x = 0.01; $x <= 0.99; $x = $x + 0.01) {?>
<option value="<?php echo $x;?>"><?php echo $x;?></option>
<?php
} ?>
You can define the incremental value as shown above
Try this:
for ($x = 0.01; $x <= 0.99; $x++0.1)
Initially, x = 0.01.
While incrementing (x++), x = 1.01.
So your condition fails second time, since 1.01 is greater than 0.99.
Hope you can figure it on your own on how to fix.

how to group number of results in a drop down list in php?

As an example I have 19 rows in the database, how do i make it so my drop down list print 10, 20, etc as opposed to 1, 2, 3, 4, 5 etc. My code below currently print 1 to 20 rather than 10, 20.
$num_rows = mysql_num_rows($page_name_qry);
$total_num_page = round($num_rows/10)*10;
for ($counter=1; $counter<=$total_num_page; $counter++){
$pagenumber = $counter;
print '<option value="'.$pagenumber.'">'.$pagenumber.'</option>';
}
Current the result shows:
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
...
But I am hoping to see:
<option value="10">10</option>
<option value="20">20</option>
Thanks
How about
$total_num_page = ceil($num_rows / 10) * 10;
for ($counter = 10; $counter <= $total_num_page; $counter += 10) {
print '<option value="' . $counter . '">' . $counter . '</option>';
}
With your code you get only 9 rows in your dropdown list. do you really want this? if not i.e you want total 19 rows as you have then you can try with the following :
$num_rows = mysql_num_rows($page_name_qry);
for ($counter=1; $counter<=$num_rows; $counter++){
$pagenumber = $counter*10;
print '<option value="'.$pagenumber.'">'.$pagenumber.'</option>';
}

Add characters to month loop?

I currently have a php loop running exactly how I need it with proper validations (in both php and javascript) with one exception, if the month is less than 2 digits, (i.e. 1,2,3,4), I need for a '0' to appear before:
01 - January
02 - February
...
10 - October
My code for the loop is currently:
<select name="Month">
<option value="">Month</option>
<?php
for ($i=1; $i<=12; $i++)
{
echo "<option value='$i'";
if ($fields["Month"] == $i)
echo " selected";
echo ">$i</option>";
}
?>
</select>
Also note, this month date is being stored in session, not interested in printing to screen
Try this when outputting the month:
sprintf("%02d", $month); // 01, 02 .. 09, 10, 11...
Use sprintf($format, [$var, [$var...).
Here, have some code:
function padLeft($char, $s, $n) {
return sprintf("%" . $char . $n . "d", $s);
}
function padWithZeros($s, $max_length) {
return padLeft('0', $s, $max_length);
}

PHP 'Years' array

I am trying to create an array for years which i will use in the DOB year piece of a form I am building. Currently, I know there are two ways to handle the issue but I don't really care for either:
1) Range:
I know I can create a year array using the following
<?php
$year = range(1910,date("Y"));
$_SESSION['years_arr'] = $year;
?>
the problem with Point 1 is two fold: a) my function call shows the first year as 'selected' instead of "Year" as I have as option="0", and b) I want the years reversed so 2010 is the first in the least and shown decreasing.
My function call is:
PHP
<?php
function showOptionsDrop($array, $active, $echo=true){
$string = '';
foreach($array as $k => $v){
$s = ($active == $k)? ' selected="selected"' : '';
$string .= '<option value="'.$k.'"'.$s.'>'.$v.'</option>'."\n";
}
if($echo) echo $string;
else return $string;
}
?>
HTML
<table>
<tr>
<td>State:</td>
<td><select name="F1State"><option value="0">Choose a year</option><?php showOptionsDrop($_SESSION['years_arr'], null, true); ?></select>
</td>
</tr>
</table>
2) Long Array
I know i can physically create an array with years listed out but this takes up a lot of space and time if I ever want to go back and modify.
ex: PHP
$years = array('1900'=>"1900", '1901'=>"1901", '1902'=>"1902", '1903'=>"1903", '1904'=>"1904", '1905'=>"1905", '1906'=>"1906", '1907'=>"1907", '1908'=>"1908", '1909'=>"1909", '1910'=>"1910", '1911'=>"1911", '1912'=>"1912", '1913'=>"1913", '1914'=>"1914", '1915'=>"1915", '1916'=>"1916", '1917'=>"1917", '1918'=>"1918", '1919'=>"1919", '1920'=>"1920", '1921'=>"1921", '1922'=>"1922", '1923'=>"1923", '1924'=>"1924", '1925'=>"1925", '1926'=>"1926", '1927'=>"1927", '1928'=>"1928", '1929'=>"1929", '1930'=>"1930", '1931'=>"1931", '1932'=>"1932", '1933'=>"1933", '1934'=>"1934", '1935'=>"1935", '1936'=>"1936", '1937'=>"1937", '1938'=>"1938", '1939'=>"1939", '1940'=>"1940", '1941'=>"1941", '1942'=>"1942", '1943'=>"1943", '1944'=>"1944", '1945'=>"1945", '1946'=>"1946", '1947'=>"1947", '1948'=>"1948", '1949'=>"1949", '1950'=>"1950", '1951'=>"1951", '1952'=>"1952", '1953'=>"1953", '1954'=>"1954", '1955'=>"1955", '1956'=>"1956", '1957'=>"1957", '1958'=>"1958", '1959'=>"1959", '1960'=>"1960", '1961'=>"1961", '1962'=>"1962", '1963'=>"1963", '1964'=>"1964", '1965'=>"1965", '1966'=>"1966", '1967'=>"1967", '1968'=>"1968", '1969'=>"1969", '1970'=>"1970", '1971'=>"1971", '1972'=>"1972", '1973'=>"1973", '1974'=>"1974", '1975'=>"1975", '1976'=>"1976", '1977'=>"1977", '1978'=>"1978", '1979'=>"1979", '1980'=>"1980", '1981'=>"1981", '1982'=>"1982", '1983'=>"1983", '1984'=>"1984", '1985'=>"1985", '1986'=>"1986", '1987'=>"1987", '1988'=>"1988", '1989'=>"1989", '1990'=>"1990", '1991'=>"1991", '1992'=>"1992", '1993'=>"1993", '1994'=>"1994", '1995'=>"1995", '1996'=>"1996", '1997'=>"1997", '1998'=>"1998", '1999'=>"1999", '2000'=>"2000", '2001'=>"2001", '2002'=>"2002", '2003'=>"2003", '2004'=>"2004", '2005'=>"2005", '2006'=>"2006", '2007'=>"2007", '2008'=>"2008", '2009'=>"2009", '2010'=>"2010");
$_SESSION['years_arr'] = $years_arr;
Does anybody have a recommended idea how to work - or just how to simply modify my existing code?
Thank you!
Not sure why you're using the session for this, but generating the array can be done with the array_combine function.
$years = array_combine(range(date("Y"), 1910), range(date("Y"), 1910));
Reversing the parameters to range will give you a descending array and array_combine will use the first array as the keys and the second as the values, giving the array(1910 => 1910, ...); map you're after.
reverse the numbers in the range to get years in descending order
$years = range(2010, 1900); // => [2010, 2009, 2008, ... ]
use date('Y') instead of hard-coding the current year
$years = range(date('Y'), 1900);
append an option "Select year" at the beginning
array_unshift($years, "Select year");
And finally why have a select drop-down for year or date of birth at all? It might be prevalent but it's super irritating. A simple text-box with validations, something like dd/mm/yyyy or mm/dd/yyyy is way better. Having drop-downs for date, month, and year only means that a user is allowed to select valid values and not necessarily correct values if they find it convoluted just to input a date. Moreover, since users can still enter junk values by modifying the DOM, validations need to be done on the server side. If validations are being done on the server-side, might as well just offer them a simple text box.
Also drop-downs make client-side coding complex. For example, if Feb and a leap year are selected, then a days dropdown should contain 29 days, otherwise 28.
Why do you need to store the array into the session?
Based on your use case, you do not need to use the array to store data beforehand.
define('DOB_YEAR_START', 1900);
$current_year = date('Y');
for ($count = $current_year; $count >= DOB_YEAR_START; $count--)
{
print "<option value='{$count}'>{$count}</option>";
}
In option 1 add:
$year = array_reverse( $year );
or just use:
$year = range( date("Y") , 1910 );
for ($count = date('Y'); $count >= 1910; $count--)
echo '<option value="' . $count . '">' . $count . '</option>';
Why don't you do this on your first approach
foreach($array as $k){
$string .= '<option value="'.$k.'">'.$k.'</option>'."\n";
}
Semantically, and functionally, speaking it's better to use the year as value than an int.
Also, use drawnonward method to get an inverted array so the year 2010 is the first, and default, value on your list.
If just reversing the order of your year array is the goal you can use the array_reverse() function.
http://www.php.net/manual/en/function.array-reverse.php
part 2:
$years = array();
for($i = 1900;$i<= 2010;$i++)
$years["$i"] = $i;
I'd go with option #1. However all you need to do is prepend a value to the array before you print it:
<?php
$years = $_SESSION['years_arr'];
// reverse the year list
rsort($years);
// prepend the 'choose a year' value to the array
array_unshift($years, 'Choose a year');
?>
<td><select name="F1State"><?php showOptionsDrop($years, null, true); ?></select>
you can simply use PHP foreach() function!
example:
$years_now = date("Y");
echo '<select name="y">';
echo '<option value="" disabled>Now:</option>';
echo '<option value="'.$years_now.'" selected="selected">'.$years_now.'</option>';
echo '<option value="" disabled>Other:</option>';
foreach (range($years_now, 1910) as $years) {
echo '<option value="'.$years.'">'.$years.'</option>';
}
echo '</select>';
Extending Brenton Alker's answer; if you need to add something to the start of the array you could do something like this:
$keys = array_merge(['any'], range(date("Y"), 1910));
$values = array_merge(['Any'], range(date("Y"), 1910));
$choice = array_combine($keys, $values);
This will add the key/value of any/Any to the start of the array whilst keeping all the subsequent keys in place

Categories