How to make a nice "date picker" in PHP?

52,366

Solution 1

There is a lot of JavaScript-based calendar widgets out there already. If you're not looking to do this for learning purposes, no reason to reinvent the wheel.

Server-side validation is of course still mandatory, but those widgets will make it impossible for the user to select an invalid date under normal circumstances.

E.g.

Solution 2

You're trying to solve a client side problem server side here imho, albeit, validation can never be omitted server side.

But invalid dates, as your example, are really not a problem, as you can use strtotime which eats most dates nicely. Of course, in this case, it will evaluate to 1st of December, but a valid date anyway. You can use the output from strtotime with date to format it in a database friendly way.

To take this slightly further, if you want to make sure the date entered is not only formally valid, you can parse it using strtotime, format it using date in the format it was sent to your script and compare the two strings. If not identical, you'll know something was wrong.

As per your example:

$datePosted = '2010-11-31';    
$fromClient = date('Y-m-d', strtotime($datePosted));

// $fromClient == '2010-12-01' 

if (strcmp($datePosted, $fromClient) != 0) {
  // Invalid date posted
} else {
  // All is well on the western front
}

You might also be interested in the DateTime class provided with newer versions of PHP.

Solution 3

There should be no need for Ajax. Ajax calls back to the server, but the server doesn't know any more about valid dates than the client does, so this can all be done in javascript. If you're already using jQuery, use the jQuery plugin, but don't load the entire jQuery library just for this: that's overkill. There are plenty of lightweight datepickers. All you want to do is reload the available days when someone changes the month/year (remember February: you need to reload on year change too).

We have that done with a method which includes the name of the day of the week alongside the date:

function OnMonthYearChange(name) {
    var week = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
    var year = document.getElementById(name + '-year');
    var mon  = document.getElementById(name + '-mon');
    var mday = document.getElementById(name + '-mday');
    if ((mon.value  == '') || (year.value == '')) {
        return;
    }

    var date = new Date();
    date.setYear(year.value);
    date.setMonth(mon.value);
    var l = getDaysInMonth(year.value, mon.value);
    var day = mday.value;

    clearSelect(mday);
    var w = 0;
    for (i = 0; i < l; i++) {
        date.setFullYear(year.value, mon.value - 1, i + 1);
        w = date.getDay();
        var o = document.createElement('option');
        o.value = getLeadingZero(i + 1);
        o.text = o.value + ' - ' + week[w];
        //alert(o.text);
        if (i == (day - 1)) o.selected = true;
        if (app.IsIE) {
            mday.add(o);
        } else {
            mday.options.add(o);
        }
    }
}
function getDaysInMonth(year, month) {
    var m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    if (month != 2) return m[month - 1];
    if (year % 4 != 0) return m[1];
    if (year % 100 == 0 && year % 400 != 0) return m[1];
    return m[1] + 1;
}
function clearSelect(e) {
    var first = e.options[0].innerHTML;
    if (first) {
        // Form does not allow selection of a blank date. Drop all existing options.
        e.options.length = 0;
    } else {
        // Form allows selection of a blank date. First option is blank. Keep it.
        e.options.length = 1;
    }
}
function getLeadingZero(n) {
    if (n < 10) n = '0' + n;
    return n;
}

See http://www.mattkruse.com/javascript/calendarpopup/ for a different approach, which pops up a calendar. It is possible to integrate the two, feeding the results from the popup calendar back into the selectboxes.

Remember that people can disable javascript and do all sorts of weird stuff on the client side, so server-side validation still matters.

Solution 4

jQuery and another JavaScript frameworks are present which would do the job.

Solution 5

You can't. You'll need a client-side solution for that.

PHP deals with processing data, so you would have a JavaScript-powered date-picker where the user selects the date, and then you would have PHP save that selected date in say, a database, on submission of a form.

Share:
52,366
BeeDog
Author by

BeeDog

Updated on July 09, 2022

Comments

  • BeeDog
    BeeDog almost 2 years

    I'm doing some experimenting with MySQL and PHP, and I'm curious about creating a nice "date picker", e.g. picking the date 2010-11-11 (today's date).

    I want to store valid DATETIME values in my MySQL database, and I want a PHP page to provide rolling lists for year, month and day (e.g. 2010-11-11) so as to avoid forcing the user to write in dates manually in a form and then do checking.

    My question is, let's say the user picks the date 2010-11-31 (which doesn't exist); how can I create the simple rolling lists so as to adjust dynamically? That is, the user FIRST picks the year, then the month, and lastly the day (which is dynamically altered to accommodate the actual number of days in the given month). Hopefully leap years will also be taken care of. After picking them all and the user presses submit, the script will submit a correctly formatted DATETIME value to the database (e.g. YYYY-MM-DD, or YYYYMMDD).

    As far as I have understood, the DATETIME type is strict as standard, meaning the server will keep track of invalid dates, which should be sufficiently easy to error-check. But I want to avoid this by doing what I described above.

    Would you say my described 'solution' is easy to implement using only PHP (and MySQL)? Or would I need some other stuff (e.g. AJAX/JavaScript, JQuery etc.) to manage this? Any suggestions and pointers are very welcome, especially alternative approaches to the same problem that may be easier to implement. Thanks in advance!

    • tina Miller
      tina Miller over 13 years
      As Pekka says, you can't do a date picker with 'just PHP', because the PHP is 'just' on the server, and your user is on the browser/client.