Thursday, March 29, 2012

jQuery Custom Effects

Although jQuery provides us with a few basic effects like slideDown/Up, fadeIn/Out etc. and a pretty powerful animate function to create animation/effects on any numeric CSS property, a lot of creative people have written some amazing effects/components that will take your breath away. While we do not plan to reinvent the wheel here but down the road, you may also need to create your own effect and would like to access it like

image

Surprisingly, being able to do so is not as difficult as it might seem at first, and can be achieved by adding a new function property to jQuery.fn object as below:

image

The above function simply extends the jQuery object by adding a new method in the jQuery prototype ( jQuery.fn object ). Before diving deep into the implementation, it is important to understand the concept of prototypal inheritance in JS and reading this article will open your eyes for sure.

Coming back, a naive implementation looks like

image 

Here, we delegate the actual work to animate method and toggle the height & opacity of the selected DOM element for the given speed if any, else a default of 400ms is used. It also allows us to specify a callback function to be called after the animation/effect is complete. To accomplish that, we first check whether the passed variable (fn) is actually a function using isFunction and then call the method passing this as the context.

Another important thing to note is that we are returning the jQuery object back from our function so that you can take advantage of chaining like:

image

So this wraps up a short and simple post on how to create custom effects by extending jQuery object. If you have any questions or comments, please leave them as comments.

Wednesday, February 15, 2012

Servlet Config, Context & Listeners

Why talk about Servlets when there are JSPs…. Right ? That’s what came into mind especially when we read about how JSPs are way more easy and fun to write. But Servlet exists for a more meaningful purpose that than just churn out HTML, for instance they act as a Controller for many frameworks. But this is not about how important Servlets are, rather today we will talk about ServletConfig, ServletContext and ServletContextListeners.
ServletConfig
ServletConfig is a helper object which we can use in our servlets to get configuration of a Servlet. The configuration can include things like Servlet name, its context (described below) and init-parameters. For example, consider the following servlet declaration in a Deployment Descriptor (DD)
image
So instead of hardcoding the feedback email in the servlet responsible for sending the feedback mail, we can simple configure it in the DD and the servlet can pick the value from using ServletConfig as shown below:
image
The container is responsible for creating a ServletConfig object per servlet and pass to it after it has been initialized so it would be good to note that we can not use this object until the init() method i.e. we cannot access these init params inside the servlet’s constructor.
ServletContext
ServletContext, on the other hand acts as a global helper and is not created once per servlet, rather it is created once per application (when an application is deployed) and is normally used to configure application level parameters amongst other things. A typical example would look like:
image
and would be accessed as
image
Now these params can be accessed across all the servlets and JSPs that the application deploys. There are a bunch of other useful information that you can grab from a ServletContext and all of that can be seen here.
ServletContextListener
What if I want to do some special handling when my web application is initialized (or deployed) or destroyed/removed ? The servlet spec gives you a way to hook into the lifecycle of your web application by implementing a ServletContextListener which can listen for these events and act accordingly. Following is an example that picks up the datasource configuration from DD and creates a corresponding DataSource object and save it in ServletContext so that it can be easily retrieved by any servlet wishing to perform a database operation:
The actual code of creating a DataSource object from the string is being left out as it does not serve any purpose for this example. This listener will have to be configured in the deployment descriptor so that it can listen and respond to the lifecycle events as:
image
There are many other types of listeners that we can write to handle different use cases viz. ServletRequestListener, ServletRequestAttributeListener, ServletContextAttributeListener to name a few but we will see them in action some other day.
Disclaimer
With Java EE Annotations, we really don’t have to configure a servlet in DD (as shown in the examples above). They are just there to make things easy to comprehend.

Saturday, December 17, 2011

HTML5 Native Drag ‘n’ Drop

HTML5 does not only mean a whole new world of tags (video, audio, header, footer, article, section etc.) and revolutionary technologies like Geolocation, Application cache, Canvas, Web Workers etc. but it also brings along a rich set of JavaScript API to developers.

Today, we witness one of the interesting feature that it provides; the capability of dragging and dropping elements natively without using any JS framework. The HTML5 spec defines the new events that we should catch in order to handle operations like

  1. Start of drag operation ( dragstart )
  2. Dragging content over another element ( dragover )
  3. Entering the drag area of another element ( dragenter )
  4. End of Drag operation ( drop )

