1

i am trying to add rows and columns dynamically into an HTML table with an button on the column header wich pop-up an alert message withe angularJs ng-click.

My columns and rows are added correctly withe jQuery, however, when the button is clicked, it doesn't call my alert function "hello()" in the controler ! 

here's my jsfiddle link for the issue: https://jsfiddle.net/said_kossouri/cw3f119h/

HTML:

<div ng-app ng-controller="LoginController">
 <table  border="1" id="mtable" class="table table-striped">
      <thead><tr>
          <td>Item</td>
          <td><button id="deleteColl">Ok</button></td>

        </tr></thead>

      <tbody><tr>
        <td>Some Item</td>
        <td><input type="text"/></td>

      </tr></tbody>

  </table><br/>
  <button ng-click="addRow()" id="irow">+ Row</button>
  <button ng-click="addCol()" id="icol">+ Column</button>

JS:

function LoginController($scope) {
    $scope.addRow = function () {
    $('#mtable tbody').append($("#mtable tbody tr:last").clone());
    $('#mtable tbody tr:last :checkbox').attr('checked',false);
    $('#mtable tbody tr:last td:first').html($('#row').val());
  }

  $scope.addCol = function () {
    $('#mtable tr').append($("<td>"));
    $('#mtable thead tr>td:last').html('<button ng-click="hello()">Hello!</button>');
    $('#mtable tbody tr').each(function(){$(this).children('td:last').append($('<input type="text">'))});   
  }  

  $scope.hello = function () {
    alert("HELLO");
  }

}
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • _My columns and rows are added correctly withe jQuery_ - This is not "correctly" at all. Why on earth do you put jQuery code inside a controller? Use `ngRepeat` or any other build-in angular directive. [Relevant tutorial](http://www.w3schools.com/angular/ng_ng-repeat.asp) – Alon Eitan Jan 27 '17 at 21:02
  • If you're using angular, IMO it's better to use a different approach. Instead of adding rows with jQuery, just modify `ng-model` which generates rows (by the way you're not doing that right now) and angular will update the table itself :) For your code I wonder why are you using angular and jQuery at the same time. It doesn't seem that you need to. Regards! – lealceldeiro Jan 27 '17 at 21:19

3 Answers3

2

The problem is with different context, process/execution time. The best way is to use only jQuery or Angularjs.

Using just Angularjs:

  • Use a object to represent the table (matrix)
  • Add row function will append a row to table object
  • Add col function will append a column on a row in the table object

Init table object:

$scope.table = [];

Add row function:

$scope.addRow = function () {
    $scope.table.push([]);
}

Add col function

$scope.addCol = function (row) {
    row.push('col value');
}

Rendering the table with Angularjs:

<!-- rows -->
<tr ng-repeat="row in table">
    <!-- cols -->
    <td ng-repeat="col in row">
        {{ col }}
    </td>

    <td>
        <button type="button" ng-click="addCol(row)">New col</button>
    </td>
</tr>

<button type="button" ng-click="addRow()">New row</button>

As the addCol function need the column target to add new item, the action button need be inside the row.

rogeriolino
  • 1,095
  • 11
  • 21
1

I suppose you're from JQuery world

Here are a couple of rule of thumbs to use AngularJS

  1. You should not use AngularJS and JQuery combined. Unless you are creating custom directives or components.

  2. For tasks with repetitive actions you should use ng-repeat.

Keep in mind that JQuery is based on DOM manipulation while AngularJS performs view modification through controller.. Keep it always in mind and welcome to angular world.

Have a look at the angular.org they have very great tutorials as well as free courses

-1

i found exactly what i was looking for in the answer for the issu in the link and the code below: create a dynamic json matrix by using angularjs

    angular.module('App', [])
    .controller('MainCtrl', ['$scope', function($scope) {
      $scope.matrix = [[0]];
      
      $scope.addColumn = function() {
        $scope.matrix.forEach(function(row) {
          row.push(0);
        });
      };
      
      $scope.addRow = function() {
        var columnCount = $scope.matrix[0].length;
        var newRow = [];
        for (var i = 0; i < columnCount; i++) {
          newRow.push(0);
        }
        $scope.matrix.push(newRow);
      };

      $scope.deleteRow = function(idx) {
        if (idx >= 0 && idx < $scope.matrix.length) {
          $scope.matrix.splice(idx, 1);
        }
      };
      
      $scope.deleteColumn = function(idx) {
        if (idx >= 0 && idx < $scope.matrix[0].length) {
          $scope.matrix.forEach(function(row) {
            row.splice(idx, 1);
          });
        }
      };

    }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
    <div ng-app="App" ng-controller="MainCtrl">
      <table>
        <tbody>
          <tr>
            <th></th>
            <th ng-repeat="column in matrix[0] track by $index">
              <button ng-disabled="matrix[0].length <= 1"
                      ng-click="deleteColumn($index)">
                Delete
              </button>
            </th>
          </tr>
          <tr ng-repeat="row in matrix">
            <th>
              <button ng-disabled="matrix.length <= 1"
                      ng-click="deleteRow($index)">
                Delete
              </button>
            </th>
            <td ng-repeat="column in row track by $index">
              <input type="number" ng-model="row[$index]">
            </td>
          </tr>
        </tbody>
      </table>
      <button type="button" ng-click="addRow()">Add Row</button>
      <button type="button" ng-click="addColumn()">Add Column</button>
      <h3>As JSON:</h3>
      <pre><code>{{matrix | json}}</code></pre>
    </div>