1. Make a Div for each menu and a Div for each item in the menu like this:
<div id="menu_1" class="menu" style="display:none;"
onmouseover="menu_on(1);" onmouseout="menu_off(1);">
<div class="submenu">
<a href="link1.php">Menu Item 1</a>
</div>
<div class="submenu">
<a href="link2.php">Menu Item 2</a>
</div>
</div>
Note the class names: "menu" for the container Div and "submenu" for the items. Also note the onmouseover and onmouseout events - these are used to show and hide the menus.
2. Add the mouse events to your existing navigationitem like this:
<span onmouseover="show_menu(1,this);"
onmouseout="hide_menu(1);"
>Existing Navigation Link
</span>
3. Add the JavaScript functions:
<script>
var active_menu = 0;
function show_menu(id,element){
active_menu = id;
menu = document.getElementById("menu_" + id);
menu.style.left = findLeft(element) - 3 + 'px';
menu.style.display="block";
}
function time_out(id){
if (active_menu != id){
document.getElementById("menu_" + id).style.display="none";
}
}
function hide_menu(id){
active_menu = 0;
setTimeout("time_out(" + id + ")",40);
}
function findLeft(obj) {
var curleft = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft;
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft;
}
}
return curleft;
}
function menu_on(id){
active_menu = id;
}
function menu_off(id){
active_menu = 0;
setTimeout("time_out(" + id + ")",40);
}
</script>
4. Add the CSS:
.menu{
top: 100px;
position: absolute;
width: 130px;
background: #b3a755;
line-height: 20px;
padding: 2px 0;
}
.submenu{
background: #b3a755;
padding: 2px;
display: block;
clear: both;
}
.submenu a{
width: 120px;
background: none;
}
.submenu a:hover{
background: #d0c897;
text-decoration: none;
}
.menu{top: expression('110px');}There is a limitation here - the menu is located at a fixed position from the window top (120px in Firefox, 110px in IE). You could get around this by detecting the offsetTop of the navigation element (just as we detected the offsetLeft in the script above). I didn't need it, so I didn't do it - but it can easily be done!). Note that the CSS here is purely cosmetic so you can modify it without messing up the functionality of the rollovers.
| [ 0 trackbacks ] | permalink | related link |




( 2.9 / 47 )
I have spent a couple of days playing with CakePHP and, I dare confess, I think I am hooked. Some of the things that leap out at me are:
* Scaffolding - great for quick admin systems which can be rendered-out to PHP code when your database schema is finished.
* Remote controllers - I have often used page classes so that I can call controller methods from another page, but CakePHP simplifies this process. You can retrieve data from another controller inside a view template.
* Multiple views per controller - this is a killer feature built into the framework. Change the URL to include "xml" or "rest" or "soap", for example, and have the controller automatically execute the relevant function to produce your Web service.
* Built in Unit testing with simpletest.
* Template helpers - AJAX, JavasScript and HTML helpers to render well formed tags that can be controlled via a centrlised INI file. Nice.
* External framework - you can store your cake files in a non-web viewable folder and, come update time, just overwrite the whole lot. Easy.
I just wish I had the time to reverse engineer all my current projects to Cake!
| [ 0 trackbacks ] | permalink | related link |




( 3.1 / 47 )The last thing you want to do when building an Ajax application is to bring your server to it's knees with too many simultaneous requests.
So, I have built a little queue into some of my ajax calls to ensure that no client makes more than a certain number of simultaneous Ajax connections. It's procedural and simple so anyone can use it.
Basically, there's a global variable that tracks the number of ajax calls in progress. When the function that makes the ajax connection is called and the number of connections is too high, a setTimeout is used to call the same function again in specified number of milliseconds.
I know it's easy, but that's why I did it that way. No subclasses, no version issues...
var ajax_conn = 0;
function load(x,y,z){
if (ajax_conn > 4 ){
setTimeout("load('" + x + "','" + y + "','" + z + "')",3000);
}else{
ajax_conn++;
var myAjax = new Ajax.Updater(
element_id,
the_ajax_url,
{
method: 'get',
parameters: 'x=' + x + "&y=" + "&z=" + z,
evalScripts: true,
onComplete: function(){load_done(x,y,z));}
}
);
}
}
function load_done(x,y,z){
ajax_conn--;
return function(originalRequest) {
return true;
}
}
Note that you have to use function() in the onComplete event or else the code will be executed immediately and you'll never get your limit reached. Likewise, the timeout is an evaluated function call.
If you're wondering why I'm passing the original parameters to the load_done function, its so I can use them to check that the update actually occurred. Plus, sometimes browsers won't re-render the object even though it is updated, but that is another story...
| [ 0 trackbacks ] | permalink | related link |




