trying to hide/show div outside ng-view but can not access it.
main controller
var vm = this;
vm.showMyDiv = false;
html
<body ng-app="app" ng-controller="ManinCtrl as main">
<div ng-show="vm.showMyDiv">
my test div
</div>
<div class="ng-view"></div>
<body>
ng-view controller
var vm = this;
vm.hideLoader = true;
how can I access it, I tried with $scope but it does not work
You're declaring the controller like this ng-controller="ManinCtrl as main" so you need to prefix the properties with main and not vm
<div ng-show="main.showMyDiv">
Working example:
angular.module('app', []).controller('mainCtrl', function() {
var main = this;
main.showMe = false;
main.toggleShow = function() {
main.showMe = !main.showMe;
};
}).controller('ctrl', function() {
var vm = this;
vm.exampleText = "I'm inner text in the controller :)";
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="mainCtrl as main">
<div ng-show="main.showMe">HELLO!!</div>
<hr>
<div ng-controller="ctrl as vm">
<div ng-bind="vm.exampleText"></div>
<button ng-click="main.toggleShow()">Click Here</button>
</div>
</div>
I am new in this field and want to write a app, now I meet some problems. Here is a simple version of my code, what I want is the API only show signUp first. After I press signUp and press submit the button shown should be only signout
I think my way is not all right, because after I change the value in service, another controller can't update its value. Could you tell me that?
please use this.logged if possible, thanks!
The process is not necessary to be same to my title. OK if it can implement my function.
https://plnkr.co/edit/1ptaVzmD7EwPZ6dU23gR?p=preview
(function(){
angular.module('myApp',['myApp.dashboard','myApp.value','myApp.signUp']);
})();
(function(){
angular.module('myApp.dashboard',[]);
})();
(function(){
angular.module('myApp.value',[]);
})();
(function(){
angular.module('myApp.signUp',[]);
})();
(function(){
'use strict';
angular.module('myApp.dashboard').controller('mainControl',mainControl);
mainControl.$inject = ['whichToShow'];
function mainControl(whichToShow){
this.logged=whichToShow.getVar();
alert(this.logged);
}
})();
(function(){
'use strict';
angular.module('myApp.value').factory('whichToShow',function(){
alert("running2");
var logged=false;
return {
getVar: function(){
return logged;
},
setVar: function(value){
logged=value;
}
};
});
})();
(function(){
'use strict';
angular.module('myApp.signUp').controller('signUpControl',signUpControl);
signUpControl.$inject = ['whichToShow'];
function signUpControl(whichToShow){
alert("haha");
this.logIn=function(){
whichToShow.setVar(true);
alert("running set!");
};
};
})();
partial html:
<body ng-controller="mainControl as mc">
<div>
<div ng-hide="mc.logged">
<button type="button" class="btn" data-toggle="modal" data-target=".signUp">Sign Up</button>
</div>
<div ng-show="mc.logged">
<button>Sign Out</button>
</div>
</div>
<div class="signUp modal fade" id="signUp" ng-controller='signUpControl as sc'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">sigh up</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
<form id="signUpForm" name="signUpForm" ng-submit="sc.logIn()">
<label for="email">
<span>email:</span>
<input type="email" name="email">
</label>
<button class="submit" id="signUpSubmit" type="submit" value="signUp">submit</button>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</body>
Basically you are setting values in factory object after user clicks on submit but that doesn't reflect in UI as you have not updated the scope object this.logged.So to tell main controller fromsign up controller that change the this.logged $scope value we can use $emit or $broadcast
Apart from $watch approach you can even use $broadcast to achieve this.
Working DEMO
Just add this below code in your JS file controllers
signUpControl
(function(){
'use strict';
angular.module('myApp.signUp').controller('signUpControl',signUpControl);
signUpControl.$inject = ['whichToShow','$rootScope'];
function signUpControl(whichToShow,$rootScope){
alert("haha");
this.logIn=function(){
whichToShow.setVar(true);
$rootScope.$broadcast('login');//broadcasting that user has logged in
//alert("running set!");
};
};
})
mainControl
(function(){
'use strict';
angular.module('myApp.dashboard').controller('mainControl',mainControl);
mainControl.$inject = ['whichToShow','$rootScope'];
function mainControl(whichToShow,$rootScope){
var mc = this;
mc.main ={};
mc.main.logged=whichToShow.getVar();
alert(mc.main.logged);
// below code will listen to the broadcast and do the necessary process..
$rootScope.$on('login',function(event,args){
mc.main.logged=whichToShow.getVar();
});
}
})
You need watch for the changes on the logged value from the service.
That is all you need to do.
(function() {
angular.module('myApp', ['myApp.dashboard', 'myApp.value', 'myApp.signUp']);
})();
(function() {
angular.module('myApp.dashboard', []);
})();
(function() {
angular.module('myApp.value', []);
})();
(function() {
angular.module('myApp.signUp', []);
})();
(function() {
'use strict';
angular.module('myApp.dashboard').controller('mainControl', mainControl);
mainControl.$inject = ['$scope', 'whichToShow'];
function mainControl($scope, whichToShow) {
$scope.$watch(() => whichToShow.getVar(), (newValue, oldValue) => this.logged = newValue)
}
})();
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
var logged = false;
var service = {};
return {
getVar: function() {
return logged;
},
setVar: function(value) {
logged = value;
}
}
});
})();
(function() {
'use strict';
angular.module('myApp.signUp').controller('signUpControl', signUpControl);
signUpControl.$inject = ['whichToShow'];
function signUpControl(whichToShow) {
this.logIn = function() {
whichToShow.setVar(true);
};
};
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="myApp">
<div ng-controller="mainControl as mc">
<div>
<div ng-hide="mc.logged">
<button type="button" class="btn" data-toggle="modal" data-target=".signUp">Sign Up</button>
</div>
<div ng-show="mc.logged">
<button>Sign Out</button>
</div>
</div>
<div class="signUp modal fade" id="signUp" ng-controller='signUpControl as sc'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">sigh up</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
<form id="signUpForm" name="signUpForm" ng-submit="sc.logIn()">
<label for="email">
<span>email:</span>
<input type="email" name="email">
</label>
<button class="submit" id="signUpSubmit" type="submit" value="signUp">submit</button>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</div>
</div>
Working solution on Codepen
You are still trying to set the value of primitives here, rather than object properties. In JavaScript, primitives are passed byValue, not byReference, so whichToShow.getVar(); is returning true or false rather than returning a reference to logged. Therefore, you won't see changes to logged unless you call .getVar() again, to get the new value. This is why most answers you have seen so far have had some form of $watch, $broadcast, or similar, to alert your mc that it should ask again for the logged variable's current value.
If you want to avoid using a $watch, you should use an object instead of a primitive. by using an object, you can pass the object byReference, which will allow angular to see the changes to the properties wherever there is a reference set.
In your factory, return an object:
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
alert("running2");
var status = {
logged: false
};
var logged = false;
return {
getVar: function() {
return status;
},
setVar: function(value) {
status.logged = value;
}
};
});
})();
In mainControl, use a reference to this object:
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
alert("running2");
var status = {
logged: false
};
return {
getVar: function() {
return status;
},
setVar: function(value) {
status.logged = value;
}
};
});
})();
And finally, use the object property in the HTML:
<div ng-hide="mc.status.logged">
...
<div ng-show="mc.status.logged">
...
https://plnkr.co/edit/Pindt2LYxDxyk8C5Axp1?p=preview
I might even go one step further and just return the object directly by the service, and skip the getVar and setVar functions.
You can put some variable globally or in your rootcontroller,lets says isLoggedIn
now with one service you can set this variable on signingIn
and use it like this
{
}<span data-ng-if="!isLoggedIn">Sign In</span>
<span data-ng-if="isLoggedIn">Sign Out</span>
Why I can't change value using function? AngularJS
html:
<div ng-controler='TestCtrl' id='TestCtrl'>
<h1>Test: {{test.name}}</h1>
<div ng-hide='showTest'>
<div class='content'>
<p>First name: <input ng-model='firstName'></p>
<p>Last name: <input ng-model='lastName'></p>
</div>
<div jq-ui-button ng-click='doSth()'>
Do something
</div>
</div>
</div>
JS:
app.controller('TestCtrl', function ($scope) {
$scope.showTest = false;
$scope.test = {name:'Test name'};
$scope.doSth = function() {
$scope.showTest = true;
}
}
It does not work. But when I write:
<div jq-ui-button ng-click='showTest = true'>
It works.
Where is the problem?
You must write ng-controller not ng-controler. That's why your code is not used. First line in your HTML.
I have a form with additional data fields displayed in a modal:
<form class="form-horizontal" name="newForm" ng-controller="FormCtrl" ng-submit="submit()">
<label>Test</label>
<div ng-controller="ModalCtrl">
<a class="btn btn-link" ng-click="open()">Open</a>
<ng-include src="'partials/modal.html'"></ng-include>
</div>
</form>
includes:
<div modal="shouldBeOpen" close="close()" options="opts">
<div class="modal-header">
<h4>I'm a modal!</h4>
</div>
<div class="modal-body">
<ul>
<input type="text" tabindex="16" ng-model="someinput" name="someinput" size="32" class="validate[someinput]" />
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-warning cancel" ng-click="close()">Cancel</button>
</div>
</div>
JS:
var ModalCtrl = function ($scope) {
$scope.open = function () {
$scope.shouldBeOpen = true;
};
$scope.close = function () {
$scope.shouldBeOpen = false;
};
$scope.opts = {
backdropFade: true,
dialogFade:true
};
};
How can I read/inject/transfer the user input from the modal form into the main form?
What you need is to communicate between two controllers and this can be achieved by creating a service.
Using this as reference.
You could create a service as follows:
angular.module('myApp', [])
.service('sharedInput', function () {
var modalInput = "";
return {
getModalInput:function () {
return modalInput;
},
setModalInput:function (value) {
modalInput = value;
}
};
});
Next, in your ModalCtrl() function, I assume that you will have a button to submit the input. Let us say that clicking this button invokes the "submitInput" function in the scope of ModalCtrl. You will write this function as:
$scope.submitInput = function() {
sharedInput.setMOdalInput($scope.someinput);
}
...and in your FormCtrl() you will write the following code to read the modal input:
var input = sharedInput.getModalInput()
You also need to pass the parameter "sharedInput" to the ModalCtrl and FormCtrl just like how you passed $scope. And now you have your two controllers communicating.
I found a comment to an issue on GitHub with a plunker explaining the problem and the solution with angular-ui, without the shared service. Works like a charm.
http://plnkr.co/edit/ktfq0Y?p=preview
As in the title, I'm trying to set a class on a div on page load ( not on a click ) with angular ng-class but I have no clue how to or if it is possible. The div is wrapped in a module and controller where I was previously trying to set the variable with $scope.frontpage but it didn't work.
<div id="main" role="main" class="clearfix" data-ng-module="ValidationBoxModule" ng-controller="ValidationBoxClassController">
<div validation-id="dataValidationSummary" validation-summary ng-class="frontpage" ></div>
<asp:ContentPlaceHolder ID="MainContentPlaceHolder" runat="server"></asp:ContentPlaceHolder>
</div>
angular.module("ValidationBoxModule", []).controller("ValidationBoxClassController", ["$scope", function ($scope) {
$scope.frontpage = "";
($("#main").find(".sliderBox")) ? $scope.frontpage = "frontpage" : $scope.frontpage = "";
}]);
So is there a way to do it ?
What you're trying to do is not the angular way. As in: "don't do DOM manipulation in the controller". Instead use a directive, e.g:
function Ctrl($scope) {
$scope.frontpage = false;
}
angular.module('app', ['app.directives']);
angular.module('app.directives', []).directive('isFrontpage', function () {
return {
restrict: 'A',
link: function (scope, element) {
scope.frontpage = angular.element(element).find('#main .sliderBox').length > 0;
}
};
});
with:
<body ng-controller="Ctrl" is-frontpage>
<div id="main">
<div class="sliderBox"></div>
</div>
<div
validation-id="dataValidationSummary"
validation-summary
ng-class="{frontpage: frontpage}">
</div>
</body>
demo: http://jsbin.com/unihon/4/