2005 2006 2007 2008 2009 2010 2011 2015 2016 aspnet azure csharp debugging exceptions firefox javascriptajax linux llblgen powershell projects python security services silverlight training videos wcf wpf xag xhtmlcss

Creating JavaScript Components and ASP.NET Controls

Every now and again I'll actually meet someone who realizes that you don't need a JavaScript framework to make full-scale AJAX applications happen... but rarely in the Microsoft community.  Most people think you need Prototype, jQuery, or ASP.NET AJAX framework in order to do anything from networking calls, DOM building, or component creation.  Obviously this isn't true.  In fact, when I designed the Brainbench AJAX exam, I specific designed it to test how effectively you can create your own full-scale JavaScript framework (now how well the AJAX developer did on following my design, I have no idea).

So, today I would like to show you how you can create your own strongly-typed ASP.NET-based JavaScript component without requiring a full framework.  Why would you not have Prototype or jQuery on your web site?  Well, you wouldn't.  Even Microsoft-oriented AJAX experts recognizes that jQuery provides an absolutely incredible boost to their applications.  However, when it comes to my primary landing page, I need that to be extremely tiny.  Thus, I rarely include jQuery or Prototype on that page (remember, Google makes EVERY page a landing page, but I mean the PRIMARY landing page.)

JavaScript Component

First, let's create the JavaScript component.  When dealing with JavaScript, if you can't do it without ASP.NET, don't try it in ASP.NET.  You only use ASP.NET to help package the component and make it strongly-typed.  If the implementation doesn't work, then you have more important things to focus on.

Generally speaking, here's the template I follow for any JavaScript component:

window.MyNamespace = window.MyNamespace || {};
//+
//- MyComponent -//
MyNamespace.MyComponent = (function( ) {
    //- ctor -//
    function ctor(init) {
        if (init) {
            //+ validate and save DOM host
            if (init.host) {
                this._host = init.host;
                //+
                this.DOMElement = $(this._host);
                if(!this.DOMElement) {
                    throw 'Element with id of ' + this._host + ' is required.';
                }
            }
            else {
                throw 'host is required.';
            }
            //+ validate and save parameters
            if (init.myParameter) {
                this._myParameter = init.myParameter;
            }
            else {
                throw 'myParameter is required.';
            }
        }
    }
    ctor.prototype = {
        //- myfunction -//
        myfunction: function(t) {
        }
    };
    //+
    return ctor;
})( );

You may then create the component like the following anywhere in your page:

new MyNamespace.MyComponent({
    host: 'hostName',
    myParameter: 'stuff here'
 });

Now on to see a sample component, but, first, take note of the following shortcuts, which allow us to save a lot of typing:

var DOM = document;
var $ = function(id) { return document.getElementById(id); };

Here's a sample Label component:

window.Controls = window.Controls || {};
//+
//- Controls -//
Controls.Label = (function( ) {
    //- ctor -//
    function ctor(init) {
        if (init) {
            //+ validate and save DOM host
            if (init.host) {
                this._host = init.host;
                //+
                this.DOMElement = $(this._host);
                if(!this.DOMElement) {
                    throw 'Element with id of ' + this._host + ' is required.';
                }
            }
            else {
                throw 'host is required.';
            }
            //+ validate and save parameters
            if (init.initialText) {
                this._initialText = init.initialText;
            }
            else {
                throw 'initialText is required.';
            }
        }
        //+
        this.setText(this._initialText);
    }
    ctor.prototype = {
        //- myfunction -//
        setText: function(text) {
            if(this.DOMElement.firstChild) {
                this.DOMElement.removeChild(this.DOMElement.firstChild);
            }
            this.DOMElement.appendChild(DOM.createTextNode(text));
        }
    };
    //+
    return ctor;
})( );

With the above JavaScript code and "<div id="host"></div>" somewhere in the HTML, we can use the following to create an instance of a label:

window.lblText = new Controls.Label({
    host: 'host',
    initialText: 'Hello World'
});

Now, if we had a button on the screen, we could handle it's click event, and use that to set the text of the button, as follows:

<div>
    <div id="host"></div>
    <input id="btnChangeText" type="button" value="Change Value" />
</div>
<script type="text/javascript" src="Component.js"></script>
<script type="text/javascript">
    //+ in reality you would use the dom ready event, but this is quicker for now
    window.onload = function( ){
        window.lblText = new Controls.Label({
            host: 'host',
            initialText: 'Hello World'
        });
         window.btnChangeText = $('btnChangeText');
         //+ in reality you would use a muli-cast event
         btnChangeText.onclick = function( ) {
            lblText.setText('This is the new text');
         };
    };
</script>

Thus, components are simple to work with.  You can do this with anything from a simple label to a windowing system to a marquee to any full-scale custom solution.

ASP.NET Control

Once the component works, you may then package the HTML and strongly-type it for ASP.NET.  The steps to doing this are very simple and once you do it, you can just repeat the simple steps (some times with a simple copy/paste) to make more components.

First, we need to create a .NET class library and add the System.Web assembly.   Next, add the JavaScript component to the .NET class library.

Next, in order to make the JavaScript file usable my your class library, you need to make sure it's set as an Embedded Resource.  In Visual Studio 2008, you do this by going to the properties window of the JavaScript file and changing the Build Action to Embedded Resource.

Then, you need to bridge the gap between the ASP.NET and JavaScript world by registering the JavaScript file as a web resource.  To do this you register an assembly-level WebResource attribute with the location and content type of your resource.  This is typically done in AssemblyInfo.cs.  The attribute pattern looks like this:

[assembly: System.Web.UI.WebResource("AssemblyName.FolderPath.FileName", "ContentType")]

Thus, if I were registering a JavaScript file named Label.js in the JavaScript.Controls assembly, under the _Resource/Controls folder, I would register my file like this:

[assembly: System.Web.UI.WebResource("JavaScript.Controls._Resource.Label.js", "text/javascript")]

Now, it's time to create a strongly-typed ASP.NET control.  This is done by creating a class which inherits from the System.Web.UI.Control class.  Every control in ASP.NET, from the TextBlock to the GridView, inherits from this base class.

When creating this control, we want to remember that our JavaScript control contains two required parameters: host and initialText.  Thus, we need to add these to our control as properties and validate these on the ASP.NET side of things.

Regardless of your control though, you need to tell ASP.NET what files you would like to send to the client.  This is done with the Page.ClientScript.RegisterClientScriptResource method, which accepts a type and the name of the resource.  Most of the time, the type parameter will just be the type of your control.  The name of the resource must match the web resource name you registered in AssemblyInfo.  This registration is typically done in the OnPreRender method of the control.

The last thing you need to do with the control is the most obvious: do something.  In our case, we need to write the client-side initialization code to the client.

