views:

53

answers:

2

I'm building a form that first asks if you have 'foo'. If the answer is 'Yes', a div appears and asks 'How many foo do you have'? Based on the quantity answered, I'd like to show only that many divs. Thus if the user answers 1, only the first div will show. If they answer three, the first three will show. I have it set so that if the user answers no, the question of the amount remains hidden, but if they answer yes, they would be prompted for the quantity. This is what I've got so far...

        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />

<!--jQuery-->
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;

    <link rel="stylesheet" href="files/mem_health_panel.css" type="text/css" media="screen" />
    <link rel="stylesheet" href="http://www.fabacherinteractive.com/slider/themes/default.css" type="text/css" media="screen" />

<style>

ul
{
list-style-type:none;
}
</style>

<script type="text/javascript">

$(document).ready(function(){

    $(window).load(function() {
        $('#amt_of_foo,.foo_panels,.next').hide();
        });

    $('#yes_foo').click(function() {
        $('#amt_of_foo').show();
        });

    $('#no_foo').click(function() {
        $('.foo_panels,#amt_of_foo,.section_panel').hide();
        $('.next').show();
        });

});

    </script>

</head>
<body>


<ul>
<li>
<div class="panel section_panel">
    <h2>Questions About Your Foo</h2>
        <span>Do you have foo?:</span><br />
        <input type="radio" name="foo" id="no_foo" /> No <br />
        <input type="radio" name="foo" id="yes_foo" /> Yes: <br/>
        <span id="amt_of_foo">
        <span>How many foo do you have?:</span>     
        <span><input id="qty_of_foo" type="text" size="5" />
        </span>
        </span>
</div>
</li>

<!--answers yes to foo, and enters amount-->

<div class="foo_panels">
<li>

        <li>
        <div class="panel foo_1">
        <h1>First foo's information</h1>
        <span>Foo name:&nbsp;<input type="text" size="20" /></span>
        </div>
        </li>

        <li>
        <div class="panel foo_2">
        <h1>Second foo's information</h1>
        <span>Foo name:&nbsp;<input type="text" size="20" /></span>
        </div>
        </li>

        <li>
        <div class="panel foo_3">
        <h1>Third foo's information</h1>
        <span>Foo name:&nbsp;<input type="text" size="20" /></span>
        </div>
        </li>
</div>

<!--answers no to foo-->

        <li>
        <div class="panel next">
        <h1>Next Question, if no foo</h1>
        </div>
        </li>

</ul>
</body>
</html>

The ul is used for a jQuery 'slider' plugin. the 'panel' class is used for global css.

+1  A: 

I would use a change handler for the quantity input. When it changes, get the number to show from its value. Use a selector to get the appropriate elements to show in a collection and filter them by their index relative to the number to show.

$('#qty_of_foo').change( function() {
    var show = parseInt($(this).val() || 0);
    $('#foo_panels > li').hide();
    $('#foo_panels').find('.panel')
                    .parent()
                    .filter( function(i) { return i < show; } )
                    .show();
});

You could also do the same with slice, though, you might have to do a bit more error checking.

$('#qty_of_foo').change( function() {
    var show = parseInt($(this).val() || 0);

    if (show <= 0) return true;

    $('#foo_panels > li').hide();
    $('#foo_panels').find('.panel')
                    .parent()
                    .slice( 0, show - 1 )
                    .show();
});
tvanfosson
A: 

first of all it will be more optimal to have "foo_panels" be an id. Then you will want your panel li's to have a class like 'panel' like this:

<li class"panel">
  <div class="foo_1">
  <h1>First foo's information</h1>
  <span>Foo name:&nbsp;<input type="text" size="20" /></span>
  </div>
</li>

Then you can hide/show the number of panels using .slice()

$(".panel").hide();​​​​​​​​
var panels = $(".panel", "#foo_panels"); //set panels group
$('#qty_of_foo').change( function() {
  $(panels).hide(); //hide any previously shown panels
  $(panels).slice(0, parseInt($(this).val())).show(); //show the slice
});

Also, you are going to want to get rid of that orphaned <li> right after <div class="foo_panels">. You also can't have a <div> in a <ul> that is not wrapped in a <li>.

UPDATE: I have created a jsFiddle that demonstrates the code (and in the process discovered an error in what I had posted which I have fixed.

Bradley Mountford
That looks good, but how can I trigger the function? Keep in mind, I'm someone who was forced into learning JavaScript under live fire. I know that I needed to learn it, but not by being thrown into hand-to-hand combat with it...
Adam
You just wrap it in $(function(){ }); (which is shorthand for $(document).ready(function(){}); ) so that it loads when the page is ready. Then $('#qty_of_foo').change( function() { is fired when you change the selection in your dropdown.
Bradley Mountford
Check out my update that includes a jsFiddle demo.
Bradley Mountford