Coldfusion Builder 2 Beta and jQuery Code Assist

I am currently using ColdFusion Builder 2 Beta for my primary projects. One item I noted was the lack of jQuery code assist.

I did find a way to turn code assist on for jQuery 1.3. After some research I really haven’t found a way to include 1.4, 1.5 or 1.6RC. But 1.3 is better than nothing.

To turn on jQuery 1.3 code insight go to [ preferences > HTML > Editors > JavaScript > Code Assist ] and select jQuery 1.3. After you click [OK] jQuery code insight will work right away.

If anyone knows how to upgrade the versions w/o major work please let me know. Thanks!

Global AJAX Loading Spinners

Many sites include what are known as AJAX Spinners. They are little graphics that show up on a web page that show something is happening behind the scenes. This is most commonly used when an AJAX request is being made and the end-user is waiting for a response.

There are many different ways you can make this happen.

One is to show and hide the spinner inside each AJAX method. Another is to show and hide the spinner inside the jQuery $.ajaxSetup configuration.

If you load individual spinners for each call this is a pain and can be cluttering. If you load a common spinner you can end up hiding it before a parallel request is finished unless you look at a queue, which is also a pain.

One easy way around all this confusion is to use jQuery’s global AJAX handlers: .ajaxStart and .ajaxStop (also look at .ajaxError)

First setup a common spinner container and graphic.

<style>
#ajaxSpinnerContainer {height:11px;}
#ajaxSpinnerImage {display:none;}
</style>

<div id="ajaxSpinnerContainer">
<img src="/images/ajax-loader.gif" id="ajaxSpinnerImage" title="working...">
</div>

One great place to generate these spinners is ajaxload.info.

The next step is to show the spinner when any AJAX request has begun and hide it when all AJAX requests have completed.

$(document)
.ajaxStart(function(){
    $("#ajaxSpinnerImage").show();
})
.ajaxStop(function(){
    $("#ajaxSpinnerImage").hide();
});

This quick and easy method avoids all the other headache associated with all the other techniques out there as long as you want the spinner shown in a single container.

#ajax, #jquery, #spinner

jQuery Templates

I decided to dig into the new official jQuery Template Plugin developed from Microsoft yesterday. After I finally got the darn thing to work it makes inserting formatted HTML populated with data way easier.

After doing some searches on Google I kept finding articles that announce that Templates would be built into the version 1.5 core. I continued down the path coding by example and researching the API Docs. However I kept running into “tmpl is not a function”. After some continued research I finally found a tiny little comment made by John Resig that it in fact did not make it into the 1.5 release. So now that error makes sense.

To resolve this issue you must still load the jQuery plugin. It appears the plugin is still in beta stages and is available for download from Github or the Microsoft CDN.

Before I’ve been unable to use Microsoft’s CDN because it did not have SSL. But I went ahead and tested to see if they now have it included, and they do!

Here’s how I use it:

<script src="//ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>

This will automatically call it via http or https depending upon the current browser protocol being used.

See a related blog for jQuery on Google’s CDN here.

#cdn, #google, #jquery, #microsoft, #plugin, #template

“How to spot outdated JavaScript”

I ran into a blog entry today by David B. Calhoun on “How to spot outdated Javascript”. I found it to be such a great resource that I had to put it here so I can always reference it.

There’s a gazillion references out there on how to do things in JavaScript, but hardly all of them are correct. So how do you know what not to do?

This blog entry not only tells you what not to do but why not to do it.

Check it out here: http://davidbcalhoun.com/2011/how-to-spot-outdated-javascript

Javascript Date Compare

I needed to validate if an end date was greater than or equal to a start date. To do this I was using:

var elemFromVal = $('#elemFromVal').val();
var elemToVal = $('#elemToVal').val();
return elemFromVal <= elemToVal;

This was working up until the point the years where different. For example “12/1/2010” to “12/2/2010” would work but not “12/1/2010” to “1/1/2011”.

To fix this issue I needed to create a new date object and compare those instead:

var elemFromVal = $('#elemFromVal').val();
var elemToVal = $('#elemToVal').val();

var d1=elemFromVal.split('/');
var d2=elemToVal.split('/');

var startDate=new Date(d1[2],(d1[1]-1),d1[0]);
var endDate=new Date(d2[2],(d2[1]-1),d2[0]);

return startDate <= endDate;

Incrementing Dynamic HTML Element Attributes

On occasion I clone DOM elements to repeat form sections dynamically. During this I need to increment the name and id attributes so I can reference them later on.

For example: name=”txtField1″ becomes “txtField2”

To make this happen I use a little but of slick jQuery magic. This increments the id and name attributes and empties the value for input, select, and textarea elements.

var newNum = new Number(num + 1);
var newElem = $('.clonedInput:last').clone(false).attr('id', 'input' + newNum);
newElem.find('input,select,textarea')
    .attr('name', function() {
        return $(this).attr('name').replace(/^(.+?)(\d+)$/, function(s, p1) {
            return p1 + newNum;
        });
    })
    .attr('id', function() {
        return $(this).attr('id').replace(/^(.+?)(\d+)$/, function(s, p1) {
            return p1 + newNum;
        });
    })
    .val('');

