jQuery validate, radio button group, nesting issue - javascript

I am trying to add a custom method to validate a group of radio buttons, using v1.9 of the jQuery validate plugin.
Contrary to this post, it is possible to have the same name attribute for radio button inputs, as long as any class rules are only applied to one of the inputs. jQuery validate then treats your input group as a single input.
This works when your inputs are children of a common parent, ie
<input type="radio" name="radiogroup" value="1" class="input-shipping" checked="checked">
<input type="radio" name="radiogroup" value="2">
<input type="radio" name="radiogroup" value="3">
<input type="radio" name="radiogroup" value="4">
But as soon as the html structure changes, the validation rules are not applied:
<div class="form-row">
<input type="radio" name="radiogroup" value="1" class="input-shipping" checked="checked">
</div>
<div class="form-row">
<input type="radio" name="radiogroup" value="2">
</div>
<div class="form-row">
<input type="radio" name="radiogroup" value="3">
</div>
<div class="form-row">
<input type="radio" name="radiogroup" value="4">
</div>
Is anyone aware of a workaround for this issue? Class rules are added as follows:
$.validator.addClassRules({
"input-shipping" : {
required: true,
dateselected: true
}
});
$.validator.addMethod("dateselected", function(value, element) {
console.log(element);
});

The reason the validation rule was not being called was that custom radio buttons were used, which set the CSS display value of inputs to none, and pseudo elements were styled up in place of the original inputs.
Once this was changed to visibility:hidden; the validator seemed to pick up the rule OK.
To create a custom method based on the value of the selected input, a further level of filtering was needed:
$.validator.addMethod("dateselected", function(value, element) {
var radios = $('input[name='+element.name+']'),
val = radios.filter(':checked')[0].value;
console.log(val);
});

Related

check one radio button with dynamic values

<input type="radio" on-click="checkDefaultLanguage" id="checkbox" >
[[names(name)]]
this is my custom input field for radio and has dynamic values in it. I am trying to select one radio at a time and deselect from the others. but I cannot find any information for this. The one I have found are either with name attribute or having static input fields.
my JS
private checkDefaultLanguage() {
const checkboxes = <HTMLInputElement>this.querySelector('#checkbox');
checkboxes.addEventListener('click', () => {
if (checkboxes.checked) {
//what is should I do inside of it to make sure only one is selected at a time.
}
});
}
Just use name on the input, all input will get assigned to 1 group
<form>
<fieldset>
<legend>Select a maintenance drone</legend>
<div>
<input type="radio" id="huey" name="drone" checked />
<label for="huey">Huey</label>
</div>
<div>
<input type="radio" id="dewey" name="drone" />
<label for="dewey">Dewey</label>
</div>
<div>
<input type="radio" id="louie" name="drone" />
<label for="louie">Louie</label>
</div>
</fieldset>
</form>
tbh i dont fully understand what you are trying to do but you could pass the button you just clicked to the function
<input type="radio" on-click="checkDefaultLanguage(this)" id="checkbox" >
In your function you could just uncheck every box no matter if it's checked or not.
After this for-loop just check the one you passed to the function.

Right way to use Radiobuttons

