Call function on pageload when ng-checked = true in AngularJS - javascript

I am building checkboxes dynamically using Angular. I set the ng-checked value based on a number of conditions.
The checkbox is appropriately checked on pageload. I need to call the makeAddressDefault() function (currently used in ng-click) on page load when ng-checked = true.
<input type="checkbox"
id="defaultAddress{{$id}}"
ng-model="addressChecked"
name="defaultAddress"
ng-click="makeAddressDefault(add, $event)"
ng-checked="addresses.length === 1 || add.IsDefault() || isSelected(add.id)">
<label ng-init="isAddressDefault(addresses, add)" for="defaultAddress{{$id}}">
{{add.FirstName}} {{add.LastName}}<br />
{{add.Address1}}<br />
{{add.City}}, {{add.State}} {{add.ZIP}}
</label>
What is the best way to handle this? Thanks!

In your controller why don't you do something like
$scope.init = function(){
angular.forEach(addresses, function(add){
if(addresses.length === 1 || add.IsDefault() || isSelected(add.id)){
makeAddressDefault(add)
}
})
}
$scope.init()
It will automatically call your init function once the controller has been initialized.

Related

Boolean filter with checkbox on AngularJS

I have an array of objects with property published which can be true or false.
I'm building a filter to be able to display only published or only not published items.
So far the published one works fine like this:
<input
type="checkbox"
ng-model="search.published"
ng-change="search.published = search.published ? true : undefined">
Published
And in the ng-repeat it looks like this:
ng-repeat="exhibitor in filterItems = (data | filter: search)"
The problem comes when I try to add another checkbox to display only unpublished items.
I've tried this with a second checkbox:
<input
type="checkbox"
ng-model="search.published"
ng-change="search.published = search.published ? false : undefined">
Unpublished
But of course it can't have the same model as the published items one. Also, the checkbox won't get ticked even if I remove the first checkbox.
Any tips on how to work around this?
Checkboxes automatically assign a true or false value to their ng-model values, so it is unnecessary to use ng-change the way you are.
<input
type="checkbox"
ng-model="search.published">
Published
When checked, search.published will be true. When unchecked, it will be false.
Same goes for the second checkbox, but you should use a different ng-model property.
<input
type="checkbox"
ng-model="search.unpublished">
Unpublished
Next you will need to create a custom filter in your controller:
$scope.myCustomFilter = function(exhibitor) {
if (exhibitor.published && exhibitor.published === $scope.search.published) {
return exhibitor;
} else if (!exhibitor.published && exhibitor.published === $scope.search.unpublished) {
return exhibitor;
}
};
You will need you make sure you define $scope.search in your controller.
$scope.search = {
published: false,
unpublished: false
};
Now for your ng-repeat:
ng-repeat="exhibitor in filterItems | filter:myCustomFilter"

HTML placeholder override the ng-model value if it is 0

Is there a way to tell ng-model if your value is 0 then show the placeholder value not the ng-model value.
The reason for this is I have an issue where the UX requires the ng-model to be one value while the business logic requires it to be another.
Something like this.
Controller
$scope.qty = 0;
//...some calculation that requires $scope.qty to be a number
HTML
<input ng-model="qty" placeholder="N/A">
<!-- This will show 0 not N/A as qty has a value-->
I do understand you can edit the functionality of ng-model with the following.
ng-model-options={getterSetter: true}
This does solve this issue in a single ng-model like above but what about when the qty is in a ng-repeat?
In the real world we are making a page that auto calculates the amount of items a user should order based on there inventory. If the inventory is 0 the placeholder is used if it is changed by the user then the value they entered in is used.
As there is more then one product they can order we have this in an ng-repeat.
Controller
$scope.products = [{
//...product data
inventory : 0
}]
HTML
<tr ng-repeat="product in products track by $index">
<td>
<input ng-model="product.inventory" placeholder="N/A">
</td>
</tr>
You can try the setter getter method but as the only value you get is the value entered into the input box you lose the context of which item the user is referring to unless you create a setter getter function for each product.
Try this. You can define a getter function for ng-model directive if you use ng-model-options by setting getterSetter as true. ng-model-options is used to modify the behaviour of ng-model.
<input ng-model="getterSetter" placeholder="N/A" ng-model-options={getterSetter: true}>
// Controller function
$scope.getterSetter = function(value) {
if(value == 0) {
return "N/A";
}
else {
return value;
}
}
You can ngModelOptions, Object to tell Angular exactly when to update the Model.
<input ng-model="updateModel" placeholder="some text" ng-model-options={updateModel: true}>
// Controller method
$scope.updateModel= function(value) {
if(value <= 0) {
return "some text";
}
else {
return value;
}
}

angular js - function firing multiple times with ng-checked inside ng-repeat

I have the following html which has an ng-repeat that generates checkboxes:
<span ng-repeat="name in $ctrl.widgetSelectorNames" class="widget-selectors">
<label class="checkbox" for="{{name}}">
<input type="checkbox" value="{{name}}" ng-model="name" ng-change="$ctrl.toggleVisibility(name)" ng-checked="$ctrl.checkIfHidden(name)"/>
{{name}}
</label>
</span>
what I'm trying to do is have ng-checked=true, if the relevant item has property of hidden as true. I think my logic is correct, but the ng-checked function runs wayy too many times:
let numTimesCalled = 0;
$ctrl.checkIfHidden = function (name){
numTimesCalled++;
console.log(numTimesCalled);
$ctrl.widgets.forEach(widget => {
if (name == widget.name && widget.hidden) {
return true;
}
})
return false;
}
there are six items in $ctrl.widgetSelectorNames yet the function is called 48 times as per the numTimesCalled variable! what's happening? if this isn't the right way to do it, what's a better way?
It's an old question but for those who want to understand what is going on behind the scene can read.
The ng-checked expression needs to be evaluated on every $digest.
See here:
https://docs.angularjs.org/guide/scope#integration-with-the-browser-event-loop

