Christian Heilmann

You are currently browsing the archives for the General category.

Archive for the ‘General’ Category

Monitoring element size and position with the YUI

Tuesday, August 28th, 2007

One of the lesser known gems of the Yahoo User Interface library is the Region utility which is part of the Dom utility. The documentation only mentions it and what it gives you but doesn’t quite live up to how powerful it can be in day to day interface development.

Please refer to the accompanying demo page about YUI Region to see the examples in this post in action.

Retrieving an element’s region

The Region utility returns you the region occupied by a certain element in the browser. You use it by sending the ID, a reference to an element or an array of elements to the getRegion() method:


var region = YAHOO.util.Dom.getRegion('reg1');

The method returns an object with several properties and some methods. The properties are:

top

the amount of pixels between the top side of the element and the top left of the window.

bottom

the amount of pixels between the bottom side of the element and the top left of the window.

right

the amount of pixels between the right side of the element and the top left of the window.

left

the amount of pixels between the left side of the element and the top left of the window.

0,1

Shortcuts for the left and top property (added for compatibility with YAHOO.util.Dom.setXY()

The really cool thing about Region is that it gives you that information regardless of the positioning of the element (static,relative,absolute,fixed). A possible result would be:


Region {top: 109, right: 571, bottom: 177, left: 371};

Check the “Get occupied space of ” link on the demo page to try it out.

Determining element overlap

Furthermore the object has several methods:

getArea()

returns the total amount of pixels occupied by the region.

contains()

returns a Boolean if a region fully contains another region

union()

returns the union region of two regions, which is the screen estate containing both of them

intersect()

returns the region that two regions have in common

The contains() method is pretty useful as it can tell you when and if an element is visually inside the other one. This can help immensely for drag and drop interfaces. You use it by defining the two regions and it returns a Boolean.


reg1 = YAHOO.util.Dom.getRegion('reg1');
reg2 = YAHOO.util.Dom.getRegion('reg2');
var contains = reg1.contains(reg2);

If the element with the id reg2 is visually completely inside the element with the id reg1 contains will be true, otherwise it is false.
You can try this out by clicking the “Is fully inside ?” link on the demo page to this post. Also resize the element with the “Resize#2” to see the change when you click the test link again and reset the element with “Undo Resize ”.

The union() method returns the screen region that encompasses both the elements. This is very useful if you want to cover both regardless of their positioning.


reg1 = YAHOO.util.Dom.getRegion('reg1');
reg2 = YAHOO.util.Dom.getRegion('reg2');
var contains = reg1.union(reg2);

The result is another region object.

The intersect() method returns the screen region that is covered by both the elements. This is very useful to determine to what percentage two elements overlap or highlight the overlapping section.


reg1 = YAHOO.util.Dom.getRegion('reg1');
reg2 = YAHOO.util.Dom.getRegion('reg2');
var contains = reg1.intersect(reg2);

The result is another region object.

You can test both methods by clicking the “Show section containing both” and “Show section occupied by both” links on the accompanying demo page about YUI Region.

Calculating element dimensions

You can use the region information for a lot of different things. Probably one of the most useful is to get the width and height of the element in a reliable fashion. All you need to do to calculate them is to substract left from right for the width and top from bottom for the height:


var region = YAHOO.util.Dom.getRegion('reg1');
var elmHeight = region.bottom - region.top;
var elmWidth = region.right - region.left;

Check the “Get dimensions of ” link on the demo page to try it out.

You can use this to for example read out the size of form elements and fix tooltips to their correct size. Say you have a DIV with the ID reg2 and a select box with the ID selectbox. The following script would position the DIV under and make it as wide as the selectbox.


var sel = YAHOO.util.Dom.get('selectbox');
var elm = YAHOO.util.Dom.get('reg2');
var size = YAHOO.util.Dom.getRegion(sel);
YAHOO.util.Dom.setXY(elm,[size.left,size.bottom]);
YAHOO.util.Dom.setStyle(elm,'width',(size.right-size.left-20)+'px');

You can try this out by clicking the “Resize to the size of the select” link on the demo page to this post.

Notice the -20 in the last line, this is a fix as the element has a padding of 10 pixels. This is neccesary as you cannot easily and reliably read out the padding of the element automatically unless you also set it with JavaScript.

This is just a teaser on what you can use Region for. Widgets like the YUI menu or container use it constantly to determine if certain functionality can be displayed or not.

[tags]YUI,dom,manipulation,positioning,css,formelements,interface,fixing,webdevtrick[/tags]

Being humbled talking about JavaScript – and more to come at @media Ajax

Wednesday, August 22nd, 2007

I am currently in [tag]Hongkong[/tag] training colleagues from Asia on how we do things in Europe. Or so I thought. I came here with [tag]Douglas Crockford[/tag] and [tag]Nate Koechley[/tag] to show what we’ve done in the US and the UK to make life easier for developers to create web sites and applications.

When we asked around for each team to show us what they work on and what things they needed input on we were in for a big surprise. It is pretty amazing what kind of implementations you see around Asian web sites and how naturally the developers here used the recommended technologies without ever asking or telling us about it. I can’t wait to bring back the findings the teams here documented to share with the folks back home.

That said, I am also learning about problems us latin font users don’t get and only come up when you use Mandarin or Korean. All in all this is a great experience, both in terms of sharing information and realizing how much of your work for the web standards movement gets used without you ever being the wiser. For example I found a translated PDF of one of my articles I didn’t know before.

Talking about being humbled talking about JavaScript, things are happening on the [tag]@mediaAjax[/tag] web site. The sessions are mostly defined and the already impressive list of speakers got some more interesting additions. Specifically the [tag]Ajaxian[/tag] folk [tag]Dion Almaer[/tag] & [tag]Ben Galbraith[/tag] and [tag]Alex Russell[/tag] of [tag]Dojo[/tag] join well-known JS speakers and scarcely seen people on the European speaker circuit. If you want to talk JS and Ajax, I am quite sure there is hardly any better summit to go to this year.

Again with the Module Pattern – reveal something to the world

Wednesday, August 22nd, 2007

Not too long ago I was raving about the beauty of the Module Pattern in JavaScript and the annoyance I felt with it when it comes to repetition of long namespaces when calling or reading public methods and properties from other public methods and properties.

To recap, the “classic” Module Pattern means you define a variable as an anonymous function that gets immediately called with (). You define private functions and variables and return your public variables and functions as properties and methods of an anonymous object:

var classicModulePattern = function(){
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  }
  return {
    publicVar:2,
    publicFunction:function(){
      classicModulePattern.anotherPublicFunction();   
    },
    anotherPublicFunction:function(){
      privateFunction();
    }
  }
}();
classicModulePattern.publicFunction();

