I am able to select multiple rows, but I would like to be able to select those datas in different tables on the same page. At the moment, when I select a row in the first table, it selects it in the second table as well, but I would like them to be independent. Anyone has an idea ?
Below is my html code
<div class="row" ng-show="{{ adultNumber }}">
<div class="col-md-8">
<h1>Adult 1</h1>
<table class="table table-bordered">
<tr ng-repeat="extra in extras" ng-class="{'selected': extra.selected}" ng-click="select(extra)" ng-model="radioExtrasAdult1">
<td ng-bind="extra.name"></td>
<td ng-bind="extra.price"></td>
</tr>
</table>
</div>
</div>
<div class="row" ng-show="{{ adultNumber >= 2 }}">
<div class="col-md-8">
<h1>Adult 2</h1>
<table class="table table-bordered">
<tr ng-repeat="extra in extras" ng-class="{'selected': extra.selected}" ng-click="select(extra)" ng-model="radioExtrasAdult2">
<td ng-bind="extra.name"></td>
<td ng-bind="extra.price"></td>
</tr>
</table>
</div>
</div>
Below angular js
$http.get('json/extras.json')
.then(function(res){
$scope.extras = res.data;
});
$scope.select = function(item) {
item.selected ? item.selected = false : item.selected = true;
}
$scope.submit = function(x) {
var x = $filter("filter")($scope.extras, {
selected: true
}, true);
console.log(x);
}
Thank you.
The thing is, when you select an object in a table, you modify its attribute to tell it it is selected. Given the fact that you are using the same object in the other table, it is updated too and so it is also selected.
There are different things you can do about it,
Make a deep copy of the objects you display so that you display one copy per table and so you don't modify the two contents simultaneously. For this, use angular.copy.
Modify different attributes on the same object when performing selection. You could for instance use item.selected[0] for the first table and item.selected[1] for the second one. The advantage of this solution is that all data is centralized in the same object. Still, you have to pass an aditional parameter to your select function to tell in which table you are selecting (0 or 1)
Hope it helped !
Related
I am new to Angularjs and I am trying to figure out how it's different modules work. So, I am working on a project on which I wanna achieve an accordion-like style for a page, in which a table is shown when I click a panel button. The HTML code that creates(dynamically from a database) the div elements I modify is posted below.The problem is that in this panel, any number of tables can be shown,while I need to only have one opened at a time,so when one opens,the one opened before it should close.Any ideas how I can achieve this functionality?(I assume the error is because the showDB variable is local to each table scope, but I don't know how to work around it.) Thanks!' `
<div ng-repeat="(key, value) in data.services">
<div ng-show="showSection(key)" class="top_panel-section">
<button class="btn top_btn btn-header" type="button" name="showDB"
ng-click="showDB=!showDB">{{key}}</button>
<table ng-show="showDB"
class="n-table toptable table-responsive n-table-standard n-table-striped n-table-hover">
<thead class="n-table-thead">
<tr>
<th width="70%">VM Name</th>
<th width="30%">Status</th>
</tr>
</thead>
<tbody class="n-table-body">
<tr ng-repeat="vm in value.vms">
<td width="76%">{{vm.vm}}</td>
<td width="24%" ng-style="getStatusStyle(vm.status)">
{{vm.status}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Yes, you should remove that local showDB variable to achieve what you need.
You can easily replace it with a $scope.activeKey and evaluating it by the
<button ... name="showDB" ng-click="activateKey(key)">{{key}}</button>
And in your controller:
$scope.activeKey = null;
$scope.activateKey = function (keyToBeActivated) {
$scope.activeKey = keyToBeActivated;
}
Now you can reach that exclusivity by checking:
<table ng-show="activeKey === key" ... >
Using table $index as unique field: (available from ng-repeat)
<button ... name="showDB" ng-click="activateKey($index)">{{key}}</button>
And
<table ng-show="activeKey === $index" ... >
I am trying to learn AngularJS 1.6 and I am trying to populate a table with rows depending on the amount of rows selected in a dropdown list. It could be anywhere from 1 to 12. So far I have the following code.
<body ng-controller="myController">
<div>
<p>Blue Corner Boxer: </p> <input type="text" ng-model="nameBlue">
<br>
<p>Red Corner Boxer: </p> <input type="text" ng-model="nameRed">
<br>
<p>Number of Rounds:</p> <select ng-model="selectedRounds"><option ng-repeat="x in rounds">{{x}}</option></select>
</div>
<div>
<table class="table table-striped">
<thead>
<tr>
<th style="text-align:center">{{nameBlue}}</th>
<th style="text-align:center">Round</th>
<th style="text-align:center">{{nameRed}}</th>
</tr>
</thead>
<tbody class="tablerows">
<tr ng-repeat="x in selectedRounds">
<td>Test</td>
<td>Test</td>
<td>Test</td>
</tr>
</tbody>
</table>
<h2 style="text-align: center">Final Score: </h2> {{scoreBlue1 + ScoreBlue2}}
</div>
</body>
Then in the js file
//Create the module
var myApp = angular.module("myModule", []);
//Create the controller and register the module in one line
myApp.controller("myController", function ($scope) {
$scope.message = "AngularJS tutorial";
$scope.score = [1,2,3,4,5,6,7,8,9,10];
$scope.rounds = [1,2,3,4,5,6,7,8,9,10,11,12];
});
So far the table will add 1 row on selection of anything 1 to 9, but 10 to 12 adds 2 rows. So I think I am wondering how to create an array length of size "selectedrounds" that will repeat rows with the repeater.
Thanks
If you need an array only for iterating and you don't worry about data in it. You can do something like this:
In your controller:
$scope.selectedRounds = 0;
$scope.getRoundsArray(){
return new Array($scope.selectedRounds);
}
We just create an array with needed length and with all elements are 'undefined'. If you create an array with 3 lenght you will get: ['undefined', 'undefined', 'undefined'].
In view:
<tr ng-repeat="x in getRoundsArray() track by $index">
You need this track by $index cause your array contains only 'undefined' values so to prevent angular arguing about duplicate keys we need to use track by.
I am trying to create a table based on the selection of a drop down list. The user would choose 1 to 12 and that number would be the amount of rows to create in the table. Here is my code so far
<body ng-controller="myController">
<div>
<p>Blue Corner Boxer: </p> <input type="text" ng-model="nameBlue">
<br>
<p>Red Corner Boxer: </p> <input type="text" ng-model="nameRed">
<br>
<p>Number of Rounds:</p> <select ng-model="selectedRounds"><option ng-repeat="x in rounds">{{x}}</option></select>
</div>
<div>
<table class="table table-striped">
<thead>
<tr>
<th style="text-align:center">{{nameBlue}}</th>
<th style="text-align:center">Round</th>
<th style="text-align:center">{{nameRed}}</th>
</tr>
</thead>
<tbody class="tablerows">
<tr ng-repeat="x in getRoundsArray(selectedRounds) track by $index">
<td><select ng-options="x for x in score"></select></td>
<td>Score</td>
<td><select ng-options="x for x in score"></select></td>
</tr>
</tbody>
</table>
var myApp = angular.module("myModule", []);
myApp.controller("myController", function ($scope) {
$scope.message = "AngularJS tutorial";
$scope.score = [1,2,3,4,5,6,7,8,9,10];
$scope.rounds = [1,2,3,4,5,6,7,8,9,10,11,12];
$scope.selectedRounds = 0;
$scope.getRoundsArray = function(rounds){
return new Array(rounds);
}
});
No matter what number I choose in the drop down list it just adds 1 row to the table at a time for each selection I make. Instead I want 6 rows as soon as user selects 6.
You need to re-architect your code slightly.
The repeat needs to be over a scoped variable (tableArray in my example) that changes whenever the dropdown changes.
You also do need the $index in the track for it to work.
Here is a working plunker.
Your function
return new Array(rounds);
has changed to
$scope.tableArray = new Array( $scope.selectedRounds * 1);
$scope.getRoundsArray = function(rounds){
return new Array(rounds);
}
});
this does not do what you think it does. You are calling it as getRoundsArray(6), which creates an array with one entry, which is 6, and not, as you want, an array with six entries.
See, for example, https://www.w3schools.com/js/js_arrays.asp.
Thus, your
<tr ng-repeat="x in getRoundsArray(selectedRounds) track by $index">
repeats for each of the one entries of that array, giving the result that you describe.
(and you don't need that track by)
<table class="table table-bordered">
<tbody>
<tr ng-repeat="playerOrTeam in template.editableTable track by $index">
<td style="text-align: center;" ng-repeat="playerOrTeamCat in playerOrTeam track by $index">
<input ng-model="playerOrTeamCat" type="text" class="form-control input-sm">
</td>
</tr>
</tbody>
</table>
template.editableTable is a multi dimensional array just filled with standard variables. when I change one of the values in the input box and then i look at the output of the template.editable table, i don't see the changes. Am I missing something obvious?
EDIT with more details because i'm getting no responses =\
//Template Class
app.factory('Template', function () {
var Template = function () {
/*
* Public Variables
*/
this.editableTable = someMultiDimensionalTable;
}
/*
* Functions
*/
Template.prototype.SeeEditableTableContents = function () {
console.log(this.editableTable);
}
}
//Main Controller
app.controller('MainController', function () {
$scope.template = new Template();
//etc
}
You cannot perform direct in-line modifications within ng-repeat. You can update your array entry using a function.
You'd want something like:
$scope.saveEntry = function (idx) {
console.log("Saving entry");
$scope.template.editableTable[idx] = angular.copy($scope.model.selected);
$scope.reset();
};
See JSFiddle for sample.
okay i actually got it to work so that i CAN make direct in-line modifications with ng-repeat by making my multidimensional table full of objects rather than soley a value.
so by doing that, i modified the table to look like this
<table class="table table-bordered">
<tbody>
<tr ng-repeat="playerOrTeam in template.editableTable track by $index">
<td style="text-align: center;" ng-repeat="playerOrTeamCat in playerOrTeam track by $index">
<input ng-model="playerOrTeamCat.value" type="text" class="form-control input-sm">
</td>
</tr>
</tbody>
</table>
got the idea looking here
Modifying objects within Angular Scope inside ng-repeat
I want to delete multiple rows on check box selection on right click menu option, in my controller am able to get index and delete the values from DOM, but on html page the values are not getting deleted as per the selection rather it is deleting the rows from last.
This is my controller.js
$scope.tableSelection = {};//used for getting checkbox selection
['Delete', function ($itemScope) {
for (var i = $rootScope.rows.length - 1; i >= 0; i--) {
if ($scope.tableSelection[i]) {
//delete row from data
$rootScope.rows.splice(i, 1);
//delete rowSelection property
delete $scope.tableSelection[i];
}
}
}];
here in controller the dom is changing correctly, means the values in $rootscope.rows is getting deleted as per the selection.
This is my html page.
<div id="table" context-menu="menuOptions" ng-controller="dictionaryElementsController">
<tbody>
<tr ng-repeat="row in rows track by $index" ng-class="{'success' : tableSelection[$index]}">
<td>
<input type="checkbox" ng-model="tableSelection[$index]">
</td>
<td ng-repeat="col in output_columns track by $index">
<enter data>
</td>
<td ng-repeat="col in input_columns track by $index">
<enter data>
</td>
</tr>
</tbody>
</div>
what should i do to delete the row as per selection and not rows from last on html page.
Can anyone please help me out in this
As you can see it is very simple using vanilla javascript.
var table = document.getElementById('sample');
var remove = document.getElementById('remove');
remove.addEventListener('click', function(e){
table.deleteRow(0);
});
<table id='sample'>
<tr><td>Cell 1,1</td><td>Cell 1,2</td><td>Cell 1,3</td></tr>
<tr><td>Cell 2,1</td><td>Cell 2,2</td><td>Cell 2,3</td></tr>
<tr><td>Cell 3,3</td><td>Cell 3,3</td><td>Cell 3,3</td></tr>
</table>
<button id='remove'>Remove</button>
You are trying to remove item inside iteration for(..) so after removing any item, array will be reset and next time wrong item will be removed. This will work only single item deletion Not for mulitple.
You need to create new array which contain not removed items you can do it using filter like
$scope.removeSelectedItems = function () {
$scope.rows = $scope.rows.filter(function (item, index) {
return !($scope.tableSelection[index] !== undefined && $scope.tableSelection[index]);
});
$scope.tableSelection = {};
}
Note - Don't mess $rootScope because it is application level global use respective controller's $scope
Check the Demo
The thing i was doing wrong was using track by.. If we don't use track by then angular itself keep track of objects and insert $$hashkey with every object. So, my logic worked after removing track by from ng-repeat in HTML page.
You can add any unique column to the tableselection.
NOte: If you do not have unique column add one. Could be timespan
<div id="table" context-menu="menuOptions" ng-controller="dictionaryElementsController">
<tbody>
<tr ng-repeat="row in rows track by $index" ng-class="{'success' : tableSelection[$index]}">
<td>
<input type="checkbox" ng-model="tableSelection[row.Id]">
</td>
<td ng-repeat="col in output_columns track by $index">
<enter data>
</td>
<td ng-repeat="col in input_columns track by $index">
<enter data>
</td>
</tr>
</tbody>
</div>
$scope.tableSelection = {};//used for getting checkbox selection
['Delete', function ($itemScope) {
for (var i = $rootScope.rows.length - 1; i >= 0; i--) {
if ($scope.tableSelection[$scope.row[i].UId]){
//delete row from data
$rootScope.rows.splice(i, 1);
//delete rowSelection property
delete $scope.tableSelection[i];
}
}
}];