Spot the web RSS 2.0
# Monday, March 17, 2008

If you've done any Ajax development then you know that much of the loading of data is done in the background. This is great from a developers stand point, but from a users stand point it can be confusing as to what is happening while the data is being loaded. The solution to this is to show a loading indicator.

A loading indicator is a great idea and a nice animated image that could be hidden would be nice. However, if you are like most developers making a nice animated image may not be your strongest point. Well, today while seeing what was getting bookmarked on del.icio.us, using the del.icio.us Spy, I found an interesting and simple service that makes it very easy to get a nice looking loading indicator.

The service is call Ajaxload and is very easy to use. You simply choose the loading icon that you like and the background/foreground colors (you can even have the background transparent). Then you just save it to your computer using the "Download It" button and then you have your own customized loading indicator.

You can go to the service by clicking here.

If you have used this or a similar service I would love to hear about your experience with it (you can leave a comment, or if you would like you can write a blog post about it on this blog, using your free Ajaxonomy account). So, remember that your users would love to see a loading indicator when it is appropriate.

Monday, March 17, 2008 10:33:41 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
AJAX | Programming | Web 2.0 | Web Design
# Monday, March 10, 2008

This article discusses the delegate type and how it can be used to point to methods in the application which can be invoked at later time. This article demonstrates also the delegate ability to multicast and delegate covariance.

A delegate is a type-safe object that can point to another method (or possibly multiple methods) in the application, which can be invoked at later time.

Delegates also can invoke methods Asynchronously.

A delegate type maintains three important pices of information :

  1. The name of the method on which it make calls.
  2. Any argument (if any) of this method.
  3. The return value (if any) of this method.

Defining a Delegate in C#

when you want to create a delegate in C# you make use of delegate keyword.

The name of your delegate can be whatever you desire. However, you must define the delegate to match the signature of the method it will point to. fo example the following delegate can point to any method taking two integers and returning an integer.

public delegate int DelegateName(int x, int y);

A Delegate Usage Example

namespace MyFirstDelegate

{

    //This delegate can point to any method,

    //taking two integers and returning an

    //integer.

    public delegate int MyDelegate(int x, int y);

    //This class contains methods that MyDelegate will point to.

    public class MyClass

    {

        public static int Add(int x, int y)

        {

            return x + y;

        }

        public static int Multiply(int x, int y)

        {

            return x * y;

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //Create an Instance of MyDelegate

            //that points to MyClass.Add().

            MyDelegate del1 = new MyDelegate(MyClass.Add);

            //Invoke Add() method using the delegate.

            int addResult = del1(5, 5);

            Console.WriteLine("5 + 5 = {0}\n", addResult);

            //Create an Instance of MyDelegate

            //that points to MyClass.Multiply().

            MyDelegate del2 = new MyDelegate(MyClass.Multiply);

            //Invoke Multiply() method using the delegate.

            int multiplyResult = del2(5, 5);

            Console.WriteLine("5 X 5 = {0}", multiplyResult);

            Console.ReadLine();

        }

    }
}

Delegate ability to Multicast

Delegate ability to multicast mean that a delegate object can maintain a list of methods to call, rather than a single method
if you want to add a method to the invocation list of a delegate object , you simply make use of the overloaded += operator, and if you want to remove a method from the invocation list you make use of the overloaded operator -= .

Note:Multicast delegate must contain only methods that return void, or you will get a run time exception.

A Multicast Delegate Example

namespace MyMulticastDelegate

{

    //this delegate will be used to call more than one

    //method at once

    public delegate void MulticastDelegate(int x, int y);

    //This class contains methods that MyDelegate will point to.

    public class MyClass

    {

        public static void Add(int x, int y)

        {

            Console.WriteLine("You are in Add() Method");

            Console.WriteLine("{0} + {1} = {2}\n", x, y, x + y);

        }

        public static void Multiply(int x, int y)