Here's our complete control:

using System;
//+
namespace JavaScript.Controls
{
    public class Label : System.Web.UI.Control
    {
        internal static Type _Type = typeof(Label);

        //+
        //- @HostName -//
        public String HostName { get; set; }

        //- @InitialText -//
        public String InitialText { get; set; }

        //+
        //- @OnPreRender -//
        protected override void OnPreRender(EventArgs e)
        {
            Page.ClientScript.RegisterClientScriptResource(_Type, "JavaScript.Controls._Resource.Label.js");
            //+
            base.OnPreRender(e);
        }

        //- @Render -//
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            if (String.IsNullOrEmpty(HostName))
            {
                throw new InvalidOperationException("HostName must be set");
            }
            if (String.IsNullOrEmpty(InitialText))
            {
                throw new InvalidOperationException("InitialText must be set");
            }
            writer.Write(@"
<script type=""text/javascript"">
(function( ) {
    var onLoad = function( ) {
        window." + ID + @" = new Controls.Label({
            host: '" + HostName + @"',
            initialText: '" + InitialText + @"'
        });
    };
    if (window.addEventListener) {
        window.addEventListener('load', onLoad, false);
    }
    else if (window.attachEvent) {
        window.attachEvent('onload', onLoad);
    }
})( );
</script>
");
            //+
            base.Render(writer);
        }
    }
}

The code written to the client may looks kind of crazy, but that's because it's written very carefully.  First, notice it's wrapped in a script tag.  This is required.  Next, notice all the code is wrapped in a (function( ) { }) ( ) block.  This is a JavaScript containment technique.  It basically means that anything defined in it exists only for the time of execution.  In this case it means that the onLoad variable exists inside the function and only inside the function, thus will never conflict outside of it.  Next, notice I'm attaching the onLoad logic to the window.load event.  This isn't technically the correct way to do it, but it's the way that requires the least code and is only there for the sake of the example.  Ideally, we would write (or use a prewritten one) some sort of event handler which would allow us to bind handlers to events without having to check if we are using the lameness known as Internet Explorer (it uses window.attachEvent while real web browsers use addEventListener).

Now, having this control, we can then compile our assembly, add a reference to our web site, and register the control with our page or our web site.  Since this is a "Controls" namespace, it has the feel that it will contains multiple controls, thus it's best to register it in web.config for the entire web site to use.  Here's how this is done:

<configuration>
  <system.web>
    <pages>
      <controls>
        <add tagPrefix="c" assembly="JavaScript.Controls" namespace="JavaScript.Controls" />
      </controls>
    </pages>
  </system.web>
</configuration>

Now we are able to use the control in any page on our web site:

<c:Label id="lblText" runat="server" HostName="host" InitialText="Hello World" />

As mentioned previously, this same technique for creating, packaging and strongly-typing JavaScript components can be used for anything.  Having said that, this example that I have just provided borders the raw definition of useless.  No one cares about a stupid host-controlled label.

If you don't want a host-model, but prefer the in-place model, you need to change a few things.  After the changes, you'll have a template for creating any in-place control.

First, remove anything referencing a "host".  This includes client-side validation as well as server-side validation and the Control's HostName property.

Next, put an ID on the script tag.  This ID will be the ClientID suffixed with "ScriptHost" (or whatever you want).  Then, you need to inform the JavaScript control of the ClientID.

Your ASP.NET control should basically look something like this:

using System;
//+
namespace JavaScript.Controls
{
    public class Label : System.Web.UI.Control
    {
        internal static Type _Type = typeof(Label);

        //+
        //- @InitialText -//
        public String InitialText { get; set; }

        //+
        //- @OnPreRender -//
        protected override void OnPreRender(EventArgs e)
        {
            Page.ClientScript.RegisterClientScriptResource(_Type, "JavaScript.Controls._Resource.Label.js");
            //+
            base.OnPreRender(e);
        }

