Andrew Whitaker

jQueryUI Autocomplete 1.9

without comments

As you might have realized from my previous post, I have an affinity for the jQueryUI autocomplete widget. With 1.9, which was recently released, autocomplete got a little love, which is what I’ll focus on in this post. I’ll go over each change and what practical implications it has.

  1. The response event

    Previously, it wasn’t possible to determine when a search had completed unless results were returned (in which case the open event was triggered). There are several ways to get around this limitation, but none of them use autocomplete’s API. This limitation made it hard to perform actions if the search returned zero results.

    Here’s what you would have had to do in jQueryUI 1.8:

    Here’s what you can do in 1.9:

    Much cleaner. This works for an autocomplete-enabled input with a remote source as well:

  2. Synchronous change event

    This is fixing a subtle, but important, limitation in 1.8′s autocomplete implementation. The change event used a small timeout right after the blur occurred. Most of the time this didn’t cause a problem, but if you wanted to validate that the user selected an item from the suggestion menu, the user could actually submit the form before the change event fired. This is best seen with an example:

    If you select an item from the menu after searching, then click out of the field (enabling the submit button), then focus the input field again and change the input’s value to something not in the suggestion list, you can submit the form.

    In 1.9, this works much better and you can prevent the user from submitting the form entirely:

    Try following the steps for the 1.8 example, and you should not be able to submit the form.

  3. Support for contentEditable

    This enhancement allows you to attach autocomplete to a contentEditable element. This functionality was not possible in 1.8. This has some very cool applications that I’ll explore in a later blog post, but here’s a simple example:

  4. Blurring a suggestion no longer changes the input’s value

    This one is hard to explain, but follow the steps outlined in the 1.8 fiddle below to see the problem:

    Now, follow the same instructions in 1.9:

    See the difference? In 1.9, the input’s value is not reset when the menu item is hovered over.

  5. Added experimental messages option for accessibility

    The jQueryUI folks explain this one better than I can show with an example:

    We now use ARIA live regions to announce when results become available and how to navigate through the list of suggestions. The announcements can be configured via the messages option, which has two properties: noResults for when no items are returned and results for when at least one item is returned. In general, you would only need to change these options if you want the string to be written in a different language. The messages option is subject to change in future versions while we work on a full solution for string manipulation and internationalization across all plugins. If you’re interested in the messages option, we encourage you to just read the source; the relevant code is at the very bottom of the autocomplete plugin and is only a few lines.

    I’m not an accessibility expert, so I had to look up what ARIA live regions are. MDN has a great explanation:

    In the past, a web page change could only be spoken in entirety which often annoyed a user, or by speaking very little to nothing, making some or all information inaccessible. Until recently, screen readers have not been able to improve this because no standardized markup existed to alert the screen reader to a change. ARIA live regions fill this gap and provide suggestions to screen readers regarding whether and how to interrupt users with a change.

    So how does this apply to the autocomplete widget? Well, now when you search for an item, if you have a screen reader installed it will read you something like “1 result is available, use up and down arrow keys to navigate.”. Pretty cool, huh?

I’ve outlined each enhancement to jQueryUI autocomplete in the 1.9 release. There are some exciting possibilities, specifically with the contentEditable support and the exposure of the Menu widget as a first-class widget. I’ll be sure to follow up on those topics in a subsequent post.

Written by Andrew Whitaker

October 8th, 2012 at 9:37 pm

jQueryUI Autocomplete: Top 5 sources of confusion

without comments

