How to show additional row in table AngularJS - javascript

is there any way to insert additional row in ng-repeat ? Here is the problem.
<tr data-ng-repeat="user in content |pagination: currentPage*limit| limitTo: limit | filter: searchText ">
<td>{{user.imie}}</td>
<td>{{user.nazwisko}}</td>
<td>{{user.data_urodzenia}}</td>
<td>{{user.imie2}}</td>
<td>{{user.imie}}</td>
<td>{{user.imie}}</td>
<td><i ng-click="showDetails()" class="fa fa-plus-square" aria-hidden="true"></i></td>
</tr>
I have this table with repeating. In last cell there is a button that will trigger function to show more details of user. So what i need is, an additional row inserted under presented row.
<tr ng-repeat...></tr>
<tr ng-show="details">additional data row</tr>
and the controller
$scope.details = false;
$scope.showDetails = function(){
if (!details) {
$scope.details = true;
}
else {
$scope.details = false
}
}
Any way to do this ? Tried few approaches and didn't worked out.

You can either put the ng-repeat on the tbody, which will likely cause some issues with styling.
Or you can use ng-repeat-start/end. As of angular 1.2, you can repeat over elements which is pretty cool - to do this you can;
<tr ng-repeat-start="user in content |pagination: currentPage*limit| limitTo: limit | filter: searchText ">
<td>{{user.imie}}</td>
<td>{{user.nazwisko}}</td>
<td>{{user.data_urodzenia}}</td>
<td>{{user.imie2}}</td>
<td>{{user.imie}}</td>
<td>{{user.imie}}</td>
<td><i ng-click="showDetails()" class="fa fa-plus-square" aria-hidden="true"></i></td>
</tr>
<tr ng-repeat-end ng-show="details">additional data row</tr>
More information here.
Hope it helps!

Use your ng-repeat in tbody tag, then you can use your additional row on a new tr tag
like this below way
<tbody data-ng-repeat="user in content |pagination: currentPage*limit| limitTo: limit | filter: searchText ">
<tr>
<td>{{user.imie}}</td>
<td>{{user.nazwisko}}</td>
<td>{{user.data_urodzenia}}</td>
<td>{{user.imie2}}</td>
<td>{{user.imie}}</td>
<td>{{user.imie}}</td>
<td><i ng-click="showDetails()" class="fa fa-plus-square" aria-hidden="true"></i></td>
</tr>
<tr>
// your additional row
</tr>
</tbody>
And one more thing, Your code is totally wrong
$scope.details = false;
$scope.showDetails = function(){
if (!details) {
$scope.details = true;
}
else {
$scope.details = false
}
}
this above code will open all row, not particular row. So you need maintain with this by Array of $index

Related

AngularJS - Target specific element inside ng-repeat

I´m using ng-repeat to iterate an array and create a table. In that table, I have a button to make a download. When I click the download button I want the link to disappear and make a loading spin appear. The problem is, the spin is showing up in all the rows and not in just the one i click.
Html -
<tbody md-body>
<tr md-row ng-repeat="">
<td md-cell>
<div layout="row" layout-align="center center">
<md-progress-circular ng-if="isSubmit"></md-progress-circular>
<a ng-if="!isSubmit" ng-click="download($index)">Download</a>
</div>
</div>
</td>
</tr>
</tbody>
JS -
$scope.download = function(index) {
angular.forEach($scope.downloads, function (download) {
// I can console log the index i click
console.log(index)
});
}
You should use the $index on the ng-repeat and instead a boolean isSubmit, use the index to compare to array index.
HTML
<tr ng-repeat="item in items">
<td>
<md-progress-circular ng-if="isLoadingIndex == $index"></md-progress-circular>
<a ng-if="isLoadingIndex != $index"
ng-click="download($index)">Download</a>
</td>
</tr>
CTRL
$scope.isLoadingIndex = null;
$scope.donwload = function($index) {
$scope.isLoadingIndex = $index;
//Rest of your code...
}

Add styles to function-returned data

