0

How add buttons with on click handler to template in directive ?

I use this script, but it not work in controller.

I'm new in angular. I got this script from https://github.com/khan4019/tree-grid-directive/blob/master/README.md

(function() {
  var module;

  module = angular.module('treeGrid', []);

  module.directive('treeGrid', [
    '$timeout', '$compile', function ($timeout, $compile) {
      return {
        restrict: 'E',
        //templateUrl:'tree-grid-template.html',
        //template:"<div><table class=\"table table-bordered table-striped tree-grid\"><thead class=\"text-primary\"><tr><th>{{expandingProperty}}</th><th ng-repeat=\"col in colDefinitions\">{{col.displayName || col.field}}</th></tr></thead><tbody><tr ng-repeat=\"row in tree_rows | filter:{visible:true} track by row.branch.uid\" ng-class=\"'level-' + {{ row.level }} + (row.branch.selected ? ' active':'')\" class=\"tree-grid-row\"><td class=\"text-primary\"><a ng-click=\"user_clicks_branch(row.branch)\"><i ng-class=\"row.tree_icon\" ng-click=\"row.branch.expanded = !row.branch.expanded\" class=\"indented tree-icon\"></i></a><span class=\"indented tree-label\">{{row.branch[expandingProperty]}}</span></td><td ng-repeat=\"col in colDefinitions\">{{row.branch[col.field]}}</td></tr></tbody><table></div>",
        template:
          "<div>\
              <table class=\"table table-bordered table-striped tree-grid\">\
                  <thead class=\"text-primary\">\
                  <tr>\
                      <th>{{expandingProperty}}</th>\
                      <th ng-repeat=\"col in colDefinitions\">{{col.displayName || col.field}}</th>\
                      <th>Actions</th>\
                  </tr>\
                  </thead>\
                  <tbody>\
                  <tr ng-repeat=\"row in tree_rows | filter:{visible:true} track by row.branch.uid\"\
                      ng-class=\"'level-' + {{ row.level }} + (row.branch.selected ? ' active':'')\" class=\"tree-grid-row\">\
                      <td class=\"text-primary\"><a ng-click=\"user_clicks_branch(row.branch)\"><i ng-class=\"row.tree_icon\"\
                                 ng-click=\"row.branch.expanded = !row.branch.expanded\"\
                                 class=\"indented tree-icon\"></i>\
                          </a><span class=\"indented tree-label\" ng-click=\"user_clicks_branch(row.branch)\">\
                            {{row.branch[expandingProperty]}}</span>\
                      </td>\
                      <td ng-repeat=\"col in colDefinitions\">{{row.branch[col.field]}}</td>\
                      <td data-title=\"''\" style=\"width: 150px\">\
                            <button class=\"btn btn-sm btn-info\" ng-click=\"handleActions.edit(row)\">\
                                <i class=\"glyphicon glyphicon-edit\"></i> \
                            </button>\
                            <button class=\"btn btn-sm btn-info\" ng-click=\"createWindow()\">\
                                <i class=\"glyphicon glyphicon-plus\"></i> \
                            </button>\
                            <button class=\"btn btn-sm btn-info\" ng-show=\"row.deletable\" ng-click=\"handleActions.delete(row)\">\
                                <i class=\"glyphicon glyphicon-remove\"></i>\
                            </button>\
                        </td>\
                  </tr>\
                  </tbody>\
              </table>\
          </div>",
        //template:
        //  "<div>\
        //      <table class=\"table table-bordered table-striped tree-grid\">\
        //          <thead class=\"text-primary\">\
        //          <tr>\
        //              <th>{{expandingProperty}}</th>\
        //              <th ng-repeat=\"col in colDefinitions\">{{col.displayName || col.field}}</th>\
        //          </tr>\
        //          </thead>\
        //          <tbody>\
        //          <tr ng-repeat=\"row in tree_rows | filter:{visible:true} track by row.branch.uid\"\
        //              ng-class=\"'level-' + {{ row.level }} + (row.branch.selected ? ' active':'')\" class=\"tree-grid-row\">\
        //              <td class=\"text-primary\"><a ng-click=\"user_clicks_branch(row.branch)\"><i ng-class=\"row.tree_icon\"\
        //                         ng-click=\"row.branch.expanded = !row.branch.expanded\"\
        //                         class=\"indented tree-icon\"></i>\
        //                  </a><span class=\"indented tree-label\" ng-click=\"user_clicks_branch(row.branch)\">\
        //                    {{row.branch[expandingProperty]}}</span>\
        //              </td>\
        //              <td ng-repeat=\"col in colDefinitions\">{{row.branch[col.field]}}</td>\
        //          </tr>\
        //          </tbody>\
        //      </table>\
        //  </div>",
        replace: true,
        scope: {
          treeData: '=',
          colDefs:'=',
          expandOn:'=',
          onSelect: '&',
          initialSelection: '@',
          treeControl: '='
        },
        link: function (scope, element, attrs) {
          var error, expandingProperty, expand_all_parents, expand_level, for_all_ancestors, for_each_branch, get_parent, n, on_treeData_change, select_branch, selected_branch, tree;

          error = function(s) {
            console.log('ERROR:' + s);
            debugger;
            return void 0;
          };

          if (attrs.iconExpand == null) {
            attrs.iconExpand = 'icon-plus  glyphicon glyphicon-plus  fa fa-plus';
          }
          if (attrs.iconCollapse == null) {
            attrs.iconCollapse = 'icon-minus glyphicon glyphicon-minus fa fa-minus';
          }
          if (attrs.iconLeaf == null) {
            attrs.iconLeaf = 'icon-file  glyphicon glyphicon-file  fa fa-file';
          }
          if (attrs.expandLevel == null) {
            attrs.expandLevel = '3';
          }

          expand_level = parseInt(attrs.expandLevel, 10);

          if (!scope.treeData) {
            alert('no treeData defined for the tree!');
            return;
          }
          if (scope.treeData.length == null) {
            if (treeData.label != null) {
              scope.treeData = [treeData];
            } else {
              alert('treeData should be an array of root branches');
              return;
            }
          }
          if(attrs.expandOn){            
            expandingProperty = scope.expandOn;
            scope.expandingProperty = scope.expandOn;
          }
          else{
            var _firstRow = scope.treeData[0], 
                _keys = Object.keys(_firstRow);
            for(var i =0, len = _keys.length; i<len; i++){
              if(typeof(_firstRow[_keys[i]])=='string'){
                expandingProperty = _keys[i];
                break;
              }
            }
            if(!expandingProperty) expandingProperty = _keys[0];
            scope.expandingProperty = expandingProperty;
          }

          if(!attrs.colDefs){
            var _col_defs = [], _firstRow = scope.treeData[0], _unwantedColumn = ['children', 'level', 'expanded', expandingProperty];
            for(var idx in _firstRow){
              if(_unwantedColumn.indexOf(idx)==-1)
                _col_defs.push({field:idx});
            }            
            scope.colDefinitions = _col_defs;
          }
          else{
            console.log(scope.colDefs);
            scope.colDefinitions = scope.colDefs;
          }

          for_each_branch = function(f) {
            var do_f, root_branch, _i, _len, _ref, _results;
            do_f = function(branch, level) {
              var child, _i, _len, _ref, _results;
              f(branch, level);
              if (branch.children != null) {
                _ref = branch.children;
                _results = [];
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                  child = _ref[_i];
                  _results.push(do_f(child, level + 1));
                }
                return _results;
              }
            };
            _ref = scope.treeData;
            _results = [];
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
              root_branch = _ref[_i];
              _results.push(do_f(root_branch, 1));
            }
            return _results;
          };
          selected_branch = null;
          select_branch = function(branch) {
            if (!branch) {
              if (selected_branch != null) {
                selected_branch.selected = false;
              }
              selected_branch = null;
              return;
            }
            if (branch !== selected_branch) {
              if (selected_branch != null) {
                selected_branch.selected = false;
              }
              branch.selected = true;
              selected_branch = branch;
              expand_all_parents(branch);
              if (branch.onSelect != null) {
                return $timeout(function() {
                  return branch.onSelect(branch);
                });
              } else {
                if (scope.onSelect != null) {
                  return $timeout(function() {
                    return scope.onSelect({
                      branch: branch
                    });
                  });
                }
              }
            }
          };
          scope.user_clicks_branch = function(branch) {
            if (branch !== selected_branch) {
              return select_branch(branch);
            }
          };
          get_parent = function(child) {
            var parent;
            parent = void 0;
            if (child.parent_uid) {
              for_each_branch(function(b) {
                if (b.uid === child.parent_uid) {
                  return parent = b;
                }
              });
            }
            return parent;
          };
          for_all_ancestors = function(child, fn) {
            var parent;
            parent = get_parent(child);
            if (parent != null) {
              fn(parent);
              return for_all_ancestors(parent, fn);
            }
          };
          expand_all_parents = function(child) {
            return for_all_ancestors(child, function(b) {
              return b.expanded = true;
            });
          };

          scope.tree_rows = [];

          on_treeData_change = function() {
            var add_branch_to_list, root_branch, _i, _len, _ref, _results;
            for_each_branch(function(b, level) {
              if (!b.uid) {
                return b.uid = "" + Math.random();
              }
            });
            for_each_branch(function(b) {
              var child, _i, _len, _ref, _results;
              if (angular.isArray(b.children)) {
                _ref = b.children;
                _results = [];
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                  child = _ref[_i];
                  _results.push(child.parent_uid = b.uid);
                }
                return _results;
              }
            });
            scope.tree_rows = [];
            for_each_branch(function(branch) {
              var child, f;
              if (branch.children) {
                if (branch.children.length > 0) {
                  f = function(e) {
                    if (typeof e === 'string') {
                      return {
                        label: e,
                        children: []
                      };
                    } else {
                      return e;
                    }
                  };
                  return branch.children = (function() {
                    var _i, _len, _ref, _results;
                    _ref = branch.children;
                    _results = [];
                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                      child = _ref[_i];
                      _results.push(f(child));
                    }
                    return _results;
                  })();
                }
              } else {
                return branch.children = [];
              }
            });
            add_branch_to_list = function(level, branch, visible) {
              var child, child_visible, tree_icon, _i, _len, _ref, _results;
              if (branch.expanded == null) {
                branch.expanded = false;
              }
              if (!branch.children || branch.children.length === 0) {
                tree_icon = attrs.iconLeaf;
              } else {
                if (branch.expanded) {
                  tree_icon = attrs.iconCollapse;
                } else {
                  tree_icon = attrs.iconExpand;
                }
              }
              branch.level = level;
              scope.tree_rows.push({
                level: level,
                branch: branch,                
                label: branch[expandingProperty],                
                tree_icon: tree_icon,
                visible: visible
              });
              if (branch.children != null) {
                _ref = branch.children;
                _results = [];
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                  child = _ref[_i];
                  child_visible = visible && branch.expanded;
                  _results.push(add_branch_to_list(level + 1, child, child_visible));
                }
                return _results;
              }
            };
            _ref = scope.treeData;
            _results = [];
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
              root_branch = _ref[_i];
              _results.push(add_branch_to_list(1, root_branch, true));
            }
            return _results;
          };

          scope.$watch('treeData', on_treeData_change, true);

          if (attrs.initialSelection != null) {
            for_each_branch(function(b) {
              if (b.label === attrs.initialSelection) {
                return $timeout(function() {
                  return select_branch(b);
                });
              }
            });
          }
          n = scope.treeData.length;
          for_each_branch(function(b, level) {
            b.level = level;
            return b.expanded = b.level < expand_level;
          });
          if (scope.treeControl != null) {
            if (angular.isObject(scope.treeControl)) {
              tree = scope.treeControl;
              tree.expand_all = function() {
                return for_each_branch(function(b, level) {
                  return b.expanded = true;
                });
              };
              tree.collapse_all = function() {
                return for_each_branch(function(b, level) {
                  return b.expanded = false;
                });
              };
              tree.get_first_branch = function() {
                n = scope.treeData.length;
                if (n > 0) {
                  return scope.treeData[0];
                }
              };
              tree.select_first_branch = function() {
                var b;
                b = tree.get_first_branch();
                return tree.select_branch(b);
              };
              tree.get_selected_branch = function() {
                return selected_branch;
              };
              tree.get_parent_branch = function(b) {
                return get_parent(b);
              };
              tree.select_branch = function(b) {
                select_branch(b);
                return b;
              };
              tree.get_children = function(b) {
                return b.children;
              };
              tree.select_parent_branch = function(b) {
                var p;
                if (b == null) {
                  b = tree.get_selected_branch();
                }
                if (b != null) {
                  p = tree.get_parent_branch(b);
                  if (p != null) {
                    tree.select_branch(p);
                    return p;
                  }
                }
              };
              tree.add_branch = function(parent, new_branch) {
                if (parent != null) {
                  parent.children.push(new_branch);
                  parent.expanded = true;
                } else {
                  scope.treeData.push(new_branch);
                }
                return new_branch;
              };
              tree.add_root_branch = function(new_branch) {
                tree.add_branch(null, new_branch);
                return new_branch;
              };
              tree.expand_branch = function(b) {
                if (b == null) {
                  b = tree.get_selected_branch();
                }
                if (b != null) {
                  b.expanded = true;
                  return b;
                }
              };
              tree.collapse_branch = function(b) {
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  b.expanded = false;
                  return b;
                }
              };
              tree.get_siblings = function(b) {
                var p, siblings;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  p = tree.get_parent_branch(b);
                  if (p) {
                    siblings = p.children;
                  } else {
                    siblings = scope.treeData;
                  }
                  return siblings;
                }
              };
              tree.get_next_sibling = function(b) {
                var i, siblings;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  siblings = tree.get_siblings(b);
                  n = siblings.length;
                  i = siblings.indexOf(b);
                  if (i < n) {
                    return siblings[i + 1];
                  }
                }
              };
              tree.get_prev_sibling = function(b) {
                var i, siblings;
                if (b == null) {
                  b = selected_branch;
                }
                siblings = tree.get_siblings(b);
                n = siblings.length;
                i = siblings.indexOf(b);
                if (i > 0) {
                  return siblings[i - 1];
                }
              };
              tree.select_next_sibling = function(b) {
                var next;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  next = tree.get_next_sibling(b);
                  if (next != null) {
                    return tree.select_branch(next);
                  }
                }
              };
              tree.select_prev_sibling = function(b) {
                var prev;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  prev = tree.get_prev_sibling(b);
                  if (prev != null) {
                    return tree.select_branch(prev);
                  }
                }
              };
              tree.get_first_child = function(b) {
                var _ref;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  if (((_ref = b.children) != null ? _ref.length : void 0) > 0) {
                    return b.children[0];
                  }
                }
              };
              tree.get_closest_ancestor_next_sibling = function(b) {
                var next, parent;
                next = tree.get_next_sibling(b);
                if (next != null) {
                  return next;
                } else {
                  parent = tree.get_parent_branch(b);
                  return tree.get_closest_ancestor_next_sibling(parent);
                }
              };
              tree.get_next_branch = function(b) {
                var next;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  next = tree.get_first_child(b);
                  if (next != null) {
                    return next;
                  } else {
                    next = tree.get_closest_ancestor_next_sibling(b);
                    return next;
                  }
                }
              };
              tree.select_next_branch = function(b) {
                var next;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  next = tree.get_next_branch(b);
                  if (next != null) {
                    tree.select_branch(next);
                    return next;
                  }
                }
              };
              tree.last_descendant = function(b) {
                var last_child;
                if (b == null) {
                  debugger;
                }
                n = b.children.length;
                if (n === 0) {
                  return b;
                } else {
                  last_child = b.children[n - 1];
                  return tree.last_descendant(last_child);
                }
              };
              tree.get_prev_branch = function(b) {
                var parent, prev_sibling;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  prev_sibling = tree.get_prev_sibling(b);
                  if (prev_sibling != null) {
                    return tree.last_descendant(prev_sibling);
                  } else {
                    parent = tree.get_parent_branch(b);
                    return parent;
                  }
                }
              };
              return tree.select_prev_branch = function(b) {
                var prev;
                if (b == null) {
                  b = selected_branch;
                }
                if (b != null) {
                  prev = tree.get_prev_branch(b);
                  if (prev != null) {
                    tree.select_branch(prev);
                    return prev;
                  }
                }
              };
            }
          }
        }
      };
    }
  ]);

}).call(this);
3
  • 11
    I want to help, but there's too much blood in my eyes. Commented Sep 16, 2014 at 20:42
  • @m59 This is why I moved most of my projects to ReactJS at this point. Angular directive templates are disgusting :/ Commented Sep 16, 2014 at 20:52
  • 1
    @Mike the template should be in another file and using templateUrl, then included with $templateCache to optimize... Including the template inline was just one of the many amazing things about this code. Commented Sep 16, 2014 at 20:59

