Showing posts with label jquery. Show all posts
Showing posts with label jquery. Show all posts

Wednesday, September 21, 2011

Encode HTML Characters in JavaScript using jQuery

Here's a quick post on how to encode and decode HTML characters in JavaScript using jQuery. I didn't come up with the solution, but I thought it was pretty clever.
function htmlEncode(value){
    return $('<div/>').text(value).html();
}

function htmlDecode(value){
    return $('<div/>').html(value).text();
}
Courtesy of http://stackoverflow.com/questions/1219860/javascript-jquery-html-encoding

Wednesday, August 10, 2011

jQuery Naming Conventions: Don't Prefix Variables With $

When working with jQuery, I hate it when developers prefix their variables with dollar signs. For example, var $buttons = $('.button');. In my opinion the dollar sign really hurts the readability of the code.

Some developers claim that adding the dollar sign is a good naming convention because it shows that the value represents a jQuery object. If that's the case, then everybody should start using Hungarian notation all of the time. Gross.

The one exception I might make is for var $this = $(this);, although even then I would rather prefer something like var me = $(this);.

Long story short, don't prefix your variables with a dollar sign. Besides, it's not like you're working with PHP or anything.

Tuesday, December 29, 2009

jQuery Autocomplete and ColdFusion

While migrating my applications from Prototype to jQuery, I needed to replace the Ajax.Autocompleter that comes with script.aculo.us, the effects library written for Prototype.

After a quick Google search, I found a pretty good plugin that looked like it would do what I wanted. However, there was a pretty big difference in how the two plugins work. Ajax.Autocompleter must return an unordered list (<ul>), with each suggestion rendered inside its own list item (<li>). Piece of cake.

However, the jQuery Autocompleter expects a string, with each suggestion rendered on its own line. This threw me for a loop at first, since ColdFusion isn't always the best at dealing with whitespace. After a little thought, here's what I came up with.

index.cfm

<link rel="stylesheet" type="text/css" href="jquery.autocomplete.css" />
<script src="jquery-1.3.2.js"></script>
<script src="jquery.autocomplete.js"></script>

<script type="text/javascript">
$().ready(function() {
$('#search').autocomplete('UserService.cfc?method=autocomplete&_cf_nodebug=true', {
multiple: true,
formatItem: function(row) {
var user = JSON.parse(row.toString());
return user.name;
},
formatResult: function(row) {
var user = JSON.parse(row.toString());
return user.email;
}
});

$('#search').result(function(event, data, formatted) {
var user = JSON.parse(data.toString());
alert('You selected user '+user.id);
});

});
</script>

<input type="text" id="search" name="search" size="60" />


UserService.cfc

component {

remote void function autocomplete(required string q) {

// get the users
var users = searchUsers(arguments.q);
var result = [];
var i = "";

for (i=1; i <= arrayLen(users); i++) {

// build the user record
var user = {};

// maintain lowercase keys
user["id"] = users[i].id;
user["name"] = users[i].name & " (" & users[i].email & ")";
user["email"] = users[i].email;

// serialize the user record and append it to the result
arrayAppend(result, serializeJSON(user));

}

// convert the result from an array to a list, with each user on its own line
var html = arrayToList(result, chr(10));

// output the JSON result
writeOutput(html);

}

public array function searchUsers(required string search) {

// normally this would query the db,
// but for this demo I'll just create a static array of users
var users = [
{id="1", name="Adam", email="adam@email.com"},
{id="2", name="Bob", email="bob@email.com"},
{id="3", name="Brady", email="brady@email.com"},
{id="4", name="John", email="john@email.com"},
{id="5", name="Kaitlyn", email="kaitlyn@email.com"},
{id="6", name="Leanne", email="leanne@email.com"},
{id="7", name="Lisa", email="lisa@email.com"},
{id="8", name="Mike", email="mike@email.com"},
{id="9", name="Nate", email="nate@email.com"},
{id="10", name="Ryan", email="ryan@email.com"},
{id="11", name="Sean", email="sean@email.com"},
{id="12", name="Tony", email="tony@email.com"},
{id="13", name="Tyler", email="tyler@email.com"}
];

return users;

}

}


On a side note, JSON.parse() is a built-in function only available to newer browsers, like Firefox 3.5 and IE 8.0. Does anybody know of a good plugin to accommodate older browsers? Something similar to Prototype's String.evalJSON would be preferred.

Wednesday, December 16, 2009

Migrating to jQuery: My First Plugin

A couple posts ago I wrote about how I couldn't justify switching from Prototype to jQuery. Well I take it back (sort of).

After spending more time with jQuery's event handling, I wanted more out of Prototype and I couldn't justify trying to port what I wanted over from jQuery and expect it to work across all browsers. I'd rather let jQuery and its large, active community help me out with testing. So I've begun the process of converting a good portion of my applications over to jQuery.

