I created a jQuery plugin that converts a text field to a 3 drop down, datepicker. It allows the user to select a Day, Month and Year rather than type the date in an input box.The original input element is hidden and a callback function is provided where the user can format the value for the input box. The id and name attributes are replaced by the original name and id of the element postfixed with Day, Month and Year respectively.I would like your inputs on the code below. It may be anything from writing better comments, architectural improvements to performance improvements or anything that comes to your mind.JavaScript/**jQuery Date picker.Convert a text box into a 3 drop down date picker with day, month and year as drop downs.Allowed Parameters:startDate: restrict the user to this Start date.endDate: restrict the user to this End date.dateFormat: a function that returns a string that will be used to fill the             hidden input box.Gautham PJ*/(function ($) {    'use strict';    // The function that handles the Datepicker.    $.fn.datepicker = function (userOptions) {        var $this,            $dayElement,            $monthElement,            $yearElement,            // Keep track of the Months and the number of days in them.            MONTHS = [                { month: 0, name: 'January', days: 31 },                { month: 1, name: 'February', days: 28 },                { month: 2, name: 'March', days: 31 },                { month: 3, name: 'April', days: 30 },                { month: 4, name: 'May', days: 31 },                { month: 5, name: 'June', days: 30 },                { month: 6, name: 'July', days: 31 },                { month: 7, name: 'August', days: 31 },                { month: 8, name: 'September', days: 30 },                { month: 9, name: 'October', days: 31 },                { month: 10, name: 'November', days: 30 },                { month: 11, name: 'December', days: 31 }            ],            // The default options for the plugin.            defaults = {                startDate: new Date(),                endDate: new Date(),                'class': 'datepicker',                dateFormat: function (day, month, year) {                    return day + '/' + month + '/' + year;                }            },            // Merge the default and User options into options.            options = $.extend({}, defaults, userOptions),            // Create the Day, Month and Year drop downs necessary for the             // Date picker and add it to the page before the selected element.            createHTMLElements = function () {                var name = $this.prop('name');                $dayElement = $('<select>')                    .prop({ id: name + 'Day', name: name + 'Day' })                    .addClass(options.class + ' ' + name + 'Day');                $monthElement = $('<select>')                    .prop({ id: name + 'Month', name: name + 'Month' })                    .addClass(options.class + ' ' + name + 'Month');                $yearElement = $('<select>')                    .prop({ id: name + 'Year', name: name + 'Year' })                    .addClass(options.class + ' ' + name + 'Year');                $this.before($dayElement);                $this.before($monthElement);                $this.before($yearElement);            },            // Check if the Starting Year has been selected.            isStartYearSelected = function () {                return $yearElement.val() == options.startDate.getFullYear();            },            // Check if the Ending Year hsa been selected.            isEndYearSelected = function () {                return $yearElement.val() == options.endDate.getFullYear();            },            // Check if the Starting Month has been selected.            isStartMonthSelected = function () {                return $monthElement.val() == options.startDate.getMonth();            },            // Check if the Ending Month has been selected.            isEndMonthSelected = function () {                return $monthElement.val() == options.endDate.getMonth();            },            // Check if the drop down contains the value that needs to be selected.            selectValueIfExists = function ($element, value) {                if (value) {                    if ($element.find('option[value=' + value + ']').length > 0) {                        $element.val(value);                    }                }            },            // Populate the Year drop down with the values or Options.            populateYear = function () {                var i,                    $option,                    previousSlectedValue = $yearElement.val();                $yearElement.empty();                for (i = options.startDate.getFullYear();                        i <= options.endDate.getFullYear(); i++) {                    $option = $('<option>').val(i).text(i);                    $yearElement.append($option);                }                selectValueIfExists($yearElement, previousSlectedValue);            },            // Populate the Month values based on the selected year.            populateMonth = function () {                var i,                    startMonth = 0,                    endMonth = 11,                    $option,                    previousSlectedValue = $monthElement.val();                // Check for Leap Year                if (parseInt($yearElement.val(), 10) % 4 === 0) {                    MONTHS[1].days = 29;                } else {                    MONTHS[1].days = 28;                }                // Check for the Start and End Year and limit the Selectable days.                if (isStartYearSelected()) {                    startMonth = options.startDate.getMonth();                }                if (isEndYearSelected()) {                    endMonth = options.endDate.getMonth();                }                // Empty and Populate the Month field.                $monthElement.empty();                for (i = startMonth; i <= endMonth; i++) {                    $option = $('<option>').val(i).text(MONTHS[i].name);                    $monthElement.append($option);                }                selectValueIfExists($monthElement, previousSlectedValue);            },            // Populate the Day drop down based on the month and year selected.            populateDay = function () {                var i,                    startDay = 1,                    endDay = MONTHS[$monthElement.val()].days,                    $option,                    previousSlectedValue = $dayElement.val();                if (isStartYearSelected() && isStartMonthSelected()) {                    startDay = options.startDate.getDate();                }                if (isEndYearSelected() && isEndMonthSelected()) {                    endDay = options.endDate.getDate();                }                $dayElement.empty();                for (i = startDay; i <= endDay; i++) {                    $option = $('<option>').val(i).text(i);                    $dayElement.append($option);                }                selectValueIfExists($dayElement, previousSlectedValue);            },            // Update the drop down values.            update = function () {                populateYear();                populateMonth();                populateDay();                if (typeof options.dateFormat === 'function') {                    var value = options.dateFormat.call($this, $dayElement.val(),                        parseInt($monthElement.val(), 10) + 1, $yearElement.val());                    $this.val(value);                }            },            // Initialize the components and perform the necessary steps to             // get the Date picker ready.            init = function () {                options.startDate.setFullYear(                    parseInt(options.startDate.getFullYear(), 10) - 30                );                createHTMLElements();                $this.hide();                update();                // Add Event Handlers for all the elements.                $yearElement.change(update);                $monthElement.change(update);                $dayElement.change(update);            };        // Return the selected element for jQuery Chaining.        return this.each(function () {            $this = $(this);            init();        });    };}(jQuery));HTML<input type=text name=dob id=dob />To call the plugin in the HTML page$(function () {    'use strict';    $('#dob').datepicker();});JSFiddle Link
jQuery Datepicker Plugin
javascript;jquery;datetime;form;plugin
One thing that caught my attention:// Check for Leap Yearif (parseInt($yearElement.val(), 10) % 4 === 0) {I reckon you know that % 4 === 0 is not a reliable check for a leap year. Although as far as I am aware all leap years fulfill this rule, not all years fulfilling the rule are leap years.I suggest that you try to avoid building calendar logic into your code as much as possible - it is always a pitfall, calendar logic is just too complicated. By the way, your code only supports one specific type of calendar, the one that is being used in western countries.Alternatively you could try something like building a test date from the selected $yearElement and verify if JavaScript accepts it as a valid date to determine whether or not the 29. of February should be supplied.Update Since JavaScript silently accepts an invalid date but represents it incorrectly, you can use that for your check:if (new Date(selectedYear, 01, 29).getMonth() == 1) {    // add 29 to the list}