Hi all, I'm relatively new to JS and I have an issue which I can't seem to get my head around...
I have a perl script which iterates through an array and populates a table with its values. Within the created table I have a link in each row which calls a js function onMouseOver(). I have tried to simplify this as much as possible.

foreach $equipment (@some_array) {
    "<a href='some_script' onMouseOver=displayPanel('box'); onMouseOut=hidePanel('box');><b>$equipment</b></a>";

print "<span id='box' class='box' style='display: none;'>";
print "<strong><u>Host Information:</u></strong><br>";
// dynamic content to be displayed here depending on which link is hovered over
print "</span>";

These JavaScript functions hide/display the span called 'box' (elementary stuff)

function displayPanel(id) {
        document.getElementById(id).style.display = 'block';
function hidePanel(id) {
        document.getElementById(id).style.display = 'none';

My problem is that I want to change the content displayed in the span box depending on which link the user has his/her mouse over. So how can I set a variable that tells me which link is being hovered over?! The only thing I could think of was giving the <a> a unique ID, but then I'd have to pass a value back to perl and this is where I start to confuse myself with the client/server-side stuff! So maybe some sort of AJAX would do the trick? Any help is much appreciated.

Edited by nonshatter: n/a

6 Years
Discussion Span
Last Post by nonshatter

The server doesn't know anything but what the client (browser) tells it and only for the duration of the current request. What that means is once the browser makes a request for the page, the server code runs and spits out the requested page and then forgets about the client. It runs the code and is done. The server cannot "see" anything in the client code unless the client code specifically sends back data to the server in either an ajax call or a page request via the url. This is true even if you are printing out client-side code via the server side code and including server variables. Once the server has printed all this to the client it stops executing and is done. The client on the other hand runs and stays in the end user's memory for as long as the current browser window is open and hasn't performed a full refresh. It can make new requests to the server but it has to tell the server everything it wants.

You can do a couple of things here and you will want to determine if you want to do your rendering of the new content on the server side or the client side and if you want to use ajax or not.
1. If you know ahead of time what the new content for each panel will be (ie. it's static content within each panel) you could render everything to start with and just hide show each panel's content along with the panel per what ever link is hovered over. This is possibly the quickest way but you will have an initial overhead of the browser loading everything at once.
2. You could set an id or other attribute on the anchor and just send it back to the server for processing and rendering. I would highly suggest using jQuery's ajax or post lib to do this as it takes care of all the browser specific stuff and the api is clean and easy to use. Then when you send your code back you could either just use prints like you normally would. To set up this method use:

my $content = "";
foreach my $equipment (@some_array) {
    $content .= "<a href='some_script' equipment='$equipment' onMouseOver=displayPanel('box',this); onMouseOut=hidePanel('box');><b>$equipment</b></a>";
print $content;
/* if you javascript is rendered as part of your perl script you will want to use
 * the keyword jQuery instead of the '$'. But if it is in it's own js file that you
 * are including then you can keep the '$'.
function displayPanel(id,el) {
        var equipment = el.getAttribute("equipment");
        var panel = document.getElementById(id);
        panel.style.display = 'block';
                var docFrag = $("<div></div>");
                docFrag.innerHTML = htmlString;
                panel.innerHTML = docFrag;
function hidePanel(id) {
        document.getElementById(id).style.display = 'none';

yourPageHere.cgi can be the same file that initially renders the page (just be on the look out for the equipment value and process it and exit before the code gets to the regular rendering stuff or can be a different file. If you are printing out the html (even in the regular rendering part) you should create a string or print multiple lines using multi-line quotes (qq) rather than using a separate print for each line. This is just an optimization thing because of how perl interprets each print its more expensive than actually doing the string concat yourself(plus it makes it a bit cleaner).


Thanks for your input scrappedcola, It's really helpful. I haven't tried to implement your solution yet, but I just came across this JQuery/AJAX method which may also work:

<script src="http://code.jquery.com/jquery-latest.js" /></script>
<style type="text/css">  
.box { 
	background-color: #504D6F; 
	border: 1px solid #FFF; 
	color: #FFF;
	height: 200px; 
	width: 200px; 
	padding: 5px; 
<script type="text/javascript">
	function displayPanel(id)
		document.getElementById(id).style.display = 'block'; 
		document.getElementById('feeds').style.display = 'block';
	function hidePanel(id)
		document.getElementById(id).style.display = 'none'; 
		document.getElementById('feeds').style.display = 'none';
	function updateInfo() {
		<a href="test.com" onMouseOver="displayPanel('box'); return false;" onMouseOut="hidePanel('box');">Link 1</a><br>
		<a href="test.com" onMouseOver="displayPanel('box'); return false;" onMouseOut="hidePanel('box');">Link 2</a>
		<span id="box" class="box" style="display: none;">
			Host Information
			<div id="feeds"> </div>

The updateInfo() function will execute the ajax.cgi script and print whatever was returned into the #feeds div. If I could pass the equipment id through the URL e.g. ajax.cgi?equip=$equip_id then I could handle the generation of dynamic content in this file alone. Although then again, I will still have the same problem determining which link was hovered over, right? Which will leave me with exactly the same scenario...
Do you have any suggestions/comments/objections on this?


For your anchor set an attribute called equipment(or whatever you want just keeping with the terms from the original post) and send the onMouseOver function the keyword "this" (which refers to the element that triggered the event) as well as 'box'. Then get the attribute off the element you send to the mouseover function and pass that to the updateInfo() function. The jquery load method will accept an optional data parameter and post that data back to the provided url(it should also work if you just pass on the url provided in url param of load and pass as a GET as well "ajax.cgi?equip=" + value_to_pass. You can then send the equipment variable back through the load method to use in your perl to generate the HTML needed for the new panel.

<a href="test.com" equipment='Link 1' onMouseOver="displayPanel('box',this); return false;" onMouseOut="hidePanel('box');">Link 1</a>
function displayPanel(id, el)
   var val_from_link = el.getAttribute("equipment");
   document.getElementById(id).style.display = 'block'; 
   document.getElementById('feeds').style.display = 'block';
function updateInfo(value_to_pass) {
   /* above could optionally be sent as :
    * $("#feeds").load("ajax.cgi?equip="+ value_to_pass);
    * and it will be a GET rather than a POST

Brilliant, I will try this tomorrow and get back to you with the result.
Thanks again

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.