Using ng-model in search filter - angularjs

I have a search filter in table and I given ng-model name as selectedGcode for it. I am calling ng-click =viewAccount() inorder to call the function on click. But I am getting $scope.selectedGcode in my controller as undefined.
HTML :
<table class="table table-striped">
<thead>
<tr class="myheading">
<th class="col-sm-2"> Code
</th>
<th class="col-sm-2">Name
</th>
</tr>
<tr>
<th class="col-sm-2" >
<input type="text" class="form-control" ng-model="selectedGcode" placeholder="Search" ng-click="viewAccount()" /></th>
<th class="col-sm-2" >
<input type="text" class="form-control" /></th>
<tr>
<tbody>
<tr data-ng-repeat="data in tableData">
<td class ="stylethecontent" >{{ data.groupzcode}}</td>
<td class ="stylethecontent" >{{data.groupzname}}</td>
</tr>
</tbody>
</table>
JS:
$scope.viewAccount = function(){
var json = {
"json": {
"request": {
"servicetype": "6",
"functiontype": "6014",
"session_id": $rootScope.currentSession,
"data": {
"shortname": $scope.selectShortName,
"groupzcode":$scope.selectedGcode
}
}
}
};
UserService.viewListAccount(json).then(function(response) {
console.log(json);
if (response.json.response.statuscode == 0 && response.json.response.statusmessage == 'Success')
$scope.tableData = response.json.response.data;
});
};

If you want to trigger viewAccount() every time something is typed you should use ng-change.
<input type="text" class="form-control" ng-model="selectedGcode" placeholder="Search" ng-change="viewAccount()" /></th>
If you want to trigger viewAccount() specifically on a click, you should use a button instead.
<input type="text" class="form-control" ng-model="selectedGcode" placeholder="Search"/></th>
<button type="button" class="btn btn-default" ng-click="viewAccount()"></button>

You should use "ng-model", or "data-ng-model", not just "model="selectedGcode""
And you can use ngKeyup instead of ngClick. Because ngClick will be triggered just when the user will click on the input form and not when it will write something.

Use 'ng-model' instead of 'model' keyword in <input> to get the value in controller.

Related

angular smart table - pagination doesn't work on refreshing data object