If you have worked with a RIA-friendly language such as ActionScript, then you will found this to be very similar. Having said that, providing this drag and drop support in the browser itself is the reason behind the fame of HTML5.

Coming back, lets see some code in action. We have some images in our page which we want to drag and drop in div container. These images are tagged with class “dragMe” (so that we can attach event listeners to them). Similarly, we have a div container in which we are going to drop these images with an id of “dropOnMe”.

htmlCode

Things to note

  • draggable=true  -  By default, images and links are draggable in nature but I have added this attribute just to convey that any HTML5 element can be selected, dragged and dropped if you add this attribute to it. Also add following CSS to make it work across different browsers

draggableTrueCss

  • Custom data-* attributes  -  Again something, HTML5-blessed. It provides us the capability to define custom data-attributes on any element. Here we use it to define properties of individual images. More on custom data-attributes here.

Next, we add some event handlers to handle drag n drop related events we defined above:

1. Adding Drag Handlers

dragStart

We took a hold of all the elements that are to be dragged and attach to each, a drag handler which will be called whenever you click and try to drag that elements. In the handler, we update the event’s dataTransfer object and set custom properties in the JavaScript object, which we defined in the markup  (yes you guessed it right, we are going to use them in the drop handler)

2. Adding Drop Handlers

dropHandler

Note that we use both e.preventDefault() and return false in the function, to make it work across different browsers; this is needed to make sure that we cancel the default action that the browser will normally take, like surfing to that location (in case of a link). Apart from that, the code just retrieves the data set in dataTransfer object and display that using innerHTML of the div.

3. Adding handlers for dragover & dragenter

dragOverEnterHandlers

Again for making the code work across different browsers (tested on Firefox, IE and Chrome), we need to use both preventDefault() and also return false from the handler in order to inform the browser that you can drop and release the dragged item on this element for which the function is called.

A Lot More…

..can be achieved like customizing the drag icon and even drag and drop across different instances of same browser or even dragging from one browser and dropping in another browser. Stay tuned or check out the spec for more details.

Final Demo Looks like

Too bad that I don’t have a proper hosting solution, so you have to do with images, until you are passionate enough to write the above code yourself.

Initial Screen

image

Dragging an Item

image

Dropped it !!

image

We can add more spice to the tut by adding CSS and some other effects but in the hope that it would overshadow the concept, I emphasize on the minimal code needed for it.

Any suggestions, improvements or bugs are welcome as comments.

Saturday, November 19, 2011

CSS3 Media Queries

Need of Media Queries

Gone were those days when designers had the liberty to design or layout a web page for fixed/minimum resolution as most people would just use their desktop for browsing the web. In this mobile/tablet era, we cannot assume that the desktop would be the only user agent. A large number of users today use their “smartphones” or “tablets” for browsing the web and so it becomes crucial that your website looks as good when viewed from such a device.

Many websites today have different version of websites, one each for desktop and mobile. By detecting the user agent when the user visits the website for the first time, it can redirect them to the mobile version if he is browsing the web using his smartphone. But this solution comes with its own headache of maintaining separate presentation layers for separate mediums and fixing bugs in both !!

This is where Media Queries come into picture. They provide an elegant solution to the problem by providing the ability to switch the CSS based on the user agent or device’s width or orientation. In short, they make your web design adaptive and responsive to change.

Wow, that’s new !!

Not really !!. They were very much a part of CSS2 and HTML4 specification where they were limited to ‘print’ and ‘screen’ only (meaning using CSS2, you can only specify different style-sheets for rendering and printing a web page). But with CSS3, more media types are supported and different style-sheets can be applied based on

  • device-width and height
  • viewport-width and height
  • orientation
  • aspect-ratio
  • device aspect-ratio
  • resolution etc..

Without wasting more time, lets see an example. We will create a layout for a widescreen (desktop layout) and using media queries, we will change the layout and color the markup when we resize the browser (to simulate tablet and mobile size)

wideLayout Layout for Wide Screen

tabletLayout Layout for Tablet or Not So Wide Screen

phoneLayout Layout for a Mobile Device

