Generated option select time does not save properly - php

I have code that generates a select dropdown with times from 8:00am-6:00pm. Upon selecting an option, and saving the form, the times are saved in the database properly. HOWEVER, I cannot retrieve the times automatically. This is my code so far :
<select value="<?php echo $starttime; ?>" name="data[InvoiceTime][<?php echo $key;?>][starttime]" id="starttime_<?php echo $key+1?>" class="form-control" autocomplete="off">
<?php
$time = mktime(0, 0, 0, 1, 1);
for ($i = 28800; $i < 42600; $i += 900) { // 1800 = half hour, 86400 = one day
printf('<option value="%1$sam">%1$sam</option>',
date('g:i', $time + $i), date('g:i a', $time + $i + 1800));
}
for ($i = 43200; $i < 65000; $i += 900) { // 12pm-6pm
printf('<option value="%1$spm">%1$spm</option>',
date('g:i', $time + $i), date('g:i a', $time + $i + 1800));
}
?>
</select>
Desired output : select "9:00am" and save form 9:00am is saved to db(which happens) reload form 9:00 appears preselected due to data saved in db
Actual output : select "9:00am" and save form 9:00am is saved to db reload form 8:00am appears(default value)
The following code works, but does not generate the option values :
<select value="<?php echo $starttime; ?>" name="data[InvoiceTime][<?php echo $key;?>][starttime]" id="starttime_<?php echo $key+1?>" class="form-control" autocomplete="off">
<option value="8:00am" <?= ($item['starttime']) == '8:00am' ? 'selected' : '' ?>>8:00am</option>
<option value="9:00am" <?= ($item['starttime']) == '9:00am' ? 'selected' : '' ?>>9:00am</option>
</select>