I'm trying to add CSS styles to a string computed in Javascript. It goes through a series of transformation functions:
var fieldSetTransformation = setFieldTransformation(iteration);
fieldSetTransformation = stylePropertyName(fieldSetTransformation);
This value then is passed to a table generated in a directive through AngularJS's ng-repeat:
<tbody class="tableBody">
<tr ng-repeat="line in linesArray">
<td ng-repeat="column in ::columns" width="{{::column.width}}" ng-class="{
'center-text' : (!line[column.key] || line[column.key].length === 0)
}">{{line[column.key] !== undefined ? line[column.key] : '--'}}<span ng-if="column.key == 'user'">
<i id="plus-icon-styling"
class="fa fa-plus-circle action-icon">
</i>
</span>
</td>
</tr>
</tbody>
So I'm struggling to append it to an existing container.
What I have tried so far?
Injecting the HTML directly into the returned value:
var htmledField = [
'<span class="propertyNameHighlight">' + fieldSetTransformation,
'<span>'].join("\n");
];
No use, since this does not seem to be accepted anymore by current navigators (correct me if wrong) since it's a security issue.
The thrown result is just <span class="propertyNameHighlight">000000</span>
appearing in the table.
Creating the element, then appending it in the view
Also a no-go:
function stylePropertyName(data){
var newSpan = document.createElement('span');
newSpan.setAttribute('class', 'propertyNameHighlight');
document.getElementsByClassName("tableBody").appendChild(newSpan);
newSpan.innerHTML = data;
return data;
}
This returns a null function exception.
I have also checked this question, which seemed the closest to my query, but in my case there is no clear container neither to wrap up the resulting string.
TL;DR: What I'm trying to achieve?
This green text over here:
That represents a cell. The data is not directly passed, it's generated dynamically through a series of functions and ng-repeats.
Any help or related disregarded question that I could get is greatly appreciated. Thanks!
As suggested by commenter Stanislav Kvitash (thanks!), I solved this by using ngBindHtml :
<tbody class="tableBody">
<tr ng-repeat="line in linesArray">
<td ng-repeat="column in ::columns" width="{{::column.width}}" ng-class="{'center-text' : (!line[column.key] || line[column.key].length === 0)}">
<span ng-bind-html="line[column.key] !== undefined ? line[column.key] : '--'"></span>
<span ng-if="column.key == 'user'">
<i id="plus-icon-styling"
class="fa fa-plus-circle action-icon">
</i>
</span>
</td>
</tr>
</tbody>

Conditional ng-class on icon in table cell

I have a table and using ng-repeat to bind my cells with the data. One cell has edit, save, delete icons. If an order has been posted then the delete/ save icons should be disabled and the icons also should be a different color. I am able to disable the click event of the delete/save icons but can not figure out how to change the css class. With this code the save and delete can not be clicked. I'd like to turn them light gray or some obviously different color.
Here is the HTML:
<tbody>
<tr ng-repeat="order in vm.orders track by $index" ng-dblclick="vm.editOrder(order)" style="cursor:pointer" ng-class="{'class':order.invoiceStatus, 'disabled-order': !order.invoiceStatus}">
<td ng-bind="(order.dtInvoiced | date:'MM/dd/yyyy' )"> </td>
<td ng-bind="order.invoiceNumber"></td>
<td ng-bind="order.invoiceItems.mdbsPoNumber"></td>
<td align="center" ng-bind="order.lines"></td>
<td ng-bind="(order.total | number:2)"></td>
<td align="center" ng-bind="order.carrier"></td>
<td>
<a ng-click="vm.editOrder(order)"><i class="fa fa-pencil fa-2x"></i></a>
<a ng-click="order.disabledToggle || vm.saveOrder(order)"><i class="fa fa-check fa-2x"></i></a>
<a ng-click="order.disabledToggle || vm.removeOrder(order)"><i class="fa fa-trash fa-2x link-icon"></i></a>
</td>
</tr>
</tbody>
Here is the JS to disable the click event of save and delete icons:
function orderItems() {
var orders;
if (vm.Criteria != null) {
orderService.getOrderData(vm.Criteria)
.then(function (result) {
vm.data = result.data;
orders = vm.data;
for (var i = 0; i < vm.data.length; i++) {
orders[i].disabledToggle = false;
if (orders[i].invoiceStatus == "RCV") {
orders[i].disabledToggle = true;
}
else {
orders[i].disabledToggle = false;
}
vm.orders.push(orders[i]);
}
});
}
}
I've also tried in the icon:
<i ng-class="order.invoiceStatus = order.disabledToggle ? 'disabled-order class' : 'class' "></i>
You can use ng-class to evaluate a variable for true. If the variable is true then a class selector will be injected into the element:
<a ng-click="order.disabledToggle || vm.saveOrder(order)"><i ng-class="{ 'cssCheckDisabled': jsCheckDisabled } class="fa fa-check fa-2x"></i></a>
In this case we are evaluating jsCheckDisabled. Once it is try the cssCheckDisabled class selector is injected into the element.
Then is as easy as making a class selector in your CSS to do what you want:
cssCheckDisabled {
color: red;
}

