data-ng-class conditions is not working when changing url manually - angularjs

I did a conditional statement on the div on data-ng-class and I want to somehow add this scope to the controller and specify when the url is /vegetarian to apply class 'egg' and i manually change url i want the class 'bacon' to be applied, but its not working, where I have i gone wrong?
html:
<div data-ng-class="{'egg': isVeggie, 'bacon': !isVeggie }">
Text here
</div>
controller:
app.controller('foodCtrl', function ($scope, $location) {
$scope.location = $location;
$scope.isVeggie = false;
$scope.isVeggie = function() {
if(isVeggie === $location.path('/vegetarian')) {
return true;
}
}
});
this is not working. When I type /vegetarian, the class egg is being applied, but when I change the url to something else like /breakfast, the class 'egg' remains. How can I make this work?
Thanks

Why the property and the function with the same name ? After all you will have only the function
$scope.isVeggie = false;
$scope.isVeggie = function() {
if(isVeggie === $location.path('/vegetarian')) {
return true;
}
}
Change your code to have only the function.
Only
$scope.isVeggie = function() {
if(isVeggie === $location.path('/vegetarian')) {
return true;
}
}
and markup
<div data-ng-class="{'egg': isVeggie(), 'bacon': !isVeggie() }">
Text here
</div>

You bind you ng-class directive to the property isVeggie and not the function isVeggie().
Change your html to:
<div data-ng-class="{'egg': isVeggie(), 'bacon': !isVeggie() }">
Text here
</div>
You can then remove the following line in your controller:
$scope.isVeggie = false;

Related

AngularJs accordion not opening with is-open attribute

I encountered a strange problem. I had written my own directive. I am trying to use
is-open
attribute to specify when accordion group needs to be opened based on model named $scope.state. Unfortunately it's property isOpen is always false, even when it is changing to true in checked() function.
Directive.html
<accordion>
<accordion-group class="my-panel-body" ng-class="{'my-panel-heading-checked':state.isOpen,'my-panel-heading-default':!state.isOpen}" is-open="state.isOpen">
<!--Accordion header -->
<accordion-heading id="{{groupId}}" >
<div ng-click="checked()" >
<i class="pull-left glyphicon" ng-class="status"></i> {{title}}
</div>
</accordion-heading>
<!--Accordion content -->
</accordion-group>
</accordion>
Directive.js
angular.module('locale').
directive('accordionList', function () {
return{
restrict: 'A',
scope: {
title: '=',
result: '=',
groupId: '='
},
templateUrl: 'html/accordionList.html',
controller: function($scope){
var glyphicon = 'glyphicon glyphicon-';
var status = glyphicon + 'unchecked';
$scope.state = {
isOpen: false
}
$scope.status = status;
$scope.checked = function(){
console.log($scope.state.isOpen) //It is always false!
if ($scope.state.isOpen) {
$scope.state.isOpen = false;
$scope.status = status;
}
else { //Always entering this part of code!
console.log("FLAG");
$scope.state.isOpen = true; //True only here when invoked.
$scope.status = glyphicon + 'check';
console.log($scope.state.isOpen);
}
}
}
};
});
I would be grateful for any help. I have no idea what is not working.
Based on your provided code, I created a plunker to reproduce your issue and it does show the problem.
The fact is that the accordion-group directive will auto bind a toggleOpen function to click event (see the template). In this case, with your own checked function your isOpen value is changed twice when element get clicked, and thus remains unchanged.
so just eliminate the 'check()' or stop changing isOpen value in it.
$scope.checked = function(){
console.log($scope.state.isOpen) //It is always false!
if ($scope.state.isOpen) {
//$scope.state.isOpen = false;
$scope.status = status;
}
else { //Always entering this part of code!
console.log("FLAG");
// $scope.state.isOpen = true; //True only here when invoked.
$scope.status = glyphicon + 'check';
console.log($scope.state.isOpen);
}
}

Changing expression provided to ngShow attribute using controller