I started out using the regex:

^(.+)(\d+)$

But that failed after 10. The .+ expression needs to be non-greedy using:

^(.+?)(\d+)$

Here’s another example using a table and an button to create a new row:

$("#productChildren").delegate("#btnAddAdditionalProductChildren", "click", function(event) {
	var $clone = $("#productChildren > tr").last().clone(false);
	$(this).remove();
	var $inputs = $( $clone ).find("input[type='text']");
	$($inputs).each(function() {
		var newNameAttr = $(this).attr('name').replace(/\d+$/, function(match, p1) {
			return parseInt(match) + 1;
		});	
		$(this).attr('name', newNameAttr);
		$(this).val('');	
	});
	$($clone).appendTo("#productChildren");
});

non-breaking spaces and jQuery.trim()

When performing a .trim() function on a string pulled via the .text() tag in jQuery, &nbsp; will convert into a special space that will not be removed.

Example:

<div id="div1">  This is text  </div>

<script type="text/javascript">
jQuery(document).ready(function() {
trimString = jQuery.trim($('#div1').text());
</script>

I was able to catch the Unicode character, which ended up being 160, by using:

alert(trimString.charCodeAt(0));

After performing a regex replace on the string, I was able to achieve a truly trimmed string.

<script type="text/javascript">
$(document).ready(function() {
trimString = $('#div1').text();
var re = new RegExp(String.fromCharCode(160), "g");
trimString = jQuery.trim(trimString.replace(re, " "));
});
</script>

Duplicate Errors Using jquery.validate on Dynamic Forms

I have a form that clones a div upon clicking an add button. For validation I use the jquery.validate plugin. When the add button is clicked, I exectute the following to clear the errors.

validator.resetForm();

However, if inline errors are displayed before this being called, and then they are displayed again after the form is reset, the inline errors are displayed one time on the first div, two times on the second div, and so-forth. The alleviate this issue I’m now destroying the error element.

validator.resetForm();
$('label.error').remove();

jQuery UI datepicker and Dynamic Forms

When implementing jQuery UI’s datepicker in a dynamic form, you may notice that it will break as you bind it to new elements. The datepicker method adds a “hasDatepicker” class which must be removed first.

This example finds all the elements with a “datePicker” class and removes the “hasDatepicker” class from the element. It then calls the datepicker method and binds the .datePicker class again.

$('body').find(".datePicker").removeClass('hasDatepicker').datepicker();

 

Move Scripts To Bottom

Last night’s jQuery Meetup was once again pretty awesome. Thanks again to BrightMix for hosting it and providing the Pizza and to Jonathan Sharp for making it all happen.

Andrew from Blue Cross Blue Shield presented on AJAX. He showed us his concept of building a global jQuery handler using a Namespace. This would allow other programmers in the organization and himself to skip all the repetitive programming. Some examples included a predefined spinner object and a global AJAX error handler. He’ll post his example to the group and I’m sure I’ll benefit from it in my projects.

One thing that caught my attention was with any larger JavaScript scripts you should consider moving the include to the bottom of the body tag. He explained this was so the page will load without hanging on scripts that must parse a lot of information. So I did a little research on this.

Remember Microsoft’s Blue Screen of Death? Thank God I haven’t seen this in a long time thanks to advancements in XP, Vista and 2007! Well, apparently there’s a similar “White Screen of Death”. This happens when the browser gets caught up in the JavaScript code for awhile before passing the content to the DOM. To avoid this move the script include to the bottom of the body tag. This will load the content into the DOM and then load things like the JavaScript and images.

The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. This is where CDN’s (content delivery networks) come into place nicely. While your website is loading your content and images using only two parallel paths, a third path can be opened to load libraries such as jQuery, not to mention it may already be cached in the browser if they visited another site using the same CDN.

I’ve always been taught to include CSS and JavaScript in the head tag, but I never really looked into the reasons behind it. Technically they can be included almost anywhere in the page. In the case of CSS includes, what you get is the Style Sheet is loaded and then the content when the CSS is included in the head tag. So when the content is being displayed, it progressively styles the content instead of going back after it’s all loaded and then style it causing some visual confusion.

Yahoo! Developer Network provides a great document titled “Best Practices for Speeding Up Your Web Site“. there are 35 best practices in 7 categories including conent, server, cookie, CSS, JavaScript, Images, and Mobile.

One more thing I picked up on; and I know I’ve seen it before; is how to break up large string blocks in JavaScript. Consider the following:

$('div').append('<ul><li>item1</li><li>item2</li><li>item3</li><li>item4</li><li>item5</li><li>item6</li></ul>');

Break it up into multiple lines for better code organization using the + sign:

$('div').append('<ul>'
+ '<li>item1</li>'
+ '<li>item2</li>'
+ '<li>item3</li>'
+ '<li>item4</li>'
+ '<li>item5</li>'
+ '<li>item6</li>'
+ '</ul>');