2

I am currently trying to make an inline datepicker object interact with a date input, and have managed everything but one thing. When I try to use the change event of the input, it throws an error:

Uncaught TypeError: $.start_widget.setDate is not a function

My Django template/jQuery code is as follows, included in a script tag which is inserted in the head of the document:

$(document).ready(function(){

  {% for string in datepickerstrings %}
    jQuery.{{ string }}_widget = $('#datepicker-{{ string }}');

    $.{{ string }}_widget.datepicker({
      inline: true,
      altField: '#event-{{ string }}',
      onSelect: function (date, instance) {
        $('#event-{{ string }}').val(date);
      }
    });
    $.{{ string }}_widget.hide();

    $('#event-{{ string }}').focusin(function () {
        $.{{ string }}_widget.show();
    });

    $('#{{ string }}-close').on("click", function (e) {
        e.preventDefault();
        $.{{ string }}_widget.hide();
    });

    $('#event-{{ string }}').change(function () {
        console.log("Changed date value from field: " + $(this).val());
        $.{{ string }}_widget.setDate($(this).val());
    });
  {% endfor %}

});

This is then processed before being sent to the client like this (relevant loop only):

$(document).ready(function(){


    jQuery.start_widget = $('#datepicker-start');

    $.start_widget.datepicker({
      inline: true,
      altField: '#event-start',
      onSelect: function (date, instance) {
        $('#event-start').val(date);
      }
    });
    $.start_widget.hide();

    $('#event-start').focusin(function () {
        $.start_widget.show();
    });

    $('#start-close').on("click", function (e) {
        e.preventDefault();
        $.start_widget.hide();
    });

    $('#event-start').change(function () {
        console.log("Changed date value from field: " + $(this).val());
        $.start_widget.setDate($(this).val());
    });

});

To me, this looks like the $.start_widget-object is clearly defined and initialised before the change event handler, and yet it throws the above exception. The console.log call shows the correct date.

I also tried replacing the setDate call with this:

$.start_widget.datepicker( "setDate", $(this).val() );

However, I got the same result. I have been trying to figure this out for hours, but seem to be unable to figure it out on my own. What is wrong with my code?

EDIT 1: With ImBack's suggestion, I get this error instead:

Uncaught TypeError: date.getDate is not a function
    _setDate @ ui.datepicker.js:1077
    _setDateDatepicker @ ui.datepicker.js:243
    (anonymous function) @ ui.datepicker.js:1426
    each @ jquery-1.8.3.min.js:2
    each @ jquery-1.8.3.min.js:2
    $.fn.datepicker @ ui.datepicker.js:1424
    (anonymous function) @ (index):66
    dispatch @ jquery-1.8.3.min.js:2
    u @ jquery-1.8.3.min.js:2
  • use this `jQuery.start_widget.datepicker( "setDate", $(this).val());` it will work for u – I'm Geeker Jun 29 '16 at 15:44
  • @I'mBack It didn't, sadly. I got an error of the same type, but with a slightly different description. I'm including it in an edit in the question. –  Jun 29 '16 at 15:52

2 Answers2

0

Try the following:

$(document).ready(function () {
    var start_widget = $('#datepicker-start').datepicker({
        inline: true,
        altField: '#event-start',
        onSelect: function (date, instance) {
            $('#event-start').val(date);
        }
    });
    start_widget.hide();

    $('#event-start').focusin(function () {
        start_widget.show();
    });

    $('#start-close').on("click", function (e) {
        e.preventDefault();
        start_widget.hide();
    });

    $('#event-start').change(function () {
        console.log("Changed date value from field: " + $(this).val());
        start_widget.datepicker("setDate", $(this).val());
    });
});

I stored your widget in a variable and then called setDate in a correct way.

Andrei Zhytkevich
  • 8,039
  • 2
  • 31
  • 45
  • I don't see how this changes anything. I stored it as a public member of the jQuery object, which allows it to be called inside functions. Both `.show()` and `.hide()` already work with the way I did it. If there is indeed a difference (other than scoping, of course), can you please explain it to me? :) –  Jun 29 '16 at 15:57
  • I had a doubt that `jQuery` and `$` are referencing to the same thing, I mean if they are references, not copies. Also, I'm used not to pollute "global" scope. I have another concern: `datepicker -> onSelect` and `$('#event-start').change(...)` look recursive: you change the date in `datepicker` in triggers value change in `$('#event-start')`, which triggers `setDate`. – Andrei Zhytkevich Jun 29 '16 at 16:03
  • I did try it, however, and received the same error: `Uncaught TypeError: start_widget.setDate is not a function`. I think Datepicker is designed for this: it does not trigger the change event (for example: [this question](https://stackoverflow.com/questions/6471959/jquery-datepicker-onchange-event-help) ). As for the global scope, I completely agree. That's why I'm using the jQuery object and not 'window' :) –  Jun 29 '16 at 16:03
0

I figured out the problem on my own. Apparently, the only thing that was necessary was to turn $(this).val() into new Date($(this).val()), as the library was unable to parse the string into a Date on its own. This leads me to believe that I have a nonstandard version of the plugin, because of how the docs clearly state:

setDate( date )

Sets the date for the datepicker. The new date may be a Date object or a string in the current date format (e.g., "01/26/2009"), a number of days from today (e.g., +7) or a string of values and periods ("y" for years, "m" for months, "w" for weeks, "d" for days, e.g., "+1m +7d"), or null to clear the selected date.