1

I am making an app, where I have a lot of input fields. Those input fields are generated from JSON object array field with AngularJS ngRepeat directive and have a button next to them which open an Angular UI Bootstrap modal to edit this value in a bigger textarea. I cannot figure out how to reference this model property to Angular UI Bootstrap so that I can save the changes made in modal. Since this functionality is needed in multiple views, I turned it into a service.

I have made a plunker to illustrate my problem.

http://plnkr.co/edit/ZrydC5UExqEPvVg7PXSq?p=preview

Currently in plunker example modal contains textarea, but I will actually need to use Text-Angular directive, because those fields contain some HTML markup and I would be easier for users to edit values with this nice addon.

TextAngular

EDIT: Please, if you are taking time to answer, you might aswell take a little more time to edit my plunker example to show exactly how your solution would look like, because seems that everyone who tries to help me, think they know the solution, but in reality it doesn't work :( Thanks!

2
  • Did you edit the Plunker so it now works? Commented Feb 19, 2015 at 6:24
  • No, but the accepted answer works, so try! Commented Feb 27, 2015 at 10:29

3 Answers 3

3

I personally like to decorate my $scope with the services (i.e. $scope.modalService = ModalService;), so I understand the source of the logic. In the ng-repeat you then pass the value item into the method call:

<div class="input-group">
    <input class="form-control" ng-model="value.value">
    <span class="input-group-addon" ng-click="modalService.openTextEditModal(value)">
       <span class="glyphicon glyphicon-align-justify"></span>
    </span>
</div>

The modal service and modal template would then reference the object, in this case a clone of the object to help with state management, not the text:

app.factory('ModalService', function($modal) {
    return {
        openTextEditModal: function(item) {
            var modalInstance = $modal.open({
                templateUrl: 'modal.html',
                backdrop: 'static',
                controller: function($scope, $modalInstance, $sce, item) {
                    var clone = {};
                    angular.copy(item, clone);
                    $scope.clone = clone;
                    $scope.close = function() {
                        $modalInstance.dismiss('cancel');
                    };
                    $scope.save = function() {
                      angular.extend(item, clone);
                      $modalInstance.close();
                    };
                },
                size: 'lg',
                resolve: {
                    item: function() {
                        return item;
                    }
                }
            });

        }
    };
});

With the corresponding modal template changes:

<div class="modal-header">
    <h3 class="modal-title">Edit text</h3>
</div>
<div class="modal-body">
    <textarea class="form-control" ng-model="clone.value"></textarea>
</div>
<div class="modal-body">
    <button class="btn btn-warning" ng-click="close()">Close</button>
    <button class="btn btn-success pull-right" ng-click="save()">Save</button>
</div>
Sign up to request clarification or add additional context in comments.

1 Comment

Finally a working answer. Glad you understood my problem. I will mark this as accepted answer. Thank you very much for help!
0

It might be easier to make a controller for your modal and pass in the objects that you need from your scope. Those will be passed by reference so changes to them will update the scope of your parent scope. Something like this in your MainCtrl :

 var modalInstance = ModalService.open({
            templateUrl: 'modal.html',
            controller: 'YourModalController',
            size: 'lg',
            resolve: {
                text: function () {
                    return $scope.editText;
                }
           }
        });

        modalInstance.result.then(function () {
        });

And then in your modal controller:

app.controller('YourModalController', ['$scope', '$modalInstance', 'text', function YourModalController($scope, $modalInstance, text) {

 $scope.text = text;
                    $scope.close = function() {
                        $modalInstance.dismiss('cancel');
                    };
                    $scope.save = function() {
                        $modalInstance.close($scope.text);
                    };

}]);

And if you want it to be reusable so you do not have to duplicate the modal instance code in the parent controller you could make that a directive.

1 Comment

I don't really understand how to make your solution work, so please modify my plunker to show me how it would work.
0

You can return the promise and then handle the success callback in the controller.

In the openTextEditModal function, return modalInstance.result;.

Then, in the controller you can do this:

$scope.editText = function(text){
    ModalService.openTextEditModal(text).then(function(newText){
        console.log(newText);
        $scope.text = newText; // do something with the new text
    });
};

1 Comment

You cannot write something like $scope.text = newText; because of the ngRepeat. Just try to make a working plunker and then you will understand the problem.

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.