I'm confused about which is the right way to use radiobuttons. Let's say i have a group of 3 radiobuttons : if all of them have the same id / name, it will work properly , only one can be checked :
<label for="input-rb1" ></label><input class="radio-input" type="radio" id="input-rb1" name="input-rb1"><label for="input-rb1" class="radio-label">First radiobutton</label>
<label for="input-rb1" ></label><input class="radio-input" type="radio" id="input-rb1" name="input-rb1"><label for="input-rb1" class="radio-label">Second radiobutton</label>
<label for="input-rb1" ></label><input class="radio-input" type="radio" id="input-rb1" name="input-rb1"><label for="input-rb1" class="radio-label">Third radiobutton</label>
The problem about this approach is i don't know how to identify which one is checked, because all of them have the same name / id.
The other way would use different names / ids :
<label for="input-rb1" ></label><input class="radio-input" type="radio" id="input-rb1" name="input-rb1"><label for="input-rb1" class="radio-label">First radiobutton</label>
<label for="input-rb2" ></label><input class="radio-input" type="radio" id="input-rb1" name="input-rb2"><label for="input-rb2" class="radio-label">Second radiobutton</label>
<label for="input-rb3" ></label><input class="radio-input" type="radio" id="input-rb1" name="input-rb3"><label for="input-rb3" class="radio-label">Third radiobutton</label>
This way i know how to use JQuery to know which is checked, but it will allow the user to select multiple radios, like it was checkboxes...
How to solve this puzzle ?
Thanks !
An id is a keyword that can be used to find a specific element on a page.
<input type="radio" id="radio1">one
<input type="radio" id="radio2">two
<input type="radio" id="radio1">one
<input type="radio" id="radio2">two
You'll notice the above snippet allows you to select both radio buttons. There's nothing joining them together and the Browser can't assume they're connected.
A name is used to determine a value from an input field - or in the case of radio buttons - a single value from multiple input fields. It joins the radio buttons together to say "Hey, only allow one of you to be checked! That's the value we're going with!"
<input type="radio" name="radio_group">one
<input type="radio" name="radio_group">two
<input type="radio" name="radio_group">one
<input type="radio" name="radio_group">two
Notice that there are no ids in the above code. id and name are not interchangeable. They are completely separate attributes aimed to do two completely different things.
The other answers use JQuery and that's all well and good, but I think it's important to give a vanilla JS example as well.
document.querySelectorAll("input[name='r_group']").forEach((radio) => {
if (radio.checked) {
//do whatever
}
});
document.querySelectorAll("input[name='r_group']").forEach((radio) => {
radio.addEventListener("change", () => {
if (radio.checked) alert(radio.value);
});
});
<input id="radio1" type="radio" name="r_group" value="one">one
<input id="radio2" type="radio" name="r_group" value="two">two
<input id="radio3" type="radio" name="r_group" value="three">three
Only name of radio buttons should be same, id is an unique attribute in elements. You should use different ids and also you can use value attribute to assign values. Code is given below
<form action="">
<input type="radio" id="1" name="gender" value="male"> Male<br>
<input type="radio" id="2" name="gender" value="female"> Female<br>
</form>
You can use jQuery to get selected radio button value as follow
$("input[type='radio']").on('change', function () {
var selectedValue = $("input[name='gender']:checked").val();
if (selectedValue) {
alert(selectedValue);
}
});
First, the values for "id" should be unique to each element. The name attribute can (and should) be the same for all elements in the group.
Then, to get the value of the checked radio use:
$('input[name=name_of_your_radiobutton]:checked').val();
The second approach is wrong, name in radio buttons is used to group them in same class, only one of them can be selected.
Just use the following script-
$('input[name="input-rb1"]:checked').val();
Avoid using hyphen - in javascript instead use _ if possible

Make check-boxes becoming one group of radio button

