How can I create mutually exclusive radio buttons with different names? - javascript

I have a few radio buttons that belong to the same category, but I want to name them differently and make them mutually exclusive. How do I do that? Based on the selected value, I do different actions, and I can't access them if they have the same name.

Why can't you access them if they have the same name? You can add IDs (you should), you can distinguish by value or just count them and use the n-th element.
You should give radiobuttons the same name to make the browser understand they are exclusive.
You could (but should not) hack around this, and give each object a different name. Then add an onSelect/onClick handler for each object, and when the event fires, "uncheck" the other buttons. This is dirty and should be avoided.

Radio buttons require the same name to be mutually exclusive. However, they can have different ID attribute values, if you want to manipulate them individually with JavaScript.
There are lots of ways to get the selected value with jQuery:
<input type="radio" name="foo" value="1" />
<input type="radio" name="foo" value="2" />
// value of checked input tag of type 'radio'
var selectedValue = $('input[type=radio]:checked').val();
// value of checked input tag having name of 'foo'
var selectedValue = $('input[name=foo]:checked').val();
// value of the first checked radio button, regardless of name
var selectedValue = $('input:checked').val();

If you have to change the name, you can access the DOM and it's elements through JavaScript.
<input type="checkbox" name="X" id="myElement" />
<script> document.getElementById('myElement').name = 'text'; </script>
http://www.w3schools.com/JS/js_ex_dom.asp

Related

One item select not working on radio buttons in AngularJS

I'm using AngularJS and filter option. When I select an item in radio buttons, its getting right data.
<input ng-click="filter = !filter" ng-value="!filter" ng-checked="filter" type="radio" ng-model="ctrl.filter[category]" />
But I need allow one select in radio buttons and its not working. What's the problem? Thanks.
DEMO
To properly work, radio inputs need a name attribute. It should be the same for all radio of the groupe.
You also need to change the ng-model of the radio to store its value in a single property.
<input ng-click="filter = !filter" ng-value="category" name="wineCategory" ng-checked="filter" type="radio" ng-model="ctrl.filter" />
Finally you need to adapt your filter methods.
All the inputs in the Radio box group must have only one reference to an ng-model which is typically the value of the input.
So, your input markup would be
<input value="{{category}}" type="radio" ng-model="ctrl.filterCategory" />
Where the value = category would be red, while or champagne.
Now likewise your filter function would change to use the ng-model like this
function filterByCategory(wine) {
return (self.filterCategory === wine.category || self.filterCategory === "") ? 'show':'hide';
}
Working demo here.
http://jsfiddle.net/nah42h1c/2/

Is there any way to make IDs unique to any element on the page, not to the document

I tried to google, but failed.
I want the element with an ID to be unique relatively to, for example, his parent, not to the document itself. Is there a way to do that?
Ok, since you need an example. I have a huge form, with tons of radio buttons and inputs, e.g.: 2 radio buttons with IDs. Each with label.
<input type="radio" id="foo" name="name">
<label for="foo">Never</label>
<input type="radio" id="bar" name="name">
<label for="bar">Daily</label>
I can not afford to change this setup.
And I have a button that clones (via .clone()) this form.
As you may guess, it all breaks, because IDs and labels are not unique.
Radio inputs can be placed inside labels. With this setup, you don't need an id for the radio to match the for of the label, and the label will work as expected (clicking it activates the radio input). This removes the need for you to create a unique for-id pair.
<label>
Here's teh label
<input type="radio" name="foo">
</label>
<label>
Here's another label
<input type="radio" name="foo">
</label>
The following is just a suggestion of an algorithm with some working code, there is logic missing from the question regarding how to determine where to insert the cloned element. I've modified the name of the controls since giving a control a name of name masks the form's own name property.
The id is generated based on the number of controls in the form with the same name. Perhaps you have some other algorithm.
function cloneRadio(control) {
// Create a document fragment for convenience
var frag = document.createDocumentFragment();
// Clone the control and add to fragment
var el = frag.appendChild(control.cloneNode());
// Get all the controls in the form with the same name
var controls = control.form[control.name];
// Give the new control an id of name + control count
el.id = control.name + controls.length;
// Add a label
var label = frag.appendChild(document.createElement('label'));
// Add text in label
label.appendChild(document.createTextNode('for ' + el.id));
// Link label to element
label.htmlFor = el.id;
// Add to end of form
control.form.appendChild(frag);
}
This assumes that you aren't removing any elements, that will mess with the numbering if you do. I've just put the cloned element at the end of the form, you'll need some way of working out where to put it but haven't mentioned it here.
Some related HTML:
<form>
<input type="button" value="clone foo"
onclick="cloneRadio(this.form.controlName[0]);">
<br>
<input type="radio" id="foo" name="controlName">
<label for="foo">Never</label>
<br>
<input type="radio" id="bar" name="controlName">
<label for="bar">Daily</label>
</form>
Edit: the OP totally changed his question after my answer. Please look at the edit history before assuming I was off topic
If you are tempted to use the same ID for multiple items, you need to use a class. You can target classes within specific parent nodes. For example, in jQuery:
var elem = $('.parentClass .childClass');
This would target only items of .childClass that are children of .parentClass. You could select other instances of .childClass with different parent elements by changing the parent element in the CSS selector.
var eleme = $('.otherParentClass .childClass');