I'm using angular-smart-table, where I'm able to display my data correctly with pagination.
And I do add new records/ update existing records on the same page. Here's the screenshot for reference -
But here, I'm facing problems with pagination after adding a new record/ updating existing one. That is on refreshing an object, it doesn't consider pagination and shows all records on same page at once.
Here is my controller code -
$scope.smartTablePageSize = 10;
$scope.rowsPerPage = [5, 10, 15, 20, 25];
// my function to add a new record
vm.insertAccount = function() {
if(vm.validateAll())
$http({
method: 'POST',
url: addAccountUrl,
data: vm.accountInfo,
headers: { 'Content-Type': 'application/json' }
}).then(function(success) {
vm.getAllAccountsData(); // refreshing data object
}, function(error) {
});
}
// function to refresh data object
vm.getAllAccountsData = function() {
$http.get(accountListUrl)
.then(function(success) {
if (success.data) {
vm.allAccountsData = success.data; // updating data here
}
}, function(error) {
})
}
And the respective HTML -
<div class="col-xlg-12 col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="col-xs-12 form-inline form-group mt-20">
<label for="rows">Rows on page</label>
<select class="form-control show-tick" id="rows" title="Rows on page" selectpicker ng-model="smartTablePageSize" ng-options="i for i in rowsPerPage">
</select>
</div>
<table class="table mt-20 mb-20" ng-if="vm.allAccountsData.length > 0" st-table="vm.allAccountsData">
<thead class="sortable">
<tr>
<th class="table-id" st-sort="id" st-sort-default="true">#</th>
<th st-sort="accounttype">Account Type</th>
<th st-sort="vendor">Vendor</th>
<th st-sort="accountnumber">Account No.</th>
<th st-sort="paymentmode">Payment Mode</th>
<th st-sort="ponumber">PO No.</th>
<th st-sort="vendorcode">Vendor Code</th>
<th st-sort="costcenter">Cost Center</th>
<th st-sort="glcode">GL Code</th>
<th>Action</th>
</tr>
<tr>
<th></th>
<th>
<input st-search="accounttype" placeholder="Search Account Type" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="vendor" placeholder="Search Vendor" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="accountnumber" placeholder="Search Account No." class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="paymentmode" placeholder="Search Payment Mode" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="ponumber" placeholder="Search PO No." class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="vendorcode" placeholder="Search Vendor Code" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="costcenter" placeholder="Search Cost Center" class="input-sm form-control search-input" type="search" />
</th>
<th>
<input st-search="glcode" placeholder="Search GL Code" class="input-sm form-control search-input" type="search" />
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in vm.allAccountsData">
<td class="table-id">{{item.index + 1}}</td>
<td>{{item.accounttype}}</td>
<td>{{item.vendor}}</td>
<td>{{item.accountnumber}}</td>
<td>{{item.paymentmode}}</td>
<td>{{item.ponumber}}</td>
<td>{{item.vendorcode}}</td>
<td>{{item.costcenter}}</td>
<td>{{item.glcode}}</td>
<td>
<button class="btn btn-info editable-table-button btn-xs" ng-click="vm.editAccount(item);">View/Edit</button>
<button class="btn btn-danger editable-table-button btn-xs" ng-click="vm.confirmDeleteAccountModal('app/pages/utilities/pdfNormalizer/confirm-delete-account.html', 'sm', item)">Delete</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="10" class="text-center">
<div st-pagination="" st-items-by-page="smartTablePageSize" st-displayed-pages="10"></div>
</td>
</tr>
</tfoot>
</table>
</div>
So, on refreshing object, What I expect is the similar table with pagination as shown above. And What I'm getting is the table with all records without considering pagination -
I struggled a bit and found an answer! We can use st-safe-src directive on angular-smart-table.
I used it as -
<table class="table mt-20 mb-20" st-table="allAccountsData" st-safe-src="vm.allAccountsData">
Where, allAccountsData is a temporary data object & vm.allAccountsData is an actual one.
Then, I iterated over allAccountsData as -
<tr ng-repeat="item in allAccountsData">
That's it! No any changes in controller code!

angularjs + get multiple checkbox value and attribute values

