ng-show doesn't work in scope - angularjs

I'm trying to show/hide something using angular but when it's called via $scope it doesn't work. If I change the show variable with ng-model it works fine.
<div id="editClient"
class="accordeon panel-group"
role="tablist"
aria-multiselectable="true"
ng-show="show">
....
</div>
And in my script this doesn't work.
client.controller('clientController', function($scope) {
$scope.show = true;
$scope.test = function() {
alert('clicked');
$scope.show = true;
}
The "clicked" is shown and I tried to use $apply, too, but result is the same.
But when I use ng-model it works
<input type="checkbox" value="true" ng-model="show">
Can someone explain me why it doesn't work with $scope.show ?

Debug.
Following works just fine using checkbox with ng-bind and button firing function in controller.
<input type="checkbox" ng-model="show">Toggle visibility
<br>
<button type="button" ng-click="toggle()">Toggle visibility</button>
<hr>
<div ng-show="show">Visible</div>
<div ng-show="!show">Hidden</div>
app.controller('Ctrl', function($scope, $http) {
$scope.show = true;
$scope.toggle = function() {
$scope.show = !$scope.show;
};
});

Following works fine using $scope. See jsfiddle
http://jsfiddle.net/ffKTy/312/

Related

How to show value in input field with ng-model?

I created edit form so I have to include default value for each text field. I wrote this HTML code:
<input type="text" ng-model="projectData.title" ng-init="projectData.title=title" name="title" class="form-control" />
In controller:
$scope.title = "This is just title";
It shows nothing in the text box. I tried ng-init="projectData.title={{title}}" and ng-init="projectData.title='title'" but it's just not working.
I'm using angularjs 1.6 and the following solution is not working too.
http://jsfiddle.net/Aejvm/337/
In your scope, you should declare the object like so:
$scope.projectData = {};
$scope.projectData.title = "This is just title";
Check This [Code][1]
[1]: http://jsfiddle.net/d4ts76ys/
Use the object to map it to ng-model
Well you are doing a little wrong.
ng-init is angular directive and you dont need curly braces.
modify your code to this :
html:
<div ng-controller="MyCtrl">
<input type="text" ng-init="rootFolders.name=name" ng-
model="rootFolders.name" >
<br>rootFolders={{name}}
</div>
js:
var app = angular.module('myApp',[]);
app.controller('MyCtrl', function($scope) {
$scope.name = "Acunisasi";
});
I have created fiddle that may help your
jsfiddle
//html
<div ng-controller='MyCtrl'>
<form>
<input ng-init="projectData.title = title" type="text" ng-model="title">
<button ng-click="formSubmit()">
submit
</button>
</form>
{{title}}
</div>
//js
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', MyController]);
function MyController($scope) {
$scope.projectData = {};
$scope.title = 'This is just title';
$scope.formSubmit = function() {
console.log("$scope.projectData ===>", $scope.projectData)
}
}

angularJS radio buttons not functioning

I'm having trouble communicating with my angularJS radio buttons. I'm using the material design framework. I'm fairly new to angular.
HTML
<div ng-controller="MainCtrl as ctrl">
<md-radio-group class="user-type">
<div layout="row" layout-sm="column" layout-align="space-between" layout-align-sm="space-around center">
<md-radio-button ng-model="userType" value="prospective" name="user_type" ng-change='newValue(value)'>Prospective Patient</md-radio-button>
<md-radio-button ng-model="userType" value="patient" name="user_type" ng-change='newValue(value)'>Patient</md-radio-button>
<md-radio-button ng-model="userType" value="caregiver" name="user_type" ng-change='newValue(value)'> Caregiver </md-radio-button>
<md-radio-button ng-model="userType" value="doctor" name="user_type" ng-change='newValue(value)'>Doctor</md-radio-button>
</div>
</md-radio-group>
</div>
JS
.controller('MainCtrl', ['$scope', function($scope) {
var self = this;
$scope.newValue = function(value) {
console.log(value);
};
$scope.$watch('userType', function(value){
if(value == "patient"){
console.log(value);
self.showPatientStepTwo = true;
}else{
console.log(value);
self.showPatientStepTwo = false;
}
});
}])
My ng-change isn't firing and my $watch isn't working either.
Can anyone find where I'm going wrong? I can't communicate between my controller and view!
When you use the controller as syntax, you should bind to that instead of the scope. I think the md-radio-button directive was creating a child scope that was messing things up but hard to reproduce without that directive.
Here's a plunker with the model and click bound to ctrl instead of $scope: http://plnkr.co/edit/fSTBDAMZLFKJgRD4br9K?p=preview
Radios changed to input, but referencing the ctrl:
<input type="radio" ng-model="ctrl.userType" value="prospective" name="user_type" class="user-type-rdo md-warn md-hue-2" ng-change='ctrl.newValue(value)'>Prospective Patient
And the controller updated to move the newValue function off $scope:
.controller('MainCtrl', ['$scope', function($scope) {
var self = this;
this.newValue = function(value) {
console.log(value);
};
$scope.$watch(function(){return self.userType;}, function(value){
if(value == "patient"){
console.log(value);
self.showPatientStepTwo = true;
}else{
console.log(value);
self.showPatientStepTwo = false;
}
});
}])
The newValue function logs undefined - not sure what you were trying to do there, but you can use self.userType in the newValue function if you want the value.
First thing: You don't need to declare an ng-model on ea. angular-material radio button when using radio groups, as per the angular-material docs for radio buttons.
The second thing is, the standard $scope events behave a bit differently when you build your controllers using controllerAs syntax See controllerAs Reference.
function MainController($scope, $log) {
var vm = this;
vm.title = 'Some Title';
vm.showPatientStepTwo = false;
// does not work
$scope.$watch('userType', function(newVal, oldVal){
// do work
});
// works
$scope.$watch('vm.userType', function(newValue, oldValue) {
// do work with newValue
});
// also works
$scope.$watch(function() {
return vm.userType;
}, function(newValue, oldValue) {
vm.showPatientStepTwo = newValue === 'patient';
});
}
Working plunkr: http://plnkr.co/edit/Dth67cQJKarwt3NiE9yp
<div class="form-group">
<label>Type of ad <b class="text-danger">*</b></label><br>
<input type="radio" name="typeofAd" value="sell" ng-model="product.typeofAd"> I want to sell
<input type="radio" name="typeofAd" value="buy" ng-model="product.typeofAd"> I want to buy
</div>
radio button this way works fine for me
refer link
https://scotch.io/tutorials/handling-checkboxes-and-radio-buttons-in-angular-forms
you need to add ng-model and ng-change event like below.
<md-radio-group ng-model="selectedVal" ng-change="showSelected()">
and in your controller you can defined function as following.
$scope.showSelected= function(){
console.log($scope.selectedVal);
}

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 data binding in controller

This works great:
<input type="text" class="search" data-ng-model="name"/>
<div class="rf-contact" data-ng-repeat="contact in contacts | filter: name">
<p class="rf-first">{{contact.first_name}} {{contact.last_name}}</p>
</div>
However I need to implement filter in the controller:
var contactsController = function ($scope, $filter){
$scope.contacts = contacts;
$scope.filteredContacts = $filter('filter')($scope.contacts, $scope.name);
}
<input type="text" class="search" data-ng-model="name"/>
<div class="rf-contact" data-ng-repeat="contact in filteredContacts">
<p class="rf-first">{{contact.first_name}} {{contact.last_name}}</p>
</div>
The problem with the code above is that the data binding is lost. When the data is changing in the text field, the filtering is not happening. Do I need to explicitly set event listeners for the input field in my controller? thanks.
You could try $watch-ing the name:
var contactsController = function ($scope, $filter){
$scope.contacts = contacts;
$scope.filteredContacts = $filter('filter')($scope.contacts, $scope.name);
$scope.$watch('name', function(newValue, oldValue) {
$scope.filteredContacts = $filter('filter')($scope.contacts, newValue);
});
}
For more info on $watch: http://docs.angularjs.org/api/ng/type/$rootScope.Scope. Anytime "something" happens through Angular (like the value of "name" changes because you type something in the text field), Angular will fire the watch you created and execute the function. This is necessary here because the initial code you wrote builds the filteredContacts scope variable when the controller is instantiated and there's nothing re-evaluating this expression.
While this solution with an explicit $watch will work, it's a little hacky. This kind of logic is better encapsulated in a custom filter. You can easily build one with arbitraty logic as described in http://docs.angularjs.org/tutorial/step_09.
Try the following
var contactsController = function ($scope, $filter){
$scope.filterContacts = function(){
$scope.contacts = contacts;
$scope.filteredContacts = $filter('filter')($scope.contacts, $scope.name);
}
}
<input type="text" class="search" data-ng-model="name" ng-change="filterContacts()"/>
<div class="rf-contact" data-ng-repeat="contact in filteredContacts">
<p class="rf-first">{{contact.first_name}} {{contact.last_name}}</p>
</div>
Here's a jsfiddle of this in action:
http://jsfiddle.net/CAuq9/

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