AngularJS on-off switch - angularjs

I want a button in angularJs, that when I press it a function is called and when I press it again it does another function, like an ON-OFF switch.
I have this:
<a ng-click="addForm(data)" href=""> <div class="starOff" ng-class="{starOn: checkF(data)}"></div> </a>
I would to call another function when I click it once.

You can use ng-switch.
<div ng-app ng-controller="Ctrl">
<div ng-switch on="selected">
<button ng-switch-when='true' ng-click='button1()'>button1</button>
<button ng-switch-when='false' ng-click='button2()'>button2</button>
</div>
</div>
function Ctrl($scope) {
$scope.selected = true;
$scope.button1 = function () {
//do logic for button 1
$scope.selected = !$scope.selected;
console.log('btn1 clicked');
}
$scope.button2 = function () {
//do logic for button 2
$scope.selected = !$scope.selected;
console.log('btn2 clicked');
}
}
Demo on jsFiddle

Why don't you change the ng-click to something other than addForm(data), like handleClick(data), and then in your controller you can define handleClick(data) to call addForm(data) if a certain flag is already true?

Another possible solution, using ng-click and ng-class to toggle the class.
HTML
<div ng-app="miniapp">
<div ng-controller="Ctrl">
<a ng-click="newClass=toggleClass($event)" ng-class="newClass" href="">Toggle</a>
</div>
</div>
JS
var $scope;
var app = angular.module('miniapp', []);
function Ctrl($scope) {
$scope.toggleClass = function(obj) {
if (obj.srcElement.className == 'starOn') {
return 'starOff';
} else if (obj.srcElement.className == 'starOff') {
return 'starOn';
} else {
return 'starOn';
}
}
};
There are probably better ways to grab the current class name.
Here's the full jsFiddle.

Try using a property instead of a call to the function checkF(). Pretend the property is mySwitch. When your addForm() is called, set mySwitch to true.

How To Toggle A Function Using ng-click
One (of many) methods to swap between two functions when using ng-click. It uses a similar method to what tnunamak suggested.
HTML
<div ng-app="miniapp">
<div ng-controller="Ctrl">
<a ng-click="toggle(toggled)" ng-init="toggled=false" href="">Toggle</a>
</div>
</div>
JS
var $scope;
var app = angular.module('miniapp', []);
function Ctrl($scope) {
$scope.toggle = function(toggled) {
if (toggled == false) {
alert('Function A');
$scope.toggled = true;
} else if (toggled == true) {
alert('Function B');
$scope.toggled = false;
}
}
};
And the full jsFiddle.

You can implement it using Font-Awesome and angular js with following example
<div class="onoffswitch" >
<input type="checkbox" name="someOnOFF" class="onoffswitch-checkbox" id="myonoffswitch6" ng-model="vm.youmodelOnOff" />
<label class="onoffswitch-label" for="myonoffswitch6">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>

Related

Can I check the condition and change the value of variable in ng-click

ng-click="(document.getElementById('procheck1').checked)?showme=true:showme=false"
(or)
ng-click="if(document.getElementById('procheck1').checked){showme=true;}else{showme=false;}"
Use some function name like this , ng-click="myFunction()" and write whole condition inside that.
myFunction(){
if(document.getElementById('procheck1').checked) {
showme=true;
} else {
showme=false;
}
}
Try this in html page
<div ng-app="MyApp" ng-controller="MyController">
<label for="chkPassport">
<input type="checkbox" id="chkPassport" ng- model="ShowPassport" ng-change="ShowHide()" />
Do you have Passport?
</label>
<hr />
<div ng-show="IsVisible">
Passport Number:
<input type="text" id="txtPassportNumber" />
</div>
</div>
and this part in controller
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope) {
//This will hide the DIV by default.
$scope.IsVisible = false;
$scope.ShowHide = function () {
//If DIV is visible it will be hidden and vice versa.
$scope.IsVisible = $scope.ShowPassport;
}
});

ng-model not updates inside ng-repeat

