views:

656

answers:

5

Suppose to have a code like this:

<div class="notSelected">
      <label>Name
          <input type="text" name="name" id="name" />
      </label> 
      <div class="description">
          Tell us what's your name to make us able to fake to be your friend 
          when sending you an email.
      </div>
</div>

Now suppose I've something like this (it's just an example) for each element of a form. I'd like to change the style from notSelected to Selected when:

  • User focus on the input element
  • User move the mouse over a notSelected div

When he change focus the Selected div should became notSelected again.

I'd like to do something like this to increment the size of the text of the selected div. Anyway it could be cool make other changes too so I'd prefer to change the class attribute.

What is the best way to do something like this in JavaScript? Is there any JavaScript framework that can boost me doing this thing? So it will be easy to add effects like fading etc...

I downloaded MooTools but with a fast read of the docs I did not see how to do this without having a specific ID for any of the forms div, but is the first time I use it. I've no problem using any other framework, but if you suggest one, please write also what should I look for specifically, thank you.

+5  A: 

I would recommend a look at jQuery for your task. It is quite easy to learn and produces nice effects quickly. But your described effect alone, pure JavaScript would also be enough.

Make your DIVs always have a class called "selectable". You can toggle other CSS classes later on. Create a CSS class named "selected" and give it the desired look.

<div class="selectable">  (=off) vs. <div class="selectable selected"> (=on)

Then add something like this to the scripts section of your document:

$(document).ready(function(){

  // handle mouseover and mouseout of the parent div
  $("div.selectable").mouseover(
    function() { 
      $(this).addClass("selected").addClass("mouseIsOver");
    }
  ).mouseout(
    function() { 
      $(this).removeClass("selected").removeClass("mouseIsOver");
    }
  );

  // handle focus and blur of the contained input elememt,
  // unless it has already been selected by mouse move
  $("div.selectable input").focus(
    function() {
      $(this).parents("div.selectable").not(".mouseIsOver").addClass("selected");
    }
  ).blur(
    function() {
      $(this).parents("div.selectable").not(".mouseIsOver").removeClass("selected");
    }
  );
});

This is untested so there might be a glitch in it, but it will give you the general idea where to start.

P.S: Changing text size on mouse move may not be the best of all ideas. It leads to rearranging the page layout which is annoying for the user.

Tomalak
Thank you for the hint, but it could be used to an area of the form. For example once he focus on the login area, or the profile zone, just as example, thank you again!
Andrea Ambu
+6  A: 

There's also a pure CSS solution to this problem. However, it doesn't work in MSIE 6. Technically, it works similar to Tomalek's solution but instead of using JavaScript to toggle the element's class, it uses CSS to toggle its style:

.selectable { /* basic styles …  */ }
.selectable:hover { /* hover styles … */ }
.selectable:active { /* focus styles … */ }
Konrad Rudolph
Very nice way, +1!
Andrea Ambu
Not compatible with older browsers, though. IE6 is still widely used and does not support the hover pseudo class on elements other than A.
Tomalak
@Tomalak: I said that in my text. However, more and more new apps are dropping IE6 support anyway. Whether this is advisable is another question. Combined with graceful degradation it's clearly an option, especially since a CSS-only approach also has advantages over JavaScript (not everyone has it).
Konrad Rudolph
Oh, I've overlooked that sentence. Sorry. CSS is a lot faster than JavaScript, and the declarative syntax is much more beautiful as well. I would also go that route if I was sure of the "browser audience".
Tomalak
The way to go. It is "wrong" to use script for the task when hover pseudo class is specifically designed for it.Of course, the site is not usable w/o the feature and IE6 users are important, you do what you have to do.
buti-oxa
How would that change the container element for an active INPUT? Is there a selector that says "this DIV when it contains an active INPUT"?
Tomalak
@Tomalak: no, this isn't possible in CSS, selectors can only affect child elements and following elements, not parent elements or preceding elements. Here, you need JavaScript.
Konrad Rudolph
+1  A: 

This is somewhat unrelated, but the label tag does not enclose the input tag. You give the label tag a "for" attribute which corresponds to the ID of the input element. Example,

<label for="username">Username</label>
<input type="text" name="username" value="Enter your username..." id="username" />
whalesalad
Whilst label-for is the usual way of doing it, it is in fact quite valid to put the input inside the label instead.
bobince
+2  A: 

@Tomalak:

Why are you querying the DOM four times?

A small edit, but a huge speed-benefit:

$("div.selectable").mouseover(function ()
{
    // ...
}).mouseout(function ()
{
    // ...
});
roosteronacid
You are right. I'll correct that.
Tomalak
A: 

Yet another unrelated-to-the-original-question answer but... jQuery also has an alternative syntax for doing mouseover/mouseout stuff called hover.

$(element).hover(function(){ /* mouseover */ }, function(){ /* mouseout */ });

Example,

$('ul#nav li').hover(function() {
    $(this).addClass('highlight');
}, function() {
    $(this).removeClass('highlight');
});

Sorry for those double $'s, I can't seem to figure out how to escape that.

whalesalad