rulururu

post Yahoo YUI Subscribe to drag drop events

December 11th, 2006

Filed under: Code, Javascript — Brenton Alker @ 23:13

I’ve been playing with the Yahoo! UI (YUI) Javascript Library recently, it contains all the useful utilities you would expect from a JavaScript library, as well as some more gratuitous features.

While I can’t honestly say I have spent the time to compare Yahoo’s efforts to those of others, such as prototype or script.aculo.us, I have taken a liking to the way the Yahoo library feels… even if it’s just their coding style just feels a little funky.

One of the staple favourites of the library, is the Drag-Drop collection. The boss (and the client) always likes it when they can drag things around their web applications, especially when it’s not just pointless eye candy. After playing with the scripts for a while, I got the feeling that something was missing. It turned out to be the ability to subscribe to drag drop events. The general way Yahoo deals with the “event” handlers for the dragged or dropped items is by overriding functions that are called. This works quiet well for most things, but seeing as another important part of the library is event handling, including custom events, it seems a shame to let it go to waste and not allow events to be fired and subscribed to by the Drag-Drop classes.

With that in mind, and borrowing some concepts from an inspiring article I wrote a simple extension to the YAHOO.util.DD class that creates custom events that can be subscribed to by any number of listeners.

There were some issues with the apparent inconsistency of the arguments being passed between functions, but I normalised it as best I could and can up with this:


/**
* @extends YAHOO.util.DD
* @constructor
* @param {String} ElId the id of the element that will cause the resize
* @param {String} sGroup the group of related DragDrop items
* @param {Array} config the arbitrary configuration array
*/
YAHOO.Gnosis.DD = function(ElId, sGroup, config)
{
if (ElId)
{
this.init(ElId, sGroup, config);
}
}
YAHOO.extend(YAHOO.Gnosis.DD, YAHOO.util.DD,
{
onStart: new YAHOO.util.CustomEvent('onStart event'),
startDrag: function(x,y,z)
{
this.onStart.fire(x,y);
},
onComplete: new YAHOO.util.CustomEvent('onComplete event'),
endDrag: function(event)
{
this.onComplete.fire(event.clientX, event.clientY, event.target);
},
duringDrag: new YAHOO.util.CustomEvent('duringDrag event'),
onDrag: function(event)
{
this.duringDrag.fire(event.clientX, event.clientY, event.target);
}
});

(Gnosis is the framework, a collection of PHP and Javascript I am putting together as a basis for my development projects.)

It seems so obvious now. I’ve put together a basic example to show how this can be used.

This is only a start, there are plenty of other events that are worth overriding in this manner, for example the onDragEnter, onDragOut, onDragDrop, onDragOver, onMouseUp and onMouseDown functions (and a few more). That’s another thing I like about the YUI, it’s designed to be extended.

post Priority When Multiple CSS Classes are Applied

November 3rd, 2006

Filed under: Code, HTML/CSS, Javascript — Brenton Alker @ 16:16

I’ve used multiple CSS classes applied to an element on many occasion, but never run into the problem I found today. It seems counter to the CSS system as I understand it, but I’ve checked it out and it works like this.

I had a page, who’s table cells all had a CSS class that applied a background colour, some font attributes and what have you.
The class (from an external stylesheet file):

td.listCell
{

color: black;
background-color: grey;

}

was applied individually to each cell like:

<td class="listCell"></td>

I needed to apply a second class on certain cells to change the background colour, this is part of an on-page Javascript search. This page has lots of content, a large form, most of which is hidden and only small parts are used at a time. The search is supposed to highlight the cells that contain the text in the search field.

So, I added a searchHighlight style to the head of the page, making it look like:


<head>

<style type="text/css">
.searchHighlight { background-color: red }
</style>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
</head>

On my way I went, coded the javascript to search the table and add the ’searchHighlight’ class to the cells that needed hightlighting. Easy. Except it didn’t work.

When the Javascript found it’s target, and changed the class (by appending searchHighlight to the className) nothing happened. I checked the Javascript had worked, using my trusty FireBug source inspector. It had. So why no change in the style?

I changed the Javascript to replace (instead of append) the searchHighlight class, that worked, except it lost all it’s normal formatting, which I was almost willing to put up with, but not quite. I tried pre-pending the searchHighlight class (hoping the styles were in priority order), but to no avail.

So I created a simple test page, to make sure I was wasn’t going (more) insane, and that multiple CSS styles ever worked.
The test page looked like this:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Multiple CSS Class Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
<style type="text/css">
.normal { font-weight: bold; background-color: red;}
.special { background-color: blue }
</style>
</head>
<body>
<div class="normal">class=&quot;normal&quot;</div>
<div class="special">class=&quot;special&quot;</div>
<div class="normal special">class=&quot;normal special&quot;</div>
<div class="special normal">class=&quot;special normal&quot;</div>
</body>
</html>

The results are sort of what I expected… the top div (normal) is red and bold, the second (special) is blue and not bold, the other two are applying both, but the order of the classes in the list doesn’t matter. So they are getting the bold from the normal style, and the background from the special style.

Great. So why didn’t it work in my application? I finally figured it out. If, in my test, I reversed the order of the declaration of the styles (so that ’special’ is declared first) and the results are very different, the ’special’ class is ignored completely.

That’s right, the styles are applied in the order they are declared in the document, the order they are listed in the element has no effect. That I now understand (although I didn’t know it previously). But what I find more suprising, is that the order of stylesheets files that are linked is also subjected to this hierachy.

For example, if (from my test page) I remove the special style, and put it in an external style sheet, and include it like so:


<style type="text/css">
.normal { font-weight: bold; background-color: red;}
</style>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />

It works, but doing this doesn’t:


<link rel="stylesheet" type="text/css" href="stylesheet.css" />
<style type="text/css">
.normal { font-weight: bold; background-color: red;}
</style>

So the include is exactly the same as typing in the style in the file. Whereas I was under the impression that styles in the file took precedence over those in external (linked) stylesheets (where they overlap of course). But it seems I was wrong. Now I know.

ruldrurd
Powered by WordPress, Web Design by Laurentiu Piron
Entries (RSS) and Comments (RSS)