jAYANT YADAV jAYANT YADAV - 3 months ago 11
AngularJS Question

adding a cell to table using add button

I am trying to make a Dynamic table in Angular.js, in which the user inputs number of columns, in a text box provided. Then add buttons are provided under each column to add as much cells as user wants. The cell will only be added to that column only.
I am using ng-repeat to repeat the number of columns and add buttons.
I am able to get the response of the user in a variable, ie, the column under which the user wants to add the cell.
Can someone please give me a controller to add a cell to the selected column either by using ng-repeat , ng-model or without it.
my table code looks somewhat like this:

<table>
<tr>
<th ng-repeat="n in arr track by $index">SET {{n.setalpha}} </th><!--table heading, dont mind this-->
</tr>
<tr ng-repeat="<!--something goes here-->">
<!--<select ng-model="name" ng-options="options.topicname for options in topics"></select>-->
</tr>
<tr>
<td ng-repeat="n in arr track by $index">
<button ng-click="addSelected($index+1)">add{{$index+1}}</button>
</td>
</tr>
</table>


where:
n in arr track by $index
, is used to repeat the table heading and add button say 'n' number of times and
addSelected($index+1)
is a function whose controller is:

$scope.addSelected = function (setno) {
console.log(setno);
$scope.thisset = setno;

}


,
$scope.thisset
is the variable in which i have the response of the user, ie, the column under which the user wants to add a cell.
NOTE: I want to add the cell in column only under which the user wants. NOT in all columns. MY CODE:



var app = angular.module('topicSelector', []);


app.controller('topicController', function ($scope) {

$scope.arr = [];
$scope.thisset = -1; //tells in which set, cell has to added.



$scope.topics = [
{
topicid: "1",
topicname: "history"
},
{
topicid: "2",
topicname: "geography"
},
{
topicid: "3",
topicname: "maths"
}
];








$scope.DefineSets = function () {

for (var i = 1; i <= $scope.no_of_sets; i++) {
$scope.arr.push({
setno: i,
setalpha: String.fromCharCode(64 + i)
});

};
};

$scope.addSelected = function (setno) {
console.log(setno);
$scope.thisset = setno;

}



});

table {
width: 100%;
}

<!doctype html>
<html ng-app="topicSelector">

<head>
<title>
topic selector
</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
<h3>Enter number of sets:</h3>
<div ng-controller="topicController">
<form ng-submit="DefineSets()">
<input type="text" ng-model="no_of_sets" placeholder="number of sets" name="no_of_sets">
<button>Submit</button>
</form>
<br>
<br>

<table>
<tr>
<th ng-repeat="n in arr track by $index">SET {{n.setalpha}} </th>
</tr>
<!--<tr ng-repeat="">
<select ng-model="name" ng-options="options.topicname for options in topics"></select>
</tr>-->
<tr>
<td ng-repeat="n in arr track by $index">
<button ng-click="addSelected($index+1)">add{{$index+1}}</button>
</td>
</tr>
</table>



</div>
</body>

</html>





LINK TO PLUNK PLUNK

Answer

In the following example I used lists instead of tables with fle display, IMHO it is a better approach:

(function (angular) {
"use strict";
  function GrowController ($log) {
    var vm = this;
    vm.cols = [];
    vm.size = 0;
    vm.sizeChanged = function () {
      var size = vm.size, cols = vm.cols,
          diff = size - cols.length;
      $log.debug("Size changed to", size, cols);
      if (diff > 0) {
        for (var i = 0; i < diff; i++) {
          cols.push([]);
        }
      } else {
        cols.splice(diff, -diff);
      }
    };
    vm.addCell = function (index) {
      var cols = vm.cols;
      $log.debug("Cell added in column", index);
      cols[index].push(index + "." + cols[index].length);
    };
  }

   angular.module("app",[])
        .controller("GrowController", ["$log", GrowController]);
}(angular));
ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.cols {
  display: flex;
}
.cells {
  display: flex;
  flex-direction: column;
}
button.add-cell {
  display: block;
}
<div ng-controller="GrowController as $ctrl" ng-app="app" ng-strict-di>
<p>
    <label for="size">Number of columns(0-10):</label>
    <input id="size" type="number" ng-model="$ctrl.size" ng-change="$ctrl.sizeChanged()" min="0" max="10">
</p>
<ul class="cols" ng-if="$ctrl.cols.length">
    <li ng-repeat="col in $ctrl.cols">
        <button class="add-cell-button" ng-click="$ctrl.addCell($index)">Add cell</button>
        <ul class="cells" ng-if="col.length">
            <li ng-repeat="cell in col">{{ ::cell }}</li>
        </ul>
    </li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>

Anyway, I Angularjs 1.5.6 you should consider using "Components" instead of "Controllers" and "one-side" bindings.

Comments