angularjs adding selected items from dropdowns to the scope - javascript

I have a table which has a dropdown above each column where the number of columns is dynamic. I created this as follows
<table class='table' >
<tr>
<th ng-repeat= "item in importTable[0]">
<select ng-model="selectedItem" ng-options="i.Name for i in optionList"></select>
</th>
</tr>
<tr ng-repeat="row in importTable">
<td ng-repeat="item in row">{{ item }} </td>
</tr>
</table>
Where optionList is the list of options in the dropdowns. All of the dropdowns have the same optionList.
How do I add the selected item along with the index of the column it is above to the scope to the model?
Here is a link to JSfiddle http://jsfiddle.net/U3pVM/769/ just click import. I want to be able to define which column is which type.

You may use $index variable that is provided by ngRepeat to set the ngModel to a specific item in an array:
In your controller you first define the array that will hold all the models:
function ImportCtrl($scope) {
$scope.selectedItems = [];
...
}
And than, inside the ngRepeat you refer your ngModel to a specific item inside the selectedItemsarray:
<select ng-model="selectedItems[$index]" ng-options="i.Name for i in columnNames"></select>
Demo FIDDLE

Related

Html/Angular toggle table rows to show hidden a table

I am completely new to angular, I need to create a table. The data array is as-follows:-
data = [{rollno: 1,name: 'abc',subject: 'maths'},
{rollno: 4,name: 'xyz',subject: 'history'},
{rollno: 2,name: 'pqr',subject: 'history'}
];
I want to create a table with some summary rows based on this data and then when I click the expand button the sub-rows should appear beneath that summary-row indicating the actual data.
For example:-
Expand/Collapse | No of Students | Subject
click here 1 Maths
click here 2 History
When I toggle the expand/collapse button on the second row for example I want actual rows to appear like this beneath it:-
Expand/Collapse | No of Students | Subject
click here 1 Maths
click here 2 History
RollNo | StudentName
4 xyz
2 pqr
How Can I achieve this?
1) Grouping the data by subject
First you need to group the data by subject and then count the items in each group.
You can use the angular.filter module's groupBy filter to do this.
1a) Add a dependency on that module as follows:
var app = angular.module("yourModuleName", ["angular.filter"]);
1b) You can then use the groupBy filter in an ng-repeat directive on a <tbody> tag like this:
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
1c) You're now dealing with the data in the format below. This is an object of key/value pairs where "maths" and "history" are both keys, and the arrays are the values
{
"maths": [
{
"rollno": 1,
"name": "abc",
"subject": "maths",
}
],
"history": [
{
"rollno": 4,
"name": "xyz",
"subject": "history",
},
{
"rollno": 2,
"name": "pqr",
"subject": "history",
}
]
}
2) Displaying the grouped data and counting the items in each group
Use key and value to display the grouped data in a table as follows:
<table>
<thead>
<tr>
<th>Subject</th>
<th>Number of Students</th>
<th>Expand/Collapse</th>
</tr>
</thead>
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
<tr>
<td>{{ key }}</td>
<td>{{ value.length }}</td>
<td>
<button>
Expand/Collapse
</button>
</td>
</tr>
<tr>
<td colspan="3">
<table>
<thead>
<tr>
<th>Roll Number</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="student in value">
<td>{{ student.rollno }}</td>
<td>{{ student.name }}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Note the extra <tr> and nested table with another ng-repeat for displaying the student data. Currently all nested student data will display, the next step is to conditionally show/hide the nested tables based on which expand/collapse button was clicked.
3) Showing/Hiding the nested student data
3a) Add an ng-click directive on the button so that it passes in the key to an onExpandClicked function on your controller:
<button ng-click="onExpandClicked(key)">
Expand/Collapse
</button>
3b) Create the onExpandClicked function in your controller:
$scope.onExpandClicked = function(name){
$scope.expanded = ($scope.expanded !== name) ? name : "";
}
This sets a value on the $scope that can be used in the view to decide whether to show/hide a section of student data. The key is passed into the function as the name parameter and $scope.expanded will either be set to name or reset to "" depending on whether the passed in name is the same as the current $scope.expanded value or not.
3c) Finally, use the $scope.expanded variable in an ng-if directive on the second <tr> tag of <tbody> to show or hide the nested student data:
<table>
<thead>
<tr>
<!-- Omitted for brevity -->
</tr>
</thead>
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
<tr>
<!-- Omitted for brevity -->
</tr>
<tr ng-if="expanded === key">
<!--
Omitted for brevity
-->
</tr>
</tbody>
</table>
Demo
CodePen: How to show/hide grouped data created by the angular.filter module's groupBy filter
Design a table with html and iterate through your data object with ng-repeat loop to display the data.
ngRepeat
W3Schools has some basic examples on how to display tables with AngularJS
Angular Tables
First you should replace the actual table by a div structure, because it is not possible to mix two kinds of table like you are planning (when I get you right).
You could toggle every row with a ng-click with the corresponding expanded content like this (pseudo code, I hope the idea gets clear):
<div class="row-header">
<span>RollNo</span>
<span>StudentName</span>
</div>
<div class="row-content" ng-if="!row_4_expanded" ng-click="row_4_expanded = !row_4_expanded">
<span>4</span>
<span>xyz</span>
</div>
<div ng-if="row_4_expanded">
<div class="row-expanded-header">
<span>No of Students</span>
<span>Subject</span>
</div>
<div class="row-expanded-content">
<span>1</span>
<span>Math</span>
</div>
<div class="row-expanded-content">
<span>2</span>
<span>History</span>
</div>
</div>
<div class="row-content" ng-if="!row_2_expanded" ng-if="row_2_expanded" ng-click="row_2_expanded = !row_2_expanded">
<span>2</span>
<span>pqr</span>
</div>
<div ng-if="row_2_expanded">
<div class="row-expanded-header">
<span>No of Students</span>
<span>Subject</span>
</div>
<div class="row-expanded-content">
<span>1</span>
<span>Math</span>
</div>
<div class="row-expanded-content">
<span>2</span>
<span>History</span>
</div>
</div>
When you now click on a row, it toggle presens with the corresponding expanded one.
Here is a working example which resolves your problem.
var indexCtrl = ['$scope', function($scope){
$scope.num = 0;
$scope.test = [{rollno: 1,name: 'abc',subject: 'maths'},
{rollno: 4,name: 'xyz',subject: 'history'},
{rollno: 2,name: 'pqr',subject: 'history'}
];
$scope.changeShow = function(index){
$scope.num = index;
};
}];
<!DOCTYPE html>
<html ng-app>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-controller='indexCtrl'>
<table>
<tr>
<td>Expand/Collapse</td>
<td>No of Students</td>
<td>Subject</td>
</tr>
<tr ng-repeat='i in test' ng-class="num == $index ? red : none">{{}}
<td ng-click='changeShow($index)'>click here</td>
<td>{{$index +1}}</td>
<td >{{i.subject}}</td>
</tr>
</table>
<table>
<tr>
<td>RollNo</td>
<td>StudentName</td>
</tr>
<tr ng-repeat='i in test'>
<td ng-show='num == $index'>{{i.rollno}}</td>
<td ng-show='num == $index'>{{i.name}}</td>
</tr>
</table>
<style>
table tr td{
border: 1px solid black
}
</style>
</body>
</html>
Hope it helps you.