I’ve been answering jQueryUI autocomplete questions on StackOverflow now for over two and a half years and I’ve noticed that there are a few things that are always coming up. This post will attempt to clear up those sources of confusion.

  1. jQuery Autocomplete vs. jQueryUI autocomplete

    jQuery autocomplete is jQueryUI autocomplete’s predecessor. Despite the multiple messages and disclaimers on the legacy plugin’s page, there is still confusion about the documentation, functionality, and status of this plugin. For some reason, some folks do not notice the following message on Jörn Zaefferer’s documentation page for the plugin:

    This plugin is deprecated and not developed anymore. Its successor is part of jQuery UI, and this migration guide explains how to get from this plugin to the new one. This page will remain as it is for reference, but won’t be updated anymore.

    The link to the migration guide explains how to migrate your old code using the original, deprecated plugin with the new one provided by jQueryUI.

  2. What format does my data need to be in?

    Another source of confusion is exactly what format does the widget’s data source need to take? This is easy to see after viewing a few examples and reading the overview tab on the documentation page.

    To summarize, the data that you send to the widget needs to be:

    1. An array of strings
    2. An array of objects. Each object should have a either a label property, a value property, or both.

    An important point on #2 is that the object can contain other properties (besides label or value). This comes in handy when doing custom things with data.

  3. I am using a server-side source and my data isn’t being filtered!

    When you use a server-side resource, you are responsible for doing the filtering. Usually this occurs by building up a database query based on the term that the user searched for.

    If you don’t want to filter your data with server-side code (which I highly recommend), you could retrieve all of the possible results via AJAX and then let the widget do the filtering. Here’s an example using StackOverflow’s API:

    This may not be ideal depending on the size of the data you are processing. You may want to handle the filtering on the server rather than bogging the browser down with filtering through thousands of results.

  4. I’m using a server-side resource that isn’t returning data in the format that autocomplete is expecting. What should I do?

    You can supply a callback function to the source parameter of autocomplete. This allows you to use virtually any source as long as you format it correctly before passing it to the response function that autocomplete uses to populate the results. Here’s another example using the StackOverflow API:

    The key here is to use $.map to transform the results into the format that the widget expects (described above).

  5. I want to implement tagging functionality. How can I go about that?

    This is the most complex of the 5, but it is doable. Check out the multiple values demo for one way to do this.

    I’ve demonstrated a more complex Google-plus like functionality in the answer to this question. Here’s an updated fiddle using the 2.1 version of the API.

    This demo is also useful because it shows a custom display of each tag including the count. Type @j to see tags starting with “j”.

jQueryUI autocomplete’s API may look simple at first glance, but this is a very extensible and capable plugin. Most people’s questions revolve around the source parameter for the plugin. Remember to look at your AJAX requests in Firebug or similar just to make sure the data you’re supplying to the widget is what you expect.

Written by Andrew Whitaker

September 29th, 2012 at 2:31 pm

jQuery.aggregate: A simple jQuery aggregation plugin

without comments

I’ve found myself needing to apply an aggregate function over a jQuery object several times. I decided to wrap the functionality in a plugin. I attempted to make $.aggregate and it’s little brother $.sum as close to LINQ’s aggregate and sum as possible. This goal obviously couldn’t be completely realized because of the dynamic nature of JavaScript. The biggest roadblock there is that you can’t really imply a “seed” value for an aggregating operation, since arrays can contain elements of various types in JavaScript.

Let’s take a look with an example:

Here, we’re building up a message from an array of numbers that correspond to letters of the alphabet. We supplied the aggregate function with a source and a function describing how we wanted to build the aggregate, based on the current value we’re iterating over and the “working” aggregate (what we’ve built up so far).

The conditional operator inside the aggregate function is kind of awkward, so lets supply an initial “seed” value to the aggregate:

Finally, we may want to supply some sort of final transformation function to our aggregated value. With the aggregate plugin, you can supply a function that will transform the aggregated value before returning it:

That’s pretty much it for $.aggregate. You should be able to get pretty creative with it.

$.sum is just a convenient way to call $.aggregate. After implementing $.aggregate, $.sum was pretty easy. $.sum sheds some parameters, but is much more readable if all you’re doing is adding some values up:

Much neater right? You can also supply a transformation function that should return the item to be “summed”:

That’s pretty much it for the “static” functions. Both $.sum and $.aggregate can take an object or an array of values to aggregate.

There are also “instance” methods on jQuery objects. These methods operate on jQuery objects:

