Change checkbox state based on multiple conditions in AngularJS - javascript

In my scenario I have a select dropdown with an ng-model assigned to it. Each item in the dropdown corresponds to a number of checkboxes that are checked when a selection is made. The difficulty is that I can't just check for a simple key:value because checkboxes aren't exclusive to any particular selection. For example:
<select>
<option>Dog</option>
<option>Cat</option>
<option>Bird</option>
</select>
<input type="checkbox">Is an animal
<input type="checkbox">Can bark
<input type="checkbox">Can meow
<input type="checkbox">Can tweet
<input type="checkbox">Has four legs
<input type="checkbox">Has wings
So as you can, the checkboxes for "Is an animal" and "Has four legs" aren't exclusive. My current implementation uses a simple conditional expression to evaluate whether or not the checkbox is marked (ng-checked="animal=='dog'") but of course this excludes the other two possibilities. So I'm wondering if there's a native Angular way to handle OR statements or an array. Or if not, how can I go about this with JavaScript or jQuery?

See this fiddle: http://jsfiddle.net/QHza7/
Template:
<div ng-app ng-controller="Test">
<select ng-model="opts" ng-options="a.opts as a.name for a in answers"></select>
<br/>
<input type="checkbox" ng-model="opts.animal" />Is an animal<br/>
<input type="checkbox" ng-model="opts.bark" />Can bark<br/>
<input type="checkbox" ng-model="opts.meow" />Can meow<br/>
<input type="checkbox" ng-model="opts.tweet" />Can tweet<br/>
<input type="checkbox" ng-model="opts.legs4" />Has four legs<br/>
<input type="checkbox" ng-model="opts.wings" />Has wings<br/>
</div>
Code:
function Test($scope) {
$scope.answers = [
{name:"Dog", opts:{animal:true,bark:true,legs4:true}},
{name:"Cat", opts:{animal:true,meow:true,legs4:true}},
{name:"Bird", opts:{animal:true,tweet:true,wings:true}}
];
$scope.opts = null;
}

Related

select default for radio buttons inside a loop modelled with dynamic ngModel

I have a for loop containing inputs, each loop consists of five radio values whose name and model are dynamic.
I want to set value 1 as default, I can use the usual html "checked" or "checked = checked" but it works only without ngModel, if I'm using ngModel, I have to initialize it in the component class but since, it's dynamic there's no way I can initialize it first.
Is there any alternative or am I missing anything??
<div class="scorecard-attribute" *ngFor="let attribute of opportunity.scorecard.scorecard_attributes">
<input type="radio" name="{{attribute.name}}" [value]=1 [(ngModel)]="newRating[attribute.id]" checked>
<input type="radio" name="{{attribute.name}}" [value]=2 [(ngModel)]="newRating[attribute.id]">
<input type="radio" name="{{attribute.name}}" [value]=3 [(ngModel)]="newRating[attribute.id]">
<input type="radio" name="{{attribute.name}}" [value]=4 [(ngModel)]="newRating[attribute.id]">
<input type="radio" name="{{attribute.name}}" [value]=5 [(ngModel)]="newRating[attribute.id]">
You can try this code in your HTML file,
<div class="scorecard-attribute" *ngFor="let attribute of opportunity.scorecard.scorecard_attributes">
<input type="radio" [value]="attribute" [(ngModel)]="newRating" (click)="click(attribute)">{{attribute.name}}
</div>
Add this code in component file,
newRating:any=opportunity.scorecard.scorecard_attributes[0];
click(obj){
console.log(obj);
}
Thanks,

Radio Buttons with different ng-models

Hi I have three radio input fields with same name but different ng-models:
<label>
<input type="radio"name="deliveryAddress"
ng-model="CC.OrderDetailsModel.IsNewDeliveryAddress">
Save address to profile for use on future orders
</label>
<label>
<input type="radio"name="deliveryAddress"
ng-model="CC.OrderDetailsModel.ExistingDeliveryAddressUpdate">
Update Existing Delivery Address
</label>
<label>
<input type="radio"name="deliveryAddress"
ng-model="CC.OrderDetailsModel.UseForThisOrderOnly">
Use address only for this order
</label>
I want to make when input is check that has value true otherwise false
Of this three ng-model only one can have true value. Something like this:
CC.OrderDetailsModel.IsNewDeliveryAddress: false,
CC.OrderDetailsModel.ExistingDeliveryAddressUpdate: false,
CC.OrderDetailsModel.UseForThisOrderOnly: true
As you explained in comments if you want to keep your logic, you can add a ng-change event on your inputs to set values:
<label>
<input type="radio" name="deliveryAddress"
ng-model="CC.OrderDetailsModel.IsNewDeliveryAddress"
ng-change="change(CC.OrderDetailsModel.IsNewDeliveryAddress)">
Save address to profile for use on future orders
</label>
<label>
<input type="radio" name="deliveryAddress"
ng-model="CC.OrderDetailsModel.ExistingDeliveryAddressUpdate"
ng-change="change(CC.OrderDetailsModel.ExistingDeliveryAddressUpdate)">
Update Existing Delivery Address
</label>
<label>
<input type="radio" name="deliveryAddress"
ng-model="CC.OrderDetailsModel.UseForThisOrderOnly"
ng-change="change(CC.OrderDetailsModel.UseForThisOrderOnly)">
Use address only for this order
</label>
The change() function will set variables to false and then the selected one to true:
$scope.change = function(changed) {
CC.OrderDetailsModel.IsNewDeliveryAddress = false;
CC.OrderDetailsModel.ExistingDeliveryAddressUpdate = false;
CC.OrderDetailsModel.UseForThisOrderOnly = false;
changed = true;
}
I would suggest to use only one variable for all your radio button, as adviced by Angular for input[radio]:
<input type="radio" name="deliveryAddress" ng-model="deliveryAddress" value="newDeliveryAddress"/>
<input type="radio" name="deliveryAddress" ng-model="deliveryAddress" value="existingDeliveryAddressUpdate"/>
<input type="radio" name="deliveryAddress" ng-model="deliveryAddress" value="useForThisOrderOnly"/>
Here is just change the value set in ng-model. You can then do your treatment based on this value.
Try it on Plunker

