How to set checkAll for in angularjs ng-repeat table - angularjs

I have a complex ng-repeat table,which I need to set the select all function for the checkbox of each row.He is my code:
JS:
$scope.getCCGenie = function(){
CCGenieService.transactionList().then(function(list){
$scope.CreditCardsList = list;
$scope.CorporateCardsNum = $scope.CreditCardsList.transactionInfo.corpCardCount;
$scope.PersonalCardsNum = $scope.CreditCardsList.transactionInfo.personalCardCount;
});
}
$scope.hasExpenseTypeLabel = false;
$scope.getCCGenie();
$scope.checkAllcorp = function(copcards) {
console.log(copcards);
if (copcards.selectedAllcorp) {
copcards.selectedAllcorp = true;
$scope.hasSelectedExpense = true;
} else {
copcards.selectedAllcorp = false;
$scope.hasSelectedExpense = false;
}
angular.forEach('copcards.transactions',function(v,k){
v.corpisSelected = copcards.selectedAllcorp;
})
};
// I need to loop the selected table to reset each corpisSelected,assign them the new value selectedAllcorp. but how?
};
Html:
<ul>
<li ng-repeat='copcards in CreditCardsList.transactionInfo.corporateCards'>
<span class='creditcardsubtitle'>{{copcards.cardName}} (****{{copcards.cardNumber}})</span>
<table class='table col-xs-12 col-md-12 col-lg-12' border="0" cellpadding="10" cellspacing="0" width="100%">
<thead>
<th class='text-center'><input type="checkbox" ng-model="copcards.selectedAllcorp" ng-change="checkAllcorp(copcards)"/></th>
<th class='text-left'>Date</th>
<th class='text-left'>Merchant</th>
<th class='text-right'>Amount</th>
<th class='text-center'>Expense Type</th>
<th class='text-left'><input type="checkbox" ng-model="selectedAllBill" ng-change="checkAllBillable()" style='margin-right:3px;'/> Billable</th>
<th class='text-center'>Attachment</th>
<th class='text-center'>Description</th>
</thead>
<tbody><tr ng-show='noExpense'><td colspan="8" align="center" style="text-align: center;" >No any Personal Cards!</td>
</tr>
<tr ng-repeat='componentObject in copcards.transactions' ng-class="{'selectedrow':componentObject.corpisSelected}">
<td type='checkbox' class='text-center'><input type='checkbox' ng-model='componentObject.corpisSelected' class='deletebox'/>{{componentObject.corpisSelected}}</td>
<td class='text-left tdwidth'>{{componentObject.transactionDateString | parseDateFormat | date}}</td>
<td class='text-left tdwidth'>{{componentObject.merchant}}</td>
<td class='text-right tdwidth'>${{componentObject.amount}}</td>
<td class='text-center tdwidth'><smart-expense-type></smart-expense-type></td>
<td class='text-left tdwidth'><input type='checkbox' ng-model='componentObject.isBillable'/></td>
<td class='text-center tdwidth'>{{componentObject.hasImage}}</td>
<td class='text-center tdwidth'><input type='text'ng-model='componentObject.description'/></td>
</tr>
</tbody>
</table>
</li>
</ul>
As you can see, I use nasted ng-repeat the loop data, there may be many tables over there, I want each table has his own selectAll function which works independently. Now the code is partly working fine, the problem is if you check the single checkbox in row, the checkall function will not work.I know I need to do something like this:
$scope.checkAllcorp = function() {
if (this.selectedAllcorp) {
$scope.hasSelectedExpense = true
this.selectedRow = true;
this.corpisSelected = true;
} else {
$scope.hasSelectedExpense = false;
this.selectedRow = false;
this.corpisSelected = false;
}
angular.forEach('selectedTable',function(v,k){
v.corpisSelected = this.selectedAllcorp;
})
};
But how can I access this 'selectedTable'?

Pass copcards to your function and then operate on that object instead of this:
ng-change="checkAllcorp(copcards)"
And then in your controller:
$scope.checkAllcorp = function(copcards) {
if (copcards.selectedAllcorp) {
$scope.hasSelectedExpense = true
copcards.selectedRow = true;
copcards.corpisSelected = true;
} else {
$scope.hasSelectedExpense = false;
copcards.selectedRow = false;
copcards.corpisSelected = false;
}
angular.forEach('selectedTable',function(v,k){
v.corpisSelected = copcards.selectedAllcorp;
})
};