(Aggregate follows the same pattern).

I’m also toying with the idea of adding $.min and $.max.

If you want to download, view the source, or run the unit tests associated with the plugin, I have it up on Github. Minified version coming soon.

Written by Andrew Whitaker

December 22nd, 2011 at 7:39 pm

Retrospective: 1 year of StackOverflow

without comments

About one year ago this month I joined StackOverflow and started participating. I wanted to take a few minutes to reflect on my experience the site. First off, why did I start answering questions?

  • A living portfolio; My StackOverflow profile is something that’s constantly growing and that I can show to employers
  • Learning. Just spending time on the site allows you to learn new things.
  • Helping others. I use tons of free software every day. This is my way of giving back.
  • Pick up new problem-solving skills. Seeing the ways others answer questions gives you a view into their thought process. Seeing solutions that you wouldn’t necessarily have come up with yourself adds tools to your problem-solving toolbox.

When I started out, answering questions was a horrifying prospect: I’m going to put something on a high traffic programming site for other people to vote on? I was sure I’d mess up and get downvoted. Over 500 answers later though (and a 15K reputation), my stage fright has subsided.

I started out motivated by the reputation system (it’s addicting). After a while though, there has to be another motivator. For me, that motivator is the knowledge that with an answer you might be helping thousands of people all over the world Googling for a problem. How cool is that? There’s also the fact that you’re learning too when you answer a question.

I quickly figured out what makes a high-quality answer (beyond the qualities of a simply “good” answer):

  • Provides a working code sample
  • Provides a good explanation of that sample (just giving people code isn’t helpful after all)
  • Links to relevant documentation
  • Link to a demo, if possible

The last point (linking to a demo) turns out to be very important. If the asker can take your code and play around with it immediately, you’re much more likely to get more upvotes and that coveted green check mark. It’s hard to argue with a working example.

For that reason, I quickly gravitated to the JavaScript, jQuery, and jQueryUI tags. With those tags, I can almost always provide a working example in an answer. JavaScript sandbox site JSFiddle proved invaluable for providing working examples.

After spending some time in those tags, I noticed the “fastest gun in the west” problem. Since I wanted to provide high-quality answers in crowded tags (where answers to simple questions are posted very quickly), I started to get more specific in the tags I watched.

Specifically, I moved toward jQueryUI-Autocomplete. Not too many people were watching questions about that widget, so it gave me more time to come up with a high-quality answer. At the same time, jQueryUI is a popular enough framework that my answers did get attention.

This is probably my biggest tip for new StackOverflow answerers: If you’re overwhelmed by the quick answers and high activity in tags, find a specific type of question within that tag to focus on.

I also set goals while on StackOverflow. I wanted to get 10K reputation by the end of the year (which I’ve met and exceeded). I also wanted a silver badge (400 upvotes) in the jQuery tag. Setting goals like this keeps it interesting. You can set goals for each tag and increase your own knowledge of a particular tag substantially.

My goals for next year include:

  • Getting a gold badge in jQuery (1000 upvotes)
  • Getting a silver badge in C# (yep, I need to branch out)
  • Edit 600 posts

The most valuable thing I’ve gotten out of StackOverflow over the last year? Better communication skills. I believe my ability to communicate a technical problem with other technical people has improved substantially. Part of providing a good answer is providing a clear explanation. This skill translates directly into the professional world.

Good luck out there, and don’t hesitate to sign-up and start answering.

 

Written by Andrew Whitaker

November 13th, 2011 at 12:16 am

Posted in Programming

Tagged with ,

Another Reason not to use Digsby

without comments

I stopped using Digsby in favor of Pidgin when I discovered the “Now playing” feature puts a link to Amazon music in your status when you use it, without your permission (I don’t know if this is still a “feature,” I haven’t looked back since then).  Similarly, today I read an article on The How-to Geek about Digsby’s installer containing tons of junk software.

