Domanda

I'm writing some code that highlights all <input type=radio /> within a "radio group" when any one of them is changed.
In the event handler for the radio "change" event, I use the following code to find all other similar radios:

radioHandler: function (event) {
    var element = $(this);
    var name = element.attr("name");
    // Find all radios in the same group:
    element.closest("form")
        .find("input[type=radio][name='" + name + "']")
        .each(function(){
            ... etc ...
        });
},

This works perfectly if the radios are indeed contained within a form.
However, I also want it to work if there are radios outside the form too.

For example, assuming all radios use the same name, the following represents 3 different radio groups (and all browsers behave this way):

       o Radio A | o Radio B | o Radio C          (Group - no form)
<form> o Radio D | o Radio E | o Radio F </form>  (Group - form 1)
<form> o Radio G | o Radio H | o Radio I </form>  (Group - form 2)

If I have an element, what's the best way to find ONLY the radios that are part of its "group"?

Also, for bonus points ... what if the element isn't part of the current document -- ie, it is contained within another "detached" context? The current solution works fine (because element.closest(...) uses the element's context).

È stato utile?

Soluzione

Instead of executing the .find on your form, execute it on your entire document:

$("input[type=radio][name='" + name + "']").each(function() {
    ... etc ...
});

Unless I'm not understanding the question here?

EDIT I didn't test the code below but it might give you the idea on how to do it.

radioHandler: function (event) {
    var element = $(this);
    var name = element.attr("name");
    // Find all radios in the same group:
    if (element.parents().find("form").length > 0) {
        name.closest("form").find("input[type=radio][name='" + name + "']")
        .each(function(){
            ... etc ...
        });
    } else {
        $("input[type=radio][name='" + name + "']").each(function() {
            if (!$(this).parents().find("form").length) {
                ... etc ...
            }
        }
    }
}

Altri suggerimenti

Think outside the box. Add a non-standard attribute to the <input type="radio" /> tags that are outside the <form>. For example:

<input type="radio" outsideform="true" />

Then use a JQuery selector like this:

$('input[type=radio][outsideform=true]')

You could also do something similar with a CSS class. The class doesn't have to actually implement any styles.

<input type="radio" class="outsideform" />

...with...

$('input[type=radio].outsideform')

If you look at the jquery-ui.js file (my version 1.11.4) you can see that internally they use this function to get all radio buttons that are in the same group:

radioGroup = function( radio ) {
 var name = radio.name,
  form = radio.form,
  radios = $( [] );
 if ( name ) {
  name = name.replace( /'/g, "\\'" );
  if ( form ) {
   radios = $( form ).find( "[name='" + name + "'][type=radio]" );
  } else {
   radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
    .filter(function() {
     return !this.form;
    });
  }
 }
 return radios;
};

They use it inside their widget( "ui.button" ) click event handler when the button type is "radio", so that they can remove the "ui-state-active" class from all the other buttons.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top