you can pass the object you are on by calling it thru the function itself like this
ng-change="checkAllcorp(copcards)
and then use it as a parameter for you checkAllcorp function instead of this in you function
example :
<div ng-repeat="name in names"><button ng-click="msg(name)"></button></div>
controller scope :
$scope.msg = function(name) { alert(name.first)};

Related

How to focus the textbox Within the table using ng-change in angularjs webapi?

When I change the quantity, the quantity focus is lost..
click here to see image
AngularJS Code: ng-change code
$scope.txtqty = function (item) {
var id = item.Id;
$http.put("/api/Products/txtqty/" + id, item).then(function (response) {
$scope.gridproducts = response.data;
})
}
HTML table code
<table>
<tbody>
<tr ng-repeat="item in gridproducts">
<td ng-click="griddelete(item.Id)"><a class="delete"><i class="fa fa-times-circle-o"></i></a></td>
<td class="name">{{item.ProductName}}</td>
<td>{{item.ProductRate}}</td>
<td><input class="form-control qty" type="text" style="width:50px" ng-change="txtqty(item)" ng-model="item.ProductQty" value="{{item.ProductQty}}"></td>
<td>{{item.TotalAmount}}</td>
</tr>
<tr></tr>
<tfoot>
<tr>
<th colspan="2"></th>
<th colspan="2"><b>Total</b></th>
<th><b>{{gridproducts[0].TotalBill}}</b></th>
</tr><tr>
<th colspan="2"><b></b></th>
<th colspan="2"><b>Total Items</b></th>
<th><b>25</b></th>
</tr>
</tfoot>
</table>
Webapi Controller code this is webapi controller here you can see the
[System.Web.Http.Route("api/Products/txtqty/{id}")]
[ResponseType(typeof(void))]
public IHttpActionResult PuttxtQTY(int id, Product Pro)
{
var q = gridlist.Where(x => x.Id == id).FirstOrDefault();
if (q != null)
{
q.ProductQty = Pro.ProductQty;
q.TotalAmount = q.ProductQty * q.ProductRate;
q.TotalBill = gridlist.Sum(x => x.TotalAmount);
foreach (var item in gridlist)
{
item.TotalBill = q.TotalBill;
}
}
return Ok(gridlist);
}
You could give each input a unique ID and manually re-focus it as such:
HTML with ID on input
<td><input class="form-control qty" type="text" id="productQty_{{item.id}}" style="width:50px" ng-change="txtqty(item)" ng-model="item.ProductQty" value="{{item.ProductQty}}"></td>
Function adjusted with re-focus logic
$scope.txtqty = function (item) {
var id = item.Id;
$http.put("/api/Products/txtqty/" + id, item).then(function (response) {
$scope.gridproducts = response.data;
document.getElementById("productQty_" + id).focus();
})
}
Hope this does the job :)

select row containing links and buttons in table by clicking anywhere on the row

