Question

The below code shows when an input is focused its parent fieldset background color changes. I would like for the fieldset to maintain that background color until an input in another fieldset is focused. The concept below works except if a fieldset contains multiple inputs the change is refired when the next input is focused. Any thoughts? Thanks!

jQuery

jQuery("input[title]").focus(function() {
    jQuery(this).closest('fieldset').animate({backgroundColor: "#7e7451", color: "#ffffff"}, 'slow');
});

jQuery("input[title]").blur(function() {    
    jQuery(this).closest('fieldset').animate({backgroundColor: "transparent", color: "#777777"}, 'slow');
});

HTML

<fieldset name="Fieldset 1" id="fieldset1">
    <legend>Fieldset 1</legend>
    <label for="input1"><strong>Input 1</strong>
        <input type="text" name="input1" id="input1" />
    </label>
    <label for="input2"><strong>Input 2</strong>
        <input type="text" name="input2" id="input2" />
    </label>
</fieldset>

<fieldset name="Fieldset 2" id="fieldset2">
    <legend>Fieldset 2</legend>
    <label for="input3"><strong>Input 3</strong>
        <input type="text" name="input3" id="input3" />
    </label>
    <label for="input4"><strong>Input 4</strong>
        <input type="text" name="input4" id="input4" />
    </label>
</fieldset>

etc
Was it helpful?

Solution

First of all, since you're animating a background color, I assume you use jQuery-UI. This means you should animate using classes instead if having the style change direclty in your javascript.

Then, to be able to do what you're trying to do, you need to save the current "active fieldset" in a variable. That way you can trigger the style change only if it's really not active anymore.

So here's how your CSS should look like:

fieldset {
    background-color: transparent;
    color: #777;
}
fieldset.active {
    background-color: #7e7451;
    color: #FFF;
}

And the JavaScript would be

var activeFs = jQuery('#fieldset1'); // must be valid

jQuery("input")
    .focus(function() {
        var fs = jQuery(this).closest('fieldset');
        if (activeFs.attr('id') != fs.attr('id')) {
            activeFs.removeClass('active', 'slow');
            activeFs = fs;
        }
        fs.addClass('active', 'slow');
    }).blur(function() {
        var fs = jQuery(this).closest('fieldset');
        if (activeFs.attr('id') != fs.attr('id')) {
            fs.removeClass('active', 'slow');
        }
    });

NB: Be aware that both event trigger at the same time, when you go from one input to another. This means you can't know on blur() if there is still a focused input somewhere, therefor this script will always keep the last fieldset that was focused active. But you can of course easily remove that active class, when the user clicks somewhere else, or submit the form.

Here's a FIDDLE if you wanna play around with the code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top