        {

            Console.WriteLine("You are in Multiply() Method");

            Console.WriteLine("{0} X {1} = {2}", x, y, x * y);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //Create an Instance of MulticastDelegate

            //that points to MyClass.Add().

            MulticastDelegate del = new MulticastDelegate(MyClass.Add);

            //using the same instance of MulticastDelegate

            //to call MyClass.Multibly() by adding it to it's

            //invocation list.

            del += new MulticastDelegate(MyClass.Multiply);

            //Invoke Add() and  Multiply() methods using the delegate.

            //Note that these methods must have a void return vlue

            Console.WriteLine("****calling Add() and Multibly() Methods.****\n\n");

            del(5, 5);

 

            //removing the Add() method from the invocation list

            del -= new MulticastDelegate(MyClass.Add);

            Console.WriteLine("\n\n****Add() Method removed.****\n\n");

            //this will invoke the Multibly() method only.

            del(5, 5);

        }

    }

}

Delegate Covariance

Assume you are designing a delegate that can point to methods returning a custom class type:

//Define a delegate pointing to methods returning Employee types.

public delegate Employee EmployeeDelegate();

if you were to derive a new class from Employee Type named SalesEmployee and wish to create a delegate type that can point to methods returning this class type you would be required to define an entirely new delegate to do so

//a new  delegate pointing to methods returning SalesEmployee types.

public delegate SalesEmployee SalesEmployeeDelegate();

Example

namespace MyEmployeesDelegate

{

    //Define a delegate pointing to methods returning Employee types.

    public delegate Employee EmployeeDelegate();

    //a new  delegate pointing to methods returning SalesEmployee types.

    public delegate SalesEmployee SalesEmployeeDelegate();

    class Program

    {

        public static Employee GetEmployee()

        {

            return new Employee();

        }

        public static SalesEmployee GetSalesEmployee()

        {

            return new SalesEmployee();

        }

        static void Main(string[] args)

        {

            EmployeeDelegate empDel = new EmployeeDelegate(GetEmployee);

            Employee emp = empDel();

            SalesEmployeeDelegate salesEmpDel = new SalesEmployeeDelegate(GetSalesEmployee);

            SalesEmployee emp2 = salesEmpDel();

        }

    }

    public class Employee

    {

        protected string firstName;

        protected string lastName;

        protected int Age;

        public Employee()

        { }

        public Employee(string fName, string lName, int age)

        {

            this.firstName = fName;

            this.lastName = lName;

            this.Age = age;

        }

 

    }

    public class SalesEmployee : Employee

    {

        protected int salesNumber;

        public SalesEmployee()

        { }

        public SalesEmployee(string fName, string lName, int age, int sNumber): base(fName, lName, age)

        {

            this.salesNumber = sNumber;

        }

    }

}

It would be ideal to build a single delegate type that can point to methods returning either Employee or SelesEmployee types.
Covariance allows you to build a single delegate that can point to methods returning class types related by classical inheritance.

Delegate Covariance Example

namespace DelegateCovariance

{

    //Define a single delegate that may return an Employee

    // or SalesEmployee

    public delegate Employee EmployeeDelegate();

    class Program

    {

        public static Employee GetEmployee()

        {

            return new Employee();

        }

        public static SalesEmployee GetSalesEmployee()

        {

            return new SalesEmployee();

        }

        static void Main(string[] args)

        {

            EmployeeDelegate emp = new EmployeeDelegate(GetEmployee);

            Employee emp1 = emp();

            EmployeeDelegate empB = new EmployeeDelegate(GetSalesEmployee);

            //to obtain a derived type you must perform an explicit cast.

            SalesEmployee emp2 = (SalesEmployee)empB();

        }

    }

    public class Employee

    {

        protected string firstName;

        protected string lastName;

        protected int Age;

        public Employee()

        { }

        public Employee(string fName, string lName, int age)

        {

            this.firstName = fName;

            this.lastName = lName;

            this.Age = age;

        }

    }

    public class SalesEmployee : Employee

    {

        protected int salesNumber;

        public SalesEmployee()

        { }

        public SalesEmployee(string fName, string lName, int age, int sNumber): base(fName, lName, age)

        {

            this.salesNumber = sNumber;

        }

    }

}

I hope you are now have a good idea with the creation and usage of delegates types.

Monday, March 10, 2008 10:28:46 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
.Net | AJAX | Microsoft | Programming | C#
# Sunday, March 09, 2008

A common - and desirable - technique for constructing JavaScript-based web applications is that of progressive enhancement: only providing capable browsers with the features that they are capable of utilizing - but providing incapable browsers with an adequate, albeit degraded, experience otherwise.

This provides the best of both worlds: Users of modern browsers (the majority audience) can get the best experience while those that are using incapable browsers (such as most mobile devices) will still get an interface that suits them well.