Javascript checkbox validation: how to alert if user didn't check a particular checkbox?

So what I am doing is something like a simple medication reminder, so the system display a list of medications the user should be taking, and the user then tick the checkbox of the medicine they have taken, but what I want to do is if for example, the user only ticked Medicine One and Two, then I want an alert saying "Why you didn't take Medicine Three?" and a drop down box appears with a list of possible reasons of which the user can choose from. And if the user only took Medicine Three, the system will display alert saying "Why didn't you taken Medicine One and Two?", and drop down box appears with a list of possible reasons. And if user has ticked all three checkbox, then display an alert saying "That great! Well Done!"
<form>
<input type="checkbox" name="a" value="one">Medicine One<br>
<input type="checkbox" name="b" value="two">Medicine Two<br>
<input type="checkbox" name="c" value="three">Medicine Three<br>
<input id=xbutton type="button" onClick="validate()" value="Submit">
</form>
I know how to do validation for one checkbox (like a terms agreement checkbox), but I'm a bit confused as to how to incorporate so many validation rules into one function.
Use querySelectorAll to iterate all the checkbox elements and check the .checked property.
Returns a list of the elements within the document (using depth-first pre-order traversal of the document's nodes) that match the specified group of selectors. The object returned is a NodeList.
input[type="checkbox"]:not(:checked) will select only those elements which are not checked.
function validate() {
var msg = [];
[].forEach.call(document.querySelectorAll('input[type="checkbox"]:not(:checked)'), function(elem, index) {
msg.push(elem.name);
});
alert(msg.length ? 'Please check ' + msg.join(' and ') : 'All are checked!');
}
<form>
<input type="checkbox" name="a" value="one">Medicine One
<br>
<input type="checkbox" name="b" value="two">Medicine Two
<br>
<input type="checkbox" name="c" value="three">Medicine Three
<br>
<input id=xbutton type="button" onClick="validate()" value="Submit">
</form>
Fiddle here
Using jquery can help you to make things easy.
Here is the fiddle: https://jsfiddle.net/swaprks/zs7tpuo0/
HTML:
<form>
<input type="checkbox" name="a" value="one">Medicine One<br>
<input type="checkbox" name="b" value="two">Medicine Two<br>
<input type="checkbox" name="c" value="three">Medicine Three<br>
<input id=xbutton type="button" value="Submit">
</form>
JAVASCRIPT:
$("#xbutton").click(function(){
validate();
});
function validate(){
if ( $('input[type="checkbox"]:not(:checked)').length == 3 ) {
alert("Select atleast one option.");
}
}

Validating if atleast one checkbox is checked or one input field is filled

I need better validation logic, where some Checkboxes and some input fields are grouped together.
The user either have to check at least one checkbox or have to fill at least one input box.
If a checkbox is checked or an input field is filled then the complete group is validated.
What will be the best possible way to validate such a situation?
e.g
<input class="checkbox" type="checkbox" name="check-deal" value="1" grouped="deal" >
<input class="checkbox" type="checkbox" name="check-deal" value="2" grouped="deal">
<input class="checkbox" type="checkbox" name="check-deal" value="3" grouped="deal">
<input class="checkbox" type="checkbox" name="check-deal" value="4" grouped="deal">
<input class="input-group" type="text" name="deal-name1" value="" grouped="deal">
<input class="input-group" type="text" name="deal-name2" value="" grouped="deal">
I have defined an extra attribute grouped for all input and checkboxes that should be grouped togather
but getting no idea how to validate the group as best practice.
DEMO
Point No.1 : There isn't any attribute called grouped for html as of my knowledge but I would suggest you to use data-* prefixed attribute names like data-grouped or data-anyname which is valid
Point No.2 : I rather categorized your checkboxes and textboxes into separate divs and below is how it is:
<div class="chkbox">
<input class="checkbox" type="checkbox" name="check-deal" value="1" />
<input class="checkbox" type="checkbox" name="check-deal" value="2" />
<input class="checkbox" type="checkbox" name="check-deal" value="3" />
<input class="checkbox" type="checkbox" name="check-deal" value="4" />
</div>
<div class="txtbxs">
<input class="input-group" type="text" name="deal-name1" value="" />
<input class="input-group" type="text" name="deal-name2" value="" />
</div>
<button class="btnValidate">Validate</button>
Point No.3 : Below is how you can validate using jquery
$('.btnValidate').on('click',function(){
var chkLength=$('.chkbox .checkbox:checked').length; //get checkbox checked length
var filledText=$(".txtbxs .input-group").val()!="";
//get bool value whether any of the text box is filled or not
if(chkLength || filledText) //check with or condition
alert('valid')
else
alert('invalid');
});
UPDATE
DEMO
As #AkshatG pointed in his answer the discrepancy was there in my answer so I've edited it and here is the updated solution.
$('.btnValidate').on('click',function(){
var chkLength=$('.chkbox .checkbox:checked').length;
var filledText=false; //First set it to false
$.each($(".txtbxs .input-group"),function(index,value){
if($(value).val()!="")
{
filledText=true//if it finds any value then set it to true
return;//break from $.each
}
})
if(chkLength || filledText)
alert('valid')
else
alert('invalid');
});
You first need to take count of each validations. And then check if any of the two has count greater than 0 or not. Guruprasad's answer won't work if you enter text on second textbox because it won't filter all the textboxes. You have to use filter function for this :
$("input[type='text'],textarea").filter(function() {
return $(this).val() != "";
}).length;
Here's a jsfiddle :
http://jsfiddle.net/myfLgpdv/
Hope this helps.

How to set up groups of checkboxes which affect each other

Sorry for the ambiguous title, but it's quite hard to condense what I'm trying to do into a few words. Here's exactly what I'm trying to do:
I want to have a series of groups of checkboxes. One would be gender, with checkboxes for Male and Female, one would be Region, with checkboxes for North, East, South and West and so on.
The aim is to allow the user to select say, Male or Female, but as soon as they put a check in a checkbox of another group e.g. any of the Region checkboxes, all of their previous 'checks' from all other groups are removed.
The point is to only allow the user to select from one group of checkboxes at a time.
I can only think of checking which checkboxes have been marked on click using javascript, but was wondering if there was a simpler way which I may be missing.
I've also thought that maybe a hidden radio button for each group could work.
If anyone has a more elegant solution I'm eager to hear it.
Its been a long time since I've done any pure Javascript, libraries like jQuery make this kind of thing so easy. Anyway, something a bit like the following might work, you'd need to test it in a few browsers and tweak to what you need.
<form name="theForm">
<input type="checkbox" id="male" name="theGroup" onClick="clearGroup(this);">male
<input type="checkbox" id="female" name="theGroup" onClick="clearGroup(this);">female
<br />
<input type="checkbox" id="north" name="theGroup" onClick="clearGroup(this);">north
<input type="checkbox" id="south" name="theGroup" onClick="clearGroup(this);">south
<input type="checkbox" id="east" name="theGroup" onClick="clearGroup(this);">east
<input type="checkbox" id="west" name="theGroup" onClick="clearGroup(this);">west
</form>
<script>
function clearGroup(elem) {
var group = document.theForm.theGroup;
for (var i=0; i<group.length; i++) {
if (group[i] != elem) {
group[i].checked = false;
}
}
}
</script>
Here is a working example to play around with.
You could do the equivalent thing in jQuery as simply as
$('input:checkbox').click(function() {
$(this).siblings(':checked').attr('checked', false);
});
and you have no browser compatibility issues to worry about.
Managed to figure it out with a little help from fearofawhack planet. Seems really simple now.
Heres a link to the JSFiddle http://jsfiddle.net/aeeN4/
if you have different groups you can use this code below.
<script>
function clearGroup(elem) {
//alert(elem.name);
var group = document.getElementsByName(elem.name);
for (var i=0; i<group.length; i++) {
if (group[i] != elem) {
group[i].checked = false;
}
}
}
</script>
<form name="theForm">
<input type="checkbox" id="male" name="theGroup2" onClick="clearGroup(this);">male
<input type="checkbox" id="female" name="theGroup2" onClick="clearGroup(this);">female
<br />
<input type="checkbox" id="north" name="theGroup" onClick="clearGroup(this);">north
<input type="checkbox" id="south" name="theGroup" onClick="clearGroup(this);">south
<input type="checkbox" id="east" name="theGroup" onClick="clearGroup(this);">east
<input type="checkbox" id="west" name="theGroup" onClick="clearGroup(this);">west
</form>

Categories

Resources