$("#datePicker").datepicker("getDate").getMonth is not a function

17,080

Solution 1

The problem is caused by jquery.ui.datepicker.mobile.js, whereever you got that from, it's clearly an incomplete hack.

The real problem is with this line:

//return jqm obj 
return this;

That means whatever you call, it will always return the hacked jQuery object for the new datepicker. In your case, it should return a date.

A solution, which is again just a hack, is to save the return value of the original datepicker call, and only return a jQuery object if the original return value was in fact a jQuery object:

...

//call cached datepicker plugin
var retValue = prevDp.call( this, options );

...

//return jqm obj
if(retValue){
    if(!retValue.jquery) return retValue;
}
return this;

...

Edit: Further problems with this extension of an extension is that it breaks all commands which require more than one parameter. The datepicker() can take as many as 5 parameters, so these extras must be passed through to the original extension.

Likewise, the adding of extra styles and the binding of the click event should only take place when the datepicker is being constructed, so there is an extra check that needs to be put in to see if the type of the first parameter is a string or not.

The resulting code should look something like this, I'll leave the rest up to the original developer :).

(function($, undefined ) {

    //cache previous datepicker ui method
    var prevDp = $.fn.datepicker;

    //rewrite datepicker
    $.fn.datepicker = function( options, param2, param3, param4, param5 ){

        var dp = this;

        //call cached datepicker plugin
        var retValue = prevDp.call( this, options, param2, param3, param4, param5 );

        //extend with some dom manipulation to update the markup for jQM
        //call immediately
        function updateDatepicker(){
            $( ".ui-datepicker-header", dp ).addClass("ui-body-c ui-corner-top").removeClass("ui-corner-all");
            $( ".ui-datepicker-prev, .ui-datepicker-next", dp ).attr("href", "#");
            $( ".ui-datepicker-prev", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-l", shadow: true, corners: true});
            $( ".ui-datepicker-next", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-r", shadow: true, corners: true});
            $( ".ui-datepicker-calendar th", dp ).addClass("ui-bar-c");
            $( ".ui-datepicker-calendar td", dp ).addClass("ui-body-c");
            $( ".ui-datepicker-calendar a", dp ).buttonMarkup({corners: false, shadow: false}); 
            $( ".ui-datepicker-calendar a.ui-state-active", dp ).addClass("ui-btn-active"); // selected date
            $( ".ui-datepicker-calendar a.ui-state-highlight", dp ).addClass("ui-btn-up-e"); // today"s date
            $( ".ui-datepicker-calendar .ui-btn", dp ).each(function(){
                var el = $(this);
                // remove extra button markup - necessary for date value to be interpreted correctly
                el.html( el.find( ".ui-btn-text" ).text() ); 
            });
        };

        if(typeof options != 'string'){
            //update now
            updateDatepicker();

            // and on click
            $( dp ).click( updateDatepicker );
        }

        //return jqm obj 
        if(retValue){
            if(!retValue.jquery) return retValue;
        }
        return this;
    };

    //bind to pagecreate to automatically enhance date inputs   
    $( ".ui-page" ).live( "pagecreate", function(){     
        $( "input[type='date'], input:jqmData(type='date')", this ).each(function(){
            $(this).after( $( "<div />" ).datepicker({ altField: "#" + $(this).attr( "id" ), showOtherMonths: true }) );
        }); 
    });
})( jQuery );

Solution 2

The problem starts with the binding of the datepicker:

$( "input[type='date'], input:jqmData(type='date')", this ).each(function(){
    $(this).after( $( "<div />" ).datepicker({ altField: "#" + $(this).attr( "id" ), showOtherMonths: true);
});

It's not bound to the input element itself, but to a div that is added behind the input element. This means you should call the datepicker api methods on the div and not on the input. You can do this by

  • giving it an id
  • looking for it by its class 'hasDatepicker' (which is added automatically when the datepicker gets initialized
  • keeping a reference to it, since the .datepicker() constructor returns the instance it created

This will give you the correct lookup but - as DarthJDG pointed out - is not enough. I altered the code in a similar way, but without the condition around the updateDatepicker call. This call is also needed when the calendar is changed (e.g. setDate), causing it to be regenerated in the DOM. So if you leave it out, your calendar won't get the mobile look.

(function ($, undefined) {

    //cache previous datepicker ui method
    var prevDp = $.fn.datepicker;

    //rewrite datepicker
    $.fn.datepicker = function (options) {

        var dp = this;

        //call cached datepicker plugin
        var retValue = prevDp.apply(this, arguments);

        //extend with some dom manipulation to update the markup for jQM
        //call immediately
        function updateDatepicker() {
            $(".ui-datepicker-header", dp).addClass("ui-body-c ui-corner-top").removeClass("ui-corner-all");
            $(".ui-datepicker-prev, .ui-datepicker-next", dp).attr("href", "#");
            $(".ui-datepicker-prev", dp).buttonMarkup({ iconpos: "notext", icon: "arrow-l", shadow: true, corners: true });
            $(".ui-datepicker-next", dp).buttonMarkup({ iconpos: "notext", icon: "arrow-r", shadow: true, corners: true });
            $(".ui-datepicker-calendar th", dp).addClass("ui-bar-c");
            $(".ui-datepicker-calendar td", dp).addClass("ui-body-c");
            $(".ui-datepicker-calendar a", dp).buttonMarkup({ corners: false, shadow: false });
            $(".ui-datepicker-calendar a.ui-state-active", dp).addClass("ui-btn-active"); // selected date
            $(".ui-datepicker-calendar a.ui-state-highlight", dp).addClass("ui-btn-up-e"); // today"s date
            $(".ui-datepicker-calendar .ui-btn", dp).each(function () {
                var el = $(this);
                // remove extra button markup - necessary for date value to be interpreted correctly
                // only do this if needed, sometimes clicks are received that don't require update
                // e.g. clicking in the datepicker region but not on a button.
                // e.g. clicking on a disabled date (from next month)
                var uiBtnText = el.find(".ui-btn-text");
                if (uiBtnText.length)
                    el.html(uiBtnText.text());
            });
        };

        //update after each operation
        updateDatepicker();

        // and on click
        $(dp).click(updateDatepicker);

        //return jqm obj 
        if (retValue) {
            if (!retValue.jquery) return retValue;
        }
        return this;
    };

})(jQuery);

Another change I found useful is an extra check when stripping the button content

$(".ui-datepicker-calendar .ui-btn", dp).each(function () {
    var el = $(this);
    // remove extra button markup - necessary for date value to be interpreted correctly
    // only do this if needed, sometimes clicks are received that don't require update
    // e.g. clicking in the datepicker region but not on a button.
    // e.g. clicking on a disabled date (from next month)
    var uiBtnText = el.find(".ui-btn-text");
    if (uiBtnText.length)
        el.html(uiBtnText.text());
});

I sometimes received click events that didn't change the calendar (clicking right next to it with your mouse, touching a disabled date of the next month, ...). which made all buttons empty.

Solution 3

I had the same problem today :)

It have no idea what kind of object the getdate returns, probably like said a hacked date object. Easiest is just to use the already stored variables in the datepicker object.

function onSelect(dateStr,dpObject)
{
    var month = dpObject.selectedMonth
    var day = dpObject.selectedDay;
    var year = dpObject.selectedYear;
    alert(year + ":" + month  + ":" + day);


};
Share:
17,080
mplungjan
Author by

mplungjan

In IT since 1986 and have been answering questions since 1997 on various sites including the hyphened one. In the time I have been here, I have enjoyed gaining enough rep to help edit question and would be happy to give more assistance since that is what I like to do in general, help people.

Updated on June 05, 2022

Comments