2 Answers 2

2

I see that you have added three buttons to the template in the directive:

<button class=\"btn btn-sm btn-info\" ng-click=\"handleActions.edit(row)\">\
  <i class=\"glyphicon glyphicon-edit\"></i> \
</button>\
<button class=\"btn btn-sm btn-info\" ng-click=\"createWindow()\">\
  <i class=\"glyphicon glyphicon-plus\"></i> \
</button>\
<button class=\"btn btn-sm btn-info\" ng-show=\"row.deletable\" ng-click=\"handleActions.delete(row)\">\
  <i class=\"glyphicon glyphicon-remove\"></i>\
</button>\

And you have added ng-click to them. Now, the functions that will be executed on the ng-click event, should be part of the scope.

In this case, when defining your directive, you are declaring a scope in the definition:

scope: {
      treeData: '=',
      colDefs:'=',
      expandOn:'=',
      onSelect: '&',
      initialSelection: '@',
      treeControl: '='
    }

So, you have created an Isolated scope. This means that the functions createWindow, edit and delete must be part of the directive scope.

You have two options, the dirty way: Copy your functions to the directive:

module.directive('treeGrid', [
[...]

<button class=\"btn btn-sm btn-info\" ng-click=\"edit(row)\">\
  <i class=\"glyphicon glyphicon-edit\"></i> \
</button>\
<button class=\"btn btn-sm btn-info\" ng-click=\"createWindow()\">\
  <i class=\"glyphicon glyphicon-plus\"></i> \
</button>\
<button class=\"btn btn-sm btn-info\" ng-show=\"row.deletable\" ng-click=\"delete(row)\">\
  <i class=\"glyphicon glyphicon-remove\"></i>\
</button>\

[...]
scope.user_clicks_branch = function(branch) {
        if (branch !== selected_branch) {
          return select_branch(branch);
        }
      };

// new code
scope.createWindow = function() {
    // your createWindow code
}
scope.edit = function(row) {
    // your edit row code
}
scope.delete = function(row) {
    // your delete row code
}

[...]
  ]);
}).call(this);

