Skip to content
bboyle edited this page Feb 24, 2012 · 9 revisions

Only ask for an email address when the users asks for a reply

<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>
var emailField = $( '#email' ),

        toggleEmailRelevance = function() {
            // is a reply requested?
            var isRelevant = $( '#reply-requested-yes' ).is( ':checked' );
            // set relevance of the email question
            emailField.forcesRelevance( '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();

Not quite there…

You will notice that relevance is being toggled on #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.

1. Intercept events

You can intercept the relevant and irrelevant events and run the show and hide functions on the '

  • ' wrapper.
    	// show/hide entire 'question' when fields become irrelevant
    	$( '.questions > li' )
    		.bind( 'relevant', function( event ) {
    			$( this ).forcesRelevance( 'show' );
    			event.stopImmediatePropagation();
    		})
    		.bind( 'irrelevant', function( event ) {
    			$( this ).forcesRelevance( 'hide' );
    			event.stopImmediatePropagation();
    		})
    	;

    2. Toggle relevant on the wrapper, instead of the field

    In the original code, emailField is $( '#email' ) which is just the textbox. It is a simple matter of making this jquery object the wrapper instead, like so:

    var emailField = $( '#email' ).closest( 'li' ),
    
            toggleEmailRelevance = function() {
                // is a reply requested?
                var isRelevant = $( '#reply-requested-yes' ).is( ':checked' );
                // set relevance of the email question
                emailField.forcesRelevance( '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!

  • Clone this wiki locally