I'm sure someone's done this before, but I'm working on making a fairly robust php xsl templating library. It's based on the php xsl extension, but I do some preprocessing of the xsl template so that I can have essentially "tag libraries" ala java. My pages are starting to look like jsp 2.0 xml pages (which I happen to really like). I'm now creating tags like this:
<lgt:input name="address" title="Address 1:" />
On the backend it's just translating these into xsl:call-template calls. It's the model of simplicity, and really removes my big beef with xml templating. Then I'm planning on using the registerPhpFunctions function of the xsl library to load in the new 'filter_data' extension. Fields such as my input tag above will call filter_data to help reduce the risk of cross-site scripting. I think with a good enough tag library this could really be a simple and elegant templating language that could easily be ported to java. Alas filter_data is not yet out in a production php version. I might have to hack together a placeholder for now.
Now I just need to convert my architecture to easily serialize my data to xml.
I love overloading the paths of my scripts. You might notice that this page has an html extension. The script itself is actually the file 'director' and everything after that are part of the query string masquerading as path elements. I'm always forgetting the proper request elements to do this in Java (requestURI or URL?) so I figured I'd put my standard function down here for posterity:
private String[] getExtendedPath(HttpServletRequest request) {
String uri = request.getRequestURI();
uri = uri.replaceFirst(request.getContextPath(), "");
uri = uri.replaceFirst(request.getServletPath() + "/", "");
return uri.split("/");
}
Note: While this article is under the Creative Commons license at the bottom of this page, the actual technique and code is released into the public domain. Please do with it whatever you wish (including using it in commercial products).
So debugging JavasSript in Internet Explorer has been a pain for quite a while. The tried and true method is to riddle to your code with alerts. This works well enough unless you're trying to figure out a sticky problem in a loop or with a mouseover.
I figured why not build a simple DHTML logger that could be easily included into a page and that would take care of popping up an absolute positioned logging div at the bottom of the page. Now all I need to do is include my .js file, and put in statements like this:
Note: While this article is under the Creative Commons license at the bottom of this page, the actual technique and code is released into the public domain. Please do with it whatever you wish (including using it in commercial products).
The Problem
The Suckerfish Dropdowns were originally described on A List Apart. They're great cross-browser drop-down menus that are implemented entirely in CSS. Unless of course your site needed to support Internet Explorer. To do so a small javascript hack was added. These menus looked great, required little code, and were fast. The problem occured when you put a menu on the same page as a form select. When the drop down covered the select in Internet Explorer, it suddenly hid behind it. An example can be found here:
Obviously this was a deal breaker for a lot of people.
The Solution
The Technique
It has been known for a while selects bleed through most divs and spans in Internet Explorer, you can place an iframe over the select and they no longer bleed through.
Let's say for example that there is a select in a form that we want to cover up with a warning message under certain conditions. In mozilla just a little positioning and the proper z-index value will allow the warning message to cover the select. In Internet Explorer the select shows through.
DANGER!
The traditional answer to this problem was to set visibility to hidden on the select when we wanted to cover it with the div. The problem occurs when the div doesn't completely cover the select. Suddenly your users have disappearing elements.
Before:
Nuclear Reactor Power:
After:
DANGER!
Nuclear Reactor Power:
It doesn't take the most astute user to wonder where the select just disappeared to, and it completely destroys the illusion that the Danger message is popping up on top of the select. Additionally if your site has a lot of forms you'll end up having custom javascript on every page to hide and unhide form elements which has the tendency to break.
The iframe is the one element that internet explorer respects as covering all elements. So all we have to do is add an iframe with the exact same dimensions as our warning popup and put it's z-index just under the div.
DANGER!
Nuclear Reactor Power:
So that's an elegant solution to the problem.
Adding to the Suckerfish Dropdowns
So how do we add this to the suckerfish dropdowns? First we add our iframe line, just below the bottom of our menu definition:
Well, now we have a big ugly iframe in the middle of the page. Let's go ahead and style that ID. We'll give it a z-index of 10. And hide it for the time being.
On mouse over we move the iframe to cover our menu. But the onmouseover event is happening on our title. So we need to get the submenu for the current menu (I leave it to you, the reader, to implement sub-sub menus):
var submenu = this.getElementsByTagName("UL");
If the submenu has length (i.e. has items) we go ahead and find the size of the menu. Internet Explorer has many properties that describe the size of a block element. You can find out more in Microsoft's article Measuring Element Dimension and Location. All we do is use these properties to size the iframe to the exact size of the submenu.
We also add the code to the onmouseout function to make the iframe invisible again.
iframe.style.display = "none";
And that's pretty much it. "Hold up", you say, "Now I just have a blank space where my menu once was. It is covering up the selects nicely though...". One last thing. We need to change the z-index of our submenu so that it will be on top of our iframe. All we need to do is change the style of our li tag.
li { /* all list items */
float: left;
position: relative;
width: 10em;
z-index: 20;
}
That's it. A simple solution that doesn't involve writing custom javascript for every page on your website. A modified version of the original page can be found below:
When the beasts of hell (marketing) compel you to finally build a popunder. And let's say this popunder must pop up 'x' number of times (where x > 1). If you use the same code each time you could run into a problem where IE stops popping up windows after 1. An example of this code is found below:
function popup {
window.open('ad.html', 'ad_window', 'height=100,width=100,top=100,left=100,resizable=yes,status=no');
}
To fix this problem, you must change your window name each time. I generally just use the session variable that tracks how many times I've popped the popup.
function popup {
window.open('ad.html', 'ad_window_', 'height=100,width=100,top=100,left=100,resizable=yes,status=no');
}