I understand the need for developers to make money (I do it for a living too).  But when developers do stuff like this it repels me from ever using the product.  There are a few alternatives for Digsby besides taking the lazy route and putting crap on unsuspecting people’s computers:

  1. Come up with a revenue model before creating a product, if you want to make money:  Obviously the Digsby people want to make some money from their product.  If this is the sole purpose of Digsby, they should figure out a creative way to make money from the IM client (which lots of people love) that doesn’t involve bloated installations or advertisements in users’ away messages.
  2. Add a “Please Donate” button in the Help -> About and on the website.  This probably won’t make a whole ton of money, but if that isn’t Digsby’s goal, then why not?
  3. Make a “pro” version and a free version (kind of like Trillian).  It might be too late for them to take this route, since they offer the whole thing for free now.

Anyway, if they keep this up I’m never going back.  I strongly recommend the open-source Pidgin if you want a free IM client that supports multiple protocols.

Software that does this drives people away, and makes the software very unprofessional.

Written by Andrew Whitaker

July 7th, 2009 at 6:26 pm

Americans, Falling Behind in Technology?

without comments

Go read The World is Flat.

Next, read this article, and you’ll understand where Vineet Nayar is coming from when he calls American IT graduates “unemployable.”  Unfortunately, I think its partly true.  In The World is Flat, Friedman warns Americans that they need to beef up education in general, and start getting students enthused about math, science, and IT.  At one point, he talks about how America still has the best graduate schools in the world.  This is changing fast though.  India in particular, although it has problems, has some very good undergraduate schools, and consequently all kinds of great companies (American and Indian alike).

How can we make students better?  Realize its a globalized world and start keeping the Indian and Chinese geniuses that come here for graduate school in the country, instead of sending them packing.  If we keep those genius kids, they’ll turn into great IT professionals or computer science professors.  We should also make it easier for potential students to get into the country.  Obviously, keeping the country safe is a priority, but we really should be letting smart people in here to contribute to our society and economy.  After all, isn’t that better than them going back home and helping their economy grow better than ours?

Go read The World is Flat.

Written by Andrew Whitaker

June 24th, 2009 at 8:11 pm

Posted in Uncategorized

A solution for Pandora and XM/Sirius

without comments

I am an XM subscriber–I like having XM because I get hundreds of commercial free music/news channels wherever I go.  I usually pick XM over my iPod for one simple reason: I discover new music on XM.  I listen to Pandora for the same reason.  This is the big difference between listening to radio or listening to music you “own,” and Pandora is much more appealing than conventional radio because it takes the extra step of picking out music you’ll like.

Wouldn’t it be cool if you could sign up for a Pandora and XM/Sirius service that would stream your Pandora station(s) to your XM reciever?  Sure, I don’t know what all the details would be, but setup seems pretty simple.  Today, if you went and bought an XM reciever (I know, unlikely) and subscribed, you would have to call XM or get online and enter your radio’s ID.  A similar method could be used in conjunction with your Pandora account:  Go to Pandora’s website and enter your XM radio’s ID, linking the two accounts.  There would probably have to be some hard limit of the number of Pandora stations each user could stream, but perhaps you could purchase new stations to stream to for a monthly fee.  You could get on Pandora and assign your favorite Pandora stations to corresponding XM stations.

The tricky part would definitely be thumbs up and down, and skipping songs.  Maybe the idea isn’t feasible just because of  the nature of Pandora and the power of thumbing up/down songs.  If you’re on a long trip, you want to be able to thumb up/down your songs while you’re driving so that your station gets better.

Maybe my idea wouldn’t work but I see similarities between XM/Sirius and Pandora.  Both radio(ish) music services with a need for income.  Pandora’s problem is that the company has no revenue model, and XM/Sirius’s problem is competition with iPod and digital music.  If the two somehow figured out streaming Pandora stations to XM/Sirius subscribers, both companies’ listeners could potentially benefit from the other service.  Additionally, XM/Sirius would benefit from having new subscribers come on board for the Pandora functionality, and Pandora would make part of the XM/Sirius subscription money when users decide to sign up for the “Pandora Package” on XM/Sirius.

