Action Button in Angular UI Grid 3.x version
Asked Answered
I

4

23

I am trying to render a simple table using Angular UI Grid (unstable version). Against each row I need a button when clicked should be handled in my parent controller.

Plunker

Javascript:-

angular.module("app", ['ui.grid', 'ui.grid.edit', 'ui.grid.selection', 'ui.grid.pagination', 'ui.grid.expandable', 'ui.grid.paging']).controller("appController", function($scope) {
  console.log("Controller is up.");
  $scope.data = [];
  for (var i = 0; i < 50; i++) {
    $scope.data.push({
      fullName: "Name" + i,
      age: i
    });
  }

  $scope.clickHandler = function(){
    // this never gets invoked ?!
    console.log("Row Action click Handler.");
  };


  $scope.gridOptions = {
    data: $scope.data,
    columnDefs:[ {name:'fullName',field:'fullName'},
              {name:'age',field:'age'},
              {name:' ',cellTemplate:'<div><button ng-click="clickHandler()">Click Here</button></div>'}
            ]
  };
});

HTML

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.min.css">
  <link rel="stylesheet" href="style.css">
     <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-touch.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-animate.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
    <script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
    <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" type="text/css">
  <script src="script.js"></script>
</head>

<body data-ng-app="app">
  <h1>Angular UI Grid unstable</h1>
  <div data-ng-controller="appController">
    <div class="grid" ui-grid="gridOptions">
      Test 
    </div>
  </div>

</body>

</html>

As in code, to render the action button I have used columnDefs with inline template for the third column.

PROBLEM

Clicking the button doesn't work. I expect ' $scope.clickHandler' function to be executed on click. Also, I should be able to pass 'name' as argument to the click handler.

Islander answered 23/12, 2014 at 13:25 Comment(3)
Here's a plunker with similar usage and it seems to fire ng-click inside clickhandler: plnkr.co/edit/BZKiZoevJQ1YgR0w7yy6?p=previewNitrate
@trainoasis; Your plunker seems to be working fine.But, 1) You are using ng-grid (the older version of UI Grid) 2) What is wrong in mine ?Islander
This plunker is not mine, just found it while searching for your solution. I can't see anything really wrong with yours at the moment, I suggest you go side-by-side with the working one and perhaps find your issueNitrate
N
21

In the new ui-grid everything happens in an isolated scope. So they added functionality to handle external scopes.

Here is what to do:

In the html define you grid like this:

<div class="grid" external-scopes="clickHandler" ui-grid="gridOptions">

Also add the external scope object (with a callable function) to your controller:

 $scope.clickHandler = {
     onClick : function(value){
        alert('Name: '+value);
     }
 };

Finally define your cellTemplate like this:

{
    name:'Action',
    cellTemplate: '<div><button ng-click="getExternalScopes().onClick(row.entity.fullName)">Click Here</button></div>'
}

Here is your forked Plunker

Negatron answered 23/12, 2014 at 16:32 Comment(2)
Thanks. It is working. Where can I read about this new 'isolated' scope approach?Islander
FYI, you can use grid.appScope with appScopeProvider instead of external-scopesDeaconess
F
41

Easier than @mainguy in my opinion is:

Adding grid.appScope. before your $scope member.
For example in your case to call $scope.clickHandler:

cellTemplate:'<button ng-click="grid.appScope.clickHandler()">Click Here</button>'
Freda answered 20/4, 2015 at 15:25 Comment(0)
N
21

In the new ui-grid everything happens in an isolated scope. So they added functionality to handle external scopes.

Here is what to do:

In the html define you grid like this:

<div class="grid" external-scopes="clickHandler" ui-grid="gridOptions">

Also add the external scope object (with a callable function) to your controller:

 $scope.clickHandler = {
     onClick : function(value){
        alert('Name: '+value);
     }
 };

Finally define your cellTemplate like this:

{
    name:'Action',
    cellTemplate: '<div><button ng-click="getExternalScopes().onClick(row.entity.fullName)">Click Here</button></div>'
}

Here is your forked Plunker

Negatron answered 23/12, 2014 at 16:32 Comment(2)
Thanks. It is working. Where can I read about this new 'isolated' scope approach?Islander
FYI, you can use grid.appScope with appScopeProvider instead of external-scopesDeaconess
C
6

Similar to @gdoron's answer but for controllerAs syntax. In your controller, you should set appScopeProvider option to point to this object:

this.gridOptions = {
  ...,
  appScopeProvider: this
};

Then, cellTemplate:'<button ng-click="grid.appScope.clickHandler()">Click Here</button>'

FYI: by default, the parent scope of the ui-grid element will be assigned to grid.appScope this property allows you to assign any reference you want to grid.appScope

Cyclopropane answered 25/11, 2015 at 15:6 Comment(1)
You can also do grid.appScope.{controllerAs variable here}.clickHandler() so if your controllerAs variable was 'm', you could do grid.appScope.m.clickHandler().Fibre
Y
0

Have notice, if you are using routing config instead of assigning the app-controller directly, getExternalScopes() method works as expected with one note

in the respective controller, assign the below statement $scope.gridScope = $scope;

Yehudit answered 1/6, 2015 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.