OpenVeo AngularJS back end

API Docs for: 7.0.0
Show:

File: app/client/admin/js/ov/DateTimePickerController.js

'use strict';

(function(app) {

  /**
   * Manages ovDateTimePicker directive.
   *
   * @class OvDateTimePickerController
   * @constructor
   * @param {Object} $element The HTML element holding the component
   * @param {Object} $timeout AngularJS $timeout service
   * @param {Object} $scope Directive isolated scope
   */
  function OvDateTimePickerController($element, $timeout, $scope) {
    var ctrl = this;
    var ngModelCtrl = $element.controller('ngModel');
    var datePickerNgModelCtrl;
    var timePickerNgModelCtrl;

    Object.defineProperties(ctrl, {

      /**
       * Indicates if the calendar is opened or not.
       *
       * @property calendarIsOpened
       * @type Boolean
       */
      calendarIsOpened: {
        value: false,
        writable: true
      },

      /**
       * The date.
       *
       * @property date
       * @type Date
       */
      date: {
        value: null,
        writable: true
      },

      /**
       * The time.
       *
       * @property time
       * @type Date
       */
      time: {
        value: null,
        writable: true
      },

      /**
       * Sets blur listeners on AngularJS Bootstrap time picker inputs.
       *
       * Date time picker component should be set as touched focus leaves one of the time picker inputs.
       *
       * @method $postLink
       */
      $postLink: {
        value: function() {

          // Wait for the end of the digest loop to be able to access time picker template elements.
          // Time picker template is loaded from templates cache
          $timeout(function() {
            var inputElements = $element[0].querySelectorAll('.ov-time-picker input');
            var datePickerElement = angular.element($element[0].querySelector('input[uib-datepicker-popup]'));
            var timePickerElement = angular.element($element[0].querySelector('div[uib-timepicker]'));

            for (var i = 0; i < inputElements.length; i++) {
              var inputElement = inputElements[i];
              angular.element(inputElement).on('blur', ctrl.setAsTouched.bind(ctrl));
            }

            // Retrieve date picker and time picker ngModel controllers
            datePickerNgModelCtrl = datePickerElement.controller('ngModel');
            timePickerNgModelCtrl = timePickerElement.controller('ngModel');
          });

        }
      },

      /**
       * Opens the date picker.
       *
       * @method openDatePicker
       */
      openDatePicker: {
        value: function() {
          ctrl.calendarIsOpened = true;
        }
      },

      /**
       * Sets the model using both date and time.
       *
       * @method updateModelValue
       */
      updateModelValue: {
        value: function() {
          if (!datePickerNgModelCtrl || !timePickerNgModelCtrl) return;
          ngModelCtrl.$setValidity('dateTime', (datePickerNgModelCtrl.$valid && timePickerNgModelCtrl.$valid));

          if (datePickerNgModelCtrl.$invalid || timePickerNgModelCtrl.$invalid) return;

          if (!ctrl.date) return ngModelCtrl.$validate();

          var date = angular.copy(ctrl.date);
          date.setHours(ctrl.time ? ctrl.time.getHours() : 0);
          date.setMinutes(ctrl.time ? ctrl.time.getMinutes() : 0);
          date.setSeconds(0);
          ngModelCtrl.$setViewValue(date);
          ngModelCtrl.$validate();
        }
      },

      /**
       * Sets form element as touched.
       *
       * @method setAsTouched
       */
      setAsTouched: {
        value: function() {
          ngModelCtrl.$setTouched();
        }
      }

    });

    /**
     * Renders the value using the model.
     *
     * The directive stores two dates: one for the date and one for the time. The model is a single date with both
     * date and time.
     *
     * It overrides AngularJS $render.
     */
    ngModelCtrl.$render = function() {
      ctrl.date = angular.copy(ngModelCtrl.$viewValue);
      ctrl.time = angular.copy(ngModelCtrl.$viewValue);
    };

    /**
     * Tests if the model is empty.
     *
     * It overrides AngularJS $isEmpty.
     *
     * @param {Date} value The date
     * @return {Boolean} true if no date, false otherwise
     */
    ngModelCtrl.$isEmpty = function(value) {
      return !ctrl.date;
    };

    /**
     * Tests if Bootstrap date picker and time picker are valid.
     *
     * @return {Boolean} true if both date picker and time picker are valid, false otherwise
     */
    ngModelCtrl.$validators.dateTime = function() {
      if (!datePickerNgModelCtrl || !timePickerNgModelCtrl) return true;
      return (datePickerNgModelCtrl.$valid && timePickerNgModelCtrl.$valid);
    };

    // Listen to date picker and time picker modifications
    $scope.$watch('$ctrl.date', ctrl.updateModelValue.bind(ctrl));
    $scope.$watch('$ctrl.time', ctrl.updateModelValue.bind(ctrl));

  }

  app.controller('OvDateTimePickerController', OvDateTimePickerController);
  OvDateTimePickerController.$inject = ['$element', '$timeout', '$scope'];

})(angular.module('ov'));