I am trying to get the multiple checkbox value and attribute values.
Each checkbox have multiple attribute values(data-id, data-ot,data-si).
How to get the checked checkbox with 3 attribute values.
<table>
<thead class="search">
<tr>
<th>
<input type="checkbox" class="selectall " ng-model="selectall" ng-click="select(data)">
</th>
</tr>
</thead>
<tbody>
<tr >
<td>
<input data-id="287" data-ot="31" data-si="541" type="checkbox" - ng-model="rowselect">
</td>
</tr>
<tr >
<td>
<input data-id="295" data-ot="331" data-si="31" type="checkbox" ng-model="rowselect">
</td>
</tr>
<tr >
<td>
<input data-id="297" data-ot="321" data-si="31" type="checkbox" ng-model="rowselect">
</td>
</tr>
<tr >
<td>
<input data-id="296" data-ot="451" data-si="671" type="checkbox" ng-model="rowselect">
</td>
</tr>
<tr >
<td>
<input data-id="293" data-ot="91" data-si="651" type="checkbox" ng-model="rowselect">
</td>
</tr>
<tr >
<td>
<input data-id="294" data-ot="13" data-si="14" type="checkbox" ng-model="rowselect">
</td>
</tr>
</tbody>
</table>
<input type="button" name="Submit" value="Submit" ng-click="ShowSelected()" />
Expected output:
For example 2 checkbox selected selected means:
[{"id":"xx","ot":"xx","si"},{"id":"xx","ot":"xx","si"},]
Code:
app.controller('MyCtrl', function($scope) {
$scope.ShowSelected = function() {
///
};
});
I don't see the point in keeping your data inside attributes like that unless that is something you specifically need for some particular reason.
The easiest way to do this is to make an object array on your scope like this:
$scope.data = [
{id: 123, ot: 234, si: 567, checked: false},
{id: 321, ot: 243, si: 789, checked: false},
{id: 345, ot: 678, si: 567, checked: false}
];
Then you can use ng-repeat to create the table and bind the checkboxes to the .checked property:
<table>
<thead>
<!-- your table header -->
</thead>
<tbody>
<tr ng-repeat="element in data">
<td>
<input type="checkbox" ng-model="element.checked">
</td>
</tr>
</tbody>
</table>
And then write the showSelected() function:
$scope.showSelected = function(){
var tempArray = [];
for(var i=0; i<data.length; i++){
if(data[i].checked) tempArray.push(data[i]);
}
return tempArray; //or maybe console.log(tempArray) or encode to JSON etc.
}
Add attribute 'checked' to your checkbox model
$scope.checkboxList = {[
{
"id": "xx",
"ot": "xx",
"checked": false
},
{
"id": "xx",
"ot": "xx",
"checked": false
}
]}
Use ng-model in your html to bind to your checked attribute
<tr ng-repeat="checkbox in checkboxList ">
<td><input type="checkbox" ng-model="checkbox.selected"></td>
<td>{{checkbox.ot}}</td>
</tr>
And in your controller you can use $filter to filter your checkboxes
app.controller('MyCtrl', function($scope, $filter) {
$scope.ShowSelected = $filter('filter')($scope.checkboxList , { $: true });
});

AngularJS: ng-submit not working

My addAct() funtion was working fine before, until I tried refactoring the index table. Now it isn't responding. Nothing is appearing in the console, for example. Maybe someone can help me figure out what's going on. I use the _form.html partial twice, but take a look at the row with id="newAct"
acts/templates/index.html
<div class="actions_body">
<div class="container">
<h2>Listing Actions</h2>
<div class="body">
<table class>
<thead>
<tr class="row">
<th class="col-md-2 active">
<label>Name</label>
</th>
<th class="col-md-5">Description</th>
<th class="col-md-2">Inspires</th>
<th colspan="2" class="col-md-2">Modify</th>
</tr>
</thead>
<tbody ng-repeat="act in acts">
<tr class="row">
<td class="col-md-2">{{act.name}}</td>
<td class="col-md-5">{{act.description}}</td>
<td class="col-md-2">{{act.inspires}}</td>
<td class="col-md-1"><button ng-click="updateActShow=true">Edit</button></td>
<td class="col-md-1"><button ng-click="deleteAct(act)">Delete</button>
<tr ng-show="updateActShow" ng-include="'acts/templates/_form.html'"></tr>
</tbody>
<tbody>
<tr class="row">
<button ng-click="newActShow=true">New Action</button>
<button ng-click="newActShow=false">Hide</button>
</tr>
<tr ng-show="newActShow" id="newAct" ng-include="'acts/templates/_form.html'"></tr>
</tbody>
</table>
</div>
</div>
</div>
acts/templates/_form.html
<div class="row" ng-controller="ActsController">
<form ng-submit="addAct()">
<td class="col-md-2">
<label for="newActName">Name</label>
<input type="text" ng-model="newAct.name" id="newActName" placeholder="Name" class="form-control">
</td>
<td class="col-md-4">
<label for="newActDescription">Description</label>
<input type="textarea" ng-model="newAct.description" id="newActDescription" placeholder="Description" class="form-control">
</td>
<td class="col-md-2">
<label for="newActInspires">Inspires</label>
<input type="number" ng-model="newAct.inspires" id="newActInspires" placeholder="Inspires" class="form-control">
</td>
<td class="col-md-2">
<input type="submit" value="+" class="btn btn-success">
</td>
</form>
</div>
acts/controllers/ActsController.js
controllers = angular.module('controllers');
controllers.controller('ActsController', [
'$scope',
'$routeParams',
'$location',
'$resource',
function($scope,$routeParams,$location,$resource) {
var Act = $resource('/acts/:actId', {
actId: "#id",
format: 'json'
}, {
'create': {
method: 'POST'
}
});
$scope.acts = Act.query();
$scope.addAct = function() {
act = Act.save($scope.newAct, function() {
$scope.acts.push(act);
$scope.newAct = '';
});
}
$scope.deleteAct = function(act) {
act.$delete();
$scope.acts.splice($scope.acts.indexOf(act), 1);
}
$scope.linkToShowAct = function(act) {
return $location.path('/acts/' + act.id);
}
}]);
You table is outside of ActsController scope. You need to put ng-controller="ActsController" on one of the elements surrounding table.

