ng-click firing twice for radio buttons - angularjs

I have the following:
<div class="csv-radio-group">
<input type="radio" id="csv" name="export-type" ng-value="csv" ng-click="$ctrl.setExportType($event, 'csv')">
<label for="csv">csv</label>
</div>
<div class="qfx-radio-group">
<input type="radio" id="qfx" name="export-type" ng-value="qfx" ng-click="$ctrl.setExportType($event, 'qfx')">
<label for="qfx">qfx</label>
</div>
<div class="ofx-radio-group">
<input type="radio" id="ofx" name="export-type" ng-value="ofx" ng-click="$ctrl.setExportType($event, 'ofx')">
<label for="ofx">ofx</label>
</div>
with the following in my controller:
const setExportType = (event, type) => {
exportTypeSelection = type;
if(event){
event.stopPropagation();
}
console.log(exportTypeSelection);
console.log(event);
}
When I click on the csv button I see:
csv
MouseEvent {isTrusted: true, isDefaultPrevented: ƒ,
stopImmediatePropagation: ƒ, isImmediatePropagationStopped: ƒ,
screenX: 1628, …}
undefined
undefined
How come the radio buttons are firing twice and how can I fix this? I'm aware I can use ng-model but if I were to use ng-click how would this be done? Thanks!

Related

ng-required changing checkbox from false to undefined