I am using ng-show and ng-hide to display/hide content. I would like to change the showme status from true to false within the controller. But when I use the code below, it doesn't work. I'm using the Controller As syntax. Any suggestions on how to get this working right?
HTML:
<h1 ng-show="showme">Confirm Order</h1>
<h4 ng-hide="showme">Contact Information</h4>
Javascript:
.controller('ContactFormCtrl',
function ($http, serviceF, $scope) {
var contactForm = this;
$scope.$watch(serviceF.get, function(valid)
{
if (valid === 'yes') {
contactForm.showme=true;
}
else
{
contactForm.showme=false;
}
});
});
Service:
.service('serviceF', function() {
var valid = 'true';
return {
get: function () {
return valid;
},
set: function (value) {
valid = value;
}
};
UI Router:
.state('payment', {
url: '/payment',
views: {
// . . .
'top': {
templateUrl: 'views/clientinfo.html',
controller: 'ContactFormCtrl as contactForm'
// . . .
}
})
I'm not sure what you're trying to do, but the Controller As syntax goes this way in HTML:
<div ng-controller="ContactFormCtrl as contactForm">
<h1 ng-show="contactForm.showme">Confirm Order</h1>
<h1 ng-show="contactForm.showme">Confirm Order</h1>
</div>
Note the 'as contactForm' thingy passed in the ng-controller directive
Now you know that showme is actually a property of contactForm which is essentially an "alias" of the ContactFormCtrl controller
From there, whenever the showme property changes in the controller, the view will behave accordingly.
// In your controller
var contactForm = this; // aliasing this
contactForm.showme = true; //or false
UPDATE:
Since you're using ui-router, you should be good without ng-controller in your view. I'm noticing you are not passing $scope to your controller, that could be a reason why $scope.$watch isn't working, thus not updating the view.
.controller('ContactFormCtrl', function ($scope, $http, serviceF) {
var contactForm = this;
$scope.$watch(serviceF.get, function(valid) {
if (valid === 'yes') {
contactForm.showme = true;
}else{
contactForm.showme = false;
}
});
});

How to change select functions in Angular Directive?

http://plnkr.co/edit/pJRzKn2v1s865w5WZBkR?p=preview
I have a large select dropdown form which is repeated in 2 places. The only thing that changes is the first select tag, which has a different function.
<!--
On simple, change ng-change function to functionOne
On advanced, change ng-change function to functionTwo
-->
<select name="name1" ng-change="functionOne('function1')" id="the-id-1">
<select name="name2" ng-change="functionTwo('function2)" id="the-id-2">
<option value="aaa">aaa</option>
<option value="bbb">bbb</option>
<option value="ccc">ccc</option>
</select>
I tried using ng-hide ng-show however there must be a different way to accomplish this.
var app = angular.module('myApp', [])
.directive('termsForm', function() {
return {
templateUrl : "termsForm.html",
restrict : "E",
scope : false,
controller : 'TermsFormController'
}
})
.directive('selectOptions', function() {
return {
templateUrl : "form.html",
restrict : "E",
scope : false
}
})
.controller('TermsFormController',
['$scope',
function($scope) {
var vs = $scope;
vs.hello = "This is the form.";
vs.showingSimple = true;
vs.showingAdvanced = false;
vs.showForm = function(type) {
if (type === 'simple') {
vs.showingSimple = true;
vs.showingAdvanced = false;
} else if (type === 'advanced') {
vs.showingSimple = false;
vs.showingAdvanced = true;
}
}
vs.functionOne = function(msg) {
alert(msg);
}
vs.functionTwo = function(msg) {
alert(msg);
}
}]);
termsForm.html
<ul class="nav nav-tabs">
<button class="btn btn-info" ng-click="showForm('simple')">Simple</button>
<button class="btn btn-info" ng-click="showForm('advanced')">Advanced</button>
</ul>
<p>The select:</p>
<div ng-show="showingSimple" class="simple-form">
<p>Simple</p>
<select-options></select-options>
</div>
<div ng-show="showingAdvanced" class="advanced-form">
<p>Advanced</p>
<select-options></select-options>
</div>
You already have a directive created for your select, that gets you half way there. Now you just need to pass the function in through whats known as the isolated scope.
.directive('selectOptions', function() {
return {
templateUrl : "form.html",
restrict : "E",
scope : {
changeFunc: '&'
}
}
})
This allows you to pass in the function you want to call on the ng-change event:
<select-options changeFunc="function1"></select-options>
<select-options changeFunc="function2"></select-options>
And then in your form.html you simply put
<select name="name2" ng-change="changeFunc()" id="the-id-2">
This way you are basically passing the funciton in as a parameter. Read this blog for a great guide on isolated scopes.
I would just refactor your markup and controller to adapt based on the simple/advanced context.
In your controller, you'd expose a 'generic' on change function for the dropdown, first...
(function () {
'use strict';
angular.module('app').controller('someCtrl', [someCtrl]);
function someCtrl() {
var vm = this;
vm.isSimple = true;
vm.nameChange = function () {
if(vm.isSimple)
functionOne('function1');
else
functionTwo('function2');
}
// Other things go here.
}
})();
...Then, on your view, your select would change to this*:
<select id="someId" name="someName" ng-change="vm.nameChange()" />
*: Assuming you're using controllerAs syntax, that is. If you're not, don't prepend the vm. on the select.

How to update value in one controller if the value is updated in different controller?

I have a page design in which i have attached the main controller to body:
<body ng-controller="firstController">
first
second
<input ng-model="hello" ng-disabled="xyz()">
<button id="test" ng-disabled="xyz()">test button</button>
{{hello}}
<div ng-view></div>
</body>
I load a template for default as
var mainApp = angular.module('mainApp',['ngRoute'])
.config(['$routeProvider',function($routeProvider){
$routeProvider.when('/',{
templateUrl: 'partials/first.html',
controller: 'firstTemplate'
})
I my template i a check box as:
<div>
<input type="checkbox" ng-model="check">
</div>
Now i want the button #id to be disable the check box is unchecked, now i thought of using factory as these two are in different controllers:
mainApp.factory('clientId',function(){
var flag = true;
return flag;
});
mainApp.controller('firstController',['$scope','clientId',function($scope,clientId){
//$scope.check = true;
clientId.flag = false;
$scope.xyz = function(){
if(clientId){
return true;
}else{
return false;
}
}
}])
I am able to get the value from factory, now i want to update the value of the flag from different controller(template controller) and the value should reflect in first controller too so that the state of button can be updated.
mainApp.controller('firstTemplate',['$scope','clientId',function($scope,clientId){
}])
How can i update the value from second controller and make it reflect in first controller. If it is not possible is there and alternative to achieve this?
You can solve this using two ways.
1. using $rootScope.
2. using services.
using $rootScope:
<input ng-model="hello" ng-disabled="flagtoDisable">
<button id="test" ng-disabled="flagtoDisable">test button</button>
{{hello}}
<div ng-view></div>
mainApp.controller('firstController', ['$scope','$rootScope','clientId',function($scope,$rootScope,clientId){
//$scope.check = true;
clientId.flag = false;
$scope.xyz = function(){
if(clientId){
return true;
}else{
return false;
}
}
}])
mainApp.controller('firstTemplate','$scope','$rootScope','clientId',
function($scope,$rootScope,clientId){
$rootScope.flagtoDisable = false;
if($scope.check == true){
$rootScope.flagtoDisable = true;
}
}])
using Service:
mainApp.factory('clientId',function(){
var flag = {
status:false; };
return{
setFlag : funcion() {
flag.status = true;
}
getFlag : funcion() {
return flag;
}
});
mainApp.controller('firstController',['$scope','clientId',function($scope,clientId){
//$scope.check = true;
$scope.xyz = function(){
var flag = clientId.getFlag();
return flag.status;
}
}])
<input ng-model="hello" ng-disabled="xyz()">
<button id="test" ng-disabled="xyz()">test button</button>
{{hello}}
<div ng-view></div>
mainApp.controller('firstTemplate',['$scope','clientId',function($scope,clientId){
if($scope.check== true){
clientId.setFlag();
}
}])
This code is not tested.you can follow this approaches.
Yes, You can do it by using $rootScope
The ways are.
Initialize the $rootScope in your controller
Call the first controller scope variable from second controller
if 1st controller varaiable is $scope.name
now you just call $rootScope instead of $scope in second controller
like
$rootScope.name

Angular Js ng-model not updating variable in an inner function

I have the following code in my controller:
appControllers.controller('myCtrl', [ '$scope',
function($scope) {
$scope.timeFreeze = false;
$scope.ws = new WebSocket("ws://localhost:8080/ws");
$scope.ws.onopen = function() {
$scope.ws.send('{...}');
};
$scope.ws.onmessage = function (evt) {
var received_msg = JSON.parse(evt.data);
//...do something with the data...
console.log($scope.timeFreeze); // This is ALWAYS false!!! Why?
if ( $scope.timeFreeze === false) {
$scope.$apply();
} else {
console.log("Frozen!"); // This never runs!!!
}
};
$scope.ws.onclose = function() {
console.log("Connection is closed...");
};
}
]);
and in my html I have:
<div>
<label>Freeze?</label>
<input type="checkbox" ng-model="timeFreeze"/>
</div>
What is meant to happen is that when the checkbox is ticked, the code should output "Frozen!" in the console. Unfortunately this code is NEVER run! The $scope.timeFreeze is always false despite me setting the ng-model for the checkbox.
Posting the answer so it can be marked:
Try using dot notation. Something like ng-model="socket.timeFreeze" and $scope.socket.timeFreeze. JB Nizet used a better naming convention so I'm gong to borrow from him:
In your controller:
$scope.time = {freeze: false };
In your view:
<input type="checkbox" ng-model="time.freeze">

Resources