1

I have an HTML form with plenty of inputs, most of which are optional. I want to apply different CSS to inputs based on their values as I think this will make it easier to see what fields have been specified.

For example, if a textbox actually has a value entered, I'd like it to have a different background/border colour. I'm not sure how I'd write a CSS selector that tests for this (nor how many browsers would support it.)

Similarly I have some radio buttons where one option is 'none', but if any other option is selected, its label text should be bold.

Ideally I'd do this with CSS, but if it required jQuery, then that's ok, especially if it would give better crossbrowserness.

EDIT Some great answers here -- looks like JS is the path here. Reading through these JS solutions I realise some requirements that would have been neatly addressed by CSS:

  • The form may be presented partially populated (when the entity is edited), meaning that no 'change' event fires.
  • The form is dynamic in that new text boxes may be added.

In the end I went for an amalgam of the below answers, which I'll include here in case someone else finds it useful:

var highlightInput = function () {
    var $this = $(this);
    if ($this.is(':text') || $this.is('textarea')) {
        $this.toggleClass('has-value', this.value.length > 0);
    } else if ($this.is(':radio') || $this.is(':checkbox')) {
        $this.parent().find('input[name="' + this.name + '"]').each(function () {
            var $label = $('label[for="' + this.id + '"]');
            var isSelected = this.checked && $label.text() != 'Unspecified';
            $label.toggleClass('selected-option', isSelected);
        });
    }
};

$('textarea, input:text').live('keyup', highlightInput)
                         .live('change', highlightInput)
                         .each(highlightInput);

$('input:radio, input:checkbox').live('change', highlightInput)
                                .each(highlightInput);

And some CSS, with crazy colours as placeholders:

input[type=text].has-value, textarea.has-value { background-color:#0F0; }
label.selected-option { background-color:#0F0; }
3
  • JavaScript would definitely give you a better cross browser experience. Commented Mar 8, 2011 at 16:39
  • I don't think there's any CSS selector that can do this. Commented Mar 8, 2011 at 16:41
  • i think you should write a function which will loop thru each field, read its value and then apply proper css property to it. Now bind onchange event to each field with same fn to process the field. If u want than i can write code. Commented Mar 8, 2011 at 16:50

6 Answers 6

4

Something like this should do the trick:

$('textarea, input:text').change(function() {
    var isEmpty = $(this).val() == '';
    $(this).toggleClass('empty', isEmpty);
});

If you'd like the class to be toggled with every key stroke, use the keypress() method instead of change().

Sign up to request clarification or add additional context in comments.

3 Comments

Ah slick use of toggleClass +1
thanks. Please see my edit -- what if the form appears populated? Then no change event fires, right? Also, the form may update dynamically, with new inputs being added to the DOM after load, depending on what the user does.
Glad to see you got it figured out!
1

Think you are going to have to go with jquery for this one. Try out this fiddle

javascript looks something like this:

$('form :input').change(function(){
    var $this = $(this);
    if($this.is(':text')) 
        $this.toggleClass('highlight', this.value.length > 0);

    if($this.is(':radio')) { // update all radios in group
        $this.parent().find('input[name="' + this.name + '"]').each(function(){
            $('label[for="' + this.id +'"]').toggleClass('bold', this.checked);
        });
    }
});

1 Comment

In the end this answer proved the most useful. I still went for live over and used keyup, but this answer was the first that showed how to do this for radio buttons too, as asked for in the original question. Many thanks.
1

I think you will have to go for jQuery - hook up to ie. 'change' event on text boxes, check the value of the text box and assign appropriate css class. Something along the lines of:

$('input:text').change(function(){
   if($(this).val() == null)
       $(this).removeClass('has-value').addClass('no-value');
   else
       $(this).removeClass('no-value').addClass('has-value');
});

Comments

1
$('input').live('change',function(){
  if($(this).val !=false){
    $(this).addClass('completed');
  }else{
    $(this).removeClass('completed')
  }
});

3 Comments

+1 for use of live. This achieves something I need -- namely the ability to respond to elements being added to the DOM after load. What, though, about when the user is editing the entity and the inputs are populated at page load? In that case, change doesn't fire, right?
I would likely add the class within my scripting language. (PHP, .NET ...)
Fair enough, though I don't think I would personally. Apart from the fact that if the user doesn't have JS enabled then it wouldn't update, it splits the logic up more that I'd like in the code. Thanks again for your answer -- I'll definitely use live.
1

http://jsfiddle.net/NaAEB/

$('input').change(function(){
    if($(this).val() !== ""){
       $(this).addClass('hasVal');
    }else{
       $(this).removeClass('hasVal');
    } 
});

$('select').change(function(){
    if($(this).val() !== "none"){
       $(this).addClass('hasVal');
    }else{
       $(this).removeClass('hasVal');
    } 
});

Comments

1

You would definitely need JavaScript (jQuery if you prefer) to accomplish this. Here's a sample to get you started:

$('input.foo').keydown(function() {
    var $this = $(this);
    var modClass = 'modified';
    $this.toggleClass(modClass, $this.val());
});

Wrote that blind, so I hope it works. Nested ifs are there for the case when it has a value and has a class.

Clarification: I used "keydown" for the sake of highlighting immediately rather than when the input loses focus. This won't be appropriate for your radios. Use change() for that, though I don't know why you'd use Live when no AJAX context was given, and when Delegate (or Live with a context) is more efficient.

1 Comment

BTW keydown doesn't seem to work very well as the key hasn't yet made its impact on the value. To see what I mean, press a key in an empty field and note that nothing changes until the next keypress. Same when you delete all the content with backspace. keyup does the trick though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.