Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Example: ui datepicker #15

Closed
geoguide opened this issue May 19, 2015 · 36 comments
Closed

New Example: ui datepicker #15

geoguide opened this issue May 19, 2015 · 36 comments

Comments

@geoguide
Copy link

I would like an example that demonstrates: ui.bootstrap.datepicker

@kentcdodds kentcdodds changed the title New Example: New Example: ui datepicker May 19, 2015
@kentcdodds
Copy link
Member

Here's a start. If anyone would like to help finish it up, I would really appreciate it.

http://jsbin.com/cupubo/edit

@kentcdodds
Copy link
Member

Here's the datepicker example: http://angular-formly.com/#/example/integrations/ui-datepicker

@sparty02
Copy link

@kentcdodds It seems like the binding for the calendar icon (the addonLeft item) isn't working (i.e. it doesn't open up the calendar control when clicked). I don't totally get the API regarding the

onClick: function (options, scope) {
        options.templateOptions.isOpen = !options.templateOptions.isOpen;
}

and how it relates to the is-open="to.isOpen" binding in the template, but I suspect that has something to do with it?

@kentcdodds
Copy link
Member

to is a shortcut for options.templateOptions. Not certain why it's not working though...

@kentcdodds
Copy link
Member

Hmmm... I think that the click event isn't getting fired for some reason, because if I invoke that function myself it works as expected...

@sparty02
Copy link

I put a debugger; in the onClick function and it got in there. I also saw options.templateOptions.isOpen changing from undefined to true.... but nothing happens.

@kentcdodds
Copy link
Member

Ah, it could be that two events are being fired so it gets set to true in the onClick and false somewhere else...

@sparty02
Copy link