You just needed to move your check for the value into the existing code.
However, I have simplified your code quite a bit; I'm not sure what you were trying to accomplish with your printf() statements. gmdate() is happy to work with just seconds (you don't want to use date() as it can deliver unexpected results, based on your current time zone.) If an <option> element doesn't have a value attribute, the contents are used instead, so I've removed it. You should always always separate your PHP from your HTML (ideally more than I've done here, but this is a start.)
And in case you aren't familiar with them, here is some info on the ternary statement and heredoc blocks.
<?php
$start = 28800;
$stop = 65000;
$interval = 900;
$options = "";
for ($seconds = $start; $seconds <= $stop; $seconds += $interval) {
$time = gmdate("g:ia", $seconds);
$selected = ($item["starttime"] === $time) ? " selected" : "";
$options .= sprintf("<option %s>%s</option>", $selected, $time);
}
echo <<< HTML
<select value="$starttime" name="data[InvoiceTime][$key][starttime]" id="starttime_$key" class="form-control" autocomplete="off">
$options
</select>
HTML;

Related

How to loop through time in select box PHP

I have a select drop down where I want to list times in the format of HH:MM with 1 minute intervals. so the list will start at 00:00 and finish at 23:59
I understand how to create a loop in a select drop down that will output 0-10
<select><?php for($i=0; $i<10; $i++){echo "<option>" . $i . "</option>";} ?>
</select>
and I understand how to output the time as HH:MM
<option><?php echo date('h:i', $supportrequest->startTime); ?</option>
But I can't work out how to do a combination of the two as I'm not sure what the parameters of the for loop should be
Using DatePeriod it'd be like that:
<?php
$begin = (new DateTime())->setTime(0,0,0); // create start point
$end = (new DateTime())->setTime(23,59,59); // create end point
$interval = new DateInterval('PT1M'); // set the interval to 1 minute
$daterange = new DatePeriod($begin, $interval ,$end); // create the DatePeriod
echo "<select>";
foreach($daterange as $date){ // loop through that period
echo "<option value='".$date->format("H:i") . "'>".$date->format("H:i")."</option>\n";
}
echo "</select>";
Using these classes makes it now easy to modify if you f.e. only want to have every 30 minutes, or need a different output format.
Do you really want to have a drop-down with one thousand, four hundred and forty option values (24 * 60 = 1440)? I think it would be better to have two <select> elements. You could style them to sit next to each other with a : in the middle if you wanted to keep the 'H:m' look.
<select id="hours">
<?php
for ($h = 0; $h < 24; $h++) printf("<option value=\"$h\"" . (!$h ? " selected" : "") . ">%02d</option>", $h);
?>
</select>
<select id="minutes">
<?php
for ($m = 0; $m < 60; $m++) printf("<option value=\"$m\"" . (!$m ? " selected" : "") . ">%02d</option>", $m);
?>
</select>
Converted Mukyuu's comment into an answer:
<select>
<?php
for($h=0; $h<24; $h++){
for($i=0; $i<60; $i++){
$time = date('h:i',strtotime($h.':'.$i));
echo "<option>".$time."</option>";
}
}
?>
</select>

Hide past time in simple PHP timepicker

My first block of code finds the nearest hour and stores it in a $nextHour variable.
I want to use this value in my second lot of code so it only shows future time in the dropdown. How do I update my second block of code to achieve this?
<?php
$date = new DateTime();
$nextHour = (intval($date->format('H'))+1) % 24;
echo $nextHour.':00'; // 5
?>
<?php
$start = "09:00";
$end = "20:00";
$tStart = strtotime($start);
$tEnd = strtotime($end);
$tNow = $tStart;
?>
<select name="callbacktime" id="callbacktime">
<?php
while($tNow <= $tEnd){
echo '<option value='.date("H:i",$tNow).'>'.date("H:i",$tNow).'</option>';
$tNow = strtotime('+1 hour',$tNow);
}
?>
</select>
$tStart = max([strtotime('09:00'), time()]);
I'd go with something like this as it saves having to do a check every loop as I previously mentioned in my comment.

How can I echo out the selected date

does anyone know how I would echo out the selected date as text with the date month and year separated outside of the form? I tried echoing out $date $month and $year outside of the form however this doesn't give me the correct date thankyou for the help
<?
$date = array('16-01-14','16-01-28','16-02-14','16-02-28','16-03-14','16-03-28','16-04-14','16-04-28',
'16-05-14','16-05-28','16-06-14','16-06-28','16-07-14','16-07-28','16-08-14','16-08-28','16-09-14','16-09-28','16-10-14','16-10-28',
'16-11-14','16-11-28','16-12-14','16-12-28');
$currentdate = date('y-m-d');
echo $currentdate;
?>
<form>
<select style="width:200px;">
<?php
foreach ($date as $i => $d) {
if ($currentdate >= $d && ($i == count($date)-1 || $currentdate < $date[$i+1])) {
$selected = "selected";
} else {
$selected = "";
}
list($year, $month, $day) = explode('-', $d);
echo "<option $selected>" . date("m/d/Y", strtotime($d)) . "</option>";
echo 'the current billing period is';
}
?>
</select>
</form>
Inside of your loop add a $selected_int variable like so:
foreach ($date as $i => $d) {
if ($currentdate >= $d && ($i == count($date)-1 || $currentdate < $date[$i+1])) {
$selected = "selected";
$selected_int = $i;
} else {
$selected = "";
}
list($year, $month, $day) = explode('-', $d);
echo "<option $selected>" . date("m/d/Y", strtotime($d)) . "</option>";
echo 'the current billing period is';
}
Then, you can reference it like:
echo date('Y-m-d', strtotime($date[$selected_int]));
Addition
I know you've already accepted the answer, but I also wanted to make a suggestion now that I see what you are using the $date for. Since you know the start date, and it is in 14-day periods, it would be easy to write that as part of the loop.
$start_date = date('Y-m-d', strtotime(date('Y').'-01-01'); //First day of the year, for the sake of argument.
$interval = 14;
for ($i = 0; date('Y') == date('Y', strtotime($start_date.' +'.($i * $interval).' days')); $i++) {//While this year is equal to the start date's year with the added interval [If I knew what your logic here was I could offer a better suggestion]
if ($currentdate >= date("Y-m-d", strtotime($start_date.' +'.($i * $interval).' days')) && (date('Y') < date("Y", strtotime($start_date.' +'.(($i + 1) * $interval).' days')) || $currentdate < date("m/d/Y", strtotime($start_date.' +'.(($i + 1) * $interval).' days')))) {
$selected = "selected";
$selected_int = $i;
} else {
$selected = "";
}
echo "<option $selected>" . date("m/d/Y", strtotime($start_date.' +'.($i * $interval).' days')) . "</option>";
}
Basically, this takes the start date, shows it as the first date option, then adds 14 days to it with each pass through. Your if/else statement should still be the same. It checks to see if you are on the last interval of the year, or if the current date is less than the next interval, and also that the current date is greater than the current interval.
After your loop, you can get the date by:
echo date("m/d/Y", strtotime($start_date.' +'.($selected_int * $interval).' days'));
I know it seems like a lot, but it would save you from having to make a date array to begin with.
Use strtotime instead list.
....
// list($year, $month, $day) = explode('-', $d);
echo "<option $selected>" . date("m/d/Y", strtotime($d)) . "</option>";
....
EDIT: Additional information - your code requires a lot modification and likely some structure changes but assuming this is for testing a method and "how to do" instead a final product.
You need to submit the selected date, catch it in the script and use the selected date to do what you need - i.e. retrieve data from database - and this should give you some idea.
<?php
// You need to create these dates by using another method. You cannot hard code these. You can create it with date functions easily.
$date = array('16-01-14','16-01-28','16-02-14','16-02-28','16-03-14','16-03-28','16-04-14','16-04-28','16-05-14','16-05-28','16-06-14','16-06-28','16-07-14','16-07-28','16-08-14','16-08-28','16-09-14','16-09-28','16-10-14','16-10-28','16-11-14','16-11-28','16-12-14','16-12-28');
// Checking if we have a posted form, with the button name user clicked
if (isset($_POST["btnSubmit"])) {
// This is your selected day - use it where you need:
$selectedDate = $_POST["selectedDate"];
// This is where your model start singing and gets necessary info for this date - just printing here as sample
print $selectedDate;
// I need dropDownDate to compare in the SELECT to preselect the appropriate date
$dropDownDate = strtotime($selectedDate);
} else {
// First time visit, preselect the nearest date by using current date
$dropDownDate = time();
}
?>
<form method="post">
<select name="selectedDate" style="width:200px;">
<?php
foreach ($date as $i => $d) {
if ($dropDownDate >= strtotime($d) &&
(!isset($date[$i+1]) || ($dropDownDate < strtotime($date[$i+1])))
) {
$selected = 'selected="selected"';
} else {
$selected = "";
}
list($year, $month, $day) = explode('-', $d);
echo "<option $selected>" . date("m/d/Y", strtotime($d)) . "</option>";
}
?>
</select>
<input type="submit" name="btnSubmit" value="Submit">
</form>
Note that I added a "submit" type input (to submit the form) and changed form method to "post", finally named SELECT as "selectedDate". I also changed your date comparison code line in the loop.
Hope this helps.

Performance tune PHP Time Query

I was wondering if I could do some performance tuning for the below PHP Script. What I am trying to do - is get every half hour from 00:00am to 23:30pm into a select list. Here is the code
<?php
$starttime = '00:00';
$time = new DateTime($starttime);
$interval = new DateInterval('PT30M');
$temptime = $time->format('H:i');
do{
echo '<option value="">'.date("H:i a", strtotime($temptime)).'</option>';
$time->add($interval);
$temptime = $time->format('H:i');
}while ($temptime !== $starttime);
?>
I believe there is a way we can do it in an easier manner - but I cannot think of it. Can someone help?
Other than hardcoding the values, you can lose all the DateTime and TimeInterval objects and use a simple loop:
for ($h=0;$h<24;$h++) {
echo '<option>' + sprintf ( "%02d", $h ) + ':00</option>';
echo '<option>' + sprintf ( "%02d", $h ) + ':30</option>';
}
If performance is what you're after, hardcoding the time strings is probably the best thing you can do.
Since they won't change, you don't really need them dynamic, would you?
foreach (range(0, 60*24, 30) as $minutes) {
echo '<option>' . date('H:i a', strtotime('00:00 +' . $minutes . ' minutes')) . '</option>';
}
Till day has 24h, you can use a good ol' for:
<select>
<?php for($i = 0; $i < 48; $i++): ?>
<option><?php echo $i%2 == 0 ? ($i / 2) . ':00' : intval($i / 2) .':30'; ?></option>
<?php endfor;?>
</select>

Compare two time values using jQuery's validate

I have two selects, one that is a time from and the other is a time to. These values are split by fifteen minute integrals. I take those values and convert them using PHP's strtotime. I would like to compare these values to make sure that the time to is not lower than the time from or that the time from is not higher than the time to using jQuery's validate.
Thanks.
Here is my PHP:
$start = strtotime('12:00 AM');
$end = strtotime('12:00 PM');
echo '<select name="TimeFrom" id="TimeFrom" class="timeSelectFrom">';
for ($i = $start; $i <= $end; $i += 900)
{
echo '<option>' . date('g:i A', $i) . '</option>';
}
echo '<option>Closed</option>';
$start = strtotime('12:00 AM');
$end = strtotime('12:00 PM');
echo '<select name="TimeTo" id="TimeTo" class="timeSelectTo">';
for ($i = $start; $i <= $end; $i += 900)
{
echo '<option>' . date('g:i A', $i) . '</option>';
}
echo '<option>Closed</option>';
echo '</select>';
You could easily translate the values from the form elements into a basic time-stamp using a simplistic formula like (seconds+60*minutes) and then compare them as required.

Categories