The "declineReasonId" variable is not updates. i use $parent to access parent variable inside "ng-repeat" but it still not working.
I have ng-template html:
<script type="text/ng-template" id="boxDeclineReasonPopup.html">
<div class="modal-header">
<h3 class="modal-title">Chose reason</h3>
</div>
<div class="modal-body">
<form>
<div class="form-group reasonPopupLabel">
<div ng-repeat="(key, value) in reasons" ng-if="key != 0">
<label>{{value}}</label>
<input type="radio" class="form-control" name="reason" ng-model="$parent.declineReasonId" ng-value="{{key}}">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-disabled="declineReasonId === '0'" ng-click="ok()">Submit</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
and my controller:
(function () {
function declineReasonModalController($scope, $modalInstance, appData) {
$scope.declineReasonId = '0';
$scope.reasons = appData.report_type;
$scope.ok = function () {
$modalInstance.close($scope.declineReasonId);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.$watch('declineReasonId', function () {
debugger;
});
}
declineReasonModalController.$inject = ['$scope', '$modalInstance', 'appData'];
var controllers = angular.module('app.controllers');
controllers.controller('DeclineReasonModalController', declineReasonModalController);
})();
The modal instance triggered by function:
$scope.decline = function () {
var modalInstance = $modal.open({
templateUrl: 'boxDeclineReasonPopup.html',
controller: 'DeclineReasonModalController'
});
modalInstance.result.then(function (reasonId) {
$scope.declineReasonId = reasonId;
$scope.declineConfirm();
}, function () { });
};
If i put "{{$parent.declineReasonId }}" inside ng-repeat is duplicate copy of variable. When i press radio button is change value of one of duplicated copies. Why?
The $parent is still not the modal controller's scope yet.
You can use $parent.$parent.declineReasonId to reach the scope in your specific case.
That is why the use of $parent is discouraged.
The best practice when using ng-model is to not reference something in $scope directly, like this:
$scope.model = {};
$scope.model.declineReasonId = '0';
Then change your ng-model this instead:
ng-model="model.declineReasonId"

Can not get the scope variable properly

I have a simple text box and a button and whenever user click on button the alert shows the text of textbox but I want to do it this way(I know there are a lot better ways but first I want to understand why this way does not work):
var app = angular.module('app', []);
app.factory('Service', function() {
var service = {
add: add
};
return service;
function add($scope) {
alert($scope.user.username);
}
});
app.controller('table', function(Service,$scope) {
//get the return data from getData funtion in factory
this.add = Service.add($scope);
});
As you can see I send the scope to factory and I define the user.username as follow:
<button class="btn btn-primary" ng-click="t.add(user.userName)">
But when I run this nothing happens can anyone tell me what is wrong with this code?
<body ng-app="app">
<form>
<div class="row commonRow" ng-controller="table as t">
<div class="col-xs-1 text-right">item:</div>
<div class="col-lg-6 text-right">
<input id="txt" type="text" style="width: 100%;"
ng-model="user.userName">
</div>
<div class="col-xs-2">
<button class="btn btn-primary" ng-click="t.add(user.userName)">
click me</button>
</div>
</div>
</form>
also the plnk link is as follow:
plnkr
The problem is in this line
this.add = Service.add($scope);
Here you are assigning the returned (which is undefined) value of the Service.add($scope) invocation to the this.add.
The right approach will be either
this.add = function(data) { Service.add($scope); }
or
this.add = Service.add;
// in the service factory.
function add(usrNm) {
alert(usrNm);
}
The first thing is you can't use $scope in a service.and in controller your not assaining this(object) to $scope.so $scope doesn't contain any value.
I suppose you to write like this
$scope.user = this;

Controller triggered via factory

I am still a novice with angular. I have asked a question similar to this before, but it seems to be a different issue at work here.
I have two controllers and a factory sharing information between them. I have two separate divs using two different controllers to show / hide using ng=show;
HTML
<div id=main>
<div ng-controller="Ctrl1">
<div ng-show="var1">Hidden Stuff</div>
</div>
<div ng-controller="Ctrl2">
<div ng-show="var1">More Hidden Stuff</div>
</div>
</div>
Both use the same var for ng-show, shared by a factory
JS Factory
app.factory('Srvc', function($rootScope) {
var Srvc = {};
Srvc.var1;
return Srvc;
});
JS Controllers
app.controller('Ctrl1', function($scope, Srvc) {
$scope.var1 = false;
if (user interacts with html in div with ng-controller="Ctrl1") {
$scope.var1 = true;
Srve.var1 = $scope.var1;
}
});
app.controller('Ctrl2', function($scope, Srvc) {
$scope.var1 = Srvc.var1;
if ($scope.var1 === true) {
update HTML in div with ng-controller="Ctrl2"
although I shouldn't need to do this really should I?
}
});
So from what I can tell the factory works ok, the data is saved in the factory Srvc.var1. However when I pass the data true to Srvc.var1 I cannot seem to get Ctrl2 to 'trigger' and update its html with ng-show=true
One way to solve this problem without explicitly creating a watcher, is to wrap var1 in an object inside the service and then pass this object as a $scope variable for both Ctrl1 and Ctrl2 controllers.
DEMO
Javascript
.factory('Svc', function() {
var service = {
data: {}
};
// If you perform http requests or async procedures then set data.var1 here
service.data.var1 = true;
return service;
})
.controller('Ctrl1', function($scope, Svc) {
$scope.data = Svc.data;
})
.controller('Ctrl2', function($scope, Svc) {
$scope.data = Svc.data;
});
HTML
<div id="main">
<div ng-controller="Ctrl1">
<div ng-show="data.var1">Hidden Stuff</div>
<button type="button" ng-click="data.var1 = true">Set data.var1 to true</button>
<button type="button" ng-click="data.var1 = false">Set data.var1 to false</button>
</div>
<hr>
<div ng-controller="Ctrl2">
<div ng-show="data.var1">More Hidden Stuff</div>
<button type="button" ng-click="data.var1 = true">Set data.var1 to true</button>
<button type="button" ng-click="data.var1 = false">Set data.var1 to false</button>
</div>
</div>
So it seems I need to $watch the service for a change within the controller.
Original answer is here.
app.controller('Ctrl2', function($scope, Srvc) {
$scope.$watch(function () {
return Srvc.var1;
},
function(newVal, oldVal) {
$scope.var1 = newVal;
}, true);
});
I think setting Var1 to $rootScope instead of Srvc should work, just call $scope.$root.$digest() after updating var1.
and use ng-show=$root.Var1 in view.

angularjs scope variable change onclick for conditional div

i have two divs i want to show them conditionally with onclick event .
my-angular-app.js
$(document).on('click', '#showless', function(el) {
var appElement = document.querySelector('[ng-app=myapp]');
var $scope = angular.element(appElement).scope();
$scope.$apply(function() {
$scope.value = false;
});
});
$(document).on('click', '#showmore', function(el) {
var appElement = document.querySelector('[ng-app=myapp]');
var $scope = angular.element(appElement).scope();
$scope.$apply(function() {
$scope.value = true;
});
});
and my div of myapp (myapp.html)
<div ng-show="desc" id="description" class="text-muted" style="padding-top:5px;padding-left:10px;padding-right:10px;color:#2E2E2E;font-size:11px;">{{myapp.value|truncate}}<span><a id="showmore" href="">more</a></span>
</div>
<div ng-show="!desc" id="description" class="text-muted" style="padding-top:5px;padding-left:10px;padding-right:10px;color:#2E2E2E;font-size:11px;">{{myapp.value}}<span><a id="showless" href="">less</a></span>
</div>
(truncate is a filter i wrote which works fine .)
I'm not exactly sure what you are trying to do, but Angular provides ng-click, so you should not have to bind to $(document).on('click').
I'd suggest a simpler approach for conditional show:
<div ng-show="desc" id="description" class="text-muted" style="padding-top:5px;padding-left:10px;padding-right:10px;color:#2E2E2E;font-size:11px;">{{myapp.value|truncate}}<span><a id="showmore" ng-click="desc = true" href="#">more</a></span>
</div>
<div ng-show="!desc" id="description" class="text-muted" style="padding-top:5px;padding-left:10px;padding-right:10px;color:#2E2E2E;font-size:11px;">{{myapp.value}}<span><a id="showless" ng-click="desc = false" href="#">less</a></span>
</div>
The above uses ng-click to set the value of desc. Therefore, you don't need any other logic in the controller to toggle the divs.

Resources