How to get ng-repeat radio-button value inside the controller? - javascript

I have a form, within there are different input-tags and labels :
form action="">
<div class="fields" data-ng-repeat="option in question.body.options">
<input id="{{option.text}}" type="radio" name="gender" ng-model="demographic_value" ng-value="{{option.text}}">
<label for="{{option.text}}">{{option.text}}</label>
</div>
</form>
I want to access the value of the selected radio button, how is the data binded? Is there any standard-method, or "isChecked" value or something like that?
EDIT: OK, to be more clear: I want to have only the option which is selected. Inside the controller, not in the view.
So i can send the selected value over HTTP to a server.
Click a radio button
do something like var checked = $scope.radiobutton
array.push(checked)
Send over to a server

Use a shared service and inject it to any controllers:
angular.module("yourAppName", []).factory("mySharedService", function(){
var mySharedService = {};
mySharedService.values = {};
mySharedService.setValues = function(params){
mySharedService.values = params;
}
return mySharedService;
});
And after inject it into any controller.
For example:
function MainCtrl($scope, myService) {
$scope.radioButtons= myService.values;
}
function AdditionalCtrl($scope, myService) {
$scope.var= myService.values;
}
EDIT: as for checked/unchecked values:
You can use watcher:
$scope.$watch('question.body.options', function (changedOptions) {
//some actions with changed options
}, true);
UPDATE:
As for your update:
1) You should create watcher, such as above.
2) Into the watcher, when value changes - you initialize necessary service property with your values (call setValue function)
3) You should inject sharedService into another controller, and can get these values from this service.
4) Call $http or $resource method to sent this value on server.

ng-repeat creates its own scope for each item, so you might have problem accessing it. Try put the model in an object from parent scope.
ng-value accepts expression but not like {{expression}}.
http://jsfiddle.net/g8qLY/
HTML:
<form ng-app ng-controller="ctrl" name="inputform">
<label for="{{option}}" ng-repeat="option in options">
{{option}}
<input id="{{option}}" type="radio" name="gender"
ng-model="inputform.radioinput" ng-value="option">
</label>
<div ng-bind-template="Radio Input: {{inputform.radioinput}}"/>
</form>
JS:
function ctrl($scope) {
$scope.options = ['Option1', 'Option2', 'Option3'];
}

Related

AngularJS how to re-initialize directive?

I have a directive in AngularJS which is first initialized by default when the parent controller of it is being loaded.
The directive takes data from remote server using AJAX and implements the data in checkboxes - each checkbox get the clue if its already checked or not.
On first load of this page (controller) and directive, the checkboxes are being checked properly.
When I move to another scope (controller) and then back again to the checkboxes scope, none of them are checked.
Even though the data is being requested again from the remote server using AJAX (I console logged it), those checkboxes are ain't get checked.
Should I re-init the directive?
This is the directive (notice the checked attribute):
<checkbox key="{{num}}" selector="{{category.key}}/{{module.key}}" changefunction="togglePermission"
checked="{{permissions[num] && permissions[num].modules.indexOf(category.key+'/'+module.key)!=-1}}"></checkbox>
and this is the checkbox directive html file:
<div class="form-group" ng-class="{'has-danger': errors[selector].length>0}">
<label class="control control-outline control--checkbox {{selector}}">
<div class="input-group">
<span ng-show="title.length>0">{{title}}</span>
<input type="checkbox"
ng-model="this[key][selector]"
ng-disabled="loading"
ng-click="this[changefunction](key, selector)"
ng-checked="checked"
/>
<span class="control__indicator"></span>
</div>
</label>
<small class="text-danger" ng-show="errors[selector].length>0">{{errors[selector]}}</small>
</div>
A quick explaination: I am sending custom key and selector names, for example:
$scope.teams = {
level: ""
}
So the teams will be the key and the level will be the selector
This is the checkbox component js file:
app.directive("checkbox", ($rootScope, parseService) => {
return {
templateUrl: "/shared/checkbox/checkbox.html",
scope: true,
link: function($scope, element, attrs) {
$scope.key = parseService.parse(attrs.key);
$scope.selector = parseService.parse(attrs.selector);
$scope.changefunction = parseService.parse(attrs.changefunction);
$scope.checked = parseService.parse(attrs.checked);
}
}
});

how can I update ng-model dynamically from inside a directive?