AngularJS Change UI not reflected in $scope for Firefox

I'm using Firefox-42.0 and AngularJS v1.4.7.
HTML :
<div class="modal-body">
<p>Select user to share with from the list below.</p>
<div class="form-group">
<label for="">Search:</label>
<input type="text" class="form-control" ng-model="SharedSearchKey" ng-model-options="{ debounce: 600 }" />
</div>
<div class="modal-table" ng-show="usersToShare && usersToShare.length">
<table class="table table-striped table-responsive table-condensed">
<thead>
<tr>
<th>Name</th>
<th>User Name</th>
<th>View Only Tasks</th>
<th>Permission</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in usersToShare">
<td ng-bind="row.ContactName"></td>
<td ng-bind="row.UserName"></td>
<td>
<input type="checkbox" ng-model="row.TaskAssign" ng-init="row.TaskAssign=true" />
</td>
<td>
<select ng-model="row.permission" ng-init="row.permission='1'">
<option value="1">Readonly</option>
<option value="2">Write</option>
</select>
</td>
<td>
<input type="checkbox" ng-model="row.selected" ng-click="toggleSelectThisUser(row)" />
</td>
</tr>
</tbody>
</table>
</div>
JS in Controller :
$scope.toggleSelectThisUser = function (user) {
console.log(user);
};
When i change dropdown and click checkBox, it doesn't reflect in $scope. $scope contains the initial value. This problem occurs in Firefox. But it works fine in google chrome.

How to calculate a dynamic value with ng-repeat for a nested object property in AngularJs