In this lame-example, we have simple created a three-column layout for a widescreen or desktop, and changed it to a two-column layout for a tablet and coloured the sidebar blue (not to show my design skills of course, but to distinguish between the layouts) and then a stacked layout for a mobile device with red coloured div. and All this by simply switching the CSS for the same HTML file. All the code is explained below:

index.html

<!DOCTYPE HTML>
<head>

<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8" />
<link media="only screen and (min-width: 800px)" rel="stylesheet" href="css/desktop.css" />
<link media="only screen and (min-width: 400px) and (max-width: 800px)" rel="stylesheet" href="css/tablet.css" />
<link media="only screen and (max-width: 400px)" rel="stylesheet" href="css/phone.css" />

</head>
<body>

<div id="header"> Header </div>
<div id="sideBar"> Side Bar </div>
<div id="content"> Content </div>
<div id="extra"> Extra </div>

</body>
</html>

desktop.css

div
{
border: 1px solid;
}
body
{
width:1000px;
margin: auto;
}
#sideBar
{
float:left;
width:250px;
height:600px;
}
#content
{
float:left;
width:448px;
height:600px;
}
#extra
{
margin-left:700px;
width:296px;
height:600px;
}

tablet.css

div
{
border: 1px solid;
}
body
{
width:700px;
margin: auto;
}
#sideBar
{
float:left;
width:200px;
height:600px;
background-color:blue;
}
#content
{
margin-left:202px;
height:600px;
}
#extra
{
clear:both;
}

phone.css

div
{
border: 1px solid;
}
body
{
width:350px;
margin: auto;
}
#sideBar
{
height:100px;
}
#content
{
height:100px;
background-color:red;
}
#extra
{
height:100px;
}

This HTML files simple contains 4 Div’s in the body and head contains links to some style-sheets with media queries using link tag, lets see what these queries mean

<link rel="stylesheet" href="css/desktop.css" media="only screen and (min-width: 800px)" />

It can be read as include the “desktop.css” file if and only if the user agent has a screen and the minimum-width of the device is 800 pixels. Similarly,

<link rel="stylesheet" href="css/tablet.css" media="only screen and (min-width: 400px) and (max-width: 800px)" />

it says that include the “tablet.css” when the user agent has a screen and its width is between 400 to 800 pixels, something that we think should be suitable for a tablet.

<link rel="stylesheet" href="css/phone.css" media="only screen and (max-width: 400px)" />

On the same lines, in this rule, we ask the browser to use “phone.css” if the width is less than 400 pixels. Note that these rules are mutually exclusive because we want them to be like so. Each rule must evaluate to a boolean value and depending on that value, the CSS file is downloaded to the client machine and is used for rendering the HTML markup.

You can also embed the media-query inline in the CSS as follows:

<style type="text/css">       
@media only screen and (max-width: 400px)
{
#content
{
height:100px;
background-color:red;
}
}
</style>

Orientation

Similarly the CSS for phone.css can be broken down into two parts: phonePortrait.css and phoneLandscape.css by applying the following media queries

<link media="only screen and (max-width=400px) and (orientation=portrait)" rel="stylesheet" href="phonePortrait.css" />
<link media="only screen and (max-width=400px) and (orientation=landscape)" rel="stylesheet" href="phoneLandscape.css" />

Width Vs Device-width

"width" refers to the width of the viewport width (or the browser’s width) whereas the "device-width" refers to the width of the device (for desktop users, it is the dimensions of the monitor used, for mobile users, it is the dimensions of the smartphone used). Common sense says we should use device as the browser size may be less than the dimension of the device (esp on desktop)

The complication comes in case of mobiles, where the likes of iDevices and Androids incorrectly reports the viewport-width and also neglects the orientation of the device while calculating the width. To make things work, Apple introduced a new meta-tag: Viewport which is usually used as follows:

<meta name="viewport" content="width=device-width, initial-scale=1">

This instructs the device to report the viewport width equal to the actual width of the device and also take orientation into account while making that calculation. More details can be read here.

Browser Support

Surprisingly, majority of browsers do support media queries but for those who don’t, a JavaScript workaround can be applied which based on the width of the browser, changes the link’s href value to point to the correct CSS file.

Spec

A lot more can be achieved by media queries, all of which has been laid out in the spec here.

Disclaimer

The HTML & CSS used above in the example are merely for demonstrating the power of Media Queries and hence have been intentionally kept lame.