Object parent key JavaScript

I'm using AngularJS to display some data on a table, for that I'm making use of ng-repeat which takes an object and displays the values of the properties of it in the table cells.
The object structure is like this:
{
...
...
"containerKey" : {
"parentKey" : {
"childKey1" : "value",
"childKey2" : "value",
"childKey3" : "value
}
}
}
The ng-repeat shows a table
<table ng-repeat="key in containerKey">
<tr>
<!-- This should display the value of the key (in my case it is the name of a day in the week, but it displayed the entire object inside key.parentKey, which is expected -->
<th id="day">{{ key.parentKey }}</th> <!-- I would like for this to show the value of the key, in my case that would be the name of the day, like "monday" -->
</tr>
<tr>
<td>{{ parentKey.childKey1 }}</td>
</tr>
<tr>
<td>{{ parentKey.childKey2 }}</td>
</tr>
<tr>
<td>{{ parentKey.childKey3 }}</td>
</tr>
</table>
How would I go about showing only the key value of the parentKey in the table cell? Consider that I'm using ng-repeat to show multiple rows and each of this rows contain the ng-repeat that contains the days (parentKey).
To clarify:
I would like the <th> element with id="day" to show the text of the parentKey key. The th element's content would be parentKey (the string parentKey), literally, instead of the value of parentKey.
Have you tried altering your ng-repeat to use the object notation:
<table ng-repeat="(key, value) in containerKey">
You should have access to the key then.
Firstly, in your code you are trying to use ng-repeat over an object. ng-repeat should iterate over arrays.
Considerating containerKey is an array of parentKey, this may works:
<table>
<tbody ng-repeat="(key, value) in containerKey">
<th>{{key}}</th>
<tr>{{value.childKey1}}</tr>
<tr>{{value.childKey2}}</tr>
<tr>{{value.childKey3}}</tr>
</tbody>
</table>

Angularjs push table row to another table

I have 2 tables i want to push the row of the first table to the second.
table 1 :
<table>
<tr ng-repeat="row in items">
<td>{{row.PRODUCTDESCRIPTION}}</td>
<td><input type="text" ng-model="quantity[$index]"></td>
</tr>
</table>
<button ng-click="pushRows(row)"> </button>
table 2 :
<table>
<tr ng-repeat="row in products">
<td>{{row.PRODUCTDESCRIPTION}}</td>
<td><input type="text" ng-model="quantity[$index]"></td>
</tr>
i need to push the row in table 1 to the table 2 (my problem is how to push the input type text with its value)
You can use ng-model and create a new property on all the items.
plunker Example

How to show/hide a UI component based on "|filter" results in AngularJS?

I have a nested table structure where a table populates based on a ng-repeat of a Javascript object "metasetHashSplit" and this table in turn has a table that gets populated based on a property within called "ids". I have a requirement where I need to hide the main ng-repeat if all the elements in the internal table is filtered out. I am using "pipe"/"|" filter for the internal tables.
I am unable to get handle on when or how to trigger the ng-show/hide based on if all the records in theinternal table is filtered out.
This is how the code is setup:
<tbody ng-repeat="(metaset, ids) in metasetHashSplit">
<tr class = "meta">
<td rowspan = 100 >{{metaset}}</td>
</tr>
<tr class = "meta" style="margin:0;padding:0;" ng-repeat="item in ids" >
<td class = "innerTable">
<table class="table child table-hover table-bordered table-condensed " >
<tr ng-repeat="buy in item.Buy | filter:{ MBC: by_buyMBC }" >
<td >{{buy.BuyId}}</td>
<td >{{buy.BuyRelease}}</span></td>
<td >{{buy.BuyComponentAffected}}</td>
<td >{{buy.BuyStatus}}</span></td>
</tr>
</table>
</td>
</tr>
Could somebody help me if they have found themselves in a position like this? Basically the tbody needs to show/hide with respect to the |filter:{MBC:by_buyMBC} results!
Based on this question use:
<div ng-repeat="buy in filtered = (item.Buy | filter:{ MBC: by_buyMBC })">
</div>
So all you would do to show and hide based off that is use ng-if="filtered.length > 0" on the right element

Filtering of selected option

How do I filter a table content based on option selected ?
I would need to refresh the table below - each time the option on the select changes.
HTML
<select ng-model="selectedGrade" ng-options="grade.Id as grade.Title for grade in grades"></select>
<table>
<tr>
<th>ID</th>
<th>Description</th>
</tr>
<tr ng-repeat="attr in attributes|filter:{grade:selectedGrade.Title}">
<td>{{attr.id}}</td>
<td>{{attr.name}}</td>
</tr>
</table>
Module
angular.module('Employee',[])
.controller('EmployeeCtl',function($scope){
$scope.grades=[
{"id":1,"Title":"MTS"},
{"id":2,"Title":"SMTS"},
{"id":3,"Title":"PMTS"},
{"id":4,"Title":"CMTS"}
];
$scope.attributes=[
{"id":1,"name":"Greg","grade":"MTS"},
{"id":2,"name":"Marlon","grade":"SMTS"},
.........
];
});
Add {{ selectedGrade }} to your template. You'll notice that what selectedGrade contains is the ID of the selected grade, since you used
grade.Id as grade.Title for grade in grades
If you want selectedGrade to contain a grade object, you should use
grade.Title for grade in grades
Read the relevant documentation.

Categories

Resources