The beef I had with that is that you need to repeat the name of the main object when you want to call one public method from another or access public variables. The other bit I was annoyed about is having to switch to object literal notation for the things you want to make public.

Inspired by the comments on the blog post on the YUI about the module pattern and pubstandards, I started advocating using a named object called pub to append methods and properties to before returning it. That way you can call public methods via the pub.methodName shortcut notation instead of repeating the main name:

var namedObjectModulePattern = function(){
  var pub = {};
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  };
  pub.publicVar = 2;
  pub.publicFunction = function(){
  pub.anotherPublicFunction();    
  };
  pub.anotherPublicFunction = function(){
    privateFunction();
  };
  return pub;
}();
namedObjectModulePattern.publicFunction();

During a Q&A session in a training in Hongkong yesterday I showed this to Douglas Crockford and asked him what he thinks of it. He didn’t mind the idea, but considered even the pub object redundant.

There is another option which I am hereby calling the Revealing Module Pattern. In this permutation you simply define all your functions and variables in the private scope and return an anonymous object at the end of the module with pointers to the private variables and functions you want to reveal as public:

var revealingModulePattern = function(){
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  };
  var publicVar = 2;
  function publicFunction(){
    anotherPublicFunction();    
  };
  function anotherPublicFunction(){
    privateFunction();
  };
  // reveal all things private by assigning public pointers
  return {
    publicFunction:publicFunction,
    publicVar:publicVar,
    anotherPublicFunction:anotherPublicFunction
  }
}();
revealingModulePattern.publicFunction();

This keeps the syntax of the whole script consistent and makes it obvious at the end which of the functions and variables can be accessed publicly. The other benefit is that you can reveal private functions with other, more specific names if you wanted to.

var revealingModulePattern = function(){
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  };
  var publicVar = 2;
  function publicFunction(){
    anotherPublicFunction();    
  };
  function anotherPublicFunction(){
    privateFunction();
  };
  // reveal all things private by assigning public pointers
  return {
    init:publicFunction,
    count:publicVar,
    increase:anotherPublicFunction
  }
}();
revealingModulePattern.init();

You can even return values as the public properties by calling the functions in the anonymous object:

var revealingModulePattern = function(){
  var privateVar = 1;
  function privateFunction(){
    alert('private');
  };
  var publicVar = 2;
  function publicFunction(){
    anotherPublicFunction();    
  };
  function anotherPublicFunction(){
    privateFunction();
  };
  function getCurrentState(){
    return 2;
  };
  // reveal all things private by assigning public pointers
  return {
    init:publicFunction,
    count:publicVar,
    increase:anotherPublicFunction,
    current:getCurrentState()
  }
}();
alert(revealingModulePattern.current) 
// => 2
revealingModulePattern.init();

