0
votes

I have a problem where jQuery datepicker fails to display the calendar, because something swallows the event. It seems like it might be AngularJS causing the problem. You can see it at: jsfiddle.net example

In the jsfiddle example, I've created one datepicker at the bottom of the page which appears all the time and isn't initialized until you click the [Init DatePicker] button.

Here's the init() method where I initialize the jQuery Datepicker as detailed in jquery docs.

function init(selId)
{
    if (console.log !== undefined)
    {
        console.log("init()...");
    }
    $(function() {
        $( ".datepicker" ).datepicker({
          changeMonth: true,
          changeYear: true
        });
      });
    if (selId !== undefined)
    {
        $(".datepickFix").on("click","#" + selId, function (){
            $(".datepicker").datepicker( "show" );
        });
    }
    else
    {
        $(".datepickFix").on("click",".datepickFix", function (){
            $(".datepicker").datepicker( "show" );
        });
    }
}

Try This

Go ahead and click the "edit" box or [click me] text and you'll see that it doesn't display the jQuery Datepicker.

Works As Expected

Now, click the [Init DatePicker] button and again, attempt to click the "edit" box and you'll see the calendar display as you expect. If you click the [click me] text it will also display. Everything works as expected.

ng-repeat - addrow() calls init() However, now click an the [Add Row] button and notice that I am doing an ng-repeat in AngularJS to add rows to a table. The row contains another "datepicker" and the Init() code is called upon adding the row.

I also call init() from the onclick of the div just to make it fire.

The Datepicker Still Doesn't Display

However, notice that even though the init() is called -- confirmed by console.log -- you will see that clicking on the "edit" box (jquery datepicker) in the new row does not display the datepicker.

Now, if you click the [click me] text in the row or you click the [Init DatePicker] the calendar will now show.

Clicking [Add Row] button twice makes the first-added row work, not the other Also, if you click the [Add row] button twice, the calendar will show upon initially clicking the first-added row.

However, if I call init() multiple times that doesn't work either. Can anyone shed some light on this issue?

1
please take a look it : github.com/angular-ui/ui-dateRamesh Rajendran
That might be interesting, but I'm looking for an explanation of how the events are handled and why something (AngularJS?) seems to be preventing the event from bubbling up through the calendar. I'd like to talk about the problem a bit and not attempt to apply another API before I understand why I should or shouldn't. Thanks.raddevus
your initialization code is not within angular's lifecycle. write a directive and do the init stuff in link function. @see: stackoverflow.com/questions/14994391/…angabriel
Wow. You get so much from AngularJS and so little. I'm amazed at the little amount of code I write with AngularJS to do the ng-repeat thing, and then just to make the Datepicker work I have to read tons, understand more and write even more code. Wow. I think that is a miss, since APIs are supposed to make things easier. Especially the simple should be easy. This is a "simple" thing made more difficult by the API. A paradox, no? I bet I just trolled in lots of replies with this one.raddevus

1 Answers

0
votes

I took angabriel's advice and learned how to do this the right way using a directive. You can see it working at: jsfiddle showing jQueryUI calendar

It took way too much work to get this going. Way!

You just have to click the [Add Item] button and a new row will be inserted via ng-repeat directive and you'll see the calendar text box and calendar button. It'll look like this: jquery calendar using angularJS

I am using the directive created at / by : https://github.com/angular-ui/ui-date All the code you need is in the src directory found in date.js file.

Wraps jQueryUI Datepicker Plugin Of course you also need to add references to jQuery and jQueryUI.

Angular Module

Once you do that you need to initialize your Angular Module, something like the following:

var myAppModule = angular.module('extra', ['ui.date']);
 myAppModule.controller('taskController', taskController);

Notice the 2nd argument to the angular.module call is the reference to the Angular directive found in the date.js file.

Markup Sample

<div class="control-group input-append input-group" >
          <input id="{{l.id}}cb"
           class="input form-control cb" ui-date="dateOptions"
           ui-date-format="DD, d MM, yy" value="{{l.completedBy}}"
          value="completedBy" type="text" data-ng-model="l.completedBy" /> 
          <span class="btn input-group-addon add-on" 
                  data-ng-click="showCalendar(l.id,'cb')" >
           <span class="glyphicon glyphicon-calendar"></span>
       </span>

Notice the ui-date attribute on the <input element is the reference which converts the text box into a datepicker.

Configure jQueryUI Datepicker :pass-thru to AngularJS Directive

The dateOptions item is object which can be sent in with values to set up your datepicker and are related to jQueryUI.

At the top of my controller I set the following options which force the datepicker to display the month and year dropdowns.

$scope.dateOptions = { changeYear: true, changeMonth: true };

Looks like this:

notice drop lists (month/year)

Only Works When You Click "Text box" portion

The problem is that the datepicker only appears when you click the text box portion. More work to do.

I added an ng-click to my (bootstrap) button and then added a method to my controller which handles the display of the calendar. It looks like this:

function showCalendar(id,datepickerType)
{
    $("#"+id+datepickerType).datepicker("show");
    console.log(id + " : " + datepickerType);
}

Challenge

The problem is that you have to have a way to hook up the calender which appears with the output value which is the original datepicker. This becomes a challenges since we can have a unknown number of rows with an unknown number of datepickers and associated "text" boxes. Notice how I do a jQuery select to get the right one, so when you choose a value, it lands in the correct datepicker text box.

NOTE: I was using Angular v1.2.3 and it was all working. Went to set up the example on jsfiddle which currently only supports AngularJS v1.2.1 and the example would not work -- calendar would not pop up. Added the CDN to the most current version of AngularJS v.1.2.6 and it started working.