I would like to check the value of the property of an object and would like to check the data of string to compare.
<div ng-if="results.dataType === 'textTable'">
This text belongs in a table.
</div>
So far all the divs appear with the text in the body where only two divs should display it.
Is there anything wrong with my ng-if statement and string comparison?
Here is the demo Jsfiddle
Js code
var app = angular.module('myApp', []);
app.controller('ctrl', function($scope) {
$scope.results = {
dataType: 'textTable'
};
$scope.flag = true;
// for testing purpose
$scope.toggle = function() {
if ($scope.flag) {
$scope.results = {
dataType: 'textTable'
};
$scope.flag = !$scope.flag;
} else {
$scope.results = {
dataType: 'textTableNot'
};
$scope.flag = !$scope.flag;
}
}
});
HTML
<div ng-app='myApp'>
<div ng-controller='ctrl'>
<div ng-if='results.dataType === "textTable"'> This text belongs in a table.</div>
{{results.dataType}}
<button ng-click='toggle()'>
Toggle
</button>
</div>
</div>
Hope this will resolve your problem
I realized that in angular 2 the if statement is: *ngIf and not ng-if.
Hope this will resolve your problem.
<div>
<input type="hidden" ng-model="myVar" ng-init="myVar = 'stringformat'">
<div ng-if="myVar =='stringformat'">
<h1>Welcome</h1>
<p>Welcome to my home.</p>
</div>
</div>
Related
How can I execute a function when a check box is checked in angular js. I have seen a few answers on stack overflow regarding this but I cannot seem to implement them on my scenario
my code:
<div ng-controller="MyCtrl">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="thirtyDay" ng-click="changeAxis()">
Last 30 Days
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="wholeTimeline" ng-click="changeAxis()">
Whole Timeline
</label>
</div>
</div>
js.
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
function changeAxis(){
if ($scope.thirtyDay) {
alert("checked 30");
}
else if($scope.wholeTimeline) {
alert("checked whole");
}
};
}
You need to place the function on the $scope, so the view will recognize it:
$scope.changeAxis = function() {
if (!$scope.thirtyDay) {
alert("checked 30");
}
else if(!$scope.wholeTimeline) {
alert("checked whole");
}
};
Another thing to notice is that when entering the function you'll get the value of the model from before the push. So if you click and it's checked, the value will still be false (hasn't been updated yet). So either use !$scope.thirtyDay or place in a $timeout.
EDIT: As Mike correctly mentioned in his comment, you would probably be better of using ng-change instead of ng-click (this way the other property won't trigger as well when interacting with the other one). I would also join the recommendation and suggest considering a different function for different properties, but I'm not sure exactly to which use you're doing this.
Here is working demo
HTML
<div ng-app="myApp">
<div ng-controller="myCtrl" >
<div class="checkbox">
<label>
<input type="checkbox" ng-model="thirtyDay" ng-change="changeAxis1()">
Last 30 Days
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="wholeTimeline" ng-change="changeAxis2()">
Whole Timeline
</label>
</div>
</div>
</div>
JS
var app = angular.module('myApp', []);
app.controller('myCtrl',['$scope', function($scope) {
$scope.changeAxis1 = function() {
if ($scope.thirtyDay) {
alert("checked 30");
$scope.wholeTimeline = false;
}
};
$scope.changeAxis2 = function() {
if($scope.wholeTimeline) {
alert("checked whole");
$scope.thirtyDay = false;
}
};
}]);
You need to add controller to myApp with this line.
myApp.controller('MyCtrl', MyCtrl);
You need to link changeAxis function to scope
$scope.changeAxis = changeAxis;
So your app.js will be something like
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', MyCtrl);
function MyCtrl($scope) {
function changeAxis(){
if ($scope.thirtyDay) {
alert("checked 30");
}
else if($scope.wholeTimeline) {
alert("checked whole");
}
};
$scope.changeAxis = changeAxis;
}
I hope you have added ng-app to your html. Also please consider the ngChange suggestion mentioned in the other answer.
I have a form field (input text) with an ng-if being false at the begining. At some point the ng-if value become true.
When this happen, I want to execute some javascript which manipulate the DOM. To keep it simple, let's say that I need to select the input value and focus the field.
<input type="text" ng-value="foo" ng-if="show" onshow="doSomething()"/>
<button ng-click="toggle()"></button>
The JavaScript
ctrl.foo = "bar";
ctrl.show = false;
ctrl.toggle = function(){
ctrl.show = !ctrl.show;
}
I know that it looks like a "non-angular approach", but here I think the action is not model related.
Since the ng-if directive execute the template each time show become true, you can use ng-init for that. See the following snippet and replace alert('test); by anything you want.
angular.module('test', []).controller('test', function($scope, $element) {
$scope.show = false;
$scope.toggle = function() {
$scope.show = !$scope.show;
};
$scope.init = function() {
alert($element.find('input').val());
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="test">
<input type="text" value="foo" ng-if="show" ng-init="init()" />
<button ng-click="toggle()">Toggle</button>
</div>
</div>
I want to change $scope within controller from the wrapping div to the object I'm currently clicking on. My code is as follows:
var blogApp = angular.module('blogApp', ['ngSanitize', 'ngRoute']);
blogApp.controller('blogPostsCtrl', function($scope, $http) {
$http.get('http://jsonplaceholder.typicode.com/posts').success(function(data) {
$scope.posts = data;
$scope.postsLoaded = 'article--loaded';
});
$scope.getPost = function(postID) {
var currentPost = document.getElementById('post-'+postID);
$scope.postsLoaded = 'article--loaded';
$http.get('http://jsonplaceholder.typicode.com/posts/'+postID).success(function(data) {
$scope.body = data.body;
currentPost.insertAdjacentHTML('beforeend', '<div class="body body--hidden" id="body-'+postID+'">'+$scope.body+'</div>');
var currentBody = document.getElementById('body-'+postID);
setTimeout(function() { currentBody.className = currentBody.className + ' body--visible'; }, 1000);
currentPost.classname = 'article one-half desk-one-whole';
});
};
});
html:
<div class="site-wrapper">
<div class="grid-wrapper" ng-controller="blogPostsCtrl">
<article ng-repeat="post in posts" ng-class="postsLoaded" class="article one-half desk-one-whole" id="post-{{post.id}}" ng-click="getPost(post.id)">
<header><h2>{{post.title}}</h2></header>
</article>
</div>
</div>
As you can see, I use function getPost inside controller and there I'm using $scope, but it's (as it should be) set for, like I said, global wrapper. How can I solve this? Please note I'm new to Angular, so I don't know if it's the valid way ;-)
I agree with #Matthew Green. Your question a bit confused. But as far as I can see, you should use directives.
Create a directive and assign to it own $scope.
Hope that will help you.
Have two different divs that can be toggled open and closed in Angualar app but trying to make sure that if one is opened that the other one closes. Seems like this should be simple enough in NG but still new to Angular. Anyone have any pointers?
Made an example fiddle here:
JS Fiddle
Here is the sample:
<body ng-app="simpleToggle">
<div ng-controller="AppCtrl">
<button ng-click="toggleCustom1()">Custom</button>
<span ng-hide="custom1">
<h2>Custom 1 is showing but Custom 2 should not be if it was already opened</h2>
</span>
<span ng-show="custom1"></span>
</div>
<div ng-controller="App2Ctrl">
<button ng-click="toggleCustom2()">Custom2</button>
<span ng-hide="custom2">
<h2>Custom 2 is showing but Custom 1 should not be if it was already opened.</h2>
</span>
<span ng-show="custom2"></span>
</div>
</body>
angular.module('simpleToggle', [])
.controller('AppCtrl',['$scope', function($scope){
$scope.custom1 = true;
$scope.toggleCustom1 = function() {
$scope.custom1 = $scope.custom1 === false ? true: false;
};
}])
.controller('App2Ctrl',['$scope', function($scope){
$scope.custom2 = true;
$scope.toggleCustom2 = function() {
$scope.custom2 = $scope.custom2 === false ? true: false;
};
}]);
Here you are dealing with the scope hierarchy, you wil want to use one of the mechanisms to coordinate between controllers. Some options are:
Using the $rootScope
Using messages
I have updated your example to use $rootScope here http://jsfiddle.net/4q7hrpc5/3/
firstly, create something to initialize the $rootScope. I created an outer controller and wrapped the two other controllers in that controller. Here is the updated HTML:
<body ng-app="simpleToggle">
<div ng-controller="OuterCtrl">
<div ng-controller="AppCtrl">
<button ng-click="toggleCustom1()">Custom</button>
<span ng-hide="!custom1">
<h2>Custom 1 is showing but Custom 2 should not be if it was already opened</h2>
</span>
</div>
<div ng-controller="App2Ctrl">
<button ng-click="toggleCustom2()">Custom2</button>
<span ng-hide="!custom2">
<h2>Custom 2 is showing but Custom 1 should not be if it was already opened.</h2>
</span>
</div>
</div>
</body>
here is the code for the controllers:
angular.module('simpleToggle', [])
.controller('OuterCtrl', ['$rootScope', function($rootScope) {
$rootScope.custom1 = false;
$rootScope.custom2 = false;
}])
.controller('AppCtrl',['$rootScope', '$scope', function($rootScope, $scope){
$scope.toggleCustom1 = function() {
$rootScope.custom1 = !$rootScope.custom1;
$rootScope.custom2 = false;
};
}])
.controller('App2Ctrl',['$rootScope', '$scope', function($rootScope, $scope){
$scope.toggleCustom2 = function() {
$rootScope.custom2 = !$rootScope.custom2;
$rootScope.custom1 = false;
};
}]);
Now this specific technique only works well for a small number of things that have to be coordinated. Messages or a service might be better if you have a large number of these things that need to be coordinated. Another alternative would be to put them all into the same controller.
It is a good practice for handling DOM Stuffs using directive. I use .next() for getting the next span. or you can use other selector for getting it.
documentation for elem: https://docs.angularjs.org/api/ng/function/angular.element
working here here
html:
<body ng-controller="MainCtrl">
<div>
<button change-toggle>Custom</button>
<span id="span1" class="toggle-show-css">
<h2>Custom 1 is showing but Custom 2 should not be if it was already opened</h2>
</span>
</div>
<div>
<button change-toggle>Custom2</button>
<span id="span2" class="toggle-show-css">
<h2>Custom 2 is showing but Custom 1 should not be if it was already opened.</h2>
</span>
</div>
</body>
css
.toggle-hide-css {
visibility: hidden;
}
.toggle-show-css {
visibility: visible;
}
directive
app.directive('changeToggle', ['$location', function($location) {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
elem.bind('click', function(event) {
var spanner = elem.next();
if(spanner.hasClass("toggle-show-css")) {
elem.parent().parent().find('span').removeClass("toggle-show-css");
elem.parent().parent().find('span').addClass("toggle-hide-css");
spanner.removeClass("toggle-show-css");
spanner.addClass("toggle-hide-css");
} else {
elem.parent().parent().find('span').removeClass("toggle-show-css");
elem.parent().parent().find('span').addClass("toggle-hide-css");
spanner.removeClass("toggle-hide-css");
spanner.addClass("toggle-show-css");
}
});
}
}
}]);
Trivial to most
Ok so I have this div that I want to bind some values into AFTER the ng-if has been set to true and AFTER the ng-init has been called.. at this point my ng-init is getting called but the message isnt binding. I might have the wrong tags on but you get what I mean.. i want the function to be called after my statement becomes true.
<div ng-repeat="field in model.fieldData">
<button class="btn-xs" ng-show="!isLocked(field.Id)" ng-click="openField(field)">
Edit
</button>
<div ng-if="isLocked(field.Id)" ng-init="msg = getLockMessage(field.Id)" ng-bind="msg">
</div>
</div>
Look this plunker:
plunker
Is a little example based on your html, and works. Make a little changes the element msg change inside the element parent, because if exist a lot of fieldData then the same variable is replaced.
The JS:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.model = {
fieldData: [{
Id: 123,
locked: false,
}]
};
$scope.isLocked = function(element) {
return element.locked;
}
$scope.openField = function(element) {
element.locked = true;
}
$scope.getLockMessage = function(element) {
return "message from " + element.Id
}
});
And the html:
<div ng-repeat="field in model.fieldData">
<button class="btn-xs" ng-show="!isLocked(field)" ng-click="openField(field)">
Edit
</button>
<div ng-if="isLocked(field)" ng-init="field.msg = getLockMessage(field)" ng- bind="field.msg">
</div>
</div>