ng-table: check box selection in each row - angularjs

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;
};

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.

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.

Insert items into table in angularJs

I need your help, I new in angularJs. My question is how can I add items into table.
This is my index.html code:
<div class="col-md-5">
<table class="table">
<tr>
<th>Name</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
<tr ng-repeat="product in products" class="quantity">
<td>{{product.name}}</td>
<td> <sapn class="plus-icon glyphicon glyphicon-minus" ng-click="minusOne($index)"></sapn>
{{product.quantity}}
<sapn class="minus-icon glyphicon glyphicon-plus" ng-click="plusOne($index)"></sapn>
</td>
<td>{{product.price }} </td>
<td>{{product.price * product.quantity}}</td>
</tr>
</table>
<span>Total: {{ getTotal() }}</span>
</br>
<button>first product</button>
<button>second product</button>
</div>
and this is controller.js file:
app.controller('MainController', ['$scope', function ($scope) {
$scope.appName = 'diyetSahovatKafe';
$scope.products = [
{
name: 'Обычный котлет',
quantity: 0,
price: 3500,
}
];
$scope.getTotal = function(){
var total = 0;
for(var i = 0; i < $scope.products.length; i++){
var product = $scope.products[i];
total += (product.price * product.quantity);
}
return total;
}
$scope.plusOne = function(index){
$scope.products[index].quantity += 1;
};
$scope.minusOne = function(index){
$scope.products[index].quantity -= 1;
};
and this is appearance
appearance
by clicking the button items should be added, can anybody help me with this?
Adding an item to products should automatically update your table since it is constructed with ng-repeat. Angular will detect the modification of products and refresh the table's rows since they are based on it.
$scope.products.push({ name : "I don't speak russian", quantity: 0, price : 4200 });

How to set checkAll for in angularjs ng-repeat table

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)};

Resources