I've been banging my head for a while on this one.
I have a checkbox typed input using ng-model, ng-required, and ng-change
When I uncheck a checkbox I expect the ng-model to be set to false, but it is actually being set to undefined
Also when the ng-required expression toggles; the ng-model also bounces between undefined and false which in turn causes ng-change to trigger.
My actual ng-change code executes some code I do not want to run multiple times.
The simple snippet below shows what I'm running into. I threw a text input into the example to see if it did the same thing. It appears to do the same thing when a user enters a string then deletes it...
This question is not about text inputs...I'm mostly surprised that a false value is not a valid checkbox value when ng-required is true.
var app = angular.module('example', []);
app.controller('controller',['$scope', function($scope){
$scope.inputModel = {
isSelected: undefined,
textInput: undefined
};
$scope.onChangeCounter = 0;
$scope.requiredModel = true;
$scope.resolveCheckboxInput = function() {
if (typeof $scope.inputModel.isSelected === "undefined") {
return "I am undefined"
}
return "I am " + $scope.inputModel.isSelected
};
$scope.resolveTextInput = function() {
if (typeof $scope.inputModel.textInput === "undefined") {
return "I am undefined"
}
return "I am " + $scope.inputModel.textInput
};
$scope.onChangeCallback = function() {
$scope.onChangeCounter++;
};
$scope.isRequired = function() {
return $scope.requiredModel;
};
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="example">
<ul>
<li> Set Checkbox Input to TRUE</li>
<li> Set Checkbox Input to FALSE</li>
<li> Toggle ng-required</li>
<li> Checkbox Input is cleary affected</li>
</ul>
<div ng-controller="controller">
<label>
<input type="checkbox"
ng-required="isRequired()"
ng-change="onChangeCallback()"
ng-model='inputModel.isSelected' />
Checkbox Input
</label>
<br><br>
<div>
<b>Checkbox Input:</b> {{resolveCheckboxInput()}}
</div>
<br><br>
<label>
<input type="text"
ng-required="isRequired()"
ng-model='inputModel.textInput' />
Text Input
</label>
<br><br>
<div>
<b>Text Input:</b> {{resolveTextInput()}}
</div>
<br><br>
<label>
<input type="checkbox"
ng-model='requiredModel' />
ng-required
</label>
<br><br>
<div>
<b>Checkbox Input ng-change Counter:</b> {{onChangeCounter}}
</div>
</div>
</div>
Credit goes to this SO question/answer: Checkbox input undefined when unchecked - AngularJS
You need to add ng-model-options.
<input type="checkbox"
ng-required="isRequired()"
ng-change="onChangeCallback()"
ng-model='inputModel.isSelected'
ng-model-options="{ allowInvalid: true }" />
I'd usually mark this as duplicate but the answer in the link wasn't accepted, so it may not be apparent that this works.

How to get selected radio value using Bootstrap radio button groups and AngularJS

I'm using Bootstrap radio button groups and am having a hard time getting the selected value into my controller. I have a small snippet of JS to set the selection on which button was clicked:
$(document).ready(function() {
$('form .btn-group label').on('click', function() {
$(this).find('input').prop('checked', true);
});
});
Here is example HTML:
<form name="add-form" ng-submit="addFavorites()" novalidate>
<div class="form-group">
<label class="control-label">Color</label>
<div class="btn-group" data-toggle="buttons">
<label class="btn">
<input type="radio" name="color" value="red" class="form-control" ng-model="favorites.color" ng-required="true">Red
</label>
<label class="btn">
<input type="radio" name="color" value="blue" class="form-control" ng-model="favorites.color" ng-required="true">Blue
</label>
</div>
</div>
</form>
Now when I submit this with ng-submit to this function, I do not get any console logged values for my radio buttons.
$scope.addFavorites = function() {
angular.forEach($scope.favorites, function(value, key) {
console.log(key, value);
});
};
What am I doing wrong?
You do not need this code:
(document).ready(function() {
$('form .btn-group label').on('click', function() {
$(this).find('input').prop('checked', true);
});
});
Your radio button is wrapped with its label so HTML5 will propagate click from the label to the radio.
Initialize your $scope.favorites object to {}
That is it, in submit you can get your $scope.favorites object with all its arguments.
Plunker: http://plnkr.co/edit/OatdIsvCUBSniHHQFyxG?p=preview

How to pre-select radio buttons in angularjs

When my model value is true then I want the radio buttons to be selected when loaded, but its happening the otherway around. All false models are getting selected. How do fix this.
http://plnkr.co/edit/DIYm4vBM3srdS61K6EPA?p=preview
angular.module('radioExample', [])
.controller('ExampleController', ['$scope',
function($scope) {
$scope.kind = [{
name: 'task',
selected: false
}, {
name: 'bug',
selected: false
}, {
name: 'other',
selected: true
}, {
name: 'rfe',
selected: false
}]
$scope.$watch('kind', function() {
console.log('changed', JSON.stringify($scope.kind, null, 2))
}, true)
}
]);
use ng-value here is the doc for angular radio
<input type="radio" name="" id="" value="" ng-model="k.selected" ng-value="true" />
then, if the ng-value is true and the model value is also true then check box will checked
here is the update Demo
<input type="checkbox" id="rempass" ng-model="rememberMe" ng-checked="rememberMeUserInfoCheck()" > $scope.rememberMeUserInfoCheck=function() { return true; }
this works for me
Add ng-checked ="true" to your radio input field
`<input type="radio" ng-model="modelName" name="radioName" value="value1" ng-checked="true">`
I fixed the plunker plunker
<form name="myForm" ng-controller="ExampleController">
<br />all 'false' radio buttons are selected when 'value' is used -------------
<br />
<div ng-repeat="k in kind">
<input type="radio" name="" id="" value="" ng-model="!k.selected" value="k.selected" />{{k.name}}
</div>
<br />all radio buttons are selected when 'ng-value' is used -------------
<br />
<div ng-repeat="k in kind">
<input type="radio" name="" id="" value="" ng-model="k.selected" ng-value="k.selected" />{{k.name}}
</div>
</form>
you had it right.... just needed to add a ! so the model will take the opposite of the scope value... since you are using them for both I guess its wont hurt your code
For those working with FormGroup and FormControl:
In the template:
Add formControlName = sameNameforAllRadioButtonsOfAChoice as an attribute to your radio button input tags.
Also add value = "true" and value = "false" (you can also do it with numbers and strings, but I will continue with boolean).
In the component:
Add the name, e.g. sameNameforAllRadioButtonsOfAChoice, to your FormGroup:
myForm = new FormGroup({sameNameforAllRadioButtonsOfAChoice: new FormControl('false')})
This sets the default value to false. In the FormControl, be careful to write it as a string!
BONUS - If you need Validation:
import { FormControl, FormGroup, Validators } from '#angular/forms';
myForm = new FormGroup({sameNameforAllRadioButtonsOfAChoice: new FormControl('false', [Validators.required])})

Angular JS + Button should be enabled if at least one checkbox is checked how To do it?

I want a button that is only enabled if at least one of a group of checkboxes is checked, similiar to the fiddle at http://jsfiddle.net/chriscoyier/BPhZe/76:
var checkboxes = $("input[type='checkbox']"),
submitButt = $("input[type='submit']");
checkboxes.click(function() {
submitButt.attr("disabled", !checkboxes.is(":checked"));
});
I want to implement this using AngularJs.
Add a function to your controller that checks if any of the check boxes are checked. If the radio button is checked its value will be true. Then, in the HTML use the ng-disabled directive on your button and set it equal to the result of your function. Example:
Controller:
$scope.isCheckboxChecked = function() {
return ($scope.checkbox1 || $scope.checkbox2 || $scope.checkbox3);
}
HTML:
<button type="button" ng-disabled="!isCheckboxChecked()">My Button</button>
It would be helpful if you posted the code you have already tried. My answer is assuming you already have functional check boxes using the ng-model directive and are just looking for how to disable the button when any of them are checked.
Update:
If you don't already have your checkboxes binding to your controller, here is an example. Note the use of ng-model to bind to a $scope.checkbox1 or $scope.checkbox2 variable in your scope.
<input type="checkbox" ng-model="checkbox1">Checkbox 1
<input type="checkbox" ng-model="checkbox2">Checkbox 2
Assuming that your form consists of a long list of check boxes, then alternatively you can create the list in the Controller's $scope and then iterate each check box items along with specific properties such as its label and its state(model) where it is checked or not. Next is to create a function that determines if any of the check box in the check box list has its state checked(isChecked).
Plunker DEMO
Controller
controller('Controller', function($scope) {
$scope.checkBoxes = [
{label: 'Option 1', isChecked: false},
{label: 'Option 2', isChecked: false},
{label: 'Option 3', isChecked: false},
{label: 'Option 4', isChecked: false},
{label: 'Option 5', isChecked: false}
];
$scope.isChecked = function() {
for(var e in $scope.checkBoxes) {
var checkBox = $scope.checkBoxes[e];
if(checkBox.isChecked)
return true;
}
return false;
};
});
At this point, you can iterate the check box list in your form and fill up properties(e.g. label) and its respective models(isChecked) in each check box.
HTML
<form ng-controller="Controller">
<div ng-repeat="checkBox in checkBoxes">
<input type="checkbox" ng-model="checkBox.isChecked" id="check-box-{{$index}}" />
<label ng-bind="checkBox.label" for="check-box-{{$index}}"></label>
</div>
<div>
<input type="submit" value="do thing" ng-disabled="!isChecked()" />
</div>
</form>
this could be a solution but it's not easy to understand what you are searching for
HTML
<h1>Button should be enabled if at least one checkbox is checked</h1>
<form>
<div>
<input type="checkbox" name="option-1" id="option-1" ng-click="check()"> <label for="option-1">Option 1</label>
</div>
<div>
<input type="checkbox" name="option-2" id="option-2" ng-click="check()"> <label for="option-2">Option 2</label>
</div>
<div>
<input type="checkbox" name="option-3" id="option-3"> <label for="option-3" ng-click="check()">Option 3</label>
</div>
<div>
<input type="checkbox" name="option-4" id="option-4"> <label for="option-4"ng-click="check()">Option 4</label>
</div>
<div>
<input type="checkbox" name="option-5" id="option-5"> <label for="option-5" ng-click="check()">Option 5</label>
</div>
<div>
<input type="button" ng-click="checkboxes" ng-disabled="enabled" value="Do thing" disabled>
</div>
</form>
JS
$scope.enabled=true
$scope.check=function(){
$scope.enabled=false
}
$scope.checkboxes=function() {
});
Finally it is done. I have done it using grep in jQuery.
$scope.userSelectionChanged = function () {
$scope.enableAddBtn = $.grep($scope.userlists, function (user) {
return user.IsSelected;
}).length >= 1;
};

AngularJS - Trigger when radio button is selected

I searched and tried many ng-xxxx kind of options but couldn't find the one..
I just want to call some function in the controller when radio button is selected.
So it might be similar to following..(Of course, below code is not working)
<input type="radio" ng-model="value" value="one" ng-click="checkStuff()"/>
Is there any way to achieve what I want?
There are at least 2 different methods of invoking functions on radio button selection:
1) Using ng-change directive:
<input type="radio" ng-model="value" value="foo" ng-change='newValue(value)'>
and then, in a controller:
$scope.newValue = function(value) {
console.log(value);
}
Here is the jsFiddle: http://jsfiddle.net/ZPcSe/5/
2) Watching the model for changes. This doesn't require anything special on the input level:
<input type="radio" ng-model="value" value="foo">
but in a controller one would have:
$scope.$watch('value', function(value) {
console.log(value);
});
And the jsFiddle: http://jsfiddle.net/vDTRp/2/
Knowing more about your the use case would help to propose an adequate solution.
Should use ngChange instead of ngClick if trigger source is not from click.
Is the below what you want ? what exactly doesn't work in your case ?
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.value = "none" ;
$scope.isChecked = false;
$scope.checkStuff = function () {
$scope.isChecked = !$scope.isChecked;
}
}
<div ng-controller="MyCtrl">
<input type="radio" ng-model="value" value="one" ng-change="checkStuff()" />
<span> {{value}} isCheck:{{isChecked}} </span>
</div>
In newer versions of angular (I'm using 1.3) you can basically set the model and the value and the double binding do all the work this example works like a charm:
angular.module('radioExample', []).controller('ExampleController', ['$scope', function($scope) {
$scope.color = {
name: 'blue'
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<html>
<body ng-app="radioExample">
<form name="myForm" ng-controller="ExampleController">
<input type="radio" ng-model="color.name" value="red"> Red <br/>
<input type="radio" ng-model="color.name" value="green"> Green <br/>
<input type="radio" ng-model="color.name" value="blue"> Blue <br/>
<tt>color = {{color.name}}</tt><br/>
</form>
</body>
</html>
For dynamic values!
<div class="col-md-4" ng-repeat="(k, v) in tiposAcesso">
<label class="control-label">
<input type="radio" name="tipoAcesso" ng-model="userLogin.tipoAcesso" value="{{k}}" ng-change="changeTipoAcesso(k)" />
<span ng-bind="v"></span>
</label>
</div>
in controller
$scope.changeTipoAcesso = function(value) {
console.log(value);
};
Another approach is using Object.defineProperty to set valueas a getter setter property in the controller scope, then each change on the value property will trigger a function specified in the setter:
The HTML file:
<input type="radio" ng-model="value" value="one"/>
<input type="radio" ng-model="value" value="two"/>
<input type="radio" ng-model="value" value="three"/>
The javascript file:
var _value = null;
Object.defineProperty($scope, 'value', {
get: function () {
return _value;
},
set: function (value) {
_value = value;
someFunction();
}
});
see this plunker for the implementation
i prefer to use ng-value with ng-if,
[ng-value] will handle trigger changes
<input type="radio" name="isStudent" ng-model="isStudent" ng-value="true" />
//to show and hide input by removing it from the DOM, that's make me secure from malicious data
<input type="text" ng-if="isStudent" name="textForStudent" ng-model="job">
<form name="myForm" ng-submit="submitForm()">
<label data-ng-repeat="i in [1,2,3]"><input type="radio" name="test" ng-model="$parent.radioValue" value="{{i}}"/>{{i}}</label>
<div>currently selected: {{radioValue}}</div>
<button type="submit">Submit</button>
</form>

Resources