Of course the example names here are far from what I would use in a real script, but it shows the power of this pattern.

The endless talk about code syntax standards and an idea to get there quicker

Tuesday, August 14th, 2007

As the readers of this blog know, I am currently working in a new team that defines the code standards, best practices and methodologies to follow for the European web development in our company. We’re trying to achieve that using a mixture of commonly regarded best practices and findings in different projects after analyzing their outcome.

There are several things that are a no-brainer, like web standards compliance, unobtrusive scripting, namespacing and so on and so forth. Where it starts to get tricky is defining code syntax standards to follow. Tabs or Spaces? Curly braces on the same line or on the next? Spaces around equal signs or not? Many a religious debate and many a working hour has been held and wasted over these.

A big portion of the endless debate is because code syntax means personal style and people are ready to defend their solution to the issue to the bitter end. A lot of times the solution does not get justified by arguments either but gets sold as “this is how I always did it”.

However, there are several arguments that speak for following a certain code syntax:

  • Code can be easily handed over to other developers
  • Version control works without false positives (a tab changed to a space is a change, but it really isn’t, now is it?)

Now, what can be done about this dilemma? Either you find a concensus and make it mandatory, or you try another option:

  • You define a standardized way of coding
  • You make sure that people create valid code
  • You also make sure that the code can be minified (all whitespace removed) as that should be done with live code to save on file size anyway.
  • You collect the different desired syntax styles
  • You offer plugins for the different editing tools in place (notepad++, dreamweaver, eclipse, textmate…) that can convert the code between the different styles by minifying and re-styling (code beautification).
  • You make it mandatory for developers to run the beautifier that creates the standard syntax before submitting the code to the version control.

It is a bit of work up-front, but it means that:

  • People can code the way they want to
  • Code will be ready to be minified for the live system
  • Developers who buy into the agreed standard won’t have to do anything extra.
  • Other developers have tools at their disposal for quick conversion

What are your thoughts? Worth persuing and sharing the plugins?

[tags]standards,standardization,code,syntax,teamwork,codesyntax,versioncontrol,methodology,workflow[/tags]

Flirting with the Flash Community

Thursday, August 9th, 2007

It doesn’t happen often that you get invited to speak at a conference about a technology you never programmed yourself. However, I will give a talk at the Flashforum Konferenz Cologne this September. I got a bit daring and came up with a topic that I couldn’t believe they signed off called Emancipated JavaScript and the Coming Out of the Flash community.

What this means is that I will try to spark a bit more enthusiasm in the Flash community to go out there and give other developers a run for their money when it comes to creating Mashups and talk about their technology as a good option when it comes to creating online applications with rich user interfaces.

While I have worked with Flash developers in the past, I always came across a certain mistrust in the technology from the business side. For example a financial application we developed didn’t get the Flex interface we prototyped because of “Flash being Active-X” and got replaced by an inaccessible obtrusive 3MB big JavaScript solution.

Working closely and loosely with amazingly talented Flash developers like Steven Webster, Ian McBurnie, Aral Balkan and Niqui Merret made me aware that there is the same “big thing to happen” feeling and enthusiasm that shook the JavaScript community some years ago.

JavaScript developers discarded the stigmata of the “move stuff around, require certain browser settings and pop things up” days of DHTML and embraced Dom Scripting and later on Ajax taking over the web application world by storm. By now having JavaScript as an interest on your CV does not get you a confused shake of the head but is actually sought after by headhunters.

There are a lot of parallels in the misunderstandings of JavaScript as a technology in the past and those that keep Flash from being a mainstream developer technology and I will try to show them and offer options to set these straight.

Currently hot technologies like maps and online video show a lot of potential but can become even better with proper Flex or Flash applications. Flash already does help JavaScript and HTML based applications like the flickr uploader to work around JS restrictions. In terms of accessibility, Flash applications can be a lot better than Ajax apps which simulate rich interfaces by using HTML and CSS and dynamically changing the latter.

While people woo the webdeveloper world with JavaScript and Canvas effects that are quite common inside Flash and nothing new you don’t see many Flash apps being featured on web development news blogs and mailing lists. Yes, Flash is not a web standard, but I personally think it is time we realise that we miss out a lot of fun and options that we just cannot achieve with JS and HTML, or simply simulate badly.

Let’s see how it goes. :)

[tags]flash,conference,talk,presentation,evangelism,domscripting,javascript,flashforumkonferenz[/tags]