( 3 / 55 )Unfortunately my DBG problem is back.... this time whenever I throw any exception! I've got nothing from NuSphere that has helped so it looks like I'm stuck with the prospect of rebuilding the server - starting from a working virtual machine, of course :)
| [ 0 trackbacks ] | permalink | related link |




( 2.9 / 48 )This is a good one! The other day I noticed one of the sites on my server was crashing Apache intermittently. All the other sites were fine. Strangely enough I hadn't changed the code - so I assumed it was a configuration problem. So I repaired apache, upgraded to PHP 5.2.3 and had no luck. I isolated the problem to the NuSphere debugger (registered version) but rolling back to previous versions didn't fix the problem either.
Eventually I found a one-line post in the NuSphere forums regarding register_argc_argv. Apparently this has to be off for the debugger to work. I had turned it on a week ago while testing Moodle, which requires it. Another reason to abandon Moodle - at least on my server!
| [ 0 trackbacks ] | permalink | related link |




( 3 / 50 )
This took a little while to debug. Basically, IE was loading a page fine and then alerting a message that "Internet Explorer cannot open the Internet Site . . ." and " Operation aborted". This was impossible to debug correctly as the debugger never got a chance to run... plus the code was working fine in FireFox and a slightly modified version was ok in IE.
To cut to the chase, I was running some JavaScript at the end of the page that was messing with the DOM (the DynArch 'coolest DHTML calendar widget', specifically). By wrapping the calendar setup code in a function call, it was possible to delay the execution until the page had finished loading (by using the onload parameter of the BODY tag).
| [ 0 trackbacks ] | permalink | related link |




( 3.1 / 50 )
Some ideas are so obvious that you never think of them. Like this guy who has written a lean JavaScript library which wraps 1-pixel DIV elements around your content elements to make rounded corners and drop shadows possible without any images. The elements' colours can be styled with CSS and there are a few other configuration options like corner radius, drop shadow size etc. Overall, a fine effort (although I had some trouble getting mulitple boxes to render correctly in IE6, which may have been due to interference with all my other JavaScript libraries - Rico, Prototype, Scriptaculous, Prototype Windows - I use them all :)
| [ 0 trackbacks ] | permalink | related link |




( 3 / 47 )
This is related to my previous post on getting Rico to work with Prototype 1.5x. I found an alternate piece of code that works equally as well at http://rvalyi.blogspot.com/2007/02/prot ... ward.html. My proposed solution is a combination...
for (var name in headers) {
if (typeof headers[name] != 'function'){
try {
this.transport.setRequestHeader(name, headers[name]);
} catch (e) {
//do nothing
}
}
}This is at line 1094 in v1.51 final...
| [ 0 trackbacks ] | permalink | related link |




( 3 / 43 )I have become very fond of my OO PHP code. I even have classes that generate other classes. But every now and then I come up against a problem that requires a procedural solution. Today I profiled a search script that was taking a bit too long (20 seconds actually!) only to discover (well,I already knew it, but I had been avoiding running the profiler) that over 300 queries were being run against the database.
Even after memcached kicked in, there were still 80 quereies or so that needed to be addressed. These queries were embedded in low-level data access objects that ran a handful of database calls each time they were being instantiated. When you have 25 search result objects per page, that adds up pretty quickly.
Now, purists would say I had written poor OO code. Of course I had. So now I am writing methods for my search class that grab multiple records for all my search objects simultaneously. Then the objects are pieced back together to resemble the originals. The upside is much faster page execution. The fact of the matter, though, is that I am hacking my OO code to run procedurally, which is totally fine by me. Procedural code is always faster and OO code is always easier to maintain, it just that sometimes you need a bit of both...
| [ 0 trackbacks ] | permalink | related link |




( 3 / 45 )I scratched my head over this for awhile... the beforeProcessing array of callback functions in xajax 0.5 works a treat. I use it to run a security check on the request before allowing it access to my logic and data classes. Then, in certain function calls, I wanted to use the afterProcessing callback array to process the data sets being returned. This may be to filter, order, concatenate or simply double-check the data. Strangely, nothing I did seemed to work... so I dug into the xajax code a little only to discover that afterProcessing hasn't been implemented yet - although it is documented!
I guess that's what happens when you use beta software! Now, I could write it myself and submit it to the repository, couldn't I? That would be a nice way of saying thanks to the kind folks who developed the rest of the code.
| [ 0 trackbacks ] | permalink | related link |




( 2.9 / 50 )Back Next



Avatar



