3

I am new to Angularjs and working on a pet project. I have a main page which has functions in HomeController. Then I have a button in the main page which on click opens a modal and the modal has a separate controller called ModalController. There is also a directive which is present in the modal which has its own controller. I have 3 other places where I need to use date picker so I created a date picker directive and using it in all 3 places.

I am not able to do the below functionalities.

  1. Click on edit I opened a dialog but I need to open it with the row data and when pressed save should update the row. (The trouble I am facing here is how to get the value of the date which is directive's controller.)
  2. Open Modal and enter the details and click save I need to create a new record and add it to the records which is present in the main controller. (How save the data from Modal controller to Home controller records.)

script.js

angular.module('myApp', ['ngAnimate', 'ui.bootstrap']);
angular.module('myApp').controller('HomeController', function($scope, $uibModal) {

  $scope.records = [{'date': new Date(), 'place': 'Bangalore'}];

    $scope.openModal = function() {
      $uibModal.open({
        templateUrl: 'modaldialog.html',
        controller: 'ModalController'
      });
    };

    // How to get the directive date-picker value and pass it and save it.
    $scope.edit = function(record) {
      $uibModal.open({
        templateUrl: 'modaldialog.html',
        controller: 'ModalController'
      });
    };

    $scope.addwithinCtrl = function() {
      var record = {'date': new Date(), 'place': 'Hyderabad'};
      $scope.records.push(record);
    };

});

angular.module('myApp').controller('ModalController', function($scope, $uibModalInstance) {
  // save the input and dismiss the dialog
  $scope.save = function() {
    // how to save the entered data before closing the dialog?
    $uibModalInstance.dismiss('cancel');
  };

  $scope.cancel = function() {
    $uibModalInstance.dismiss('cancel');
  };
});


angular.module('myApp').directive('dateDirective', function() {
  return {
    restrict: 'A',
    templateUrl: 'date.html',
    controller: function($scope) {
      $scope.format = 'dd-MMM-yy';

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

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

Plunker: PLUNKER

2
  • I checked your code and did not get why did you wrap all angular-ui directives with your ones. Can you tell me why did you write another directive for datepicker as you already use uib-datepicker inside? Commented Nov 13, 2015 at 7:52
  • @wickY26 I checked your code and did not get why did you wrap all angular-ui directives with your ones I am not getting it as I am a beginer here. Can you elaborate? Commented Nov 13, 2015 at 8:31

1 Answer 1

3

There are multiple steps you need to make yet in order to complete your task. I will give you a good start regarding passing data to and from modal controller and setting proper date to datepicker.

First of all, make sure you isolate scope of the datepicker, it would make your life simpler in future. Then pass necessary model into this directive and bind it to datepicker (in datepicker template ng-model="model"):

angular.module('myApp').directive('dateDirective', function() {
    return {
        scope: {
            model: '=ngModel'
        },
        // ... rest of code is unchanged 
    }
});

Then you need to pass record object into modal controller. For this you would use resolve instruction of the modal:

$scope.edit = function(record) {
    $uibModal.open({
        resolve: {
            record: record
        },
        templateUrl: 'modaldialog.html',
        controller: 'ModalController'
    });
};

where in HTML you need to pass record to the edit function:

<button class="btn btn-primary" type="button" ng-click="edit(record)">edit</button>

Finally, in order to update the original record you would need to subscribe to resolved promise returned by $uibModal.open method:

.controller('ModalController', function($scope, $uibModalInstance, record) {

    $scope.record = angular.copy(record);

    $uibModalInstance.result.then(function() {
        angular.extend(record, $scope.record);
    });

    // ...
});

Note, that in modal controller you need to make a copy of the original record and use it in modal template. This is necessary because you want to affect original record only if Save is pressed - then you extend original model with changed data.

Demo: http://plnkr.co/edit/Hq0wFilQpZ26Ha2nyNxN?p=info

Adding new record from outside of controller

As for your second question, this is another interesting question. Since in your original code you stored records in the scope array, this is actually not really convenient design solution for adding new records. In real world you would likely have a separate model layer responsible for fetching existing and creating new records. In Angular you use services for this. So you need to register a new service object with methods to get, update and save records. In terms of MVC it would correspond to M-layer. Then whenever you want to add new record from any controller you would use this service which is singleton object same in every controller.

Here is an example of very simple service in your case:

angular.module('myApp').service('records', function() {

    this.data = [{
        'date': new Date(),
        'place': 'Bangalore'
    }];

    this.fetch = function() {
        return this.data;
    };

    this.save = function(record) {
        this.data.push(record);
    };
});

And finally, here is complete example for your problem which can save new records both from controller and from outside using services and also allows editing.

Demo: http://plnkr.co/edit/NxP0HJurZuLA7odzzdie?p=preview

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

4 Comments

Thanks. I have few questions here. 1. Isolating date picker suggestion is good as i am using it in multiple places. So how do we make it isolated? Also what does scope : { model: ="ngModel" } do ? 2. When I click on save it calls $uibModalInstance.close(). So it inturn calls $uibModalInstance.result.then function? 3. Can you also answer my second question? That is how to add new record from model controller to HomeCtrl? I am able to add within the HomeCtrl but not outside of it.
1. {model: ="ngModel"} instructs that new isolated scope should be created for directive. Isolated scope.model will be bound to outer scope expression passed in ng-model attribute. 2. $uibModalInstance.result is a promise object. When you call $uibModalInstance.close it resolved this promise and all callbacked registered with $uibModalInstance.result.then get invoked. 3. will update the answer shortly.
See complete final example for your problem with some explanations.
Great. I heard about service thanks for example. Now I am able to do delete also by adding delete method in service. Keep rocking.

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.