I have an AngularJS application managing contacts. The main page contents the list of contacts with a table with different rows. When the user clicks anywhere on the row (except the link for editing and the button for deleting the contact in the last column), he has to be redirected on a section (contact details) of my page.
I tried to do that. It's working but my button for deleting the contact is not working. How can I get that button to work?
Here is my template:
<table ng-show="contacts.length" class="table table-striped table-hover spacer">
<thead>
<tr>
<th class="colPerson">
Person
<span class="hSpacer" ng-class="cssChevronsTri('PERSON')"></span>
</th>
<th class="colCompany">
Company
<span class="hSpacer" ng-class="cssChevronsTri('COMPANY')"></span>
</th>
<th class="colDate">
Date
<span class="hSpacer" ng-class="cssChevronsTri('REQUESTTRUEDATE')"></span>
</th>
<th class="colDescription">
Description
<span class="hSpacer" ng-class="cssChevronsTri('REQUESTDESCRIPTION')"></span>
</th>
<th class="colAction">Action</th>
</tr>
</thead>
<tbody ng-repeat="contact in contacts | filter:searchText | orderBy:champTri:triDescendant" ng-click="selContact(contact,contact.ID)">
<tr class="clickable">
<td class="colPerson" ng-class="{sel:selIdx==$index}">{{contact.PERSON}}</td>
<td class="colCompany">{{contact.COMPANY}}</td>
<td class="colDate">{{contact.REQUESTTRUEDATE | date:'dd/MM/yyyy'}}</td>
<td class="colDescription">{{contact.REQUESTDESCRIPTION}}</td>
<td class="colNbRequest">{{contact.NBREQUEST}}</td>
<td class="colAction">
<a href="#/edit-contacts/{{contact.ID}}" class="inline btn btn-primary">
<span class="glyphicon glyphicon-pencil"></span>
</a>
<button class="inline btn btn-default" data-ng-click="confirmDelPerson(contact.ID)">
<span class="glyphicon glyphicon-remove"></span>
</button>
</td>
</tr>
</tbody>
</table>
If I click anywhere on the row the page for seeing details is displayed.
If I click in the last column on the link for editing the page for editing, it is equally working.
But if I click on the button for deleting it is not working (the page for seeing details appears).
Here is a part of my controller:
app.controller('ctrlContacts', function ($scope, ContactService) {
$scope.contacts = null;
$scope.searchButtonText = "Search";
$scope.test = false;
$scope.reSearch = function () {
// simulate search
$timeout(function () {
// search is complete
}, 2000);
}
$scope.search = function (searchText) {
if (!searchText.length) {
//alert("searchText empty");
}
if (searchText.length > 2) {
$scope.loading = true;
$scope.test = true;
$scope.searchButtonText = "Loading...";
ContactService.fastSearch(searchText).success(function (contacts) {
var length = contacts.length;
$scope.loading = false;
if (length == 0) {
$scope.searchButtonText = "No result";
} else {
$scope.searchButtonText = length + " results found";
}
// For the orderby date
for (var i = 0; i < length; i++) {
if (contacts[i].REQUESTTRUEDATE != "") {
contacts[i].REQUESTTRUEDATE = new Date(contacts[i].REQUESTTRUEDATE.replace(/-/g, "/"));
} else {
contacts[i].REQUESTTRUEDATE = null;
}
}
$scope.contacts = contacts;
$scope.champTri = 'PERSON';
$scope.selIdx = -1;
$scope.selContact = function (contact, idx) {
$scope.selectedContact = contact;
$scope.selIdx = idx;
window.location = "#/view-contacts/" + idx;
}
$scope.isSelContact = function (contact) {
return $scope.selectedContact === contact;
}
});
} else {
$scope.contacts = null;
}
}
// recherche
$scope.searchText = null;
$scope.razRecherche = function () {
$scope.searchText = null;
}
// tri
$scope.champTri = null;
$scope.triDescendant = false;
$scope.personsSort = function (champ) {
if ($scope.champTri == champ) {
$scope.triDescendant = !$scope.triDescendant;
} else {
$scope.champTri = champ;
$scope.triDescendant = false;
}
}
$scope.cssChevronsTri = function (champ) {
return {
glyphicon: $scope.champTri == champ,
'glyphicon-chevron-up': $scope.champTri == champ && !$scope.triDescendant,
'glyphicon-chevron-down': $scope.champTri == champ && $scope.triDescendant
};
}
$scope.confirmDel = function (id) {
if (confirm('Do you want to delete this contact?')) {
ContactService.delContact(id).success(function () {
ContactService.getContact().success(function (contacts) {
$scope.contacts = contacts;
});
});
}
$scope.orderby = orderby;
};
});
It could be this
<tbody ... ng-click="selContact(contact,contact.ID)">
Try to put this ng-click in the <td> tags.
<tbody ng-repeat="contact in contacts | filter:searchText | orderBy:champTri:triDescendant" >
<tr class="clickable">
<td ng-click="selContact(contact,contact.ID)" class="colPerson" ng-class="{sel:selIdx==$index}">{{contact.PERSON}}</td>
<td ng-click="selContact(contact,contact.ID)" class="colCompany">{{contact.COMPANY}}</td>
<td ng-click="selContact(contact,contact.ID)" class="colDate" >{{contact.REQUESTTRUEDATE | date:'dd/MM/yyyy'}}</td>
<td ng-click="selContact(contact,contact.ID)" class="colDescription">{{contact.REQUESTDESCRIPTION}}</td>
<td ng-click="selContact(contact,contact.ID)" class="colNbRequest">{{contact.NBREQUEST}}</td>
<td class="colAction">
<a href="#/edit-contacts/{{contact.ID}}" class="inline btn btn-primary">
<span class="glyphicon glyphicon-pencil"></span>
</a>
<button class="inline btn btn-default" data-ng-click="confirmDelPerson(contact.ID)">
<span class="glyphicon glyphicon-remove"></span>
</button>
</td>
</tr>
</tbody>
Also I recommend you to use flex and not the <table> tag, I've had a lot of problems with this tag.