        //- @Render -//
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            if (String.IsNullOrEmpty(InitialText))
            {
                throw new InvalidOperationException("InitialText must be set");
            }
            writer.Write(@"
<script type=""text/javascript"" id=""" + this.ClientID + @"ScriptHost"">
(function( ) {
    var onLoad = function( ) {
        window." + ID + @" = new Controls.Label({
            id: '" + this.ClientID + @"',
            initialText: '" + InitialText + @"'
        });
    };
    if (window.addEventListener) {
        window.addEventListener('load', onLoad, false);
    }
    else if (window.attachEvent) {
        window.attachEvent('onload', onLoad);
    }
})( );
</script>
");
            //+
            base.Render(writer);
        }
    }
}

Now you just need to make sure the JavaScript control knows that it needs to place itself where it has been declared.  To do this, you just create a new element and insert it into the browser DOM immediately before the current script block.  Since we gave the script block and ID, this is simple.  Here's basically what your JavaScript should look like:

window.Controls = window.Controls || {};
//+
//- Controls -//
Controls.Label = (function( ) {
    //- ctor -//
    function ctor(init) {
        if (init) {
            if (init.id) {
                this._id = init.id;
                //+
                this.DOMElement = DOM.createElement('span');
                this.DOMElement.setAttribute('id', this._id);
            }
            else {
                throw 'id is required.';
            }
            //+ validate and save parameters
            if (init.initialText) {
                this._initialText = init.initialText;
            }
            else {
                throw 'initialText is required.';
            }
        }
        //+
        var scriptHost = $(this._id + 'ScriptHost');
        scriptHost.parentNode.insertBefore(this.DOMElement, scriptHost);
        this.setText(init.initialText);
    }
    ctor.prototype = {
        //- setText -//
        setText: function(text) {
            if(this.DOMElement.firstChild) {
                this.DOMElement.removeChild(this.DOMElement.firstChild);
            }
            this.DOMElement.appendChild(DOM.createTextNode(text));
        }
    };
    //+
    return ctor;
})( );

Notice that the JavaScript control constructor creates a span with the specified ID, grabs a reference to the script host, inserts the element immediately before the script host, then sets the text.

Of course, now that we have made these changes, you can just throw something like the following into your page and to use your in-place JavaScript control without ASP.NET.  It would look something like this:

<script type="text/javascript" id="lblTextScriptHost">
    window.lblText = new Controls.Label({
        id: 'lblText',
        initialText: 'Hello World'
    });
</script>

So, you can create your own JavaScript components without requiring jQuery or Prototype dependencies, but, if you are using jQuery or Prototype (and you should be!; even if you are using ASP.NET AJAX-- that's not a full JavaScript framework), then you can use this same ASP.NET control technique to package all your controls.

kick it on DotNetKicks.com

Cross-Browser JavaScript Tracing

No matter what system you are working with, you always need mechanisms for debugging.  One of the most important mechanisms a person can have is tracing.  Being able to see trace output from various places in your application is vital.  This is especially true with JavaScript.  I've been working with JavaScript since 1995, making stuff 12 years ago that would still be interesting today (in fact, I didn't know server-side development existed until 1998!) and I have noticed a clear correlation between the complexity of JavaScript applications and the absolute need for tracing.

Thus, a long, long time ago I built a tracing utility that would help me view all the information I need (and absolute no more or less).  These days this means being able to trace information to a console, dump arrays and objects, and be able to view line-numbered information for future reference.  The utility I've created has since been added to my Themelia suite (pronounces the-meh-LEEUH; as in thistle or the name Thelma), but today I would like to demonstrate it and deliver it separately.

The basis of my tracing utility is the Themelia.Trace namespace.  In this namespace is.... wait... what?  You're sick of listening to me talk?  Fine.  Here's the sample code which demonstrates the primary uses of Themelia.Trace, treat this as your reference documentation:

//+ enables tracing
Themelia.Trace.enable( );
//+ writes text
Themelia.Trace.write('Hello World!');
//+ writes a blank line
Themelia.Trace.addNewLine( );
//+ writes a numbered line
Themelia.Trace.writeLine('...and Hello World again!');
Themelia.Trace.writeLine('Another line...');
Themelia.Trace.writeLine('Yet another...');
Themelia.Trace.writeLine('One more...');
//+
//++ label
//+ writes labeled data to putput (e.g. 'variableName (2)')
Themelia.Trace.writeLabeledLine('variableName', 2);
//+
//++ buffer
//+ creates a buffer
var buffer = new Themelia.Trace.Buffer( );
//+ declares beginning of new segment
buffer.beginSegment('Sample');
//+ writes data under specific segment
buffer.write('data here');
//+ nested segment
buffer.beginSegment('Array Data');
//+ write array to buffer
var a = [1,2,3,4,5];
buffer.write(a);
//+ declares end of segment
buffer.endSegment('Array Data');
buffer.beginSegment('Object Data');
//+ write raw object/JSON data
buffer.write({
    color: '#0000ee',
    fontSize: '1.1em',
    fontWeight: 'bold'
});
buffer.endSegment('Object Data');
//+ same thing again
buffer.beginSegment('Another Object');
var o = {
    'personId': 2,
    name: 'david'
};
buffer.write(o);
buffer.endSegment('Another Object');
buffer.endSegment('Sample');
//+ writes all built-up data to output
buffer.flush( );

Notice a few thing about this reference sample:

  • First, you must use Themelia.Trace.enable( ) to turn tracing on.  In a production application, you would just comment this line out.
  • Second, Themelia.Trace.writeLine prefixes each line with a line number.  This is especially helpful when dealing with all kinds of async stuff floating around or when dealing with crazy events.
  • Third, you may use Themelia.Trace.writeLabeledLine to output data while giving it a name like "variableName (2)".
  • Fourth, if you want to run a tracer through your application and only later on have output, create an instance of Themelia.Trace.Buffer, write text to it, write an array to it, or write an object to it, then call flush( ) to send to data to output.  You may also use beginSegment and endSegment to create nested, indented portion of the output.
  • Fifth, notice you can throw entire arrays of objects/JSON into buffer.write( ) to write it to the screen.  This is especially handy when you want to trace your WCF JSON messages.

Trace to what?

Not everyone knows this, but Firefox, Google Chrome, Safari, and Opera each has its own console for allowing output.  Themelia.Trace works with each console in its own way.  Here are some screen shots to show you what I mean:

Firefox

Firefox since version 1.0 has the Firefox Console which allows you to write just about anything to a separate window.  I've done a video on this many years ago and last year I posted a quick "did you know"-style blog post on it, so there's no reason for me to cover it again here.  Just watch my Introduction to the Firefox Console for a detailed explanation of using the Firefox Console (you may also opt to watch my Setting up your Firefox Development Environment-- it should seriously help you out).

Firefox

Google Chrome

Chrome does things a little different than any other browser.  Instead of having a "browser" wide console, each tab has its own console.  Notice "browser" is in quotes.  Technically, each tab in Chrome is it's own mini browser, so this console-per-tab model makes perfect sense.  To access this console, just hit Alt-` on a specific tab.

Chrome

Safari

In Safari, you go to Preferences, in the Advanced Tab to check "Show Develop menu in menu bar".  When you do this, you will see the Develop menu show up.  The output console is at Develop -> Show Web Inspector.

Safari

Opera

In Opera 9, you go to Tools -> Advanced -> Developer Tools and you will see a big box show up at the bottom.  The console is the Error Console tab.

Opera9

Internet Explorer

To use Themelia.Trace with Internet Explorer, install Nikhil's Web Developer Helper.  This is different from the IE Developer Toolbar.

IEWebDevHelper

Firebug

It's important to note that, in many situations it's actually more effective to rely on Firebug for Firefox or Firebug lite for Safari/Chrome, IE, and Opera, then to use a console directly.  Therefore, Themelia.Trace allows you to set Themelia.Trace.alwaysUseFirebug to true and have all output redirected to Firebug instead of the default console.  Just try it, use the above sample, but put "Themelia.Trace.alwaysUseFirebug = true;" above it.  All data will redirect to Firebug.  Here's a screen shot (this looks basically the same in all browsers):

FirebugLite

There you have it.  A cross-browser solution to JavaScript tracing.

Links

Love Sudoku? Love brain puzzles? Check out my new world-wide Sudoku competition web site, currently in beta, at Sudokian.com.

kick it on DotNetKicks.com

March 2008 Web Technology Update

Recently a bunch of technologies have been released and/or updated and I would like to mention a few of them briefly.

First and foremost, Silverlight 2 Beta 1 has finally been released and you may download it immediately.  There is also an accompanying SDK.  You can find a nice development tutorial series on Scott Guthrie's blog.  If you are already familiar with WPF, you can just skim this entire series in less than 5 minutes.  Given that this technology isn't the same as the full WPF and given that it's designed for the web, there will obviously be differences.  It's important to remember that Silverlight 2 isn't simply WPF for the web.  I would call WPF 3.5's XBAP support for IE/Firefox "WPF for the web".  No, this is possibly the biggest web technology improvement since the release of Firefox 1.0, which in turn was the biggest technology release since the printing press.  Alight, alight... since .NET 1.1.  It's support for the dynamic language runtime is going to completely revolutionize our web development.

When reading through Scott's tutorial series (serious, at least skim it), it's interesting to note that Silverlight 2 allows cross-domain communication.  It does this by reusing the Flash communication policy files.  This is really awesome as it means that you can start accessing resources that Flash has been using for a while.  Being able to dynamically access resources from different domains is critical to the success of web architecture in the future.

Speaking of cross-domain communication, John Resig and I received a very depressing e-mail the other day telling us horrible news: cross-domain communication will probably be removed from Firefox 3 before it's official release.  Apparently a bunch of paranoid anti-architects were complaining about the dreaded evils of being able to access resources from different domains.  Um ok.  Fortunately, however, Firefox 3 has a feature called postMessage that allows you to get around this.  Malte Ubl has produced a library called xssinterface to demonstrate just this concept.  You could, of course, get around this completely with some iframe hacks or some other scripting magic.

Speaking of web browsers, I would like to bring people's attention to a technology that I've been following for some time now: Apple WebKit.  This is basically the brains inside Safari.  I absolutely love the Safari web browser.  It's by far and away the easiest web browser to use.  It also has the same keyboard short-cuts as Firefox, which is how I'm able to use it.  It's also incredibly fast, but I should mention that it uses even more memory than Firefox.  My last instance passed 500MB.  Given it's lack of an extension or configuration (i.e. about:config) system, it's obviously no where near the same caliber as Firefox though.  It is, however, my primary web browser as has been since October '07.

The reason I mention WebKit is because as very few people know, this is an open source project and has nightly binaries released on their webkit.org web site.  One of the most interesting thing about nightlies that you can actually watch the progress of development as time goes on.  About every month or so I like to get the latest Firefox nightly.  It's always interesting to see the major experiments that the developers try about 2 months after a major release of Firefox.  There's always some really awesome "teaser" feature in there that later grows into a fully grown technology.  The same can be said for WebKit.

None of that is, however, my primary reason for mentioning WebKit.  As, most web developers know, the Acid2 test has been the standard for checking a web browsers compatibility with the CSS standard.  I've been pushing this test for a long time, but I've never pushed it as the only test.  There are many things that a web browser must do and many features a web browser must have before it can be considered appropriate for use.  Merely focusing on CSS, while completely ignoring DOM support, JavaScript, and general user usability can lead a browser to be as impossible to use as Opera 9.

As I've said time and time again, I'm not a CSS specialist.  Part of the definition of being a professional web develop is that I have a solid understand of the inner workings of CSS including specificity, the various selectors, and how to merge absolute, floating, and relative position on the same elements, tasks "coders" see as nearly impossible to learn.  However, my focus is on AJAX interaction as seen from the JavaScript and DOM worlds.  Therefore, we need to have a test for browsers that goes beyond the simple Acid 2 test for CSS.  I'm not the only one thinking this way, because recently the Acid3 test was published and it tests CSS, JavaScript and DOM support.  This is the new standard for web browsers.

So far no web browser has even gotten close, with the lowest score from a web browser being 39% in Safari to the best score being 50% in Firefox 2.0.0.12.  However, in terms of non-released software, Firefox 3.0b3 has a score between 59% and 61%, depending on its mood (update: b4 is steady at 67%) and the latest WebKit nighty has a score is 90% (watch WebKit progress on Acid 3 at http://bugs.webkit.org/show_bug.cgi?id=17064).  That's phenomenal!  The newly released Internet Explorer 8 beta 1 has a score of 17%.  Those of you who have naively praising the IE team for being YEARS late on getting near the Acid 2 test need to wake up and realize this is 2008.  Time moves-- keep up.  Firefox has been close for the longest time and has always had the next-gen's next-gen JavaScript and DOM support, but has only recently completely passed the finish line of the Acid 2 test.  So, they are finally off my watch list there, but I will not stop bugging them until they pass the Acid 3 test.

For more information on the Acid 3 test, see John Resig's most entitled "Acid 3 tackes EMCAScript".  He's about as passionate as I am for web standards and Firefox and his blog is an invaluable resource for all things JavaScript.  His work is so good that I would like to take the time to plug his book he is currently writing: Secrets of the JavaScript Ninja.  I absolutely guarantee you that this book will redefine the entire world of JavaScript and will raise the bar incredibly out of the reach of "coders". To all of you coders who think you know JavaScript, do a view-source on the Acid 3 source code (you may want to bring a change of underwear with you).

Lastly, it's not necessarily a "new" technology, but it's so incredibly phenomenal that I need to mention it: Prototype 1.6.  It's amazing to me that people actually go out of their way to use ASP.NET AJAX 3.5 (I still find the ICallbackEventHandler interface more productive).  ASP.NET AJAX 3.5 is not nearly as bad as extremists think, but the design is still flawed.  Prototype on the other hand is absolutely incredible.  I've written about Prototype before, but this version 1.6 is even more powerful.  There a A LOT of changes from Prototype 1.5.  It's so good that I no longer call it "prototype/script.aculo.us".  Script.aculo.us is a great animation system, but, honestly, the main reason I used it was for the DOM abstraction in the Builder object.  Prototype now has an Element object to help create DOM objects, thus allowing me to remove Script.aculo.us from most of my projects (it's not as complete as the Builder object, but it allows object chaining-- which greatly increases code readability, conciseness and understanding!).  The Template object is also amazing as it gives you the ability to go far beyond simple String.Format formatting.  The new Class object for OOP is also great.  It's so much easier to use than Prototype 1.5.  Also, being able to hide all elements with a particular CSS pattern with one shot is very useful! (for example, $$('div span .cell-block').invoke('hide')).  It even allows you to use CSS 3 selectors on the most dead of web browsers.  It really makes developing for Internet Explorer 6 and 7 bearable!  Even if I have to use ASP.NET AJAX 3.5, I'll still including prototype.js.  If you do anything with JavaScript, you need Prototype!

 

Links

Dojo 1.0: Client-Side Web Development Framework

Recently I started a deeper study of the Dojo JavaScript Toolkit 1.0.  When I first got into Dojo, my reaction was something like "my goodness this is complicated", but then I woke up.  In reality, Dojo is not simply a JavaScript framework like prototype or an animation framework like script.aculo.us, but, rather, it's an entire client-side web development framework.  You can think of it as being a client-side version of the ASP.NET.  Because of this, I'm not going to compare it to prototype or script.aculo.us, products, which have completely different applications than Dojo.

Here is a simple break down of an example based on the hello world example found on the Dojo web site.  First let's add the dojo.js file:

<script src="dojoroot/dojo/dojo.js" djConfig="parseOnLoad: true" type="text/javascript"></script>

What in the WORLD is the djConfig attribute?  Well it's not in any XHTML DTD that's for sure.  This is something to tell Dojo to, obviously, parse the file on load.  Duh.  That's not really the fun part though.  Check this out, you actually use a PHP style "require" statement to load specific portions of Dojo:

<script type="text/javascript">
   dojo.require('dijit.form.Button');
</script> 

By doing this, now we can add the following control into our page structure:

<button dojoType="dijit.form.Button" id="hola">
  Hola Mundo!
  <script type="dojo/method" event="onClick">alert('Hola');</script>
</button>

This creates a simple button which alerts 'Hola' when clicked.  As you can see, it gives you a very nice declarative programming model.  I personally think this is incredible because 1) I believe that we should focus on web development from a client-side perspective and therefore create controls on the client, 2) I love declarative programming, 3) I don't want to build this thing myself.  With Dojo I get a declarative client-side programming model without having to architect the internals.  This is really awesome, since I'm a strong advocate of client-side perspective programming (a.k.a. web 2.0).

One interesting aspect of Dojo is that it loads only the files that you need for that specific page.  This is a rather nice compromise between the Prototype and mooTools methods.  Prototype loads the entire thing into memory and mooTools allows you to download each section you want.  Dojo, however, installs on the server as a set of files that are available for download and you retrieve them as you need them.  To add to this, you don't add them via the <script /> element, you add the dojo.js file that way, but you load the others by calling dojo.require( ).  What's nice about this is that you load modules, not files.  It also gives it a more native programming feel, but it also makes sure you don't load the same file twice.  Here's an example of what I'm talking about:

<script type="text/javascript">
  dojo.require('dojo.parser');
  dojo.require('dijit.form.Button');
  dojo.require('dijit.form.FilteringSelect');
  dojo.require('dijit.form.CheckBox');
</script>

Here you can see that I'm loading up four different modules.  What's interesting about this is that it's kind of similar to how we import .NET namespaces.  However, it's even more like how we load .NET assemblies.  Think of each one of these as being an assembly we need to reference.  In .NET, you add a reference, let fusion and it's buddies find and load the assemblies, and simply use the controls as if they were local; you don't care about "files".  This is very similar to the model presented in Dojo.  It's like you are adding a Dojo "assembly" reference, letting it load it for you, and you access it as it were local.  This is all in direct contrast to the model that PHP as well as most JavaScript/AJAX framework use.  In PHP and in these frameworks, you typically load "files" directly.  One of the hardest things for a PHP developer to do is make the mental transition from file files to "magically loading" .NET assemblies.  In .NET assembly names don't need to match their DLL names, in fact as assembly can span more than a single DLL file!  In the same way, Dojo's module names don't have a one-to-one module-to-file mapping and loads whatever physical files you need based on the logical name you request.  Very nice! The analogy isn't perfect and like I've already mentioned it's a bit like the .NET namespace import model as well.

Dojo contains a number of very nice controls as part of it's Dojo Widjet Library, also known as Dijit.  Many of these are controls that most of us have wanted for years, but just have never had the time to mess with.  For example, Dojo including a slider control, a dynamically expanding textarea, and a filtering select box.  There's a whole host of others, but these are the ones that I personally have wanted to see in a professional framework for a long time.  There's also a progress bar control and a dialog control for those of you who are into business apps.  Dojo actually provides a tooltip dialog control as well.  This control, as the name suggests, shows a dialog as a tooltip.  The only time ever seen a control like this used was on the Facebook login screen, specifically when you check "Remember me".  Another interesting thing related to controls is that Dojo gives you the ability to transform controls into a more beautified form.  It's able to do this because it ships with a few CSS files that give Dojo its initial look and feel.  Furthermore it also includes a number of themes.  You can see this in a few of the more basic demonstrations in the Dojo documentation.

Dojo also includes many layout controls including a split container, accordion, tab control and what is called a StackContainer.  This container shows a pane on the screen and gives you a next and previous button so you can go back and forth between panes.  There's also a rich text editor control.  That should get some people's attention right there.  As cool as that is though, I don't think anything beats the grid control.  The grid is like a combination of ASP.NET's GridView and WPF's Grid.  It allows databinding like GridView, but it also allows complex row and column adjustment like the Grid.  Technically it's not part of the core of Dojo, but it's incredibly amazing.  You can see a great example of a Grid with it's code, see this example.  The code for this Grid is so simple, that you probably won't even believe your eyes.  Even still, the author of that example writes about the example here.  The Grid really is one of the most powerful controls I've ever seen in a client or server technology.  Again, can you see how Dojo is like a client-side ASP.NET?

It should go without saying at this point, but Dojo also includes various validation controls.  You can actually put an <input /> element on the screen and set dojoType="dijit.form.DateTextBox" and you get an entirely new animal that loads a calendar control when you click in the textbox.  If you prefer to type the date out by hand, the field will be validated automatically.  You can also validate against money.  Look at this example from the Dojo documentation:

<input type="text" name="income1" value="54775.53"
  dojoType="dijit.form.CurrencyTextBox"
  required="true"
  constraints="{fractional:true}"
  currency="USD"
  invalidMessage="Invalid amount.  Include dollar sign, commas, and cents." />

That's seriously detailed.  The data is validated as the user types.  If you want to validate numbers that don't represent money, you can use the NumberTextBox Dojo control (also set via the dojoType attribute).  Or, if you want more powerful validation, use a ValidationTextbox and set the regExp attribute and validate directly against a regular expression.  Your regular expression doesn't have to be inline in the regExp attribute either.  Take a look at this example from the Dojo documentation:

<input type="text" name="zip" value="00000"
  dojoType="dijit.form.ValidationTextBox"
  regExpGen="checkForFiveDigitZipCode"
  required="true"
  invalidMessage="Zip codes after 5, county name before then." />

Here you can see that the JavaScript function (checkForFiveDigitZipCode) is called for validation.  To see these examples run and to see more information on validation in Dojo see the validation page in their documentation.

At this point I think I should mention something.  As many of you know, I'm a strong standards advocate and an extremely outspoken opponent of the mere existence of Internet Explorer.  Having said that, laws exist for a purpose and, frankly, only within the bounds of that purpose.  The purpose of standards are to give us a common ground and to help us have cleaner, more professional work (my "having higher web standards" thing I'm always talking about).  In terms of web browsers, each browser needs to continually keep up with the standards.  Why?  Obviously so web developers can ship out content and not want to change their career every single time they realize that browser X, Y, or Z doesn't support a specific feature.  With this in mind, there is absolutely nothing wrong with Dojo using custom attributes on types.  Dojo is requiring new functionality, but it's also providing that functionality at the same time.  That which is requires, it provides.  This is completely legal within the bounds of the purpose of standards.  So, there is no reason for anyone to start crying about Dojo adding custom attributes.  There was a time when I was a standards extremist (~2003), going so far as to even use a custom DTD on my pages where I would use custom attributes (set via JavaScript), but I've since realized that standard extremism is practically a cult and have ran from it.  Also, and you may want to sit down for this one, I think that Dojo holds nicely to semantic web principles.  Notice we aren't creating an input and procedurally making it do validation, rather, we are creating something that is a validation box.  It's not as semantic as a <validationtextbox /> would be, if it were to exist, but as with most things, semanticism (huh?) is a continuum.  If it weren't a continuum, <input type="hidden" /> shouldn't exist or ever be used (I would argue that this does in fact have some semantic value!)  Because of this, I don't see Dojo involving itself with the evils of pragmatism.  However, Dojo would be an evil pragmatic framework with little semantic structure, if it instead tried to setup some type of configuration system by setting class names.  Can you even imagine the chaos?  I've done this before as a standards extremist and it's really nasty.

Another thing that's insanely cool about Dojo is the event system.  As we ASP.NET developers know, events aren't simply things you use on visual controls.  No, you use events to notify entities of (...drum roll please...) events.  So, you could have multiple entities monitoring a centralized entity, perhaps a service and when that centralized entity sends out an update, all the other entities immediately receive the update.  It's the observer pattern, but you may know it as the publish/subscribe model.  Normally when you think of JavaScript events you think of events in terms of visual control events just as you would with ASP.NET.  With Dojo, however your event model gets an upgrade with a publisher/subscriber model.  Here's an example for you to ponder:

<script type="text/javascript">
  function Client (name) {
    this._name = name;
    
    dojo.subscribe('update', this, update);
    
    function update(args) {
      console.debug(this._name + ': ' + args);
    }
  }
        
  var Server = {
    sendUpdates: function(message) {
      dojo.publish('update', [message]);
    }
  };
  
  var clientA = new Client('Client A');
  var clientB = new Client('Client B');
  
  Server.sendUpdates('event occured!');
</script>

One thing on which I would like to warn all my .NET colleagues is this: they use Java terminology.  They fire their events whereas we like our events and think they are doing a great job so we raise them.  Personally, I've never understood that terminology, especially in systems like the web that allow for event bubbling where events are RAISED to the top.  OK, enough rant.  Before moving on though, just think about what I keep mentioning : this is like a fully fledged client-side ASP.NET.  You must surely be noticing that by now.

Dojo, of course, also gives you a XMLHttpRequest abstraction layer so that you don't need to mess with all that browser detection nonsense.  The syntax is rather similar to prototype's very intuitive syntax.  This is fortunate, because not all frameworks have a nice abstraction layer.  I've given up on trying to figure out mooTool's abstraction layer a long time ago.  It's doable, but the complexity curve is very steep.  In Dojo, however, the complexity curve is relatively flat, like prototype's.  Here's an example based on a Dojo documentation example of a simple XHR call (if you like, you can set 'json' instead of 'text' in the handleAs).  This code isn't anything fancy, but that's kind of my point:

<script type="text/javascript">
dojo.xhrGet({
  url: '/file/1.txt',
  handleAs: 'text',
  timeout: 3000,
  load: function(response, ioArgs) {
    alert(response);
    return response;
  },
  error: function(response, ioArgs) {
    console.error('Status code: ', ioArgs.xhr.status);
    return response;
  }
});
</script>

As simple as this is though, you can do much more with Dojo's abstraction layer than what I've seen in any other framework.  For example, there's actually a dojo.io.iframe object to give you the ability to do iframe-based AJAX.  Dojo also includes the dojo.rpc object, which allows for incredibly poweful RPC calls.  Gone are the days of having to choose to either create your own end-to-end communication or to completely use a flawed product.  You now have a nice middle ground for your AJAX service access. In a sense it's kind of similar to .NET remoting, in how it's not SOAP, but it's not quite sockets either.  The dojo.rpc concept is amazing quite possibly my favorite Dojo feature.  You can expect me to write more about this feature in the future.  I'm been completely taken in by this incredible feature and can see an incredible number of applications for it.  If you want to see something else wildly awesome, check out the dojo.data data access layer.  The documentation needs to be developed a bit more, but it's wild.  Whereas dojo.rpc may be similar to .NET remoting, dojo.data is kind of like WCF binding.  You just connect to a built-in or custom data store and your can bind Dojo controls directly to it!  Bind directly to your Flicker.com datastore or write your own.  For a few good examples of using this feature, check out this blog entry.

There are also features which we would kind of expect from a client-side framework like drag-n-drop support, animation support (though barely documented-- here's a PDF of an example), and DOM node selection (see dojo.query).  It also gives you control over internationalization (and unicode encoding) and the power to handle the back button in AJAX applications (of course by using the # syntax).  There's also the ability to create object-oriented class with inheritance.  One downside to this feature is that Dojo went back to the days of C++ and impossibly complex object graphing by allowing multiple inheritance.  You may want to set a corporate guideline to stop people from doing this, lest your object graphs become completely unreadable.  In any case, you also have an abstraction for arrays (to help emulate JavaScript 1.6), cookies, strings and dates.  You are also provided a mechanism for converting the data of an entire form into JSON data.

As if that weren't enough, Dojo also provides a unit testing framework called D.O.H.  You can do anything from simple asserts to full test cases, including grouping test cases.  In addition to the unit testing, Dojo allows you to send informational and debug messages to the Firebug console.  The documentation is packed with more testing samples than you will know what to do with.  Most of them are for testing the Dojo framework, but these tests use D.O.H. and give you a world of insight into the variety of things you can do with Dojo.

As far as documentation, there is more documentation for Dojo than I have seen in all the other JavaScript/AJAX frameworks combined.  The online "Book of Dojo" is incredibly long.  In fact, some may say that it's too long.  The Dojo people thought of this though and allow you to quickly get ROI from their "Dojo for the Attention-Impaired".  This page demonstrates the basic idea behind Dojo by showing a quick Hello World example.  I would recommend you do skim through this page, do the demo, then skim through the rest of the book, doing demos as you go.  One thing I should mention about the documentation is that while there is a lot of it, it's very hard to read at times.  I had to read the event system documentation numerous times before I was able to get anything from it.  This is definitely something the Dojo guys should look into.

Another thing they should look into is their use of double quotes in their JavaScript documentation.  This is something most ASP.NET AJAX books do and it really makes the code hard to read and hard to manage (do you really want to escape every single double quote in your HTML controls? ouch!)  It's makes about as much sense as using double quotes in your T-SQL code (which, yeah, would require a setting, but that's my point-- it's lame).  The Dojo documentation seems to go between various authors who either respect for the JavaScript guidelines (') or who don't even realize it exists (").  To make things worst, at times they use single quotes in their HTML!  There doesn't seem to be any consistency here.  I'm glad they didn't try to mix their code with any type of server-side work.  I don't even want to try to read double-quotes JavaScript in the midst of PHP, Java, or C# code.  That would e painful to read.  Other than these two concerns, the documentation was fairly exhaustive.  Some developers, however prefer to learn by seeing.  If you're one of those, you can check out the official Dojo demos.

In terms of deployment, you actually don't even need to install Dojo.  It's on the AOL Content Delivery Network (CDN), so you can quickly just include the Dojo entry file from their server and be done with it.  If you really want to download it to your system, you can hit up the Dojo web site and download it from there.  You could also head on over the the Dojo web site that parodies the script.aculo.us web site: dojo.moj.oe.  Also, remember that everything you need is accessible from the single Dojo entry file (often dojo.js) and that you use dojo.require( ) statements to bring in functionality at a module level, not a file level.  Therefore, the AOL CDN method should be perfect for most people.

Dojo is currently in version 1.0, however, this is an open source 1.0, not a Microsoft 1.0.  When Microsoft has an alpha, it's a preview.  When they have a beta 1, it's pretty nice.  When they have a beta 2, I'm usually using it in production.  When it's RTM as v1.0, everything breaks and I end up removing it.  Google products as well as Firefox and Dojo on the other hand are hardcore and stable when they hit 1.0.  Their idea of 1.0 is like Microsoft's idea of an SP2.  Shall I remind everyone that Gmail is STILL marked as beta after all these years??  Dojo is a stable system that have been in development and testing for an extremely long time.

Dojo really is a fascinating client-side web development framework which can bring great elegance as well as a great declarative programming model to your AJAX applications.  Furthermore, given it's rich set of controls, Dojo is absolutely perfect for web-based business applications.  Dojo is also probably one of the great technologies of all time that are destined for completely misunderstanding as a product comparable and/or equal with products that don't even come close to it.  There are people living today that still try to compare Internet Explorer with Firefox, VSS with Subversion, Gimp with Photoshop (oh yes, I went there!), the Zune (which is a media player) with the iPod Touch (which is an Internet device)and Gmail with Yahoo! Mail or Hotmail.  Compare them and you will see there is no comparison.  As I said at the beginning, this neither replaces prototype or script.aculo.us, which would be used in more minimal environments.  Dojo is a different framework to be used when a project has different requirements.  Besides, you should never choose one tool as your end all be all for everything.  That's a naive way of thinking, unless you actually think it wise to cut your bread with a butter knife or spread your butter with a bread knife.  Rarely are things in life one-side-fits-all.  Frameworks are free; use them, but use them wisely.  Hopefully many of you will seriously consider using Dojo in your current or future AJAX and ASP.NET projects.

Links

Developers and Web Developers

(This is a sequel to my Coders and Professional Programmers article)

I'm fairly sure the year was 2001. It was before I did my transition from coder to professional, but it was long after I became a real web developer (1994).  This was the year that the web became severely corrupted by an influx of thousands of MFC/VB developers thinking they were web developers simply because they knew how to drag-n-drop a control onto a canvas and make something appear in a web browser. The influx was, of course, due to the release of ASP.NET. These people were not web developers and that same coder-mill continually throws out unprofessional after unprofessional today.  This was the year I got so upset with the pragmatic, unprofessional web developers running around taking my work that I retired for 3 years to go back to college.

So, what is a web developer?  Surely is at least one definition per person in the entire industry, but I must say that, at root, it's a person who understands and can proficiently interaction with web technologies.  What web technologies?  Today, these include, at a minimum, semantic XHTML, CSS, and Modern JavaScript.  In a sense, you could easily mark these as the pillars of web programming.  Without academic and hands-on knowledge of these technologies, there is no web devolvement (yes, both are required-- and despite what the pragmatists think, the former is critical). Furthermore, this technology list changes over time.  If I were to retire today, I have no right to come back in 5 years claiming to be a web developers.  To be a web developer at that time, I need to learn a new X, Y, and Z in including their guidelines and best practices.  You must keep up or be left behind.

Having said that, PHP, JSP, and ASP.NET developers often inappropriately call themselves web developers.  Not all PHP, JSP, or ASP.NET developers are like this, especially PHP developers! Respect, respect!  In any case, I can kind of see the confusion here, but even still, a quick realization of what these technologies are should have killed any thoughts of this a long time ago.  These people work with server-side technologies, not web technologies.  The same CGI model used 15 years ago is the same model today.  The only thing these people are doing is creating code that runs on a server and shipping the output.  Period.  That's not web development; this is the same work you would do if you were to build an Excel report.  It’s just work behind the scenes that may or may not touch a web browser.  Even then, just because it hit a web browser, doesn’t mean its web development.  There’s no client-side technologies involved at all. Without deeply interacting with client-side technologies, there is no web development.  In fact, the inanimate object known as a web server is more of a web development than server-side-only people.

Web development begins at the point when you begin to ponder the technologies and implementation from the perspective of the client-side.  I'm sure most people won't believe me when I say this, but I did web development for my 4 years of high school before I even knew that you could use server-side software to dynamically create pages.  Everything I did was in pure JavaScript and fancy frame manipulation.  This was web development.  I didn't need CGI or Perl.  PHP, JSP, and ASP.NET simply sends out a stream and it just so happens that a web browser may be the one making the request.  The output may be for a web browser, but that in absolutely no way makes it web development.  That's like going to a foreign country and using a translator device and saying because you have that device, you speak the language.  You in absolutely no way speak the language!  Worst, some people will defend, virtually to the death, the idea that they do speak the language simply because they know a few words to "fix" the translation!  We see this in server-side-only developers who, because they know a few HTML tags, think they know the technologies.

Most of the time, however, server-side-only developers really think they are web developers. So, this simple and obvious explanation won't do.  Therefore, we are forced to make a distinction between web 1.0 and web 2.0 developers.  We often think of web 2.0 as being quick, dynamic, and smooth client-side dynamics.  This is from a marketing perspective, but it's hardly a definition that satisfies the computer scientist.  The distinction I use is actually a bit more straightforward: web 2.0 development is development from the client-side perspective.  This definition actually reminds me of the definition of a series I learned in my Real Analysis class in college: a mapping from N to R.  How in the WORLD is that a series!? Isn't a series a set of entities or something?  Well, somehow it's a mapping from N to R (I've yet to hear another professor give this same definition, but the point is that "formal definitions" in mathematics rarely look like their application in reality).

When I talk about web 2.0 to a colleague or a client I'm talking about web-specific design and implementation from the perspective of the client. From this perspective calls are made to various services for interaction with outside data.  In other words, web 2.0 is a client-service model for the web.  In this sense, what is web 1.0?  Just the opposite: development from the server-side perspective.  This is ASP.NET development, for example.  When you are working with ASP.NET, you are working from the perspective of the server and you send data out.  In this model, you have a logically central system with entities accessing it. In reality, this isn’t web development—it’s development of something that may or may not do web development for you. Web 1.0 is a server-client model for the web (notice the word server, instead of service—as seen in the web 2.0 model)  If you are a deep Microsoft developer you recognize the web 2.0 paradigm: WPF/WCF allows you to easy create a client-service model bypassing the client-server model all together.  You create your client interfaces in WPF and access WCF servers as you need them.

In this perspective, what does this mean in terms of the actual technologies?  Well, almost all my web applications are done using the web 2.0 model.  That is, all my programming is done from the perspective of being inside the web browser.  I'll directly modify the DOM and access data via AJAX calls as required.  Some of my applications are pure-AJAX. That is, not single postback in the entire system (like meebo.com-- meebo is a prime example of a web 2.0; everything is from the perspective of the client with communication via AJAX services.)  In fact, my controls are very Google-ish.  Google is also deep into this model.  See their AdSense, AdWords, or Analytics controls; insert a declarative script and it does the rest from the perspective of the client.  As you can see here, you don't even need the XHR object for web 2.0!

What does ASP.NET AJAX bring?  In this model, ASP.NET AJAX is as web 1.0 technology that gives you the dynamics of web 2.0.  This was actual the entire point behind creating it.  Web 1.0 developers (who are often not web developers at all!) can use their existing server-side perspective and paradigms to implement dynamics on the remote system (in a web 1.0 model the client is the remote entity-- whereas in web 2.0 the services are remote).  ASP.NET AJAX very much allows for a web 2.0 model, but that's not how it's primarily marketed.  As a side note, I should mention that, this model for explaining web 1.0 and 2.0 is only a logical representation and therefore can not be right nor can it be wrong.  The fancy marketing representation kind of works too, but it's often too abstract to have real meaning.

Personally, I think the web 1.0 model of development is counterproductive and encourages sloppy priorities.  The user experience is the point of the system. Without that, the entire point of the web site is dead.  One of my problems with ASP.NET AJAX is how it's marketed.  The server-perspective model of development encourages development that seems backwards.  Furthermore, because of this, the aforementioned so-called "web developers" continue to spread their disease of pragmatism all over the world further aiding in the disintegration of quality.  As I've originally stated, most of these people don't understand even the basics of semantic XHTML, which is the single most fundamental aspect of web development, which can be seen in their use of div-soup or <br/> mania.  These people may be awesome server-side professionals putting my enterprise architecture skills to absolute shame and run circles around me in just about any algorithm or design pattern implementation, but they are only coders when it comes to the web.

After years and years of dealing with people like this, I've come to notice a few signs of web 1.0 coders:

  • If someone says "Firefox?  How's that better than IE?", it goes without saying that this person not only hasn't the first clue about web development, they don't even understand the tool which represents the core purpose of web development: the web browser.  People like this are almost always helpless.  You could try to explain the true power of CSS, the fact that SVG, HTML5, and Canvases are in every web browser except IE, or talk about how Firefox has the architecture of an operating system with its console, it's own registry (about:config), as well as the ability to install apps (extensions), but you're probably only going to get the same pragmatic blank stare of a coder. Fortunately, I haven’t heard say this in at least 3 years.
  • If someone says "I know CSS, here..." and shows you how they used font-size, color, and font-weight on a few elements contained in a table embedded in a table embedded in yet another table, then you have your work cut out for you, because you met a person who thinks HTML is the latest cool technology on the block and hasn't the first clue what CSS really means.  As I've stated in my article "CSS Architecture", CSS is not just a styling technology.  Furthermore, we web 2.0 developers realize that CSS is to be used in harmony with semantic XHTML and therefore understand the dangers of using a table.  These people obviously don't.  Of course, the minute their boss asks for mobile support, they come running to you because they now realize "DOH! Tables are too wide! AHH! Tables make the page size too big!" They will have to learn their lesson eventually.
  • If someone says "I know JavaScript, here... " and they show you a validation function, then you need to explain to them that JavaScript isn't merely a scripting language, but is rather a very powerful object-oriented/functional programming language which often puts strongly-typed languages to shame.  It includes closures, namespaces, an extremely rich object system, object-oriented access levels, multi cast events, and a boat load of core JavaScript objects.  Yet web 1.0 developers haven't the first clue. This problem isn’t nearly as bad as it used to be, though. MSDN magazine devoted some time to the topic in the May 2007 issue and the number of JavaScript experts in the Microsoft community is growing very rapidly.
  • If someone says "Hmm... I don't see the control you are talking about in my toolbox", then you know you are dealing with a coder.  Not only that, you're probably dealing with a person who has never, ever learned what semantic development even is.  Typically people like this will use the dead concept of a WYSIWYG designer to drag-n-drop controls and set properties with their mouse.  Clearly, these people focus more on how something seems to look at the moment, not how the page is actually built.  Pragmatists.  Personally, I’ve never designer support into anything, ever. If you can’t program it, don’t develop it! I personally find it extremely unprofessional to even allow designer-support. The target audience typically has absolutely no concept of the difference between a semantic <h1></h1> and a pragmatic <div id="myHeader"></div>.  Not only will their code cause problems down the road, your code will never integrate with it, which, of course, means you will be rewriting everything. Anyone who understands the importance of semantic XHTML understands the sheer severity of this problem.  You will break a page's structure by relying on a designer.  A designer should only be used by a professional who knows how to fix it's flaws.  Since only a professional would be able to fix the flaws, it follows that only a professional should do web development.  Duh?  For more information on semantic XHTML, see any modern web 2.0 book or my mini-article here (a quick note-- when I was formatting this post in WLW, every one of my list items would start a new list-- if I didn't understand semantic XHTML, I would have been completely stuck [also notice I'm using the semantic term "list item" not the syntactical term "<li />"-- focus on what things ARE, not what they DO-- try focusing on what something IS using a WYDIWYG designer!])

I know I've written about this topic before, but it's is just such a critically important topic.  Just because someone does something, that doesn't mean they are in that profession.  I change my own oil and change my tires, but this doesn't make me a mechanic.  A few months ago I was talking to a guy who actually said that he doesn't care about what he produces, because "it's just a job".  Just a job!?  Why don't you just get another one!  These people need to stop masquerading as web developers, stop undercutting my professional company by offering $3.75/hour unprofessional "development", start upping their own standards and start showing a little respect to us that were here first.  To a lot of us professionals this isn’t just a “job”; it’s actually become part of us! Unfortunately, I've learned years ago that people don't change.  Not for their marriage, not for their family, and especially not for their careers.  It's hopeless.  Moving on.

1 2 3 4 5

Powered by
Python / Django / Elasticsearch / Azure / Nginx / CentOS 7

Mini-icons are part of the Silk Icons set of icons at famfamfam.com