0

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

1 Answer 1

0
  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)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.