I'm new to Angular and can't figure out what I am doing wrong while trying to get ng-model to display an object value.
The goal:
I want to create a directive that reads an Object and generates radio buttons based on Object data. Inside of this Object I have {logAs: 'radioGroupName'}. This should get stored into another object called formData.
Example:
{logAs: 'dog', options: [{option: 'poodle'}, {option: 'pitbull'}]}
This should create two radio buttons, one for pittbull and another for poodle. Both should have ng-model set to dog. If user selects Poodle then final output in the formData Object should be:
{dog: 'poodle'}
The Issue:
I believe I am close, everything works fine except for ng-model. Inside of ng-model the actual Object value (dog) wont show up as I'd like, instead I get the Object path that I typed in.
This is my html:
<div ng-app="test">
<div ng-controller="myController">
<p>formData: {{formData}}</p>
<h3>Static (updates formData)</h3>
<input type="radio" ng-model="formData.dog" value="pitbull"> Pitbull<br/>
<input type="radio" ng-model="formData.dog" value="Bull Dog"> Bull Dog<br/>
<input type="radio" ng-model="formData.dog" value="Poodle"> Poodle
<h3>Dynamic (wont update formData)</h3>
<directive form="formInfo"></directive>
</div>
This is the Javascript:
angular.module('test', [])
.controller('myController', function($scope){
$scope.formData = {};
$scope.formInfo = {
title: 'What type of dog do you have?',
logAs: 'dog',
options: [{option:'Pitbull'}, {option: 'Bull Dog'}, {option:'Poodle'}]
}
})
.directive('directive', function(){
return {
restrict: 'E',
template: '{{form.title}}<div ng-repeat="option in form.options"> <input type="radio" ng-model="form.logAs" value="jack" > {{option.option}}</div>',
scope: {
form: '='
}
}
});
How can I get ng-model to show the output of the object ('dog') instead of the object path?
Here is a fiddle
In your fiddle, it's because on line 3 of your html, you have {{formData}} when it should be {{formData.dog}}

trying to achieve two way binding between ng-repeate and a form

Values of selected row in ng-repeate get populated in a form below it. to accomplish this i am doing a simple thing
<p ng-repeat="item in array" ng-click="SetCurrVariable(item)">
{{item.ThresholdSet}}
</p>
in the controller i have a function
$scope.array = [
{ ThresholdSet: false },
{ ThresholdSet: false },
{ ThresholdSet: false }
];
$scope.SetCurrVariable = function (variable) {
$scope.CurrVariable = variable;
};
form have a check-box that i bind to a property of CurrVariable
<input id="chkThr" type="checkbox" ng-model="CurrVariable.ThresholdSet">
i am trying to achieve this behavior that if i click the check-Box in the form. The change gets visible in ng-repeate like a two way binding.
Plunkr setup
Updated with $scope
$scope.SetCurrVariable = function (variable) {
$scope.CurrVariable = variable;
};
Use this code in your controller, then the two-way binding should work

Populate/clear array when checkbox checked/unchecked

I'm currently using angular-google-maps to build out a map with several different marker types. Below my map I have a simple set of checkboxes like so:
<div class="mapOptions">
<form action="" class="form-inline" style="text-align:center">
<label for="">General:</label>
<input type="checkbox" checked value="Games">
<label for="" style="color:#000033">Games</label>
<input type="checkbox" checked value="Practices">
<label for="" style="color:#ffd900">Practices</label>
</form>
</div>
Within my controller I initialize empty arrays then populate them with 'markers' through calls to my API endpoints:
vm.markersGames = [];
vm.markersPractices = [];
What I want to do is clear each respective array when its checkbox is unchecked (ex: User unchecks 'Games', method within my controller sets vm.markersGames = []), and re-populate each array when checkbox clicked (ex: User checks 'Practices', method within my controller calls API endpoint and populates vm.markersPractices).
The issue I've run into is not knowing how to properly add 'check/uncheck handlers' to my inputs.
Attempt to reload markers when checked:
vm.checkToggle = function(isChecked, value) {
if (!isChecked) {
vm[value] = [];
} else {
getPlayerAddress();
$scope.$apply();
}
};
getPlayerAddress() calls API to populate markers array.
You can use the ngChange directive in order to listen change on your input.
Here is an example :
Controller
(function(){
function Controller($scope, Service) {
//Object to know if the input is checked or not
$scope.form = {};
$scope.markersGames = [];
$scope.markersPractices = [];
//isChecked : input checked or not
//value : keyname of your array, for example markersGames
$scope.change = function(isChecked, value){
!isChecked
//If input is not checked, set our $scope[value] to empty array
? $scope[value] = []
//If the input is checked, call Service
: Service.get(value).then(function(data){
//Retrieve and set data
$scope[value] = data;
});
}
}
angular
.module('app', [])
.controller('ctrl', Controller);
})();
Then you can use a Service with promise to make your requests
Service
(function(){
function Service($q){
function get(url){
var defer = $q.defer();
var promise = defer.promise;
if (url === 'markersGames') {
defer.resolve([1,2,3,4]);
} else {
defer.resolve([4,6,8,1,5,2]);
}
return promise;
}
var factory = {
get: get
};
return factory;
}
angular
.module('app')
.factory('Service', Service);
})();
Then you can add ngChange directive in your html :
HTML
<body ng-app="app" ng-controller="ctrl">
<form action="" class="form-inline" style="text-align:center">
<label for="">General:</label>
<input type="checkbox" checked value="Games" ng-model="form.game" ng-change="change(form.game, 'markersGames')">
<label for="" style="color:#000033">Games</label>
<input type="checkbox" checked value="Practices" ng-model="form.practice" ng-change="change(form.practice, 'markersPractices')">
<label for="" style="color:#ffd900">Practices</label>
</form>
{{markersGames}}
{{markersPractices}}
</body>