There's one thing, overriding in all of this, however: Progressive enhancement is nearly only ever applied to the JavaScript functionality of web applications. Presumably it's assumed that if a browser is capable of supporting the desired JavaScript features of an application then it must, also, be capable of supporting the specific CSS styling as well.

One technique that has greatly interested me, as of late, is one employed by the Filament Group (a local design shop here in Boston): Progressive CSS Enhancement. The premise is that progressive enhancement is done with page styling in mind, primarily, rather than from a purely-JavaScript perspective.

This is particularly important for a couple reasons:

  • It should be easy to degrade page styling in a manner that isn't reliant upon CSS browser hacks - this technique makes it so.
  • Not all pages utilize heavy JavaScript (and, thus, progressive JavaScript enhancement does not apply to them).

Their technique works as follows: You choose to provide the user with, either, the enhanced or the decreased experience by default. In either case a basic script is run which attempts to verify a couple CSS styling behaviors along with some basic JavaScript functionality (just enough to be able to run the test).

A couple of the CSS techniques that they test for:

  • Box model: make sure the width and padding of a div add up properly using offsetWidth.
  • Positioning: position a div and check its positioning using offsetTop and offsetLeft.
  • Float: float 2 divs next to each other and evaluate their offsetTop values for equality.
  • Clear: test to make sure a list item will clear beneath a preceding floated list item.
  • Overflow: wrap a tall div with a shorter div with overflow set to 'auto', and test its offsetHeight.

With those in place you can pretty safely begin designing a useful CSS-based layout. Note that the experience will only ever be upgraded if all of the tests pass - if any fail then it simply won't continue. Obviously there'll still exist some browser discrepancies (like in the differences in the box model between Internet Explorer 6 and most other browsers) but that's usually an acceptable level of hackage (meaning that you won't have to deviate much from what you're already doing).

The actual implementation is quite simple. It consists of a number of JavaScript-based rules that test for behavior. For example the following rule tests for a working box model:

var newDiv = document.createElement('div');
document.body.appendChild(newDiv);
newDiv.style.visibility = 'hidden';
newDiv.style.width = '20px';
newDiv.style.padding = '10px';
var divWidth = newDiv.offsetWidth;
if(divWidth != 40) {document.body.removeChild(newDiv); return false;}

That check, alone, is able to knock off a number of older browser whom aren't able to successfully implement that CSS behavior. Currently all the rules are in a large code block, which makes maintenance unwieldily. I think that this library could definitely benefit from extensibility (being able to add/remove rules that you wish to honor).

When it comes time to actually use this technique within your application there are a number of strategies that you can use. However, for the sake of discussion here, let's assume that you're sending, by default, the degraded experience to the client (optionally upgrading if the browser is capable). Then you would be able to use these two techniques:

  • A class of "enhanced" is assigned to the body element to be used for optional CSS scoping (such as: body.enhanced {background: red;}).
  • Any links to alternate stylesheets that have a class of "enhanced" will be enabled.

In this manner you can specify all of your stylesheets in your header with some disabled (being alternate stylesheets) or with some CSS rules being only applied with the body.enhanced match.

Their implementation also allows you to only execute JavaScript if all the rules pass - however I'm not sure if that's an acceptable solution, in this situation. If you want to verify that your desired JavaScript functionality is able to operate then you should check for just that. However, in this case, we can get the other side of the equation: Verifying that CSS works as you would expect it to, knowing that an adequate experience can be provided.

If you're curious as to which devices are supported by the default rules in the test file you can view the result matrix on the tool's site.

I definitely think that this technique has a lot of merit, especially in the realm of mobile-accessible web sites. Since it's virtually impossible to design, and test, your pages to work on such a large number of obscure platforms this degraded strategy is really one that will help to benefit both you, and your users, in the long run.

Sunday, March 09, 2008 11:24:37 AM (Jerusalem Standard Time, UTC+02:00)  #    Comments [0] - Trackback
CSS | Programming | Web Design
Navigation
Archive
<March 2008>
SunMonTueWedThuFriSat
2425262728291
2345678
9101112131415
16171819202122
23242526272829
303112345
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Guy Levin
Sign In
Statistics
Total Posts: 63
This Year: 0
This Month: 0
This Week: 0
Comments: 14
Themes
All Content © 2012, Guy Levin