Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the AngularJS way of handling a modal like this

Tags:

angularjs

I know you're not supposed to put your display logic inside of a controller and I'm struggling with the proper AngularJS way to approach this.

I'm presenting forms inside modals. I'm using Zurb Foundation's reveal for the modal.

Markup:

<div class="button" ng-click="modalAddWidget">Add Widget</div>
<div id="modalAddWidget" class="reveal-modal">
  <h6>New Widget</h6>
  <form>
    <fieldset>
      <legend>Widget Name</legend>
      <input type="text" ng-model="ui.add_widget_value" />
    </fieldset>
    <div class="small button right" ng-click="addWidget()">Add Widget</div>
    <div class="small button right secondary" ng-click="addWidgetCancel()">Cancel</div>
  </form>
</div>

Controller:

  ...
  $scope.modalAddWidget = function() {
    $("#modalAddWidget").reveal();
  }
  $scope.addWidget = function() {
    $scope.myobject.widgets.push({"name": $scope.ui.add_widget_value});
    $scope.ui.add_widget_value = '';
    $('#modalAddWidget').trigger('reveal:close');
  }
  $scope.addBudgetCancel = function() {
    $scope.ui.add_widget_value = '';
    $('#modalAddWidget').trigger('reveal:close');
  }
  ...

Note: $scope.ui is an object I am using to store UI values that shouldn't be bound to my object until the user actually clicks "Add Widget"

$scope.myobj is where my data is stored.

Foundation's $("#modalAddWidget").reveal(); function presents the modal overlay.

Since I shouldn't be putting my display code inside the controller, what is the proper way to approach this?

like image 839
Coder1 Avatar asked Feb 19 '13 20:02

Coder1


People also ask

How to close popup window in AngularJS?

By default, dialog can be closed by pressing Esc key and clicking the close icon on the right of dialog header. It can also be closed by clicking outside of the dialog using hide method. Set the closeOnEscape property value to false to prevent closing of the dialog when pressing Esc key.


1 Answers

You don't want to manipulate the DOM (or even reference it) from your controllers.

A directive is best here.

app.directive('revealModal', function (){
   return function(scope, elem, attrs) {
     scope.$watch(attrs.revealModal, function(val) {
        if(val) {           
           elem.trigger('reveal:open');
        } else {
           elem.trigger('reveal:close');
        }
     });
     elem.reveal();
   }
});

then in your controller:

$scope.modalAddWidget = function (){
   $scope.ui = { add_widget_value: '' };
   $scope.showModal = true;
};

$scope.addWidget = function (){
    $scope.myobject.widgets.push({"name": $scope.ui.add_widget_value});
    $scope.ui.add_widget_value = '';
    $scope.showModal = true;
};

And in your HTML

<div class="button" ng-click="modalAddWidget()">Add Widget</div>
<div id="modalAddWidget" class="reveal-modal" reveal-modal="showModal">
  <h6>New Widget</h6>
  <form name="addWidgetForm" ng-submit="addWidget()">
    <fieldset>
      <legend>Widget Name</legend>
      <input type="text" name="widgetValue" ng-model="ui.add_widget_value" required />
      <span ng-show="addWidgetForm.widgetValue.$error.required">required</span>
    </fieldset>
    <button type="submit" class="small button right">Add Widget</button>
    <div class="small button right secondary" ng-click="showModal = false;">Cancel</div>
  </form>
</div>

Basically you'd set a boolean in your scope to show and hide your modal. (I'm not sure of reveal modal's open/close mechanism, so I'm guessing in my code above).

ALSO: I went through the effort of adding some validation in there.

like image 101
Ben Lesh Avatar answered Dec 09 '22 05:12

Ben Lesh