We help IT Professionals succeed at work.

Eliminate duplication here

Colin Brazier
Colin Brazier used Ask the Experts™
on
Obvious duplication here, just because I need an ascending date range in one, and descending in the other.  But I can't think how to do it with one version only.

function DateDropDown($startdays,$size,$DateDropName,$SatSun) 
{
   // $startdays = for results, we start at present day (0), for fixtures, we start at next week(7).
   // $size = the number of days to display in the drop down
   
   echo "<select class='formSelect' id='$DateDropName' name='$DateDropName' >\n";
   for ($i = $startdays; [b]$i >= $size; $i--[/b]) 
   {
      $theday = mktime (0,0,0,date("m") ,date("d")+$i ,date("Y"));
      $option=date("D M j, Y",$theday);
      $value=date("Y-m-d",$theday);
	  
      echo "<option value=\"$value\">$option</option>\n";
   }
   echo "</select>\n";
   return;
}

function DateDropDownFix($startdays,$size,$DateDropName,$SatSun) 
{
   // $startdays = for results, we start at present day (0), for fixtures, we start at next week(7).
   // $size = the number of days to display in the drop down
   
   echo "<select class='formSelect' id='$DateDropName' name='$DateDropName' >\n";
   for ($i = $startdays; [b]$i <= $size; $i++[/b]) 
   {
      $theday = mktime (0,0,0,date("m") ,date("d")+$i ,date("Y"));
      $option=date("D M j, Y",$theday);
      $value=date("Y-m-d",$theday);
	  
	  echo "<option value=\"$value\">$option</option>\n";      
   }
   echo "</select>\n";
   return;
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
Hey Colin,

There are several ways to do it, but whichever way you choose, you'll need someway of telling your function to reverse the order - easiest way is by passing in an additional parameter.

Looking over your code and there seems to be a few bugs in there. For example, if you pass $startDays of 0 and $size of 5 into your first function, your loop will never run. Also, the $size needs to be added to the $startDays for the loops to work as expected.

I would go about this slightly differently. Using the DateTime objects, just create an array that includes your full date range, and then reverse sort that array if needed. Once done, loop through the array and ouput your options. Also, I would return the value from your function rather than echo it out inside.

Something like this:

function DateDropDown($startDays, $size, $dateDropName, $reverse = false) {
    $dates = [];
    $date = new DateTime();
    $date->modify('+' . $startDays . ' day');

    for ($i = $startDays; $i < ($size + $startDays); $i++) {
        $dates[$date->format('Y-m-d')] = $date->format('D M j, Y');
        $date->modify('+1 day');
    }

    if ($reverse) krsort($dates);

    ob_start();
 
    printf('<select class="formSelect" id="%1$s" name="%1$s">', $dateDropName);
    foreach ($dates as $value => $text) {
        printf('<option value="%s">%s</option>', $value, $text);
    }
    echo '</select>';

    return ob_get_clean();
}

Open in new window

You'd use it like so:

echo DateDropDown(0, 7, "MyDropdown"); // 7 dates from today
echo DateDropDown(0, 7, "MyDropdown", true); // 7 dates from today reverse sorted.

echo DateDropDown(7, 7, "MyDropdown"); // 7 dates from next week
echo DateDropDown(7, 7, "MyDropdown", true); // 7 dates from next week reverse sorted.

Open in new window

NorieAnalyst Assistant

Commented:
Perhaps something like this.

It creates a range for your days to add to the date and the extra argument $desc determines how that range is sorted, and in which order the days are added to the day.
function DateDropDown($startdays,$size,$DateDropName,$SatSun, $desc=True) 
{
   // $startdays = for results, we start at present day (0), for fixtures, we start at next week(7).
   // $size = the number of days to display in the drop down
   
  $days = range($startdays, $startdays+$size);

  if($desc){
    rsort($days);
  }

  echo "<select class='formSelect' id='$DateDropName' name='$DateDropName' >\n";

   foreach($days as $i)
   {
      $theday = mktime (0,0,0,date("m") ,date("d")+$i ,date("Y"));
      $option=date("D M j, Y",$theday);
      $value=date("Y-m-d",$theday);
	  
      echo "<option value=\"$value\">$option</option>\n";
   }
   echo "</select>\n";
   return;
}

Open in new window


Here's some sample output.

Function call: DateDropDown(0,8,"Dropdown","SatSun", False);

Output:
<select class='formSelect' id='Dropdown' name='Dropdown' >
<option value="2019-12-04">Wed Dec 4, 2019</option>
<option value="2019-12-05">Thu Dec 5, 2019</option>
<option value="2019-12-06">Fri Dec 6, 2019</option>
<option value="2019-12-07">Sat Dec 7, 2019</option>
<option value="2019-12-08">Sun Dec 8, 2019</option>
<option value="2019-12-09">Mon Dec 9, 2019</option>
<option value="2019-12-10">Tue Dec 10, 2019</option>
<option value="2019-12-11">Wed Dec 11, 2019</option>
<option value="2019-12-12">Thu Dec 12, 2019</option>
</select>

Open in new window


Function call: DateDropDown(0,8,"DropDown","SatSun", True);
Output:
<select class='formSelect' id='DropDown' name='DropDown' >
<option value="2019-12-12">Thu Dec 12, 2019</option>
<option value="2019-12-11">Wed Dec 11, 2019</option>
<option value="2019-12-10">Tue Dec 10, 2019</option>
<option value="2019-12-09">Mon Dec 9, 2019</option>
<option value="2019-12-08">Sun Dec 8, 2019</option>
<option value="2019-12-07">Sat Dec 7, 2019</option>
<option value="2019-12-06">Fri Dec 6, 2019</option>
<option value="2019-12-05">Thu Dec 5, 2019</option>
<option value="2019-12-04">Wed Dec 4, 2019</option>
</select>

Open in new window

Author

Commented:
Thanks Chris, will check it out tomorrow.

Author

Commented:
and Norie!

Author

Commented:
Thanks guys.  Especially Chris who introduced me to some different concepts etc., notably output buffering.
NorieAnalyst Assistant

Commented:
Colin

output buffering

I was wondering what was going on here in Chris' code.:)
 return ob_get_clean();

Open in new window

Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
No worries. Output buffering is a nice way to build strings for return using the output functions (echo / printf etc). I tend to find it's a cleaner way of handling it rather than trying to concatenate strings into a variable.