Updating a value in an array using a function - Angular JS

I'm relatively new to AngularJS and I've found myself slightly confused.
Here is my controller:
app.controller("calcController", function($scope) {
$scope.interests=[{time:'month',amount:0},
{time:'quarter',amount:0},
{time:'year',amount:0}];
$scope.rates=[{rate:0.01,lower:0,upper:1000,desc:'£0 - £1000'},
{rate:0.02,lower:1000,upper:5000,desc:'£1000 - £5000'},
{rate:0.03,lower:5000,upper:'none',desc:'£5000+'},];
$scope.balance=0;
$scope.updatedIntAmount=function(balance){
if(balance<0){
return 0;
}
else if(balance>=rates[1].lower && balance<rates[1].upper){
return balance*rates[1].rate;
}
else if(balance>=rates[2].lower && balance<rates[2].upper){
return balance*rates[2].rate;
}
else {
return balance*rates[3].rate;
}
}
});
What I want is some way to bind the value of interests.amount to updatedIntAmount.
Here's my HTML:
<div ng-controller="calcController" class="container">
<div class="form-group">
<label for="balInput">Balance:</label>
<input id="balInput" type="text" class="form-control" ng-model="balance">
</div>
<p ng-repeat="interest in interests">{{'per '+interest.time+':'+interest.amount}}</p>
</div>
So what I have is interests.amount dependent on calculateIntAmount, which in turn is dependent on both rates.rate and balance. How can I get these interests.amount values to change whenever balance is updated?
Thanks
Try adding ng-change to your input field like so <input id="balInput" type="text" class="form-control" ng-model="balance" ng-change="updatedIntAmount(balance)">. This will allow you to call the function on a change to the input field and thus do whatever you want within the function in your controller.
You can learn more at the official AngularJS documentation page
You can look into using $scope.$watch to observe any changes in your balance variable, and then update your interests.amount accordingly.
In your controller, you would have:
$scope.$watch('balance', function(newBalance) {
$scope.interests.amount = $scope.updatedIntAmount(newBalance);
});
Lot of errors are present in your code.
as first there is nothing like rates[1] instead you should change it to $scope.rates[1].
Second : your updatedIntAmount function contains rates[3] which is again wrong as you have rates[2] as max limit according to array index rule.
Your updatedIntAmount function return a single value based upon the balance is inserted. in that case after correcting the errors just add :
{{updatedIntAmount(balance)}}
in your html code. it will change as soon as change in balance.
$scope.updatedIntAmount=function(balance){
if(balance<0){
return 0;
}
else if(balance>=$scope.rates[0].lower && balance<$scope.rates[0].upper){
return balance*$scope.rates[0].rate;
}
else if(balance>=$scope.rates[1].lower && balance<$scope.rates[1].upper){
return balance*$scope.rates[1].rate;
}
else {
return balance*$scope.rates[2].rate;
}
}

How to get ng-repeat radio-button value inside the controller?

I have a form, within there are different input-tags and labels :
form action="">
<div class="fields" data-ng-repeat="option in question.body.options">
<input id="{{option.text}}" type="radio" name="gender" ng-model="demographic_value" ng-value="{{option.text}}">
<label for="{{option.text}}">{{option.text}}</label>
</div>
</form>
I want to access the value of the selected radio button, how is the data binded? Is there any standard-method, or "isChecked" value or something like that?
EDIT: OK, to be more clear: I want to have only the option which is selected. Inside the controller, not in the view.
So i can send the selected value over HTTP to a server.
Click a radio button
do something like var checked = $scope.radiobutton
array.push(checked)
Send over to a server
Use a shared service and inject it to any controllers:
angular.module("yourAppName", []).factory("mySharedService", function(){
var mySharedService = {};
mySharedService.values = {};
mySharedService.setValues = function(params){
mySharedService.values = params;
}
return mySharedService;
});
And after inject it into any controller.
For example:
function MainCtrl($scope, myService) {
$scope.radioButtons= myService.values;
}
function AdditionalCtrl($scope, myService) {
$scope.var= myService.values;
}
EDIT: as for checked/unchecked values:
You can use watcher:
$scope.$watch('question.body.options', function (changedOptions) {
//some actions with changed options
}, true);
UPDATE:
As for your update:
1) You should create watcher, such as above.
2) Into the watcher, when value changes - you initialize necessary service property with your values (call setValue function)
3) You should inject sharedService into another controller, and can get these values from this service.
4) Call $http or $resource method to sent this value on server.
ng-repeat creates its own scope for each item, so you might have problem accessing it. Try put the model in an object from parent scope.
ng-value accepts expression but not like {{expression}}.
http://jsfiddle.net/g8qLY/
HTML:
<form ng-app ng-controller="ctrl" name="inputform">
<label for="{{option}}" ng-repeat="option in options">
{{option}}
<input id="{{option}}" type="radio" name="gender"
ng-model="inputform.radioinput" ng-value="option">
</label>
<div ng-bind-template="Radio Input: {{inputform.radioinput}}"/>
</form>
JS:
function ctrl($scope) {
$scope.options = ['Option1', 'Option2', 'Option3'];
}

Categories

Resources