Knockout Js Radio Bindings not setting Value

Here is the documentation I'm looking at : Example Adding Radio Buttons
It says:
KO will set the element to be checked if and only if the parameter value equals the radio button node’s value attribute
Which I have done in this: jsfiddle
self.radioValue = ko.observable(1);
and the HTML:
<input type="radio" name="teloremail" value="1" data-bind="checked: radioValue" />
For me, this doesn't automatically set the radio to checked
Any reason for this?
The type of the radio button node’s value attribute is string, so you need to store the value as string also in your observable:
self.radioValue = ko.observable("1");
Demo JSFiddle.
The example also uses a string: "almond".

Checkbox irregularities with jQuery

Here's some html:
<form>
<input type="checkbox" id="check-123" />
<input type="text" id="text-123" onchange="doSomething('123')" />
</form>
And here's some javascript:
function doSomething(key)
{
var textbox = $('#text-'+key);
var checkbox = $('#check-'+key);
checkbox.attr('checked',(textbox.val()!="") );
}
My goal here is to check the checkbox anytime there's a value in the text box, and uncheck when that value is removed. This appears to work fine in the html (I can see checked="checked" being added to the checkbox), but the checkbox only appears checked the first time something is entered in the textbox.
Why would a checkbox show unchecked even if checked="checked" was added to the html?
Use element properties rather than attributes to change their state via javascript
checkbox.prop('checked',(textbox.val()!="") );
From the jQuery docs on .attr() and .prop():
As of jQuery 1.6, the .attr() method returns undefined for attributes that have not been set. To retrieve and change DOM properties such as the checked, selected, or disabled state of form elements, use the .prop() method.
The emphasis is jQuery's own. Only the checked property will reflect and control the checkbox's current state. The checked attribute shouldn't be used to control the checkbox state.
consider something like:
function doSomething(el) {
el.form['check-' + el.name.split('-')[1]].checked = !!el.value;
}
<form>
<input type="checkbox" name="check-123">
<input type="text" name="text-123" onchange="doSomething(this)">
</form>
I've seen some funny things with the checked attribute in IE8 and lower. In some cases I've had to set both the property and the attribute, even though modern browsers seem to be okay with just adjusting the property:
checkbox.prop('checked',textbox.val()!="");//property
Note, the following is only necessary if you come across any browser related inconsistencies.
if(textbox.val()!="")
{
checkbox.attr('checked','checked');
}
else
{
checkbox.removeAttr('checked');
}

Angularjs radio buttons

I know that this has been spoken about in some Google Threads but I still can't find the right solution to bind my radio inputs to a model (in clean'n simple manner),
Currently I have HTML:
<input ng-model="searchByRma" type="radio" name="search-type">
<input ng-model="searchByDelivery" type="radio" name="search-type">
And in Controller:
$scope.searchByRma = true;
$scope.searchByDelivery = false;
This does not work (as it would with the checkboxes)...
Any ideas on how to set the default value on the first radio button without loosing data-binding?
Thanks!
I think you should use same variable with different values in those
two radio buttons.
<input ng-model="searchBy" value="Rma" type="radio" name="search-type">
<input ng-model="searchBy" value="Delivery" type="radio" name="search-type">
Then, you should have searchBy set either "Rma" or "Delivery" depending on
user input.
What has worked for me is to set the model variable to { } and that will reset the radio buttons to their default (not selected) state. Of course, this will only work if you have your radio button tags correct as in tosh's answer.
In your case:
$scope.searchBy = { };

Categories