Raymond Camden justed posted an article on detecting jQuery AJAX operation using ColdFusion. I honor of that post, I thought I'd share the UDF I've been using in my application for quite some time:
The code uses the exact same logic the technique in Raymond's post, but having the code in a function makes your detection code a lot easier to read.
Now when you want to detect if a request came from an AJAX operation, you can just do:
Doesn't get any easier than that!
If you've ever tried using the "mouseover" tipStyle in <cfchart /> with an image, you may have noticed there are several issues with the JavaScript that the WebCharts3D engine generates:
Here we can see an example of the tooltip running off the screen:
You can see the scrollbar and how the tip goes off the edge of the screen. Obviously, this isn't very usable. To fix the problem, we're going to have to override the native mouse handler functions. Unfortunately, this isn't particularly easy to fix because when the <cfchart /> is executed, it embeds an external call to a JavaScript file which looks something like:
This makes overriding the functions a bit tricky. You can override the functions during the window.onload event, but what happens is you're loading your chart via AJAX? Plus, why load JS you have no intention on using?
The solution is to strip out the <script /> call. You can do this by wrapping your <cfchart /> call inside the <cfsavecontent /> tag. This will give you a string containing the HTML you'll need to embed in the page. You can then use a regular expression to strip the <script /> from the output before writing it to the output stream. What you end up with is some source code that looks like:
By using a regular expression we're able to completely remove the reference to external script that contains the mouse handlers. Now we've got to replace the functionality with code that actually works.
The WebCharts3D script file contains a number of functions, but there are only two functions that are actually used by the HTML generated: xx_set_visible() and xx_move_tag().
The xx_set_visible() function handles hiding/showing the tooltip and the xx_move_tag() function handles positioning the tooltip on the screen.
Since my site is already using jQuery, I'm going to leverage jQuery to handle the positioning of the tooltip. In the new code I'm going to:
So what does our code look like? Here it is:
That's all there is to it! Now our tooltips will never run off the edge of the page! Here's the result of our new custom mouse handlers:
Internet Explorer 7 has some issues with fading transparent PNGs. If you've gotten to the this page because you're seeing a black border where the transparent edges in your PNG are, then here are some tips for fixing the problem:
The above tips will usually sort out any fading issues I'm having in IE7.
My current employer (Giva, Inc) has released another jQuery plug-in today called the Linkselect jQuery Plug-in. This plug-in converts a normal <select /> element into a component that can be highly stylized via CSS. While there are a number of similar plug-ins already, there are a several of key differences which we think make this unique:
We've put together an example page that demos many of the features and how to use the plug-in.
I seem to be writing a lot of code as of late that needs to check if a certain element is a child of another element. This is extremely useful in drag and drop operations (for determine where an element is being dropped) or if you want to make sure that a global event was trigger on a specific set of elements (I use this to check if a document.click occurred on a specific container.)
While jQuery makes this easy enough to do, I don't find the code very readable or reusable so I started using the following snippet:
What this does is checks to see if the current element is a child of the specified selector. For example:
This function definitely comes in handy when doing any sort of event delegation and I hope it eventually makes its way into the jQuery core in some form or another.
A few weeks ago I needed a jQuery swap() function for some drag and drop code I was writing. While it would have been easy enough to whip up a quick little function, I found this little snippet courtesy of Brandon Aaron's blog:
This particular method only works with the first DOM element in each of the jQuery objects. Using the code is easy enough, the following example would swap the first and last nodes in an unordered list who's id is "list".
I'm working on an interface that uses drag-n-drop to arrange how some fields appear on the page. The page basically has two containers—a canvas and a toolbar. You drag fields from the toolbar to the canvas, and then you can position the fields in the canvas to order them anyway you want. To remove a field, just drag it from the canvas back to the toolbar.
One of the things I wanted to implement was to always make sure the fields in the toolbar stayed in alphabetically ordered. While I knew it would be easy enough to whip up a sorting function, I decided to first search the jQuery Plug-ins to see if I could find something that was already written. That's when I found the TinySort jQuery Plug-in.
This plug-in allows you to sort an number of sibling DOM elements and you can sort by either it's text, an attribute or even a child element. Here's some examples (taken from the Sjeiti website:)
The "place" option (as seen in the last example) is interesting because it allows you to control how the matching siblings are ordered in context to their non-matching siblings. In most cases you're probably sorting all of the children items of an element, but there may be times when you're ignoring certain elements (like disabled items.)
There are lots of working examples on the authors home page. If you need a way to quickly sort some elements on the page, I definitely recommend checking this plug-in out. It seems to have every option one would need to implement some basic sorting to some generic elements on a page.
I just installed the lastest nightly build of Firefox v3.1a2pre, because I was very curious to see how an application I've been working on (which is very JavaScript intensive) would work with Mozilla's new TraceMonkey (JavaScript JIT) engine.
I'm extremely impressed by the performance of the JIT. The application I'm working has a lot of dependencies on JS behaviors that are initialized on page load. I've spent a lot of time to minimize the the impact of this code on page load, but there can be a good 250-1250ms delay (depending on PC hardware, the configuration of the page, etc.) before every element on the page is completely usable. So while there is a delay, I've designed things so that it should be pretty transparent to the user because they see the page immediately and by the time they'd actually go to do anything on the page, everything should be initialized.
While just testing the page under the latest nightly Firefox 3.1 build, this page is blazingly fast. It's so fast, I generally can't even see the initialization occur. I'm very impressed and I think things will only get better.
The addition of JavaScript JIT compilers is just a natural progression and I think it'll be the way we see all browsers head. The dependence on JavaScript in web design is greater than ever and with good reason—it allows us to build better web-based applications. However, with the greater dependence on the usage of JavaScript, it can be a really battle at times to tweak performance out of an application. It looks like TraceMonkey is making great strides in handling this problem natively in the browser.
I definitely recommend reading John Resig's blog post on TraceMonkey. It contains a lot of technical detail as well as a brief overview on how it all works.
I ran into a really weird bug this morning. I was having an issue with a jQuery plug-in I wrote, where for some reason IE7 was not triggering the onmouseover event properly. After spending a bunch of time trying to track down the problem, I finally realized that it wasn't triggering the event until it got inside the padding of the element—which is the wrong behavior.
I whipped up a quick test case of a <div> with onmouseevent and some padding, but that worked as expected (with the event firing as soon as it reached the padding of the element.) As I started to debug the problem, I added a background color to the root element in order to see if I could tell when the even actually fired. However, as soon as I added the background-color, the event started firing correctly.
I'm not exactly sure what combination of HTML/CSS is causing the problem. I've been trying to to put together a straightforward example that illustrates the problem, but I've yet to be able to recreate without really complex code.
I believe the problem is related to having an absolutely positioned parent element with relatively positioned children and then moving the parent item's position in the DOM. Even stranger was that if I hide the entire content and would re-show it, everything would work properly.
It sounds like it's a pretty obscure buried bug, but if you're ever having problems getting an event to fire properly in IE7, try defining a background-color for the element to see if that fixes the problem.
Addressing some more behavior issues being brought up (and adding a few new features,) Giva just released a new version of the mcDropdown plug-in:
Just a quick note that over the weekend I updated the code to the jQuery mcDropdown Plug-in to v1.1a. The update contains:
Back in April, I posted a preview of a multicolumn dropdown plug-in I was developing for a project at work. Well today we finally officially released the mcDropdown plug-in. I was hoping to release the plug-in sooner, but other projects took precedence and releasing it just got delayed.
I'm really proud of the plug-in and think it provides a really unique form control.
Here's a list of the features:
You can view a live example over at the plug-in page.
If you like what you see, make sure to digg it.
Massimiliano Balestrieri posted a neat little script today in honor of Firefox 3 Download Day 2008. The concept is simple, change the appearance of the page in IE6 slightly by making it show up in black and white. So if you really want to protest IE6, this is a comical way to do it on your blog. I just find the effect hysterical.
/* * * Black'n'White plugin 1.0 * $Date: 2008-06-17 15:38:15 +0200 (mar, 17 giu 2008) $ * $Rev: 177 $ * @requires jQuery v1.2.6 * * Copyright (c) 2008 Massimiliano Balestrieri * Examples and docs at: http://maxb.net/blog/ * Licensed GPL licenses: * http://www.gnu.org/licenses/gpl.html * */ if(!window.BlacknWhite) var BlacknWhite = {}; BlacknWhite = { init : function(options) { options = jQuery.extend({minor : 7}, options); if(jQuery.browser.msie && jQuery.browser.version < options.minor) jQuery("html").css("filter","gray"); } }; jQuery(document).ready(function(){ BlacknWhite.init(); //BlacknWhite.init({minor : 8}); });
You'll need jQuery on your page to use this script (at least as-is) but it would be simple to adapt to either plain JS or another JS framework. The only thing really going on is it's setting a filter on the <html/> tag to show the whole page in gray.
I've added this script to this blog entry so you can easily view the effect.
One of the UI components I'm in need of from time to time, is a hierarchy tree where the user needs to select an option. While there are plenty of "tree" scripts, they take up a lot of screen reality and involve lots of clicking. I've always thought I could come up with a better UI component, so we started working on script that would create downdown component that supported hierarchical data.
The problem with doing a dropdown is that if you have a lot of data (which is often the case for us) data really quickly rolls off the screen. To resolve this issue, we split the list into multiple columns when there's too much data. Here's a screenshot of what the dropdown looks like:
I've been pretty quite the past two weeks. I've been really plugging away doing a lot of client-side UI programming in jQuery. I'm working on a complete revamp of some portions of our application and than means modernizing the UI.
One of the tasks I needed to accomplish was to create a UI component that would allow for sortable, collapsible table rows. jQuery already has a very good (an official) plug-in for sorting column rows called tablesorter.js. The Tablesorter is part of the jQuery UI project and allows for sorting of multiple columns—which is a really nice feature.
However, the current tablesorter.js codebase does not have anything in place to allow for "children" rows—which is needed to provide a collapsible architecture. Essentially I need a way to tell certain rows that they belong with the row above.
After playing around with some different variations I finally came up with a solution that worked elegantly and had minimal impact on the Tablesorter codebase. The way I solved the problem is to add a class to "children" rows, which tells the Tablesorter plug-in to include the row as part of the last row that does not have the "child" class. This allows me to actually have multiple children rows, that are all grouped together and ignored by the sorting algorithms.
I'm working with Christian Bach to get the mods added to the official codebase—and it looks like that might happen as early as next week. I've upload my Tablesorter mod and an example of implementing collapsible rows.
The example uses the "Pager" add-on for Tablesorter, just to show my mod attempted not to break backwards compatibility.
If you have any comments, please leave them. They will only help me and Christian in the long run.