Slava
Slava

Reputation: 6650

How to make date input max attribute work in custom angular 1.5 component?

I wrote this custom component:

<datetime value="vm.woComplete.CompleteDate" max="2016-10-25"></datetime>

max attribute doesnt work as it should in html5 validation date input.

Why?

// DateTimeComponent is used for date/time input with 2-way binding and UTC correction

namespace AppDomain {
    "use strict";

    class DateTimeController {

        value: Date;
        displayValue: Date;
        max: string;

        static $inject = ["$scope"];

        // West from UTC - TimezoneOffset is positive , East from UTC - TimezoneOffset is negative

        constructor($scope: ng.IScope) {
            $scope.$watch(
                "$ctrl.displayValue",
                (newValue: Date, oldValue: Date) => {
                    this.value = newValue;
                    var offset = this.displayValue.getTimezoneOffset() / 60;  // getTimezoneOffset returns minutes, we need hours
                    this.value.setHours(this.value.getHours() + offset); // LOCAL to UTC = UTC + Offset

                }
            );
        }

        $onInit() {
            this.displayValue = this.value;
            var offset = this.displayValue.getTimezoneOffset() / 60; // getTimezoneOffset returns minutes, we need hours
            this.displayValue.setHours(this.displayValue.getHours() - offset); // UTC to LOCAL = UTC - Offset
        }
    }

    const DateTimeComponent: ng.IComponentOptions = {

        //template: "<p><input type='date' class='form-control' ng-model='$ctrl.displayValue'></p><p><input type='time' class='form-control' ng-model='$ctrl.displayValue'></p>",
        template: "<p><input type='datetime-local' class='form-control' ng-model='$ctrl.displayValue' max='{{$ctrl.max}}'></p>",
        bindings: {
            value: "=",
            max: "@"
        },
        controller: DateTimeController

    };

    angular.module("app").component("datetime", DateTimeComponent);
}

Plunker: http://plnkr.co/edit/iYt0sS?p=preview

Upvotes: 0

Views: 482

Answers (1)

Andriy
Andriy

Reputation: 15442

  1. max attribute for date input should be in format yyyy-mm-dd, so your component should be (max is set to October 28th for this example):

    <datetime value="app.dateTime" max="2016-10-28"></datetime>
    
  2. getHours() function returns local (not universal like getUTCHours()), so you do not need to add and subtract offset hours, it is calculated by the JS Date object.

  3. in your component you do not need a $watch and $init, just set value's binding as displayValue: '=value':

    namespace myApp {
      const dateTimeComponent = {
        templateUrl: 'app/datetime.component.html',
        bindings: {
          displayValue: '=value',
          max: '@'
        }
      };
    
      angular.module('app').component('datetime', dateTimeComponent);
    }
    

plunker: http://plnkr.co/edit/fFNY9C?p=preview

BTW, date type input has different behavior in different browsers, in some browsers (MAC Firfox, >IE10) calendar is not displayed at all. Styling and error messages are different, so, I would recommend you some third party widgets like bootstrap UI date picker - https://angular-ui.github.io/bootstrap/#/datepicker (probably along with time picker - https://angular-ui.github.io/bootstrap/#/timepicker)

Upvotes: 0

Related Questions