-
Notifications
You must be signed in to change notification settings - Fork 2
Forms example
Only ask for an email address when the users asks for a reply
<ol class="questions">
...
<li>
<fieldset>
<legend>
<span class="label">Would you like a reply?</span>
<abbr title="(required)">*</abbr>
</legend>
<ul class="choices">
<li><input type="radio" name="replyRequested" id="reply-requested-yes" value="yes" /><label for="reply-requested-yes">Yes</label></li>
<li><input type="radio" name="replyRequested" id="reply-requested-no" value="no" /><label for="reply-requested-no">No</label></li>
</ul>
</fieldset>
</li>
<li>
<label for="email">
<span class="label">Email</span>
<abbr title="(required)">
</label>
<input type="email" id="customer-email" name="emailField" required="required" size="40" />
</li>
...
</ol>
var emailField = $( '#customer-email' ),
toggleEmailRelevance = function() {
// is a reply requested?
var isRelevant = $( '#reply-requested-yes' ).is( ':checked' );
// set relevance of the email question
emailField.relevance( 'relevant', isRelevant );
}
;
// check relevance whenever the radio buttons are clicked
$( ':radio[name=replyRequested]' ).bind( 'click', toggleEmailRelevance );
// set the initial relevance when the form is loaded/refreshed
toggleEmailRelevance();
You will notice that relevance is being toggled on #customer-email
. This is the text field for the email address, but does not include the label. If we leave it like this, the text box will be shown and hidden but the label will always be visible.
We really want to show/hide the entire "question"—that is, the <li>
element that wraps the label and the input.
There are 2 ways to solve this.
You can intercept the relevant
and irrelevant
events and run the show
and hide
functions on the <li>
wrapper.
// show/hide entire 'question' when fields become irrelevant
$( '.questions > li' )
.bind( 'relevant', function( event ) {
$( this ).relevance( 'show' );
event.stopImmediatePropagation();
})
.bind( 'irrelevant', function( event ) {
$( this ).relevance( 'hide' );
event.stopImmediatePropagation();
})
;
In the original code, emailField
is $( '#customer-email' )
which is just the textbox.
It is a simple matter of making this jquery object the wrapper instead, like so:
var emailField = $( '#customer-email' ).closest( 'li' ),
toggleEmailRelevance = function() {
// is a reply requested?
var isRelevant = $( '#reply-requested-yes' ).is( ':checked' );
// set relevance of the email question
emailField.relevance( 'relevant', isRelevant );
}
;
// check relevance whenever the radio buttons are clicked
$( ':radio[name=replyRequested]' ).bind( 'click', toggleEmailRelevance );
// set the initial relevance when the form is loaded/refreshed
toggleEmailRelevance();
Option 2 is probably easier for most situations, but the choice is yours! Often when scripting with forms, you are already accessing and/or modifying the actual input elements and it’s easier to just toggle relevance on those existing objects. In this case, the code shown in Option 1 needs only be included once and can be used across an entire website to handle this situation.
You can use both if you like.