views:

285

answers:

5

Hi all - I'm new to jquery and trying to accomplish something. My HTML looks like:

<li>
  <div class="yes"><input type="radio" name="Group 1"></div>
  <div class="no"><input type="radio" name="Group 1"></div>
  Group 1  
  <ul>
    <li style="padding-left:25px">
      <div class="yes"><input type="radio" name="Item 1"></div>
      <div class="no"><input type="radio" name="Item 1"></div>
      Item 1
    </li>
    <li style="padding-left:25px">
      <div class="yes"><input type="radio" name="Item 2"></div>
      <div class="no"><input type="radio" name="Item 2"></div>
      Item 2
    </li>
  </ul>
</li>
<li>
  <div class="yes"><input type="radio" name="Group 2"></div>
  <div class="no"><input type="radio" name="Group 2"></div>
  Group 2  
  <ul>
    <li style="padding-left:25px">
      <div class="yes"><input type="radio" name="Item 3"></div>
      <div class="no"><input type="radio" name="Item 3"></div>
      Item 3
    </li>
    <li style="padding-left:25px">
      <div class="yes"><input type="radio" name="Item 4"></div>
      <div class="no"><input type="radio" name="Item 4"></div>
      Item 4
    </li>
  </ul>
</li>

It took a while to get the html right (I need the divs around the radio buttons for appearances), and now I'm moving on to the JQuery processing. Primarily, I need to propagate changes to Group 1 to all of its "child" items. I'm not really sure how to accomplish that using jquery (we use 1.1.3.1).

Any tips?

UPDATE: I edited the HTML as suggested, cordoning off the groups.

A: 

Hi,

$("div") => Selects all div elements
$(".yes") => Selects all elements which have class name "yes"
$("#elementId") => Selects element which Id value is "elementId"

$("div .yes") =>Selects elements under div element (all the descendants) and have class name "yes"

$("div > .yes") =>Selects elements right under div elements. Not all descendants, just direct children

Hope it helps.

For example $("li div[class=yes] input") will select :

<div class="yes"><input type="radio" name="Group 1"></div>
<div class="yes"><input type="radio" name="Item 1"></div>
<div class="yes"><input type="radio" name="Item 2"></div>
<div class="yes"><input type="radio" name="Group 2"></div>
<div class="yes"><input type="radio" name="Group 5"></div>
<div class="yes"><input type="radio" name="Item 3"></div>
<div class="yes"><input type="radio" name="Item 4"></div>

For more information, you can check jQuery Selectors : http://docs.jquery.com/Selectors

or The best book is jQuery in Action, well I am learning from this book :)

Select sibling elements of li : $("li")

P.s : In normal javascript $() means getElementById() but it works a little bit different in jQuery because jQuery power comes from its selectors, it uses Css selectors as well as its own custom and powerful selectors.

Braveyard
Thanks for taking the time to write a response! Unfortunately, I think this is more general-purpose info regarding jquery than an answer to my specific problem. I've tried a lot of different selector types and have (thus far) been unable to select *just* `Item 1` and `Item 2` after clicking on `Group 1`.
JustLoren
+1  A: 

EDITED: Changed some code, damn old jquery.

First off, your radios have no values. That's going to be a fly in your ointment, since they're both the same.

For your HTML, I would do:

<li class="group" id="group1">
    <div class="yes"><input type="radio" name="group1" value="yes"></div>
    <div class="no"><input type="radio" name="group1" value="no"></div>
    Group 1  
    <ul>
        <li>
        <div class="yes"><input type="radio" name="Item1" value="yes"></div>
        <div class="no"><input type="radio" name="Item1" value="no"></div>
        Item 1
        </li>

        <li style="padding-left:25px">
        <div class="yes"><input type="radio" name="Item2" value="yes"></div>
        <div class="no"><input type="radio" name="Item2" value="no"></div>
        Item 2
        </li>
    </ul>
</li>

The extra serves the dual functions of delimiting the subgroups in a logical way, and providing a nice hook. Instead of setting the padding as a style, do li ul li{ padding-left: 25px;}

Then, you can do

        $(document).ready(function(){
            $(".group>div>input").change(function(){
                val = $(".group>div>input:checked").val();
                var inputs = $(this).parents("li").find("ul li div input[@value="+val+"]");
                inputs.each(function(){$(this).attr("checked","checked")});
            });
        });

This will trigger the inside function on a change in one of the group 1 inputs.