While updating the code is more tedious than anything, I found myself missing the convenience of Prototype's direct access to DOM elements. For example, I no longer have the following:


if ( $('checkboxA').checked ) {
$('checkboxB').checked = false;
}


Granted with jQuery there are multiple ways to accomplish the same thing but, while they're not too much longer, they're still longer:


if ( $('#checkboxA').attr('checked') ) {
$('#checkboxB').attr('checked',false);
}

if ( $('#checkboxA').is(':checked') ) {
$('#checkboxB').removeAttr('checked');
}

if ( $('#checkbox:checked').length ) {
$('#checkboxB').attr('checked',false);
}


Since I like to write as little code as possible and everybody else seems to really like jQuery's plugin architecture, I figured I'd try write my own plugin. And since it's my first plugin, please don't make too much fun of it.


jQuery.each(('checked,disabled').split(','), function(i, name) {
jQuery.fn[name] = function() {
return arguments ? this.attr(name, arguments[0]) : this.attr(name);
};
});


It works similar to the built-in jQuery event helpers, such as $(selector).change() and $(selector).click(fn). In my plugin, if you pass an an argument, it sets the attribute's value. If you don't pass in an argument, it returns the attribute's value.

Here's how I can write my sample code now:


if ( $('#checkbox').checked() ) {
$('#checkboxB').checked(false);
}


I'll admit it's not much shorter, but it reads a lot better to me. Plus, I don't have to directly call .attr() anymore, which is basically just a generic getter/setter. And if you didn't notice, I also added the same logic for .disabled() for good measure.

I haven't decided if I want to fully embrace a plugin that accomplishes something so trivial, but for some reason I like it.

Thursday, December 10, 2009

Firing Native JavaScript Events using Prototype

I've been using Prototype as my JavaScript library of choice for a couple years now. While I'll admit I would probably choose jQuery if I were to rewrite all of my code from scratch, that's simply not an option at this point. I can't justify rewriting perfectly good code for the sake of rewriting it -- if it ain't broke, don't fix it.

For the most part, Prototype has everything I need: Ajax, CSS selectors, DOM manipulation, event handling, and a slew of convenience methods for working with objects and classes. However, I've always been a little bothered by the inability to fire native JavaScript events, meaning there's no way to fire an element's change event. While Prototype allows you to fire custom events using Element.fire, all event names must be namespaced using a colon, which rules out $(id).fire('change').

So today, after some quick Googling, I wrote my own Prototype-based version of jQuery's change() method in order to fire native events. Here's what I came up with:


(function() {
var methods = {};
var events = 'blur,change,click,dblclick,error,'+
'focus,keydown,keypress,keyup,load,'+
'mousedown,mouseenter,mouseleave,'+
'mousemove,mouseout,mouseover,mouseup,'+
'resize,scroll,select,submit,unload';
events.split(',').each(function(event) {
methods[event] = function(element, fn) {
if (fn == undefined) {
if(document.createEvent) {
var evt = document.createEvent('HTMLEvents');
evt.initEvent(event,true,true);
return !element.dispatchEvent(evt);
}
else {
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt)
}
}
else {
element.observe(event,fn);
}
}
});
Element.addMethods(methods);
})();


With this, you can simply call $(id).change() to fire the element's change event or $(id).change(function(){...}) to add an observer to the element's change event.

I did a quick test and it seems to work in both IE8 and Firefox, but I can't guarantee anything about older browsers, so use at your own risk.

On a final note, I don't know why Prototype seems to be overlooked by so many people in favor of jQuery. I actually prefer the Prototype syntax in many cases, but that's probably because I've been working with it longer. Maybe it's because developers who weren't too familiar with JavaScript stumbled upon jQuery one day and decided they didn't have to look at any other libraries out there, which seems really wrong to me. That would be the same as choosing Mach-II without looking at Model-Glue or ColdBox. Or choosing PHP without looking at ColdFusion or Ruby. You really can't know if you've made the right decision unless you've evaluated all your options.

Monday, February 9, 2009

jQuery vs Prototype

After using Prototype for the past 3 years, I've decided to check out jQuery a little more. I first heard about jQuery around a year and a half ago, but didn't spend too much time working with it since Prototype had everything I needed. After reading how everyone gushes over jQuery, I figured I should give it another shot, at least for comparison sake.

After first pass, it seems pretty powerful. The markup is a little foreign at first compared to Prototype. I'm not saying it's better or worse, just different. The selectors are much better in jQuery, which might be reason enough to convert. I haven't worked with Ajax in jQuery yet, but from what I've read the syntax appears pretty simple. Granted the syntax in Prototype is pretty simple too, so that's not such a big deal.

The biggest pain transition is going to be adjusting to the new $ method, which now returns an array of jQuery objects. Not exactly looking forward to the confusion.