ng-table: check box selection in each row

I have a ng-table where i am trying to implement selection using check box in each row.
<table id="List" class=" table table-bordered table-striped"
ng-table="tableParams" show-filter="true" template-pagination="custom/pager">
<tbody>
<tr ng-repeat="item in $data" >
<td style="width: 35px">
<input type="checkbox" name="selectedIds[]" value="{{item.id}}" ng-checked="isRowSelected(item.id)" ng-click="toggleSelection(item.id)" />
</td>
<td data-title="'Name'" sortable="'Name'" filter="{ 'Name': 'text' }" >
{{ item.Name}} </a>
</td>
<td data-title="'Email'" sortable="'Email'" >
{{ item.Email}}
</td>
<td data-title="'Phone Number'" sortable="'PhoneNumber'">
{{ item.PhoneNumber}}
</td>
</tr>
this is the controller:
angular.module("umbraco").controller("ListController",
function ($scope, $http, $routeParams) {
$scope.selectedIds = [];
$scope.toggleSelection = function (val) {
var idx = $scope.selectedIds.indexOf(val);
if (idx > -1) {
$scope.selectedIds.splice(idx, 1);
} else {
$scope.selectedIds.push(val);
}
};
$scope.isRowSelected = function (id) {
return $scope.selectedIds.indexOf(id) >= 0;
};
$scope.isAnythingSelected = function () {
return $scope.selectedIds.length > 0;
};
});
i am trying to select individual rows however the above code selecting all the rows on any row click.
any suggestion on this please?
You are not using the power of angular correctly :)
You should try something like that in your view:
<input type="checkbox" ng-checked="item.isRowSelected" ng-click="toggleSelection(item)" />
and in the controller:
$scope.toggleSelection = function(item){
item.isRowSelected = !item.isRowSelected;
}
$scope.isAnythingSelected = function () {
for(var i = 0; i < $scope.data.length; i++){
if($scope.data[i].isRowSelected === true){
return true;
}
}
return false;
};

Lazy loading without scrolling

<div class="table-responsive">
<table class="table table-striped table-hover table-bordered table-condensed">
<thead>
<tr style="text-align: left!important;">
<th width="4%">Part#</th>
<th width="5%">Description</th>
<th width="3.8%">{{title}}</th>
</tr>
</thead>
<tbody>
<tr ng-if="show" ng-repeat="item in dataElemet |orderBy:orderByField:reverseSort" class="PartData">
<td>
<div ng-if="item.isWarningIconShow == true"><img ng-src="../cim/images/projIcons/warning.png"/></div><span ng-bind="item.number"></span>
</td>
<td ng-bind="item.description"></td>
<td ng-bind="item.Number"></td>
<td ng-bind="item.prodCategory"></td>
</tr>
<tr ng-if="show" ng-repeat="item in dataElemet |orderBy:orderByField:reverseSort" class="PartData">
<td>
<div ng-if="item.isWarningIconShow == true"><img ng-src="../cim/images/projIcons/warning.png"/></div><span ng-bind="item.number"></span>
</td>
<td ng-bind="item.description"></td>
<td ng-bind="item.prodCategory"></td>
</tr>
</tbody>
</table>
$scope.intializePartsData = function(objId, dataType){
$scope.loading = true;
$scope.dataElemet = null;
$scope.dataElemet2 = null;
if($scope.show == true && $scope.title == "Show Non Prod"){
objectService.getParts(objId).then(function(parts){
if(dataType == "Elemet") {
$scope.dataElemet = parts.data;
$scope.partsOriginalElemet = angular.copy($scope.dataElemet);
} else {
$scope.dataElemet2 = parts.data;
$scope.partsOriginalElemet2 = angular.copy($scope.dataElemet2);
}
});
} else {
objectService.getPartsProduction(objId).then(function(parts){
if(dataType == "Elemet") {
$scope.dataElemet = parts.data;
$scope.partsOriginalElemet = angular.copy($scope.dataElemet);
} else {
$scope.dataElemet2 = parts.data;
$scope.partsOriginalElemet2 = angular.copy($scope.dataElemet2);
}
});
}
$scope.loading = false;
}
$scope.showHideParts = function(dataType){
$scope.intializePartsData($scope.objId, dataType);
if($scope.show == true && $scope.title == "Show Non Prod"){
$scope.title = "Hide Non Prod";
$scope.show = false;
}else{
$scope.title = "Show Non Prod";
$scope.show = true;
}
}
This is my code its work fine normally . But When there is more data it takes time. So I want to implement lazy loading but as client not interested in scrolling, i need to to do lazy loading without scroll. Is it any way to do lazy loading in angularjs without any event from user.

