2

So I have created an order form in HTML + Javascript, and what I am wanting to use Javascript for is when someone hovers over the "label" for the soup, a hidden div will be visible (later on I intend on getting the code that will display info about the soup whose label was hovered over). I have managed to get that working but i know the Javascript code I implemented is obtrusive and am wanting to put the same code (or equivalent) onto my external Javascript file to make it not obtrusive.

Here is a fragment of code from my form (with the "obtrusive" Javascript):

<form method="post" action="#" name="souporderform" id="souporderform" onsubmit="return validate()">
**<div id="soupinfo"></div>** <!-- hidden div -->

<table>

<tr><th>Item</th><th>Price</th><th>Quantity</th><th id="subtotal_header">Subtotal</th>
<tr>
<td><label for="chicken_quantity" onmouseover="document.getElementById('soupinfo').style.visibility = 'visible';" onmouseout="document.getElementById('soupinfo').style.visibility = 'hidden';">Chicken Soup</label></td>
<td>$3.50<input type="hidden" id="chicken_price" value="3.50"></td>
<td class = "center"><select id="chicken_quantity" name="chicken_quantity" size="1">
<option value="10">10</option>
<option value="9">9</option>
<option value="8">8</option>
<option value="7">7</option>
<option value="6">6</option>
<option value="5">5</option>
<option value="4">4</option>
<option value="3">3</option>
<option value="2">2</option>
<option value="1">1</option>
<option value="0" selected>0</option>
</select>
</td>
<td id="chicken_subtotal"></td>

I'm sure the obtrusive Javascript is obvious to experienced Javascript coders viewing this...

Here is the fragment of CSS code concerned with the "hidden" div:

#soupinfo{
position:absolute;
background-color:#ff0000;
color:#000000;
width:100px;
height:20px;
margin-top:-20px;
margin-left:0px;
border:1px solid black;
visibility:hidden;
}

I do have an external Javascript file and this is what I was trying to do to replicate what I want in an unobtrusive manner:

var soupInfoDiv = document.getElementById("soupinfo");
var formLabel = document.getElementsByTagName("label");

for(var i = 0; i < formLabel.length; i++){
formLabel[i].onmouseover = soupInfoDiv.style.visibility = 'visible';
formLabel[i].onmouseout = soupInfoDiv.style.visibility = 'hidden';
}

This code is placed in a function called "setup", which is executed when the page is loaded, with the following code:

if (document.getElementById) {
window.onload = setup;
}

So if anyone can help me out, I will be very greatful :). If supplying the code fragments makes the overall problem difficult to decipher, I can upload all the code to my site and share it on here.

Rob
  • 1,272
  • 6
  • 24
  • 35
  • 1
    To ease your development struggles, have you looked at a JavaScript library? I would suggest [jQuery](http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery). – Blender Sep 07 '11 at 04:20
  • 1
    Why are you checking for the existence of `document.getElementById`? – shesek Sep 07 '11 at 04:30

2 Answers2

2

The main issue that I see is that mouseover and mouseout handlers need to be functions.

var soupInfoDiv = document.getElementById("soupinfo");
var formLabel = document.getElementsByTagName("label");

for(var i = 0; i < formLabel.length; i++){
  formLabel[i].onmouseover = function() {
    soupInfoDiv.style.visibility = 'visible';
  }
  formLabel[i].onmouseout = function() {
    soupInfoDiv.style.visibility = 'hidden';
  }
}

I would recommend you consider jQuery though because all of this, including the window.load could be be simplified to this:

$(function() {
  $('#souporderform label').hover(
    function() {
      $('#soupinfo').css('visibility', 'visible');
    },
    function() {
      $('#soupinfo').css('visibility', 'hidden');
    }
  );
});
loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • `window.onload` is not `$(document).ready()`, its `$(window).load()`. But, the doc ready is preferred, as its much earlier than the window load, and totally stable for event binding. – Yahel Sep 07 '11 at 04:32
0

As commented by Blender, I also recommend using a javascript libary for this, for example jQuery or MooTools. Now, if I understand you correctly, you simply want to make it so that when you hover over element x, you want element y to be shown. This can be done pretty simply by using the data-attributes of html 5 (which works in older browsers), and a javascript framework (I'll use jQuery here, but if you need mootools instead, just ask and I'll translate it).

First you should anote the element you want to hover over like so:

<div data-hover-elm="id_of_item_to_show">.......</div>

It might be a div, a label, or whatever you want.

Then, in the external js file, all you need to do is this:

$(function() {
    var elms = $('[data-hover-elm]');
    $.each(elms, function() {
        var $this = $this,
            $itm = $('#' + $this.attr('data-hover-item'));
        $this.hover(function() {
            $itm.show();
        }, function() {
            $itm.hide();
        });
    });
});
Alxandr
  • 12,345
  • 10
  • 59
  • 95
  • Or simply `$('[data-hover-elm]').hover(function(){$('#' + $(this).data('hover-item')).show();}, function(){$('#' + $(this).data('hover-item')).hide();})`. No need to bind each `hover` event separately. The `data()` method can be used to get `data-` attributes. Also, you can use `$('[data-hover-elm]').each(...)` instead of `$.each($('[data-hover-elm]'), ...)` – shesek Sep 07 '11 at 04:39
  • Hey everyone, Thanks for all your ideas :)... @Logan F. Smyth - Your solution worked perfectly :). So with situations like this (and for other things e.g checkboxes, radio buttons etc) you have to use functions? I just thought by using a for loop that iterated through each "label" element in the form and using the mouse events would make it work, but I understand your solution and will take this as a learning exercise. Even though I have been doing php and Java for a year, Javascript is still very new to me but in a couple months I should have a good grasp of at least the basics... – Rob Sep 07 '11 at 08:28
  • @logan f.smyth - Forgot to add this to reply... So when you're implementing handlers in general, do they need to be integrated as functions? I already understand, it just would help to confirm my thoughts about it thats all :). – Rob Sep 07 '11 at 09:31
  • Just a tips Rob, you should accept one or the other as answer to get your acceptens-rate != 0%. – Alxandr Sep 07 '11 at 16:30