Or, if you have an iPhone, you could just hook that up to the AUX port in your car…

Written by Andrew Whitaker

June 1st, 2009 at 5:48 pm

Posted in Technology

The Java to VB.NET Conversion (Part IV)

without comments

Another “feature” in VB.NET that threw me for a loop:  Integer division.  In Java and C++, using the “/” operator with integers truncates the result.  That is, 9/2 yields 4.  If you want the same kind of result in VB, you’ve got to use the “\” operator.  Weird!  And again, just like with the array issue I ran into earlier, why make this functionality different than that of C-based languages?

Read all about it here.

Written by Andrew Whitaker

May 21st, 2009 at 9:38 pm

Posted in Programming

Tagged with ,

The Java to VB.NET Conversion (Part III)

without comments

Today I ran into what I view as another VB quirk:  Array initialization.  In C, C++, and Java, you initialize an array as follows:

[sourcecode language='java']
/* Declares an array with 4 elements, indexed 0 to 3 */
int[] a = new int[4];
[/sourcecode]

The key part of declaring an array here is that you can’t actually index an item at position 4.  a[4] would throw an error.  In other words, the array indices are 0 to (array size -1).

In VB.NET, array initialization is a different story.  You initialize an array using a lower and upper bound:

[sourcecode language='vb']
‘ Declares an array of length 4, indexed 0 to 3
Dim a(3) As Integer
a(0) = 1
a(1) = 2
a(2) = 3
a(3) = 4
[/sourcecode]

Weird right?  At least to us C-based programmers.  I’d love to know the decision behind that one.  I spent a few minutes with the debugger trying to figure out why I should initialize an array with one element like this:

[sourcecode language='vb']
‘ Declares an array of length 1
Dim a(0) As Integer
a(0) = 1
[/sourcecode]

Examples like the above are where you really notice the difference.  I’m sure I’ll get used to this in a while, but I’m not sure that I want to.   All of the programming languages that I’ve come across (besides VB) initialize arrays in the C-style.  Why is VB any different?

Written by Andrew Whitaker

April 20th, 2009 at 8:25 pm

Posted in Programming

Tagged with ,

The Java to VB.NET Conversion (Part II)

without comments

Recently I ran into bugs related to logical operators in VB.  I’ll first go over what Java programmers are used to with logical operators and then explain the issues I was having in VB.

Logical Operators in Java

In Java, the standard logical operators (&& and ||) are short-circuit operators.  This is what you want normally–short circuit operators make more efficient code (your program doesn’t call functions unless it has to), and adds a kind of implicit error handling.  Consider the following Java snippet:
[sourcecode language='java']
int i = 0, j = 4

if (i != 0 &&  j/i > 1) {…}
[/sourcecode]

The above code will never execute j/i if i < 0, because of short-circuit evaluation.  The way I learned Java, && and || were the standard operators.  You can use & and | as logical operators too, but they do not use short-circuit evaluation.

Logical Operators in VB.NET

Perhaps due to my Java background, I though And and Or would be the standard logical operators, and therefore short-circuiting.  This isn’t the case: VB uses AndAlso and OrElse as the short-circuit operators.  The code above would be written as:

[sourcecode language='vb']
Dim i as Integer = 0
Dim j as Integer = 4

If (i <> 0 AndAlso j/i > 1) Then

End If
[/sourcecode]

Based on this article, I’m inclined to believe that short-circuit operators are new in VB .NET (as opposed to VB6).  Why would a programming language not have short-circuit operators as a standard feature?  The results of And and AndAlso will always be the same, unless you call a function in the would-be short-circuited side of an expression, although this seems like bad coding practice to me.

Of course, this is probably a silly post for experienced VB programmers.  This is just my experience as a Java/C/C++ programmer moving to VB.

Written by Andrew Whitaker

April 7th, 2009 at 6:58 pm

Posted in Programming