I have an add button which adds the row containing texbox. However I want to remove the row of the table by clicking the respective remove button.
The view page code is like this:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>showintable</title>
<script src="~/scripts/jquery-3.1.1.min.js"></script>
<script src="~/scripts/angular.min.js"></script>
<script src="~/scripts/angular-messages.min.js"></script>
<script src="~/app/controller/checkCtrl.js"></script>
<script src="~/app/filter/filterrange.js"></script>
</head>
<body ng-app="app">
<div ng-controller="sayCtrl">
<table border="1">
<tr>
<th>S. No.</th>
<th>Textbox1</th>
<th>Texbox2</th>
</tr>
<tr ng-repeat="v in [] | range:tellrange">
<td>{{$index+1}}</td>
<td><input type="text" ng-model="Namemodel[$index]" /></td>
<td><input type="text" ng-model="Addressmodel[$index]" /></td>
<td><input type="button" ng-click="subtractrow()" value="Remove" /></td>
</tr>
<tr><td align="right" colspan="4"><input ng-click="addrow()" type="button" value="Add" /></td></tr>
</table>
</div>
</body>
</html>
The controller checkCtrl.js of angularjs is like this:
angular.module('app', ['ngMessages']).controller('sayCtrl', SayController);
SayController.$inject = ['$scope', '$http'];
function SayController($scope, $http) {
$scope.Namemodel = [];
$scope.Addressmodel = [];
$scope.tellrange = 1;
$scope.addrow = function () {
$scope.tellrange = $scope.tellrange + 1;
};
$scope.subtractrow = function () {
};
}
The filter filterrange.js of angularjs is like this:
angular.module('app').filter('range', function () {
return function (input, total) {
total = parseInt(total);
for (var i = 0; i < total; i++) {
input.push(i);
}
return input;
};
});
The page looks like this:
https://drive.google.com/open?id=0B8ZNi-QTxOOYUjNqcnlraDVydVE
I have searched for it but I could not get the relevant answer. Any help is appreciated.
Thanks in advance..............
First, make it easier to iterate through the rows. You want N rows, and each row should have two pieces of information: a name and an address.
So don't use two arrays. Use one array, of rows, where each row has a name and an address:
$scope.rows = [
{
name: 'name 1',
address: 'address 1'
},
{
name: 'name 2',
address: 'address 2'
}
];
To add a row, all you need is
$scope.rows.push({
name: '',
address: ''
});
To iterate on the rows, all you need is
<tr ng-repeat="row in rows">
<td>{{$index+1}}</td>
<td><input type="text" ng-model="row.name" /></td>
<td><input type="text" ng-model="row.address" /></td>
<td><input type="button" ng-click="removeRow(row)" value="Remove" /></td>
</tr>
As you see, you need to pass what row to remove in your removeRow function.
And to remove the row, all you need is to find its index in $scope.rows, and remove that index:
$scope.removeRow = function(row) {
var index = $scope.rows.indexOf(row);
$scope.rows.splice(index, 1);
}
I don't know exactly what each row is supposed to represent. I guess it might be a user, for example, so feel free to rename rows to users, and row to user. Naming things, and having a good, correct model, is the key. Your page displays a table of users. Not two tables of names and addresses.
Related
I have an add button which adds the row containing texbox. However I want to remove the row of the table by clicking the respective remove button.
The view page code is like this:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>showintable</title>
<script src="~/scripts/jquery-3.1.1.min.js"></script>
<script src="~/scripts/angular.min.js"></script>
<script src="~/scripts/angular-messages.min.js"></script>
<script src="~/app/controller/checkCtrl.js"></script>
<script src="~/app/filter/filterrange.js"></script>
</head>
<body ng-app="app">
<div ng-controller="sayCtrl">
<table border="1">
<tr>
<th>S. No.</th>
<th>Textbox1</th>
<th>Texbox2</th>
</tr>
<tr ng-repeat="v in [] | range:tellrange">
<td>{{$index+1}}</td>
<td><input type="text" ng-model="Namemodel[$index]" /></td>
<td><input type="text" ng-model="Addressmodel[$index]" /></td>
<td><input type="button" ng-click="subtractrow()" value="Remove" /></td>
</tr>
<tr><td align="right" colspan="4"><input ng-click="addrow()" type="button" value="Add" /></td></tr>
</table>
</div>
</body>
</html>
The controller checkCtrl.js of angularjs is like this:
angular.module('app', ['ngMessages']).controller('sayCtrl', SayController);
SayController.$inject = ['$scope', '$http'];
function SayController($scope, $http) {
$scope.Namemodel = [];
$scope.Addressmodel = [];
$scope.tellrange = 1;
$scope.addrow = function () {
$scope.tellrange = $scope.tellrange + 1;
};
$scope.subtractrow = function () {
};
}
The filter filterrange.js of angularjs is like this:
angular.module('app').filter('range', function () {
return function (input, total) {
total = parseInt(total);
for (var i = 0; i < total; i++) {
input.push(i);
}
return input;
};
});
The page looks like this:
https://drive.google.com/open?id=0B8ZNi-QTxOOYUjNqcnlraDVydVE
I have searched for it but I could not get the relevant answer. Any help is appreciated.
Thanks in advance..............
First, make it easier to iterate through the rows. You want N rows, and each row should have two pieces of information: a name and an address.
So don't use two arrays. Use one array, of rows, where each row has a name and an address:
$scope.rows = [
{
name: 'name 1',
address: 'address 1'
},
{
name: 'name 2',
address: 'address 2'
}
];
To add a row, all you need is
$scope.rows.push({
name: '',
address: ''
});
To iterate on the rows, all you need is
<tr ng-repeat="row in rows">
<td>{{$index+1}}</td>
<td><input type="text" ng-model="row.name" /></td>
<td><input type="text" ng-model="row.address" /></td>
<td><input type="button" ng-click="removeRow(row)" value="Remove" /></td>
</tr>
As you see, you need to pass what row to remove in your removeRow function.
And to remove the row, all you need is to find its index in $scope.rows, and remove that index:
$scope.removeRow = function(row) {
var index = $scope.rows.indexOf(row);
$scope.rows.splice(index, 1);
}
I don't know exactly what each row is supposed to represent. I guess it might be a user, for example, so feel free to rename rows to users, and row to user. Naming things, and having a good, correct model, is the key. Your page displays a table of users. Not two tables of names and addresses.
I have a table generated with a ng-repeat directive.
Each cell can be editable and each row has a submit button.
The submit button must send only the data of the affected row to the controller instead of sending the complete table. Then the controller will send it to a database. So if my table is huge and has a lot of rows, I prefer to just send one row to the database instead of the complete table.
Most of the time I use <form name="myForm" ng-submit="sendMyData()"> to send data from the view to the controller but in this case I have multiple forms (one per each row).
My problem is that I have no idea how to identify each row generated by the ng-repeat.
I am using AngularJS Material.
You don't need forms to do this. I'll demonstrate how to achieve this using sample data:
Controller:
app.controller("MyController", function($scope) {
$scope.persons = [
{ id: 1, name: "Bob" },
{ id: 2, name: "Alice" }
];
$scope.submitPerson = function(person) {
// do something to person - send to backend etc...
};
});
View:
<div ng-controller="MyController">
<table>
<tr ng-repeat="person in persons">
<td>{{person.name}}</td>
<td><button ng-click="submitPerson(person)">Submit</button></td>
</tr>
</table>
</div>
By clicking the submit button within each row - the individual person object will be passed to the submitPerson function in your controller where you can send it to the backend or do anything else.
You can try something like below just to submit one row at a time and also change in any number of rows and tick box which rows to be updated at once by clicking Submit ALL button.
var app = angular.module('app',[]);
app.controller('noduesaccountsmodalcontroller',function($scope){
$scope.nodueaccountassets = [{'name':'x'},{'name':'a'},
{'name':'b'},{'name':'c'},{'name':'d'}];
$scope.init= function(){
};
$scope.selectedItems =[];
$scope.rowSubmit = function(row){
$scope.submittedRow = row;
};
$scope.submit = function(acc){
angular.forEach($scope.nodueaccountassets,function(emp){
if(emp.selected){
$scope.selectedItems.push(emp.name);
}
});
};
});
<script data-require="jquery#*" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script data-require="angularjs#1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<body ng-app="app" ng-controller="noduesaccountsmodalcontroller" ng-init="init()">
<table class="table">
<thead>
<tr>
<th>item</th>
<th>received</th>
</tr>
</thead>
<tbody ng-repeat="emp in nodueaccountassets track by $index">
<tr>
<td><input type="text" ng-model="emp.name"/></td>
<td>
<input type="checkbox" ng-model="emp.selected" value="{{emp.name}}" />
</td>
<td> <button type="button" value="submit" ng-click="rowSubmit(emp)">Submit</button></td>
</tr>
</tbody>
</table>
{{selectedItems}}
Submitted row --- {{submittedRow}}
<button type="button" ng-click="submit()" value="submit">Submit ALL</button>
</body>
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
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.
Someone help me please!
Lets say I have an a list of a checkboxes, each checkbox have an ID.
I would like to $scope an array with checked checkboxes IDs.
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<table>
<tr ng-repeat="(key, value) in providers">
<td><input type="checkbox" ng-model="ids[value.Id]"> {{value}} </td>
</tr>
</table>
{{ids}}
</div>
And my controller:
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.providers = [{Id:5},{Id:6},{Id:8},{Id:10}];
$scope.ids = {};
});
Now my array output (if all check boxes are checked) is: {"5":true,"6":true,"8":true,"10":true}
And I would like: [{Id:5},{Id:6},{Id:8},{Id:10}]
this is a possible solution:
<input type="checkbox" ng-model="ids[$index]" ng-true-value="
{{value}}" ng-false-value="{{undefined}}"/>{{value}}
In this way, you will have an array of objects, because you are assigning ids[$index] = value.
There is a cons however: when you double check a checkbox, you will have an empty element in the array.
var app = angular.module('myapp', []);
app.controller('ctrlParent', function($scope) {
$scope.providers = [{
Id: 5
}, {
Id: 6
}, {
Id: 8
}, {
Id: 10
}];
$scope.ids = [];
$scope.$watchCollection('ids', function(newVal) {
for (var i = 0; i < newVal.length; ++i) {
console.log(newVal[i]);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<table>
<tr ng-repeat="(key,value) in providers">
<td>
<input type="checkbox" ng-model="ids[$index]" ng-true-value="{{value}}" ng-false-value="{{undefined}}" />{{value}}
</td>
</tr>
</table>{{ids}}</div>
</div>
http://jsfiddle.net/b9jj0re2/3/
<input type="checkbox" ng-model="ids[$index]" ng-true-value="{{value}}" >
Addign the ng-true-value directive will solve the problem
and in controller change the ids from object to array
plunker
I come from China,my English very poor,so I do a demo.how can I update array inside ng-repeat?
The HTML:
<body ng-app="main" ng-controller="DemoCtrl">
<table ng-table class="table">
<tr ng-repeat="user in users">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
<td>
{{user.spms|json}}
<div ng-repeat="u in user.spms">
<span ng-bind="u"></span>
<input type="text" ng-model="u" ng-change='updateArray($parent.$index, $index, u)'>
</div>
</td>
</tr>
</table>
</body>
The JS:
var app = angular.module('main', []).
controller('DemoCtrl', function($scope) {
$scope.users = [{
name: "Moroni",
age: 50,
spms: [
6135.7678,
504.4589,
2879.164,
669.7447
]
},
{
name: "seven",
age: 30,
spms: [
34135.7678,
5034.42589,
22879.1264,
63469.72447
]
}
];
$scope.updateArray = function(parent, index, u) {
$scope.users[parent].spms[index] = u * 1; // multiply by one to keep the value a Number
}
})
There are issues here are every update is changing the scope, so you can only change one time them click then change - so I would recommend add a update values button and implementing more or less the same logic to update the array values.
DEMO