0

I have a directive function scope.automaticallySelectClosingTime(). It takes the value of first selected dropdown value and creates a list of time on the second select drop-down. It triggers on ng-change.

Directive:

 .directive('closingTimeSync', function() {
    return {
      template: `<md-select ng-disabled="time.uiStoreOpen === false" ng-model="openCloseSet[1]">
                        <md-option ng-repeat="uiTime in closingTimes" ng-value="uiTime.msValue">
                            {{::uiTime.display}}
                        </md-option>
                    </md-select>`,
      replace: true,
      transclude: true,
      link: function(scope) {
        scope.automaticallySelectClosingTime = function(msValue) {
          scope.closingTimes = scope.uiAvailableTimes;
          var dayMS = 86400000 - 1;
          var remainingTimings = [];
          var index = scope.closingTimes.map(function(obj) {
            return obj.msValue;
          }).indexOf(msValue);
          index = (index === scope.uiAvailableTimes.length - 1) ? 1 : index + 1;
          scope.closingTimes = scope.closingTimes.slice(index, scope.uiAvailableTimes.length);
          if (msValue !== dayMS) {
            remainingTimings = scope.uiAvailableTimes.slice(1, index - 1);
          }
          scope.closingTimes = scope.closingTimes.concat(remainingTimings);
        };
      }
    };
  })

Controller .

.controller('TestCtrl', function($scope) {
     init();

    // CREATE AVAIABLE TIMES
    $scope.uiAvailableTimes = [];
    $scope.uiAvailableTimes.push({
      'msValue': 0,
      'display': '12:00 Morning'
    });
    for (var msValue = 900000; msValue <= 85500000; msValue += 900000) { // 90.000ms = 15 min, 85.500.000ms = 11:45PM
      $scope.uiAvailableTimes.push({
        'msValue': msValue,
        'display': moment(msValue).utc().format("h:mm A")
      })
    }
    var dayMS = 86400000 - 1;
    $scope.uiAvailableTimes.push({
      'msValue': dayMS,
      'display': '12:00 Midnight'
    });


    $scope.closingTimes = $scope.uiAvailableTimes;

    function init() {
      $scope.uiHoursOfOperation = [] // FROM SERVER
    }

  });

This works fine. But I've data that coming from the server as well. That means my select fields are preselected via ng-model.

How can I call the $scope.automaticallySelectClosingTime() from the controller. Maybe inside init(). So that it also creates the list of time to second drop-down on init() function call or on page load. And I don't have to create $scope.uiAvailableTimes in the controller.

Working Example: PLUNKER

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Raihan
  • 3,551
  • 3
  • 22
  • 38
  • 1
    Take a look here: https://stackoverflow.com/a/24161191/264607 for how to go about exposing an api on your directive – BlackICE May 27 '18 at 16:04
  • 1
    Because `ng-repeat` creates multiple child scopes, that function gets instantiated multiple times. There is no robust way to do it. (There are some flakey ways that are not worth the trouble). The best way is to have `ng-change` call a function in the parent controller with the index of the item, i.e. `ng-change="updateClosingTimeChoices($index)"`. Simply update the closing time choices when the opening time changes. – georgeawg May 27 '18 at 23:28
  • Consider using [angular-material-time-picker](https://github.com/classlinkinc/angular-material-time-picker). – georgeawg May 28 '18 at 05:03
  • Currently, I'm doing ng-change. like when I change the first drop-down 2nd dropdown do update(you can see the example 2nd dropdown start with 15min after of the selected value of the first drop-down). But I also need to change the 2nd dropdown when 1st dropdown data is loaded after page load. I need to trigger the scope.automaticallySelectClosingTime() somehow initially – Raihan May 28 '18 at 12:19

1 Answers1

1

try to add scope parameter to the directive, you can use this:

.directive('closingTimeSync', function() {
    return {
      template: `<md-select ng-model="ngModel" ng-disabled="time.uiStoreOpen === false" ng-model="openCloseSet[1]">
                        <md-option ng-repeat="uiTime in closingTimes" ng-value="uiTime.msValue">
                            {{::uiTime.display}}
                        </md-option>
                    </md-select>`,
      scope: {
            ngModel: '='
      },
      replace: true,
      transclude: true,
      link: function(scope) {
        scope.automaticallySelectClosingTime = function(msValue) {
          scope.closingTimes = scope.uiAvailableTimes;
          var dayMS = 86400000 - 1;
          var remainingTimings = [];
          var index = scope.closingTimes.map(function(obj) {
            return obj.msValue;
          }).indexOf(msValue);
          index = (index === scope.uiAvailableTimes.length - 1) ? 1 : index + 1;
          scope.closingTimes = scope.closingTimes.slice(index, scope.uiAvailableTimes.length);
          if (msValue !== dayMS) {
            remainingTimings = scope.uiAvailableTimes.slice(1, index - 1);
          }
          scope.closingTimes = scope.closingTimes.concat(remainingTimings);
        };
      }
    };
  })

and also you will need to add the ng-model inside the directive:

<closing-time-sync ng-model="paramFromController"></closing-time-sync>

hope that will resolve your issue.