That sounds likely. Along those lines, I saw something similar happening in the onFocus (I've sinced removed that handler), where when setting focus to the field, the calendar would popup for a few milliseconds, then disappear.

@kildareflare
Copy link

I am seeing the same problem. Stepping through with the debugger I can see that the popup is initially opened, but then closed.
The reason for this would appear to be linked to the documentClickBind method of ui.bootstrap.

When isOpen changes, the documentClickBind click handler is set up.
For some reason this is being called and clearing the value of isOpen

      scope.$watch('isOpen', function(value) {
        if (value) {
          scope.$broadcast('datepicker.focus');
          scope.position = appendToBody ? $position.offset(element) : $position.position(element);
          scope.position.top = scope.position.top + element.prop('offsetHeight');

          $document.bind('click', documentClickBind);
        } else {
          $document.unbind('click', documentClickBind);
        }
      });
      var documentClickBind = function(event) {
        if (scope.isOpen && event.target !== element[0]) {
          scope.$apply(function() {
            scope.isOpen = false;
          });
        }
      };

@dannycallaghan
Copy link
Contributor

Has a solution been found for this? I'm seeing the same issue.

@jorgeramos
Copy link

BTW, my temp solution is to set the state to open after a brief delay. I know this isn't the same as a toggle but it's the only way i could get it to stay open for now.

onClick: function(options, scope) {
  $timeout(function(){
    options.templateOptions.isOpen = true;
  }, 100);
}

@dannycallaghan
Copy link
Contributor

I think @kildareflare is spot on. When the datepicker is opened, an event is added to the whole document whereby any click then closes the datepicker. That event checks only that the event's target isn't the datepicker itself. This means that clicking on the icon fires the close event, when we want it to open the datepicker again.

I've done this...

I've added a name of 'datepicker-control' to any element that I want to use as a 'opener and closer' of the datepicker (the calendar icon, for example). I've then edited to the documentClickBind function, like so:

var documentClickBind = function (event) {
    if (scope.isOpen && event.target !== element[0]) {
        if (event.target.name && event.target.name === 'datepicker-control') {
            return;
        }
        scope.$apply(function() {
            scope.isOpen = false;
        });
    }
};

So, now, it skips this step if one of my 'datepicker-controls' is clicked. It's not ideal, but it works.

@kentcdodds
Copy link
Member

If you look at the example on ui-bootstrap's page they actually have a calendar button that they're using and it works fine. Perhaps this example could do the same thing...

@hrishi1183
Copy link
Contributor

Has a solution been found for this? I'm seeing the same issue...
trying above timeout workaround.. but somehow its not working :(

@juanpujol
Copy link

With the release of angular-bootstrap 0.13.2 I can't get to work this example http://angular-formly.com/#/example/integrations/ui-datepicker.

When a date comes from the server, It always results on a validation error on the form that I can't figure out what it could be.

{
  "$error": {
    "date": [
      {
        "$viewValue": "August 08, 2015",
        "$modelValue": "2015-08-08T00:00:00",
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [
          null
        ],
        "$formatters": [
          null,
          null
        ],
        "$viewChangeListeners": [
          null,
          null
        ],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "date": true
        },
        "$name": "modelStartDate",
        "$options": null
      }
    ]
  }
}

If I change the date using the datepicker it gets valid.

Did anyone else had this problem recently? Thank you.

@wordsandnumbers
Copy link

My solution to the calendar button issue was to not use the addonLeft templateOption. Instead, I modified the example's template to use $event.stopPropagation() to prevent the click event from triggering the datepicker to close:

formlyConfig.setType({
    name: 'datepicker',
    template: '<div class="input-group"><div class="input-group-addon" ng-click="$event.stopPropagation();to.isOpen=!to.isOpen;"><i class="glyphicon glyphicon-calendar"></i></div><input ng-click="to.isOpen=true" class="form-control" ng-model="model[options.key]" is-open="to.isOpen" datepicker-options="to.datepickerOptions" /></div>',
    wrapper: ['bootstrapLabel', 'bootstrapHasError'],
    defaultOptions: {
        ngModelAttrs: ngModelAttrs,
        templateOptions: {
            onFocus: function($viewValue, $modelValue, scope) {
                scope.to.isOpen = !scope.to.isOpen;
            },
            datepickerOptions: {}
        }
    }
});

@dannycallaghan
Copy link
Contributor

I believe this issue has been fixed.

Today I grabbed the very latest version of the ui.bootstrap.datepicker - version 0.13.3.

My config looks like this:

     formlyConfigProvider.setType({
            name: 'datepicker',
            templateUrl: '/btFormly/btFormly.datepicker.template.html',
            defaultOptions: {
                ngModelAttrs: ngModelAttrs,
                templateOptions: {
                    datepickerOptions: {
                        format: 'dd/MM/yyyy',
                        initDate: new Date(),
                        showWeeks: false
                    }
                }
            },
            controller: ['$scope', function ($scope) {
                $scope.formlyDatePicker = {};

                $scope.formlyDatePicker.status = {
                    opened: false
                };

                $scope.formlyDatePicker.open = function ($event) {
                    $scope.formlyDatePicker.status.opened = true;
                };
            }]
        });

And my template looks like this:

    <p class="input-group">
        <input  type="text"
                id="{{::id}}"
                name="{{::id}}"
                ng-model="model[options.key]"
                class="form-control"
                ng-click="formlyDatePicker.open($event)"
                datepicker-popup="{{to.datepickerOptions.format}}"
                is-open="formlyDatePicker.status.opened"
                datepicker-options="to.datepickerOptions" />
        <span class="input-group-btn">
            <button type="button" class="btn btn-default" ng-click="formlyDatePicker.open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
        </span>
    </p>

And it works as required.

@kentcdodds
Copy link
Member

Awesome! If you want to clone the existing example and add your updates, I'd happily accept a PR with the updated ID :-)

@mikeerickson
Copy link

Is there a version of this example which also supports timepicker? If you don't have one, I would willing to create the example (have a need this week for it)

@kentcdodds
Copy link
Member

@mikeerickson
Copy link

kinda ;-) but that is a good starting point..

I need to integrate this one...

https://github.com/Recras/angular-jquery-timepicker

@yaronmiz
Copy link

Hi,
I recently added formly to a new project and I am getting the same problem as juanpujol - that when the datepicker (from the example) gets the date from the server, the date field is not validated. Exactly the same issue.

