I have a div that I am hiding/showing using angular in my HTML, but I want to know how to check if it is currently hidden or not in my controller.
Any solutions I have found so far are jQuery based using 'hasClass' to find ng-hide, but I don't want to use jQuery.
My div looks like this
<div class="item item-input" ng-show="showDetails"></div>
<button class="button button-block button-light leftTextButton"
ng-click="showDetails = ! showDetails; updateTimes()">
<i ng-class="{'icon icon ion-minus-round': showDetails,
'icon icon ion-plus-round': !showDetails}"></i> End Time</button>
I thought from my controller I could just call if($scope.showDetails) and that would return true or false, but it is undefined.
How can I check if a div if hidden or showing from my controller? Thanks
I'm guessing you are having a scoping issue. Passing it to the function that will check it is the best bet. Otherwise if it is in scope the controller should be able to access it.
angular.module('MyApp', [])
.controller('MyController', ['$scope',
function($scope) {
$scope.myBoolean = false;
$scope.checkMyBooleanOnScope = function() {
alert($scope.myBoolean);
};
$scope.checkMyOtherBooleanOnScope = function() {
alert($scope.myOtherBoolean);
};
$scope.checkBooleanByPassingIt = function(bool) {
alert(bool);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="MyController">
<p>myBoolean predefined in the controller:{{myBoolean}}
<input type="checkbox" ng-model="myBoolean" />
</p>
<p>
<button ng-click="checkMyBooleanOnScope()">checkMyOtherBooleanOnScope</button>
<button ng-click="checkBooleanByPassingIt(myBoolean)">checkMyBooleanByPassingIt</button>
</p>
<p>myOtherBoolean defined on the page with ng-model:{{myOtherBoolean}}
<input type="checkbox" ng-model="myOtherBoolean" />
</p>
<p>
<button ng-click="checkMyOtherBooleanOnScope()">checkMyBooleanOnScope</button>
<button ng-click="checkBooleanByPassingIt(myOtherBoolean)">checkMyOtherBooleanByPassingIt</button>
</p>
</div>
Related
I am using ng-switch when method to append divs. This is the code created
<input type="checkbox" ng-model="data" />
<ng-switch on="data">
<span ng-switch-when="true">
<div class="firstSwitch"></div>
</span>
<span ng-switch-default>
<div class="secondSwitch"></div>
</span>
</ng-switch>
Its working fine now. But when i want to append something in the div.
Say, i want to append text using javascript inside secondSwitch div, but i can't append it because initially the secondSwitch div is not appended.
setTimeout(function(){
$(".secondSwitch").html("<p>Second Switch is displayed</p>");
$(".firstSwitch").html("<p>First Switch is displayed</p>");
},100);
Here the text is appended properly inside firstSwitch div because initially it is created but the text is not appended inside secondSwitch div because it's not created.
So, i can't append inside that div. So, how to overcome this problem guys. Here is the Plnkr
As you already noticed ng-switch modifies DOM and firstSwitch is not created initially. You should use binding to get this working. Here is working demo
<ng-switch on="data">
<span ng-switch-when="true">
<div class="firstSwitch"><p>{{firstText}}<p></div>
</span>
<span ng-switch-default>
<div class="secondSwitch"><p>{{secondText}}<p></div>
</span>
app.controller('MainCtrl', function($scope, $timeout) {
$scope.data = false;
$timeout(function(){
$scope.firstText = "First Switch is displayed";
$scope.secondText = "Second Switch is displayed";
},100);
Update
And here's demo for binding to html
Try this
<div class="secondSwitch"><div id="replacediv"></div></div>
var divElement = angular.element(document.querySelector('#replacediv'));
var appendHtml = $compile('<div>test</div>')($scope);
divElement.append(appendHtml);
you can use ng-show directive for this.
// Code goes here
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope,$timeout) {
$scope.data = false;
$scope.show = false;
$scope.change = function(){
$timeout(function(){
$scope.show = !$scope.show;
},300);
}
});
<script src="http://code.jquery.com/jquery-1.12.2.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="plunker">
<div ng-controller="MainCtrl">
<input type="checkbox" ng-model="data" ng-change="change()" />
Check
<ng-switch on="data">
<span ng-switch-when="true">
<div class="firstSwitch">
<p ng-show="show">First Switch is displayed</p>
</div>
</span>
<span ng-switch-default>
<div class="secondSwitch">
<p ng-show="!show">Second Switch is displayed</p>
</div>
</span>
</ng-switch>
</div>
What is the best way of populate a div (or ng-include) with a ready .html template using anuglarjs, not using ng-view and routing?
for ex:
<div>
<ng-include src="" />
</div>
<input type="button" ng-click="getTemplate()" value="Get template" />
$scope.getTemplate = function() {
//Get and..populate template here
}
Using ng-show/ng-hide/ng-if
<div ng-controller="TodoCtrl">
<div ng-show="show">Hello</div>
<button ng-click="showHide()">Boom</button>
</div>
function TodoCtrl($scope) {
$scope.show = true;
$scope.showHide = function(){
$scope.show = !$scope.show
}
}
fiddle
Difference between ngShow/ngHide & ngIf - ng-if will remove elements from DOM. This means that all your handlers or anything else attached to those elements will be lost. ng-show/ng-hide does not remove the elements from DOM. It uses CSS styles to hide/show elements, also ng-if creates a child scope while ng-show/ng-hide does not
Thanks
Use ng-if or ng-show:
<div ng-if="templateVisible">
<ng-include src="" />
</div>
<input type="button" ng-click="getTemplate()" value="Get template" />
$scope.getTemplate = function() {
$scope.templateVisible = true;
}
And using ng-show:
<div ng-show="templateVisible">
<ng-include src="" />
</div>
<input type="button" ng-click="getTemplate()" value="Get template" />
$scope.getTemplate = function() {
$scope.templateVisible = true;
}
The difference between the two is that ng-if doesn't populate the DOM, when the condition is false, while ng-show does, but marks it as display: none.
I had a hard issue figuring out on how to hide and show icon/text with angular code. I am completely new to angular and tried hard on the below fiddle code. How do I hide + or minus icon with .closest in such dom scenarios.
<div ng-controller="MyCtrl">
{{name}}
<div data-toggle="collapse" aria-expanded="true" data-target="#list-item-line-0" id="expandCollapseChild" ng-click="addExpandCollapseChildIcon()">
<div>
<div>
<label>
<div>
<span class="icon-expand">-</span>
<span class="icon-collapse">+</span>
</div>
<div>
Click me to hide minus icon
</div>
</label>
</div>
</div>
</div>
</div>
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.addExpandCollapseChildIcon = function() {
alert('');
if (angular.element('#expandCollapseChild').hasClass('collapsed')) {
angular.element(this).closest('.icon-collapse').css('display', 'none');
} else {
if (angular.element('#expandCollapseChild').hasClass('collapsed')) {
angular.element(this).closest('.icon-collapse').css('display', 'block');
}
}
}
In Angular, this is the wrong approach. You shouldn't actually show or hide elements inside the controller. That's applying a jQuery style (working directly on the DOM) to Angular.
In Angular, you'd use something like ng-if, ng-show or ng-class, all of which can link back to a property on the scope object that is accessible via the controller.
Here are some examples:
<div ng-if="myProp === 'ShowMe'">
<div ng-show="myProp === 'ShowMe'">
<div ng-class="{myCssClass: myProp === 'ShowMe'">
Inside your controller, you'd have something like this:
function MyCtrl($scope) {
$scope.myProp = 'ShowMe';
$scope.addExpandCollapseChildIcon = function(newPropValue) {
$scope.myProp = newPropValue;
}
}
Here's some links to documentation on ng-if, ng-show and ng-class:
https://docs.angularjs.org/api/ng/directive/ngIf
https://docs.angularjs.org/api/ng/directive/ngShow
https://docs.angularjs.org/api/ng/directive/ngClass
AngularJS has a bunch of angulary ways of doing things, your question for example might look like this:
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
$scope.collapsed = true;
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ctrl">
<span ng-bind="collapsed ? '+' : '-'"></span>
</div>
</div>
It watches a model and changes it's appearance based on that model using the ternary operator within ng-bind.
The way you defined your app and controller was incorrect. There's a bunch of different ways to do this as you can see from the answers.
I took this approach:
<div ng-app='myApp' ng-controller="MyCtrl">
{{name}}
<div>
<div>
<div>
<label>
<div>
<span ng-show='(collapsed != false)' class="icon-expand">-</span>
<span ng-show='(collapsed == false)' class="icon-collapse">+</span>
</div>
<div ng-click='collapsed = !collapsed'>
Click me to hide minus icon
</div>
</label>
</div>
</div>
</div>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
$scope.name = 'Superhero';
$scope.collapsed = false;
});
</script>
Create a scoped variable that indicated whether or not it is collapsed . Then change that variable and the ng-shows will react.
I am having problem with angular ng-Click.
My Controller
var ParentController = function ( ) {
this.MyEvent = function () {
alert('foo-bar');
};
this.AddHTML= function () {
$("#ButtonSec").html('<input type='button' ng-click='Parent.MyEvent()' value='inner button'/>');
};
};
angular.module('myApp', []).controller('ParentController', ParentController);
HTML - 1 (Works as expected button ng-click binds to 'inner button' as expected):
<div ng-app='testComponent'>
<div id="content" ng-controller="ParentController as Parent">
<div id="ButtonSec">
<input type='button' ng-click='Parent.MyEvent()' value='inner button'/>
</div>
</div>
</div>
HTML-2 (Not working):When rendering html using Add HTML button. Event not binding to inner button as it should (important thing I can't use $scope as per client requirement)
<div ng-app='testComponent'>
<div id="content" ng-controller="ParentController as Parent">
<div id="ButtonSec">
</div>
<input type='button' ng-click='Parent.AddHTML()' value='Add HTML'/>
</div>
</div>
I'd suggest you to use ng-if directive which will add or remove html on the Expression which we will provide to it. To showing hiding that div you need to maintain one variable inside your controller context that will be responsible for showing that div on html.
Html
<div ng-app='testComponent'>
<div id="content" ng-controller="ParentController as Parent">
<div ng-if="Parent.showContent" id="ButtonSec">
<input type='button' ng-click='Parent.MyEvent()' value='inner button'/>
</div>
<input type='button' ng-click='Parent.showContent = true' value='Add HTML'/>
</div>
</div>
Not sure why you don't want to use $scope because angular manage $scope eventually internally. This is hack way using $rootScope
var ParentController = function ($compile,$rootScope ) {
this.MyEvent = function () {
alert('foo-bar');
};
this.AddHTML= function () {
$("#ButtonSec").html($compile("<input type='button' ng-click='Parent.MyEvent()' value='inner button'/>")($rootScope.$$childHead));
};
};
Let's say i have a search box and i want to display it after user click on button . so far so good .
but i want to add another feature , when user click anywhere search box go away .
How can i do this with AngularJs ?
this is my code :
HTML
<button class="btn btn-info " ng-click="addStyle()" ><i class="fa fa-search"></i>
Search</button>
<input type="text" placeholder="Type" class="{{noneStyle}} {{visibleStyle}}">
Angular
app.controller("MainCtrl", function($scope,$http){
$scope.noneStyle = "noneVisible";
$scope.addStyle = function(){
$scope.noneStyle = "visibleStyle";
}
})
any idea ?
Thx in advance
I'd recommend use ng-if instead
app.controller("MainCtrl", function($scope,$http){
$scope.visible = true;
$scope.changeStatus = function(){
$scope.visible = !$scope.visible;
}
$scope.hideAll= function(){
$scope.visible=false;
}
})
HTML
<div class="well" ng-controller="MyController">
<button class="btn btn-primary" ng-disabled="checked" ng-click="changeStatus()" ng-blur="hideAll()">BUTTON</button>
<hr/>
{{visible}}
<input type="text" placeholder="Type" ng-if="visible">
</div>
look at this jsFiddle
try it out!
Use ng-blur/ng-focus to achieve this.
I demonstrate a simple code over here. http://jsfiddle.net/lookman/1Lp95or0/
var myApp = angular.module('myApp',[]);
myApp.controller('MyController', function($scope) {
$scope.visible = true;
$scope.changeStatus = function(){
$scope.visible = !$scope.visible;
}
$scope.hideAll= function(){
$scope.visible=false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyController">
<button ng-disabled="checked"
ng-click="changeStatus()">Click to show/hide the input box</button>
<hr/>
<p>Current visible status: {{visible}}</p>
<input type="text" placeholder="Type" ng-show="visible" ng-blur="hideAll()">
</div>
</div>
Note that in this example, you need to click on input box first before clicking elsewhere to hide it. I hope this is what are you looking for and this helps.
Use the ng-blur directive to update your model when the user clicks somewhere else:
<button class="btn btn-info " ng-click="addStyle()" ng-blur="removeStyle()">
You could do it using standard JavaScript, registering an event listener once the search box is displayed and unregistering it, as soon as the user has clicked anywhere:
$scope.addStyle = function()
{
$scope.noneStyle = "visibleStyle";
// register event listener
document.addEventListener("click", hideSearchBox);
}
function hideSearchBox()
{
// set style to hide search box
$scope.noneStyle = "noneVisible";
// unregister event listener
document.removeEventListener("click", hideSearchBox);
}
I'm not sure if there is a more Anuglar-way of doing it. To do so, you would need to register something on document level, as you want the search box to be hidden if you click anywhere. And "anywhere" might not be where the Angular root scope is registered..