Monday, January 3, 2011

Dark Color Scheme for Visual Studio 2010 - Chinese Takeout

For some reason I always thought people who coded with dark color schemes were emo. But after getting a Windows Phone 7, I really started to appreciate dark themes. It makes a lot of sense to have one while you're coding, so you're not just staring at a white light bulb for hours. I've tried a few that are out there, but one that I really like is a color scheme that comes with NetBeans called Norway Today. Inspired by that scheme, I created my own for Visual Studio that I call Chinese Takeout.

I love it and feel obligated to share it with the world. You can download it here.


Currently it's configured for JS, CSS, XML, and CS files.

Thursday, December 9, 2010

Creating HTML with JavaScript

When I first started creating HTML elements with JavaScript, I used the standard JavaScript DOM methods (e.g. createElement, createAttribute, etc.). Although building HTML this way provides a natural way to store references to all the important elements, for all but trivial scenarios, you'll end up with a convoluted mess.

Next I started writing out the HTML as a big string, and then using the innerHTML property to build the actual elements. That was easier to write, but I found it difficult to reference the various elements in my HTML. Sure I could provide IDs and use getElementById to get the actual references, but let me try to explain some of the issues with this approach.

Consider this scenario: I want to create a PictureButton class. When building the HTML for the control, I might do something like this:
     // Define the markup for the control  
     var html = '';  
     html += '<div id="PictureButton">';  
     html += ' <img id="Picture" src="Picture.png" />';  
     html += '</div>';  
   
     // Add control to the DOM  
     Parent.innerHTML = html;  
   
     // Get a reference to our elements (perhaps for wiring up events, etc)  
     var PictureButton = document.getElementById('PictureButton');  
     var Picture = document.getElementById('Picture');  

There are three issues here:
1. IDs are global to the entire document, so this will quickly fall apart as subsequent buttons are created.
2. I might want to reference the elements of my control before I'm ready to add them to the document.
3. I might want to append my control to the parent, without having to clear the inner HTML.

Frustrated by the limitations of both approaches, I put together a routine that, I think, addresses all of the limitations discussed.

Here it is:
 function CreateElementsFromHtml(html, elements){  
   // Create a temporary container so we can build  
   // our HTML structure  
   var container = document.createElement("div");  
   container.innerHTML = html;  
   
   // Traverse through the nodes looking for elements  
   // with a "eid" and store references to those elements  
   Traverse(container.childNodes, elements);  
   
   function Traverse(elementsToTraverse, elements){  
     for (var i = 0; i < elementsToTraverse.length; i++) {  
       var element = elementsToTraverse[i];  
   
       // Check to see if the "eid" attribute was set  
       if(element.getAttribute){  
         var id = element.getAttribute('eid');  
         if(id){  
           // If found, remove the attribute (since it's not a  
           // valid attribute) and store the reference to this  
           // element using the "eid" as the property name.  
           element.removeAttribute('eid');  
           elements[id] = element;  
         }  
       }  
   
       // Recursively repeat this operation for the child  
       // nodes.  
       if(element.childNodes.length != 0){  
         Traverse(element.childNodes, elements);  
       }  
     }  
   }  
 }  

Here's how it can be used:
     // Will be used to house our element references. Should be  
     // global to the class.  
     var E = {};  
   
     // Define the markup for the control  
     var html = '';  
     html += '<div eid="PictureButton">';  
     html += ' <img eid="Picture" src="Picture.png" />';  
     html += '</div>';  
   
     // Create the elements and add all references we  
     // defined with "eid" to the object E.  
     CreateElementsFromHtml(html, E);  
   
     // Now we can easily reference our elements using E  
     // (E.PictureButton, E.Picture, etc.).  
   
     // Add control to the DOM  
     Parent.appendChild(E.PictureButton);  

The idea is so simple, yet it can really clean up your DHTML. Basically, we're abandoning element IDs all together. Instead, we just have JavaScript references to all the elements we care about (all grouped together with that "E" object). Since E is unique to the instance of the control object, you can define as many of these controls as you want, and you won't have any conflicts. We identify which elements we care about by simply adding the "eid" attribute in the HTML (which will get removed during creation). Further, you can add the elements to the document whenever you please.

I'd be really curious to know if anyone has any other solutions for creating HTML with JavaScript. For now, though, I'm going to experiment further with this approach.