To reproduce: Just go to the example in the UI datepicker page (http://angular-formly.com/#/example/integrations/ui-datepicker) - go to the JS and set a UTC date like vm.model = { date : '2015-08-31T21:00:00.000Z'};

You will see the error at the output

Any idea why?

@juanpujol
Copy link

@yaronmiz I did some research, and found out that since ui-bootstrap 0.13.2 they stopped support for strings on the datepicker, now only works with Date objects. This's a nightmare because if you formated your dates before now it will broke, also you can't control timezones and other problems, but at least there's an issue here: angular-ui/bootstrap#4287 (comment)

Give it a +1 so they can push a fix soon.

@kentcdodds
Copy link
Member

Perhaps you could use parsers to get around that issue...?

-Kent C. Dodds

On Thu, Sep 10, 2015 at 4:20 PM, Juan Pujol notifications@github.com
wrote:

@yaronmiz https://github.com/yaronmiz I did some research, and found
out that since ui-bootstrap 0.13.2 they stopped support for strings on the
datepicker, now only works with Date objects. This's a nightmare because if
you formated your dates before now it will broke, also you can't control
timezones and other problems, but at least there's an issue here: angular-ui/bootstrap#4287
(comment)
angular-ui/bootstrap#4287 (comment)

Give it a +1 so they can push a fix soon.


Reply to this email directly or view it on GitHub
#15 (comment)
.

@yaronmiz
Copy link

OK, i think I have a workaround for this issue:
At the SetType datePicker definition i have added the following to the controller:

// The date picker type
formlyConfigProvider.setType({
  name: 'datepicker',
  templateUrl: '/myDatepicker.html',
  wrapper: ['bootstrapLabel', 'bootstrapHasError'],
  defaultOptions: {
    ngModelAttrs: ngModelAttrs,
    templateOptions: {
      datepickerOptions: {
        format: 'yyyy/MM/dd',
        initDate: new Date()
      }
    }
  },
  controller: [
    '$scope', function ($scope) {
      $scope.datepicker = {};

      // make sure the initial value is of type DATE!
      var currentModelVal = $scope.model[$scope.options.key];
      if (typeof (currentModelVal) == 'string'){
        $scope.model[$scope.options.key] = new Date(currentModelVal);
      }


      $scope.datepicker.opened = false;

      $scope.datepicker.open = function ($event) {
        $scope.datepicker.opened = true;
      };
    }
  ]
});

Please let me know if this kind of workaround makes sense or is there better way to do it.
Thanks,
Yaron

@kentcdodds
Copy link
Member

That looks like a reasonable workaround to me! Thanks :-)

@juanpujol
Copy link

Thank you @yaronmiz your solution worked with ui-bootstrap 0.14.2

@juanpujol
Copy link

I tested a little more and I realize the date comes with the wrong timezone, same problem than before, expect that now we can't remove the timezone part because it needs to be a valid Date object.

Is anyone else having the same problem? Thanks,

@kentcdodds
Copy link
Member

@juanpujol, that sounds like an issue with ui-bootstrap...

@juanpujol
Copy link

@kentcdodds you're right, the issue angular-ui/bootstrap#4287 (comment) is still open there.

@yaronmiz
Copy link

You can have the timr zone to be part of either object or string format. The two work just fine
בתאריך 20 באוק׳ 2015 16:55,‏ Juan Pujol notifications@github.com כתב:I tested a little more and I realize the date comes with the wrong timezone, same problem than before, expect that now we can't remove the timezone part because it needs to be a valid Date object.

Is anyone else having the same problem? Thanks,

—Reply to this email directly or view it on GitHub.

@cerdrifix
Copy link

Hi,

I reused the code from http://jsbin.com/cadaga/2/edit?html,css,js in my project to add a datepicker to my fields list.
I noticed that datepicker is the only field not having a formControl attribute.
Have you got some suggestions on what can cause the issue? I can't figure out how to put my code in a jsbin, since it is part of a bigger project.
All the other stuff (fields creation, validation, etc..) works fine!

Thank you,
Davide.

@kentcdodds
Copy link
Member

@cerdrifix, that's surprising because the example itself adds a formControl just fine. Could you produce an example of what you're seeing? http://help.angular-formly.com

@johannesjo
Copy link

Any news on this one? I'm still struggeling with it.

@totallytotallyamazing
Copy link

@kentcdodds Yes I'm having the same issue too with datepicker not having a formControl attribute. Any help would be greatly appreciated. I did get formly to do realtime validation and datepicker working in angular 1.2, in order to support ie8.

@totallytotallyamazing
Copy link

totallytotallyamazing commented Jun 21, 2016

@kentcdodds @cerdrifix and @johannesjo I got my formControl and fields accepting datepicker objects by leaving the id="" and name="" attributes of the html template blank (see below):

   <script type="text/ng-template" id="datepicker.html">
        <p class="input-group">
            <input  type="text"
                id=""
                name=""
                ng-model="model[options.key]"
                class="form-control"
                ng-click="datepicker.open($event)"
                uib-datepicker-popup="{{to.datepickerOptions.format}}"
                is-open="datepicker.opened"
                datepicker-options="datepickerOptions"
                min-date="to.minDate"
                max-date="to.maxDate"
                date-disabled="to.dateWeekEndsDisabled(date, mode)" />
            <span class="input-group-btn">
                <button type="button" class="btn btn-default" ng-click="datepicker.open($event)" ng-disabled="to.disabled"><i class="glyphicon glyphicon-calendar"></i></button>
            </span>
        </p>
    </script>

Keep in mind that I could not use the one-time-binding syntax "::" in these attributes e.g. id="{{::}} name={{::id}}, because AngularJS 1.2 does not recognize one-time-binding syntax. Also you may notice that the "to." is taken out of datepicker-options="to.datepickerOptions", this was also part of getting it all working to support ie8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests