Sunday, January 20, 2008
Interpolation is just a fancy word for variable substitutioin in a string.

According to the free dictionary interpolate means:
1. To insert or introduce between other elements or parts.
2.
    a. To insert (material) into a text.

Perl does this very well, other language less so.  Less is a hybrid of the C# method for string formatting.  I find it pretty convenient when creating a lot of dynamic html to insert using that oh so hander innerHTML property.  Remember, innerHTML is usually the fastest way to add dynamic html.

function format(format) {
var params = arguments;
var toReturn = format;

for (var i = 0; i < params.length - 1; i++) {
var rString = '\\$\\{' + (i) + '\\}';
var regex = new RegExp(rString, "g");
toReturn = toReturn.replace(regex, params[i + 1]);
}

return toReturn;
}

Here's the original interpolation function that extended the string object.  I don't really think that extending builtin objects is a great idea unless there is no other way.

Sunday, January 20, 2008 7:46:19 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, November 15, 2006
As you may have noticed, I'm on a performance kick as of late.  Here's one more tip for you.  Compressing / Minimizing / Shrinking your JavaScript files can decrease download times.  Putting your scripts together in one file will also help performance.  Here's a good article on reducing page load times from a Google engineer.  This article is the source for most of this wisdom.

So armed with this new knowledge I went in search of some pre-shrunk versions of the Prototype and Scriptaculous JavaScript Libraries.  This is what I found.  I still need to test the library but it seems promising.  I will keep you posted.

Wednesday, November 15, 2006 11:44:42 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, August 18, 2006

Here's a piece of JavaScript code that allows you to format strings in a style similar to C#.

String.prototype.format = function() {
   var params = String.prototype.format.arguments;
   var toReturn = this;

   for (var i = 0; i < params.length; i++) {
      var regex = new RegExp("\{" + i + "\}", "g");
      toReturn = toReturn.replace(regex, params[i]);
   }

   return toReturn;
}

Original Source:  http://chapnickman.com/2006/02/10/string-formatting-in-javascript/

I love this because I can program in a style in which I am familiar.  However does this reduce portability or can it lead to a collision?  If we all add our own little extensions to the built in objects will we end up with a uncooperative mess?  This comes to mind because of the way the very popular prototype javascript library extends the build in JavaScript objects.  Some people people criticize prototype.js pointing out that is monolithic or bloated and lacks documentation.  While it is rather large it is also very powerful and everthing works together.  I don't have to include 5 different libraries from 5 different authors and hope that they work and play together nicely.  The documentation criticism is certainly legitimate as the author provides very little documenation.  However many sites have posted articles and even whole user guides that have come in very handy. 

I haven't even discussed Scriptaculous yet.  Scriptaculous is a visual JavaScript framework that uses Prototype for a foundation.  I have used this library for several sites and it works well and that is the whole point.  Both of these frameworks Just Plain Work!  I don't have to cobble something together each time I need a visual effect or an AJAX updater I can just use something in this toolkit. 

There is something to be said for re-using the same set of tools.  You become very proficient with those tools over time and you can use them more effectively as your experience grows.  I find this especially true of using the .NET framework also. 

You can't get anywhere by reinventing the wheel each time you need to build a cart.  Use other people's experience and work as a foundation for your own and become more productive. 

Friday, August 18, 2006 9:51:05 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, June 27, 2006

I'm developing a set of server controls in ASP.NET 2.0 that use several JavaScript, image and stylesheet (CSS) files.  One of the problems with distributing controls is that you usually have to send along these files and tell the end user to install them in the appropriate directory.

Along comes ASP.NET 2.0 and the ability to embed resources right into assemblies and then access these resources via URLs.  My first impression is that this seems like a good idea but I'm wary because I've been burned by MS's good ideas in the past.  My main concerns are debugging and the effect this embedding has on caching. 

Caching

One of the problems with frameworks like ASP.NET is that they sometimes take you too far away from the underlying system.  HTTP and HTML is rather straight forward.  Embedded resources in ASP.NET call the the resources via URL's and  use cache headers to insure the browser caches the content correctly.  Also the output cache in the form of disk output cache is automatically used to cache these resources.  So these embedded resources should still allow a fairly performant solution.  My question is still whether this is as good as a plain static file and the caching IIS can perform on these files.  I still need to research this.

Debugging

One of the problems I've run into involves debugging.  When a JavaScript file is embedded and it contains an error, Visual Studio.NET 2005 will open a file dialog asking for the location of the file.  This is a pain as you lose the precious JavaScript debugging ability that we gained with VS 2005.  Is this behavior by design or is there something I'm missing in regards to debugging JavaScript as an embedded resource?  My tempo ray solution is to keep the JavaScript files in a static folder while I'm debugging and then switch them to Embedded Resources when I'm deploying the control. 

However on the plus side of debugging when you change the JavaScript file it is automatically picked up the next time you do a build.  The URL of the embedded resource is changed and thus the browser grabs the newer file.  However this has a downside in that you must stop the running project to make changes to the JavaScript file and then rebuild the project to have the changes show up.

I've found that the static file path is much easier for debugging.

 An excellent article that I've referenced for this post:

http://www.nikhilk.net/WebResourceAttribute.aspx

 |  |  | 
Tuesday, June 27, 2006 3:45:02 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, June 22, 2006

I've upgraded the GreaseMonkey Google Navigator script to fix some minor issues with the next and previous keys in groups.google.com and I've added the "open link in new tab" functionality via the 't' key.  Check it out:

http://userscripts.com/scripts/show/3984

Or right here at:

http://www.pragmaticprose.com/content/binary/googlenavigator.user.js

Thursday, June 22, 2006 8:36:30 PM (Central Standard Time, UTC-06:00)  #    Comments [1]

This JavaScript Code will cycle through all elements on a page and find the next one that should recieve the focus.  This worked well in IE6 but the results in FireFox where mixed.  I don't have time right now to clean it up but I wanted to post it as this is one of those gems that you know you will want in the future.

Original Source: http://www.codecomments.com/message290822.html

Original Author: Daniel Kirsch

// returns the next focusable object for a given one
function getNextFocusElement(elm,restart,dir,_looped) {
var allElm = document.getElementsByTagName('*');
var found = false; //(start == true);
var allowedElements = 'input,textarea,a,button';
if (!dir) dir = 1;
var start = dir > 0 ? 0 : allElm.length-1;
var end = dir > 0 ? allElm.length : -1;
jslog.info('start: ' + start + ' end: ' + end);

for (var i=start; i!=end; i+=dir) {
if (!found) {
if (allElm[i] == elm) {
if (_looped) return null;
found = true;
jslog.info('i: ' + i );
continue;
}
}
if (found || (restart && _looped)) {
if (allElm[i].focus && allElm[i] != elm) {
if (isInList(allElm[i].nodeName.toLowerCase(),allowedElements)
&& isVisible(allElm[i]))
jslog.info('i: ' + i);
return allElm[i];
}
}
}
jslog.info('starting next loop...');
return (_looped) ? null : getNextFocusElement(elm,true,dir,true);

}

function isVisible(elm) {
if (elm.style.visibility == 'hidden' || elm.style.display == 'none')
return false
else
return elm.parentNode && elm.parentNode.style ?
isVisible(elm.parentNode) : true;

}

function isInList(aItem,aList,aSep,aCaseSensitive) {
if (typeof aItem == 'undefined' || typeof aList == 'undefined')
return false;

// make sure, the element is a string.
aItem = String(aItem);
if (aCaseSensitive !== true && typeof aItem == 'string') {
if (typeof aList == 'string')
aList = aList.toLowerCase();
aItem = aItem.toLowerCase();
}
if (!aSep) aSep = ',';
var lString = aSep+aList+aSep;
return (lString.indexOf(aSep+aItem+aSep) > -1);

}

Thursday, June 22, 2006 1:19:21 PM (Central Standard Time, UTC-06:00)  #    Comments [1]
 Monday, June 19, 2006

Do you want to limit the imput of a text input (textbox) to valid date characters?  Here you go:

// START SCRIPT

function runKeyFilter(e) {
 if (e.srcElement.readOnly) return;

 var key_code = e.keyCode;
 var oElement = e.srcElement;
 //alert (key_code);

 try {
  if (!window.event.shiftKey && !window.event.ctrlKey && !window.event.altKey) {
   if (
     (key_code > 47 && key_code < 58) ||  // numbers on top of keyboard
     (key_code > 95 && key_code < 106)  ||  // number on numpad at right of keyboard
     (key_code > 36 && key_code < 41) ||  // arrow keys
     (key_code == 35) || // end
     (key_code == 36) || // home
     (key_code == 45) || // dashes
     (key_code == 111) || // forward slash /
     (key_code == 191) || // forward slash /                      
     (key_code == 8) || // backspace
     (key_code == 46) || // delete
     (key_code == 9) || // tab
     (key_code == 16) //SHIFT TAB
      )
   {
    e.returnValue = true;
    return;
   }      
  } 
 }
 catch (ex) {
  alert('Error Message: ' + ex.message );
 
 }
 // if we get here then we didn't have a number
 e.returnValue = false;

}  // end runKeyFilter()

//using the helper functions from prototype.js
Event.observe('|CONTROL|', 'keydown', runKeyFilter, false);  

// END SCRIPT

Monday, June 19, 2006 1:22:50 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, May 01, 2006
Yet another Greasemonkey script.  This one is for navigating the My Yahoo page with the keyboard.  Press H once you install it to get the key mappings.

myyahoonavigator.user.js (3.9 KB)
Monday, May 01, 2006 2:11:49 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Sunday, April 30, 2006

A Greasemonky script( http://greasemonkey.mozdev.org/ ) to allow keyboard navigation of google pages including the search results.  Press the H button once the script is installed for more help.

googlenavigator.user.js (8.07 KB)
Sunday, April 30, 2006 11:42:54 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, February 14, 2006

This seems to be an under documented feature of ASP.NET 2.0.

You can easily embed resources (text files, images, etc) in you assemblies.  This is very handy for server control deployment.  However the documentation for this is somewhat lacking.

Here goes:

At the top of your class add an attribute to allow an embedded attribute:

[assembly: WebResource("MyProject.ResourcesFolder.JavascriptFolder.AutoCompleteTextBox2.js", "text/javascript")]

(This can also go in the AssemblyInfo.cs)

One big gotcha here is the fact that the first argument is the default namespace + folder location + the actual name of the file to embed.

So if my default namespace is "MyProject" and the file is located in /Resources/Javascript and named AutoCompleteTextBox2.js then the resource will be embedded correctly. 

Then to make sure that the javascript link is embedded in the page:

protected override void OnPreRender(EventArgs e)
{
    this.Page.ClientScript.RegisterClientScriptResource(

       typeof(MyType), 

       "MyProject.ResourcesFolder.JavascriptFolder.AutoCompleteTextBox2.js");

    base.OnPreRender(e);
}

You need to place this in the PreRender event handler for the code to be placed correctly in the page.

Finally, make sure your resource is compiled into your assembly.  By Changing the build action on EACH resource that you want to include.  Check out the image below.  the date_control.js file is now an embedded resource and can be accessed using the methods listed above.


Tuesday, February 14, 2006 3:42:04 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, December 15, 2005

You may be annoyed if you are used to a convenient trim function on your strings that eliminates leading and trailing whitespace and you've found that it doesn't exist in javascript.

Here's a quick fix:

//start code
// add the missing trim functions
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };

//end code

Add this in any javascript file or in between some <script> tags and your javascript strings will magically have the trim function.

This is because javascript classes are mutable.  There is a more accurate and technical explanation but I will spare you the pain. 

We are simply adding the trim function to the string class at runtime.  The trim function uses regular expressions to trim the string of leading and trailing whitespace. 

Thursday, December 15, 2005 11:47:55 AM (Central Standard Time, UTC-06:00)  #    Comments [0]