I want to calculate taxes in relation with a user-input that correspond to the price.
I have no problem when I don't use ng-repeat. But I can't figure out how to make it works with ng-repeat. For information, the code below refers to an invoice controller where I add items to the invoice.
Here is what I have:
Controller
App.controller('FacturesSoloController', function($scope, $stateParams, Facture ) {
$scope.factureId = $stateParams.factureId;
Facture.get({ id: $stateParams.factureId }, function(data) {
$scope.facture = data;
$scope.ajouterItem = function(){
$scope.facture.items.push({});
}
});
$scope.calculTps = function() {
$scope.item.tps = $scope.item.prix*5/100;
};
$scope.calculTvq = function() {
$scope.item.tvq = $scope.item.prix*9.975/100;
};
$scope.calculGrandTotal = function() {
$scope.item.grandtotal = parseFloat($scope.item.prix)+parseFloat($scope.item.tps)+parseFloat($scope.item.tvq);
};
});
Here is my HTML file
<table class="table">
<thead>
<tr>
<th><strong>Description</strong></th>
<th class="text-right"><strong>Prix</strong></th>
<th class="text-right"><strong>TPS</strong></th>
<th class="text-right"><strong>TVQ</strong></th>
<th class="text-right"><strong>Grand Total</strong></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in facture.items">
<td class="bold" width="50%">
<input type="text" class="form-control" name="description" id="description" ng-model="item.description"></td>
<td class="text-right">
<input type="text" class="form-control" name="prix" id="prix" ng-model="item.prix"></td>
<td class="text-right">
<input type="text" class="form-control" name="tps" id="tps" ng-model="item.tps" value="{{calculTps()}}"></td>
<td class="text-right">
<input type="text" class="form-control" name="tvq" id="tvq" ng-model="item.tvq" value="{{calculTvq()}}"></td>
<td class="text-right">
<input type="text" class="form-control" name="grandtotal" id="grandtotal" ng-model="item.grandtotal" value="{{calculGrandTotal()}}">
</td>
</tr>
<tr>
<td class="bold"></td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right">Grand Total</td>
</tr>
</tbody>
</table>
And here is what {{facture.items | json}} returns
[
{
"id": 1,
"facture_id": 10200,
"description": "Item numéro 1",
"prix": "15.00",
"tps": "0.75",
"tvq": "1.50",
"grandtotal": "17.25",
"created_at": "2015-02-21 15:07:18",
"updated_at": "2015-02-21 15:07:18"
},
{
"id": 2,
"facture_id": 10200,
"description": "Deuxième item quoi",
"prix": "135.00",
"tps": "6.75",
"tvq": "13.47",
"grandtotal": "155.22",
"created_at": "2015-02-21 15:07:18",
"updated_at": "2015-02-21 15:07:18"
}
]
So, I would like the "tps" and the "tvq" to calculate automaticly when I enter a number in the "prix" input. I wonder what is wrong.
In your javascript you still need to refer to 'item' as part of the 'facture' array. The controller doesn't know what '$scope.item' is. You can use '$index' to call a function which will do your calculations for each element in the array.
App.controller('FacturesSoloController', function($scope, $stateParams, Facture ) {
$scope.factureId = $stateParams.factureId;
Facture.get({ id: $stateParams.factureId }, function(data) {
$scope.facture = data;
$scope.ajouterItem = function(){
$scope.facture.items.push({});
}
});
$scope.calculTps = function(i) {
$scope.facture.items[i].tps = $scope.facture.items[i].prix*5/100;
};
$scope.calculTvq = function(i) {
$scope.facture.items[i].tvq = $scope.facture.items[i].prix*9.975/100;
};
$scope.calculGrandTotal = function(i) {
$scope.facture.items[i].grandtotal = parseFloat($scope.facture.items[i].prix)+parseFloat($scope.facture.items[i].tps)+parseFloat($scope.facture.items[i].tvq);
};
$scope.doCalculations = function(i) {
$scope.calculTvq(i);
$scope.calculTps(i);
$scope.calculGrandTotal(i);
}
});
and your HTML
<table class="table">
<thead>
<tr>
<th><strong>Description</strong></th>
<th class="text-right"><strong>Prix</strong></th>
<th class="text-right"><strong>TPS</strong></th>
<th class="text-right"><strong>TVQ</strong></th>
<th class="text-right"><strong>Grand Total</strong></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in facture.items">
<td class="bold" width="50%">
<input type="text" class="form-control" name="description" id="description" ng-model="item.description"></td>
<td class="text-right">
<input type="text" class="form-control" name="prix" id="prix" ng-model="item.prix" ng-change="doCalculations($index)></td>
<td class="text-right">
<input type="text" class="form-control" name="tps" id="tps" ng-model="item.tps"></td>
<td class="text-right">
<input type="text" class="form-control" name="tvq" id="tvq" ng-model="item.tvq"></td>
<td class="text-right">
<input type="text" class="form-control" name="grandtotal" id="grandtotal" ng-model="item.grandtotal">
</td>
</tr>
<tr>
<td class="bold"></td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right">Grand Total</td>
</tr>
</tbody>
</table>
https://docs.angularjs.org/api/ng/directive/ngRepeat
https://docs.angularjs.org/api/ng/directive/ngChange
UPDATE:
You should also use ngChange to call both calculation functions each time the 'prix' is updated

Resources