AngularFire 3-way data binding is not updating firebase when a checkbox change

I'm developing a simple todo app with Angular and Firebase using AngularFire module.
So I have a boolean attribute in my model represented by a checkbox in the template, the problem is that I'm trying to use the three way data binding from AngularFire using the $bind method to keep the all changes syncronized (firebase data, DOM and ng-model) but the firebase data is not updating when I select a checkbox.
Here's my controller where I'm using the AngularFire $bind method:
angular.module('singularPracticeApp')
.controller('TodoCtrl', ['$scope', 'TodoService', function ($scope, todoService) {
$scope.todos = todoService;
$scope.todos.$bind($scope, 'todo.done');
$scope.addTodo = function () {
$scope.todos.$add({text: $scope.todoText, done:false});
$scope.todoText = '';
};
$scope.remaining = function () {
var count = -11;
angular.forEach($scope.todos, function(todo){
count += todo.done? 0 : 1;
});
return count;
};
$scope.clear = function (id) {
$scope.todos.$remove(id);
};
}]);
And here is the tempalte file:
<div ng-controller="TodoCtrl">
<h4>Task runner</h4>
<span>{{remaining()}} todos left.</span>
<ul>
<li ng-repeat="(id, todo) in todos">
<input type="checkbox" ng-model="todo.done">
<span ng-if="todo.done" style="color: #ddd;">{{todo.text}}</span>
<span ng-if="todo.done == false">{{todo.text}}</span>
<small ng-if="todo.done">clear</small>
</li>
</ul>
<form ng-submit="addTodo()">
<input type="text" ng-model="todoText" placeholder="New todo item">
<input type="submit" class="btn btn-primary" value="add">
</form>
</div>
Am I missing something? Is really possible to make this work with a simple checkbox?
Thanks in advance.
You haven't included todoService here so it's going to be difficult to give you an accurate answer. I'll assume that todoService returns a $firebase instance containing the todos since that seems likely. Keep in mind that the problem could be in that code as well.
Several problems you can address, which may resolve your issue:
Your TodoCtrl is not per-item
You seem to be using TodoCtrl as if it were created per-item in the ng-repeat. However, it exists outside the scope of ng-repeat and is only created once for the entire list.
Ng-repeat does not re-use your existing controller scope.
Directives operate in an isolate scope. That means that they do not share scope with your controller. So when you do ng-repeat="todo in todos" you do not add todo into your controller's scope.
This makes sense since each ng-repeat iteration would overwrite the same todo object.
You are trying to double-bind to a synchronized object
You are trying to create a three-way binding $scope.todos.[$todo].done, but you have already created a three-way binding on $scope.todos. Instead, let $scope.todos take care of synchronization.
You've attempted to bind $scope.todos to a property in itself
When you call $bind, you are binding $scope.todos to $scope.todos.todo.done. Obviously this self-referential statement isn't what you intended. I can't tell what is returned by your service but maybe you meant this:
todoService.$bind($scope, 'todos');
If you don't want to automatically push changes on the entire todos list, you can add a $save call instead of using $bind:
$scope.todos = todoService;
<input type="checkbox" ng-model="todo.done" ng-change="$parent.todos.$save(id)">
All together:
angular.module('singularPracticeApp')
.service('todoService', function($firebase) {
return $firebase( new Firebase(URL_TO_TODOS_LIST) );
});
.controller('TodoCtrl', function($scope, todoService) {
todoService.$bind($scope, 'todos');
$scope.addTodo = function () {
$scope.todos.$add({text: $scope.todoText, done:false});
$scope.todoText = '';
};
/** ... and so on ... **/
});

Categories

Resources