views:

83

answers:

4

I have a form, like so:

<form action="" method="post">
   <select name="pageType">
      <option value="main">Main Page</option>
      <option value="sub">Sub Page</option>
      <option value="sub-sub">Sub-Sub Page</option>
   </select>

<br />

<label>Choose Sub Sub Name:</label> <input type="text" name="sub-sub-name" />

<br />

<input type="submit" name="submit" value="GO!" />

</form>

What I would like to achive is for this text field (and it's label):

<label>Choose Sub Sub Name:</label> <input type="text" name="sub-sub-name" />

to only appear if the 3rd option (sub sub page) is selected from the drop down and not show up otherwise. How can this be done with either javascript or the jquery framework?

EDIT

by the way, it would be nice if this can be achieved without the page needing to refresh and losing previously submitted form data. I know form data can still be kept using variables that store the values even on page refresh, but I was hoping for that effect that I see on a lot of sites where the additional text area (or other form element) just appears without page refresh.

A: 

$("select[name=pageType]").change(function(){ if($(this).attr("selectedIndex")) == 2) $('#subsub').show(); });

Then wrap your form element in a div:

<div id="subsub" style="display:none;"><label>Choose Sub Sub Name:</label> <input type="text" name="sub-sub-name" /></div>
Aaron Harun
+2  A: 

Hiding/showing the label and the field is easy. Put the field in the label (which associates them), give the label style="display: none", and give it an ID. E.g.:

<label id='thirdField' style='display: none'>Choose Sub Sub Name: <input type="text" name="sub-sub-name" /></label>

Then you can show it via show

$("#thirdField").show();

...and hide it via hide:

$("#thirdField").hide();

...or (and it's not hyper-clear from the docs, but if you get to the bottom of the page you'll find it) you can toggle based on a boolean value using toggle:

$("#thirdField").toggle(true); // true to show, false to hide

So now what you need is a trigger that fires when the third option in the select is chosen. There's the change event, but it doesn't fire until the focus leaves the select field. (jQuery normalizes that; otherwise, when it fired would be browser-dependent.) You could try click on the option itself, but I don't know if it's reliable when navigation is via the keyboard.

To be proactive (which is particularly important if the field you're showing immediately follows the select box in the tab order!), I tend to use a timer to watch for changes (an idea I got from the Prototype guys, they have a whole class for this):

var selectField = $("#mySelectField");
var thirdField = $("#thirdField");
var handle = setInterval(watchForChange, 250); // Every quarter second
function watchForChange() {
    thirdField.toggle(selectField.val() === "sub-sub");
}

(There I assume you've given the id mySelectField to your select field.) When you don't need to do this anymore, you want to cancel the interval:

clearInterval(handle);
handle = 0;

Naturally you wouldn't do all of the above at the top level, that would itnroduce a bunch of global variables. You'd put it inside a scoping function.

T.J. Crowder
`$("#thirdField").toggle(selectField.val() === "sub-sub")` :)
Nick Craver
Could you post a source for this "different browser trigger onChange at different times" thing? I never saw or thought of using a timer to achieve this effect. I won't downvote you though, you might be right, afterall, that's why I'd like some source for this affirmation.
Spidey
@Spidey: Try it out in Firefox vs. IE. IE fires when you select the option, Firefox waits until focus leaves the field. (When using the keyboard, that is.)
T.J. Crowder
Ah, alright, that definitively could lead to problems.
Spidey
@Spidey: Hmmm, maybe it isn't a browser difference (just tried it in IE7 and it waited until focus was lost). Either something's changed or I'm mis-remembering; in any case doing it with a timer ensures the field shows up right away. Editing...
T.J. Crowder
@T.J. - jQuery normalizes the change event for consistency and bubbling, you can see the code here: http://github.com/jquery/jquery/blob/master/src/event.js#L745 *normally* you're right, if you bound right to the DOM event and not using jQuery.
Nick Craver
@Nick: Thanks! I thought I was going nuts. (I used to only use Prototype, I've been picking up jQuery lately.) And thanks also for the `toggle` thing, I'd missed that in the API docs. (Blasted hyper-overloaded jQuery API...)
T.J. Crowder
A: 

jQuery

$(document).ready(function(){
  $('#pagetype').change(function(){
    $('#choosesubsub')[$(this).val()=='sub-sub' ? 'show' : 'hide']();
  });
});

HTML

<form action="" method="post">
  <select name="pageType" id="pagetype">
    <option value="main">Main Page</option>
    <option value="sub">Sub Page</option>
    <option value="sub-sub">Sub-Sub Page</option>
  </select>

  <br />

  <div id="choosesubsub" style="display: none;"><label>Choose Sub Sub Name:</label> <input type="text" name="sub-sub-name" /></div>

  <br />

  <input type="submit" name="submit" value="GO!" />
</form>

As you can see in the HTML, I added some IDs, so that I can more easily identify the elements. Also, I wrapped the "Choose Sub Sub Name" with a DIV.

Gert G
A: 

You'll have to register an onChange event handler to your dropdown list, so that when it's value changes, you'll check if it's current selected item is the one you want, and then show the input, or hide it otherwise.

I'd advise you first to wrap the label + input in a div and hide it using CSS (display:none;), and give it an ID.

Then, using jQuery:

$('form select[name=pageType]').change(function(){
  if ($('form select option:selected').val() == 'sub-sub'){
    $('#input_with_label_id').show();
  }else{
    $('#input_with_label_id').hide();
  }
});
Spidey