angularJS radio buttons not functioning - angularjs

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);
}

Related

Focus on textbox when radiobutton is selected in AngularJS

can someone please give me an idea on how will i set focus on my textbox when I click the radiobutton assigned to it? Im using angular js. Thanks for any idea
I created example for you.
HTML:
<body ng-app="scopeExample">
<div ng-controller="MyController">
<div ng-repeat='item in mas'>
<input type="radio" name='somename' ng-model="item.select" value="true" ng-click='clear(item)'>
<input type='text' focus='item.select'/>
<br>
</div>
</div>
</body>
Javascript:
angular.module('scopeExample', [])
.controller('MyController', ['$scope', function($scope) {
$scope.mas=[
{id:1,select:false},
{id:2,select:false},
{id:3,select:false},
{id:4,select:false}
];
$scope.clear = function(item){
$scope.mas.forEach(function(x){
if(x != item)
x.select=false;
});
}
}]).directive('focus',['$timeout', '$parse', function($timeout, $parse){
return {
link:function (scope, element, attrs) {
var model = $parse(attrs['focus']);
scope.$watch(model, function (value) {
if (eval(value))
$timeout(function () {
element[0].focus();
});
});
}
}
}]);
I will provide you pseudo code which you can alter on the basis of your needs. For now, the code has one radio button which when selected will focus on the input element. However, you can achieve those on list, on checkbox as per your need.
HTML:
<div ng-controller="MyCtrl">
<input type="radio" ng-model="focusRadio" value=0>
<input ng-model="name" focus>
</div>
Script:
var myApp = angular.module('myApp',[]);
myApp.directive('focus', function() {
return function(scope, element) {
scope.$watch('focusRadio',
function (newValue) {
newValue && element[0].focus()
})
}
});
function MyCtrl($scope) {}
Here is the plunker: http://plnkr.co/edit/ABHCRIm95EyNUI8nWczh?p=preview . Change the input type to checkbox to better know about the functionality.

How to get a jQuery plugin wrapper in directive to update AngularJS scope variable?

How can I get the selected date from the jQuery datetimepicker to update the AngularJS scope variable date1?
http://jsfiddle.net/edwardtanguay/3tef6dmr/11
<script type="text/ng-template" id="templateCalendarPicker">
<div class='input-group date datepicker_format' id='datepicker' style="width:{{width}}px">
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</script>
<div ng-controller="mainController">
<div calendar-picker width="200" date="date1"></div>
<div>The selected date is <b>{{date1}}</b>.</div>
</div>
angular.module('myApp', [])
.controller('mainController', function($scope) {
$scope.date1 = '2015-09-19';
})
.directive('calendarPicker', function() {
var controller = function ($scope) {
var vm = this;
$('#datepicker').datetimepicker({
format:'YYYY-MM-DD',
defaultDate: new Date($scope.date)
});
};
return {
restrict: 'A',
scope: {
date : '=',
width : '#'
},
controller: controller,
controllerAs: 'vm',
bindToController: true,
templateUrl: 'templateCalendarPicker'
};
});
I think you can listen for change event of the picker and update the your model.
$(document).on('dp.change', '#datepicker', function (a) {
var selected_date = moment(a.date._d).format('YYYY-MM-DD');
$scope.date = selected_date;
$scope.$apply();
});
here you need to use $scope.$apply(); because this change event is out of angular knowledge, so we need to tell angular to trigger the $digest cycle manually to tell the angular to update the scope and the view.
here is the DEMO,
and to add something more, detach the datepicker when scope is destroying
$scope.$on('$destroy', function() {
$('#datepicker').data("DateTimePicker").destroy();
});
EXAMPLE
hope this make sense :).
Do you need to use a jQuery date picker? jQuery does not cooperate with AngularJS very well.
There are plenty of AngularJS date pickers that will allow you to access the value through a two-way binding (ng-model) or similar.

ng-show doesn't work in scope

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/

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