I cannot make the input name same or value same. The second and third inputs come from a loop using c# razor. I have 2 sets of radio inputs first one is one set and second and third are another set. Because the second and third have the same name, checking one makes the other unchecked. I want the same for all of them together so it would be like I have one set of 3 radio buttons. Like I said above I am not able to make the name or value same due to back-end data display issue. Here is my attempt below.
//first radio <br/>
<div class="radio">
<label>
<input id="dcenter-allradio" type="radio" value="0" />All
</label>
</div>
//this radio button is a loop <br>
<input type="radio" name="#Model.Facet.Key" value="#item.Key">tagitem.j
<div class="radio">
<label>
<input id="dcenter-listradio" type="radio" name="#Model.Facet.Key" value="#item.Key" />tagItem.Name
</label>
</div>
<script>
$(document).ready(function () {
if ($('#dcenter-listradio').prop("checked", true)) {
$('#dcenter-allradio').prop("checked", false);
}
if ($('#dcenter-allradio').prop("checked", true)) {
$('#dcenter-listradio').prop("checked", false);
}
});
</script>
If you can give them all the same class, then you can just use jQuery to detect when a change has occurred and then uncheck other items in the same class.
$(document).ready(function() {
var selector = ".groupTogether";
// or if you can't give same class, you could use "#unrelatedRadio, input[name='related']"
$(selector).change(function()
{
if(this.checked)
{
$(selector).not(this).prop('checked', false);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="unrelatedRadio" name="unrelated" type="radio" class="groupTogether">unrelated</input>
<input id="relatedA" name="related" type="radio" class="groupTogether">Related A</input>
<input id="relatedB" name="related" type="radio" class="groupTogether">Related B</input>
Or, if you can't give them the same class, just replace the selector with something that selects both sets (in my example, "#unrelatedRadio, input[name='related']")
let radios = document.querySelectorAll("input");
for (let i of radios){
i.name="same"
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
//first radio <br/>
<div class="radio">
<label>
<input id="dcenter-allradio" type="radio" value="0" />All
</label>
</div>
//this radio button is a loop <br>
<input type="radio" name="#Model.Facet.Key" value="#item.Key">tagitem.j
<div class="radio">
<label>
<input id="dcenter-listradio" type="radio" name="#Model.Facet.Key" value="#item.Key" />tagItem.Name
</label>
</div>

How to set a default radio button with a value?

General issue: I cannot set a default radio button in my radio groups unless I remove the value attribute from the inputs.
Specifics: Each input has a value that is needed as it is being used by angular in other places in the app. So, I need to know how to set an input to default checked while retaining the values on the inputs. It has the same behavior if I try to add checked with jQuery instead of in HTML.
I have looked at several related questions including here. The specific issue is I need to have values and be able to set one input to checked as a default. The first input is set to checked, but it does not actually work unless I remove the value from that input.
Here is the HTML:
<div class="radio">
<label>
<input type="radio" ng-model="optionsRadios" id="new" value="new" checked>
New
</label>
<label>
<input type="radio" ng-model="optionsRadios" id="used" value="used">
Used
</label>
<label >
<input type="radio" ng-model="optionsRadios" id="broken" value="broken">
Broken
</label>
</div>
You have to use ng-checked="true" instead of checked
<input type="radio" ng-model="optionsRadios" id="new" value="new" ng-checked="true">
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="">
<p>My cars:</p>
<input type="radio" ng-model="all" value="Volvo" ng-checked="true">Volvo<br>
<input type="radio" ng-model="all" value="Ford">Ford<br>
<input type="radio" ng-model="all" value="Mercedes">Mercedes
</body>
</html>
If you have a group of radio button and you want to set radio button checked based on model, then radio button which has same
value and ng-model is checked automatically.
<input type="radio"
ng-model="optionsRadio" value="1" >
<input type="radio"
ng-model="optionsRadio" value="2" >
<input type="radio"
ng-model="optionsRadio" value="3" >
If the value of optionsRadio is "2" then second radio button will be selected automatically.
In Your Case:
When u r initiating the controller all u have to do is to assign a value to your model to keep atleast one radio button selected.
Controller part:
$scope.optionsRadio = "new";
Form part:
<input type="radio" ng-model="optionsRadio" value="new" >
<input type="radio" ng-model="optionsRadio" value="used" >
<input type="radio" ng-model="optionsRadio" value="broken" >
First radio button will be selected automatically.
Note:
If value doesn't work u can use ng-value.

Javascript: get radiobutton label with a specific "for" in label

I have a form element like this:
<div id="myformelement">
<input type="radio" id="option1">
<label for="option2">Option 1</label>
<input type="radio" id="option2">
<label for="option2">Option 2</label>
<input type="radio" id="option3">
<label for="option3">Option 3</label>
<input type="radio" id="option4">
<label for="option4">Option 4</label>
</div>
I want to hide the input fields "option2" and "option3" and their labels.
I can hide the input bullets by addressing the id. Unfortunately the corresponding labels to the input fields only have a "for" tag with the id in it.
How can I do this with javascript (no jquery).
I found this question (Find html label associated with a given input), but this seems only to work with one label within an ID, I can not use this.
Thanks in advance!
Kind regards,
Malte
In pure JavaScript you can use querySelector:
document.querySelector("label[for='option2']").style.display = "none";
You can do it with nextSibling:
var rdo = document.getElementById("option2");
var lbl;
rdo.style.display = "none";
for (lbl = rdo.nextSibling; lbl && lbl.nodeName.toUpperCase() !== "LABEL"; lbl = lbl.nextSibling) {
}
if (lbl) {
lbl.style.display = "none";
}
But I have a better option for you: It seems to be a well-kept secret that label elements can contain the input they relate to, and when they do no for is required at all. So if you change your HTML to:
<div id="myformelement">
<label><input type="radio" id="option1"> Option 1</label>
<label><input type="radio" id="option2"> Option 2</label>
<label><input type="radio" id="option3"> Option 3</label>
<label><input type="radio" id="option4"> Option 4</label>
</div>
...it gets a lot easier:
document.getElementById("option2").parentNode.style.display = "none";
You just find the input, traverse up to its parent which is the label, and hide that (which will hide the input as well).

Categories