Rails+jQuery: Get the Value of an Item Inside a Table to Use in a Prepend Function

Say I have a table:
<table class="table table-bordered table-hover employes_list_panel">
<thead>
<tr>
<th></th>
<th></th>
<th class="center">Name <i class="fa fa-angle-double-down"></i></th>
<th class="center">IQ <i class="fa fa-angle-double-down"></i></th>
<th class="center">Efficiency <i class="fa fa-angle-double-down"></i></th>
<th class="center">Focus <i class="fa fa-angle-double-down"></i></th>
<th class="center">Happiness <i class="fa fa-angle-double-down"></i></th>
<th class="center">Quality <i class="fa fa-angle-double-down"></i></th>
<th class="center">Salery <i class="fa fa-angle-double-down"></i></th>
</tr>
</thead>
<tbody>
<%Employe.where(company_id: company.id, request: false).each do |employe|%>
<tr>
<td class="center cd-popup-trigger" id="popup3"><i style="color: red;" class="fa fa-close"></i></td>
<td class="center cd-popup-trigger" id="popup4"><i style="color: green;" class="fa fa-arrow-up"></i></td>
<td class="center"><%=employe.name%></td>
<td class="center"><%=employe.iq%></td>
<td class="center"><%=employe.efficiency%></td>
<td class="center"><%=employe.focus%></td>
<td class="center"><%=employe.happiness%></td>
<td class="center"><%=employe.quality.capitalize%></td>
<td class="center"><%=employe.salery%></td>
</tr>
<%end%>
</tbody>
</table>
And I want to get the value of the employe name <%=employe.name%> when popup3 for example is clicked. Note there can be more than one "employe" in the list. How can I get the value of the employe that is on the line where the user clicked the popup, so that I can prepend it using jQuery into the popup <p>.
Ex:
Click to Open Popup | Kevin |...
Click to Open Popup | Sam |...
I need to get the value Sam when I click the "second popup", the
problem is all popups currently have the same id.
Thank you.
Given your code, popup3 (and popup4 for that matter) is gonna be present multiple times on the page (once per tr). You need to give it a class, not an id. I personally like to prefix my JavaScript classes (not used for styling) with js-. In your HTML:
<td class="center cd-popup-trigger js-popup3"><i style="color: red;" class="fa fa-close"></i></td>
You also need to identify the cells which contain the employee name (you'll see why later).
<td class="center js-employee-name"><%= employe.name %></td>
In your JS code, you first need to select the all the td with the js-popup3 class:
$('js-popup3')
Then, you want to trigger something when an event occurs on the element you selected. With jQuery, you would do it like this:
$('js-popup3').on('click', function() {});
Lastly, you want to describe what should be done when the event occurs. This is done in the callback function.
$('.js-popup3').on('click', function() {
# employeeName is the value you want
employeeName = $(this).siblings('.js-employee-name').text();
});
I invite you to read a lot about JS (try to code without jQuery first). Once you feel confident with it, start looking at jQuery.
You can create a click function for the Table tr's and get the value of the third column (index 2):
$('table.reference.notranslate tbody').delegate("tr", "click", function(){
var YourEmployeName = $(this).find('td').eq(2).text();
alert(YourEmployeName);
});
To make the popups ahve unique id's according to employee try something like this:
">
Then I presume you have some js somewhere to handle the popup clicks. This js can extract the employee id with
emp_id = my_clicked_popup_trigger.attr("id").split('-')[-1]

AngularJS - Building a dynamic table based on a json

Given a json like this:
{
"name": "john"
"colours": [{"id": 1, "name": "green"},{"id": 2, "name": "blue"}]
}
and two regular html inputs:
<input type="text" name="name" />
<input type="text" name="color" />
<input type="submit" value="submit" />
I need to build a table with all the possible variations, ex:
John green
John blue
That means that if a user continues adding values through the inputs new rows will appear building the new variations, for instance:
I also need to have available the id to handle it, and I need that when I add new values using the inputs for instance: "Peter" "Black", I need to autofill the id (colour id) dynamically like an auto increment in mysql, resulting in something like this:
{
"colours": […...{"id": 3, "name": "black"}]
}
Is that possible? Which options do I have for doing that with angular? I'm still thinking in the jQuery way and I would like to do it in the angular way.
I took a look to hg-repeat, and used it, but I'm not figuring out how to deliver the expected result, the only thing that come to my mind was to use nested ng-repeats, but it didm´t work.
Thanks so much in advance,
Guillermo
Just want to share with what I used so far to save your time.
Here are examples of hard-coded headers and dynamic headers (in case if don't care about data structure). In both cases I wrote some simple directive: customSort
customSort
.directive("customSort", function() {
return {
restrict: 'A',
transclude: true,
scope: {
order: '=',
sort: '='
},
template :
' <a ng-click="sort_by(order)" style="color: #555555;">'+
' <span ng-transclude></span>'+
' <i ng-class="selectedCls(order)"></i>'+
'</a>',
link: function(scope) {
// change sorting order
scope.sort_by = function(newSortingOrder) {
var sort = scope.sort;
if (sort.sortingOrder == newSortingOrder){
sort.reverse = !sort.reverse;
}
sort.sortingOrder = newSortingOrder;
};
scope.selectedCls = function(column) {
if(column == scope.sort.sortingOrder){
return ('icon-chevron-' + ((scope.sort.reverse) ? 'down' : 'up'));
}
else{
return'icon-sort'
}
};
}// end link
}
});
[1st option with static headers]
I used single ng-repeat
This is a good example in Fiddle (Notice, there is no jQuery library!)
<tbody>
<tr ng-repeat="item in pagedItems[currentPage] | orderBy:sortingOrder:reverse">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.description}}</td>
<td>{{item.field3}}</td>
<td>{{item.field4}}</td>
<td>{{item.field5}}</td>
</tr>
</tbody>
[2nd option with dynamic headers]
Demo 2: Fiddle
HTML
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th ng-repeat="header in table_headers"
class="{{header.name}}" custom-sort order="header.name" sort="sort"
>{{ header.name }}
</th>
</tr>
</thead>
<tfoot>
<td colspan="6">
<div class="pagination pull-right">
<ul>
<li ng-class="{disabled: currentPage == 0}">
<a href ng-click="prevPage()">« Prev</a>
</li>
<li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) "
ng-class="{active: n == currentPage}"
ng-click="setPage()">
<a href ng-bind="n + 1">1</a>
</li>
<li ng-class="{disabled: (currentPage) == pagedItems.length - 1}">
<a href ng-click="nextPage()">Next »</a>
</li>
</ul>
</div>
</td>
</tfoot>
<pre>pagedItems.length: {{pagedItems.length|json}}</pre>
<pre>currentPage: {{currentPage|json}}</pre>
<pre>currentPage: {{sort|json}}</pre>
<tbody>
<tr ng-repeat="item in pagedItems[currentPage] | orderBy:sort.sortingOrder:sort.reverse">
<td ng-repeat="val in item" ng-bind-html-unsafe="item[table_headers[$index].name]"></td>
</tr>
</tbody>
</table>
As a side note:
The ng-bind-html-unsafe is deprecated, so I used it only for Demo (2nd example). You welcome to edit.
Here's an example of one with dynamic columns and rows with angularJS: http://plnkr.co/edit/0fsRUp?p=preview
TGrid is another option that people don't usually find in a google search. If the other grids you find don't suit your needs, you can give it a try, its free
Check out this angular-table directive.
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th ng-repeat="header in headers | filter:headerFilter | orderBy:headerOrder" width="{{header.width}}">{{header.label}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users" ng-class-odd="'trOdd'" ng-class-even="'trEven'" ng-dblclick="rowDoubleClicked(user)">
<td ng-repeat="(key,val) in user | orderBy:userOrder(key)">{{val}}</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
refer this https://gist.github.com/ebellinger/4399082
First off all I would like to thanks #MaximShoustin.
Thanks of you I have really nice table.
I provide some small modification in $scope.range and $scope.setPage.
In this way I have now possibility to go to the last page or come back to the first page.
Also when I'm going to next or prev page the navigation is changing when $scope.gap is crossing. And the current page is not always on first position. For me it's looking more nicer.
Here is the new fiddle example:
http://jsfiddle.net/qLBRZ/3/

Categories

Resources