Adam Bard
The problem is there are some <li>s further up in the hierarchy of the page, so .parents("li") winds up setting everything. Plus, your `val =` statement would only select the first group. I fixed it all by changing to `val = $(this).parent().parent().find(...)` and `var inputs = jQuery(this).parent().parent().find(...)` Thanks for all the help!
JustLoren
Could someone clear up whether my "fix" is a hack or is the correct way of doing it?
JustLoren
When in doubt, add some descriptive classnames. That way you can use something like .parents("li.group"). That way you're defended if you have to change the nesting levels.
Adam Bard
A: 

The problem I see with the markup that makes it hard for you to select "child" elements is that the Items are on the same hierarchical level as the Group items.

Visually, you were able to distinguish the parent (Group) from the children (Item) by giving the children padding. Is there a reason why they're on the same level?

To keep your mark-up semantic, and to more easily do what you're trying to do, I suggest changing your structure as such:

<li>
    <div class="yes"><input type="radio" name="Group 1"></div>
    <div class="no"><input type="radio" name="Group 1"></div>
    Group 1
    <ul>
     <li style="padding-left:25px">
      <div class="yes"><input type="radio" name="Item 1"></div>
      <div class="no"><input type="radio" name="Item 1"></div>
      Item 1
     </li>
     <li style="padding-left:25px">
      <div class="yes"><input type="radio" name="Item 2"></div>
      <div class="no"><input type="radio" name="Item 2"></div>
      Item 2
     </li>
    </ul>  
</li>
Jacob Gube
A: 

Give each of your group 1 children a class called "group1" or something that distinguish it from the rest of the other items in the other groups. Or put a container around the group1 items like a or .

Then add a click event handler to the Group 1 radio button so that when they click "yes", then select all the radio buttons inside the "yes" classes that are inside your container class.

<li>
  <div class="yes"><input type="radio" name="Group 1"></div>
  <div class="no"><input type="radio" name="Group 1"></div>
  Group 1  
</li>
<li class="group1" style="padding-left:25px">
  <div class="yes"><input type="radio" name="Item 1"></div>
  <div class="no"><input type="radio" name="Item 1"></div>
  Item 1
</li>
<li class="group1" style="padding-left:25px">
  <div class="yes"><input type="radio" name="Item 2"></div>
  <div class="no"><input type="radio" name="Item 2"></div>
  Item 2
</li>
<li>
  <div class="yes"><input type="radio" name="Group 2"></div>
  <div class="no"><input type="radio" name="Group 2"></div>
  Group 2  
</li>
<li class="group2" style="padding-left:25px">
  <div class="yes"><input type="radio" name="Item 3"></div>
  <div class="no"><input type="radio" name="Item 3"></div>
  Item 3
</li>
<li class="group2" style="padding-left:25px">
  <div class="yes"><input type="radio" name="Item 4"></div>
  <div class="no"><input type="radio" name="Item 4"></div>
  Item 4
</li>

To check off all the "yes" buttons in group 1, you can do:

$(".group1 > .yes").children().val("true");

or something like that, I can't remember what the syntax is to check the radio box but that's the idea.

Willson Haw
A: 

This shouldn't be too bad, even without restructuring your code. However, if you're trying to write a selector, it would help to know exactly which elements you're trying to select. Is it the li, the div, the inputs, or something else?

That said, it seems like you should really just wrap each "group" in a div, which will enable you to select each group without having to "know" which elements are associated. The (incorrect) indentation in the code in your question shows that you really do want to create, in the markup, the hierarchy you're trying to pretend exists. So, either:

<div id="Group1">
<li>
  <div class="yes"><input type="radio" name="Group 1"></div>
  <div class="no"><input type="radio" name="Group 1"></div>
  Group 1  
</li>
<li style="padding-left:25px">
    <div class="yes"><input type="radio" name="Item 1"></div>
    <div class="no"><input type="radio" name="Item 1"></div>
    Item 1
</li>
<li style="padding-left:25px">
    <div class="yes"><input type="radio" name="Item 2"></div>
    <div class="no"><input type="radio" name="Item 2"></div>
    Item 2
</li>
</div>

or:

<li>
  <div class="yes"><input type="radio" name="Group 1"></div>
  <div class="no"><input type="radio" name="Group 1"></div>
  Group 1  
</li>
<div id="Group1">
<li style="padding-left:25px">
    <div class="yes"><input type="radio" name="Item 1"></div>
    <div class="no"><input type="radio" name="Item 1"></div>
    Item 1
</li>
<li style="padding-left:25px">
    <div class="yes"><input type="radio" name="Item 2"></div>
    <div class="no"><input type="radio" name="Item 2"></div>
    Item 2
</li>
</div>
Matt Ball