Or you can pass the handlers as parameters using the expression binding (&) (like the code is doing for the onSelect handler):

module.directive('treeGrid', [
[...]

<button class=\"btn btn-sm btn-info\" ng-click=\"onEdit(row)\">\
  <i class=\"glyphicon glyphicon-edit\"></i> \
</button>\
<button class=\"btn btn-sm btn-info\" ng-click=\"createWindow()\">\
  <i class=\"glyphicon glyphicon-plus\"></i> \
</button>\
<button class=\"btn btn-sm btn-info\" ng-show=\"row.deletable\" ng-click=\"onDelete(row)\">\
  <i class=\"glyphicon glyphicon-remove\"></i>\
</button>\

[...]
scope: {
      treeData: '=',
      colDefs:'=',
      expandOn:'=',
      onSelect: '&',
      createWindow: '&',
      onEdit: '&',
      onDelete: '&',
      initialSelection: '@',
      treeControl: '='
    }
[...]
  ]);
}).call(this);
Sign up to request clarification or add additional context in comments.

1 Comment

A can't use templateUrl because I have ng-class=\"'level-' + {{ row.level }} + (row.branch.selected ? ' active':'')\" class=\"tree-grid-row\">\ which throw exception
0

If you want only add some buttons to a column, you can add in columns definition using $scope.col_def in your controller, like this:

$scope.col_defs = [{ field: "id" }, 
            {
                field: "Action",
                cellTemplate: $templateCache.get('buttonTemplate.html'),
                cellTemplateScope: {
                    doSomething: function () {                            
                        console.log('call your function here, or put what you want to do');
                    }
                }
            }];

and the 'buttonTemplate.html' can be defined in your view, inside the controller, and define the col_defs in the treeGrid:

<div ng-controller="HomeController">        
    <script type="text/ng-template" id="buttonTemplate.html">
        <button class="btn btn-sm btn-danger" ng-click="cellTemplateScope.doSomething()">Do Something</button>
    </script>

    <tree-grid tree-data="yourTreeData" col-defs="col_defs"></tree-grid>
</div>

So it will run this template inside your column, and call the function doSomething() when you click on the button, in this case.

Comments

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.