ng-Repeat going through 3 arrays with different properties

I am making a table where I can show data from 3 arrays (2 has identical properties, 1 different).
<table class="table table-striped table-condensed table-hover">
<thead>
<tr ng-bind-html="head">
</tr>
</thead>
<tbody>
<tr ng-repeat="item in book[bigCurrentPage]">
<td ng-bind="{{row.item1}}"></td>
<td ng-bind="{{row.item2}}"></td>
<td ng-bind="{{row.item3}}"></td>
<td ng-bind="{{row.item4}}"></td>
<td ng-bind="{{row.item5}}"></td>
<td ng-bind="{{row.item6}}"></td>
<td ng-bind="{{row.item7}}"></td>
</tr>
</tbody>
</table>
$scope.row = { item1: "item.code", item2: "item.name" };
$scope.row = { item1: "item.num", item2: "item.name", item3: "item.category", item4: "item.location.name", item5: "item.toloc.name", item6: "item.department", item7: "item.adm", item8: "item.person.name" };
First array has 7 properties (num,name,category,location,department,adm,person) and other 2 arrays has 2 properties (code,name)
The problem lies in that when I use 2 of cells in a row, then other cells are still visible without any content. Is there a way to have one table which can ngRepeat arrays with different properties and property count?
Solution:
<table class="table table-striped table-condensed table-hover">
<thead>
<tr ng-bind-html="head"></tr>
</thead>
<tbody ng-include=activeTable>
</tbody>
</table>
<script type="text/ng-template" id="assets.html">
<tr ng-repeat="item in book[bigCurrentPage]">
<td ng-bind=item.num></td>
<td ng-bind=item.name></td>
<td ng-bind=item.category></td>
<td ng-bind=item.location.name></td>
<td ng-bind=item.department></td>
<td ng-bind=item.adm></td>
<td ng-bind=item.person.name></td>
</tr>
</script>
<script type="text/ng-template" id="persons.html">
<tr ng-repeat="item in book[bigCurrentPage]">
<td ng-bind=item.code></td>
<td ng-bind=item.name></td>
</tr>
</script>
<script type="text/ng-template" id="locations.html">
<tr ng-repeat="item in book[bigCurrentPage]">
<td ng-bind=item.code></td>
<td ng-bind=item.name></td>
</tr>
</script>
$scope.assetshow = function () {
$scope.asse = true;
$scope.pers = false;
$scope.loca = false;
$scope.bigTotalItems = $scope.copy.data.assets.length;
$scope.book = PageItems($scope.copy.data.assets, 17);
console.log($scope.bigCurrentPage)
$scope.row = { item1: "item.num", item2: "item.name", item3: "item.category", item4: "item.location.name", item5: "item.toloc.name", item6: "item.department", item7: "item.adm", item8: "item.person.name" };
$scope.head = '<th>Asset code</th><th>Asset name</th><th>Category</th>'
+ '<th>Location</th><th>Department</th><th>Administration</th><th>Person in charge</th>';
$scope.activeTable = "assets.html";
},
$scope.locationshow = function () {
$scope.asse = false;
$scope.pers = false;
$scope.loca = true;
//produce pages.
$scope.bigTotalItems = PageItems($scope.copy.data.locations);
$scope.book = PageItems($scope.copy.data.locations, 17);
$scope.head = '<th>Kods</th><th>Nosaukums</th>';
$scope.row = { item1: "item.code", item2: "item.name" };
$scope.activeTable = "locations.html";
},
$scope.personshow = function () {
$scope.asse = false;
$scope.pers = true;
$scope.loca = false;
//produce pages.
$scope.bigTotalItems = PageItems($scope.copy.data.persons);
$scope.book = PageItems($scope.copy.data.persons, 17);
$scope.head = '<th>Kods</th><th>Nosaukums</th></tr>';
$scope.row = { item1: "item.code", item2: "item.name" };
$scope.activeTable = "persons.html";
};
By changing activeTable string value table content changes.
DEMO: plnkr

Resources