This is Part 2 of on ongoing series. Part 1 may be read here.
So, last time we used jQuery to build a widget that reminded us how Objective C selector syntax worked. While the code ran, it’s not without its problems.
The biggest problem? It’s obtrusive Javascript. The plugin attached to a single div, meaning without javascript nothing shows up on the page.
This is easy enough to fix with a little rewrite. Here’s the finished product, with an explanation afterwards.
//fake method to past in the box below...
-(void) this:(int)param is:(NSString)param2 an:(NSObject)param3 example:(NSArray)param4
Code Changes
So what’s different? First, our markup
<!-- An Actual textarea -->
<textarea id="widget"></textarea>
<noscript><input type="submit" /></noscript>
We’re placing an actual textarea in the document flow, and a submit button hidden by a <noscript> tag. This way, non-javascript users still see something, and we’re able to provide some kind of server side experience for them.
Next, our jQuery code needs to change. First, we need to make sure our end coder has attached the plugin to the correct element type.
if(this.length === 1 && this[0].nodeName.toLowerCase() == 'textarea'){
//the good stuff goes here
}
else{
throw "Must attach to a single textarea";
}
Inside of a plugin, the this keyword refers to a jQuery object/collection that holds any elements matched when the plugin is attached
//attach a plugin
$('#widget').objectiveCMethodHighlight();
What we’re checking for is
- Have we matched a single element?
- Is that element a textarea?
An alternate, more robust, choice would have been to allow users to attach to as many elements as they want to. The downside is our code structure would need to change to account for multiple instance of the item in the DOM, and we’d have to define/test “what happens when we attach to a textarea vs. an input vs. a div vs. etc.”.
The second change to our code is from inserting into our matched element to inserting after out matched element. Thanks to jQuery, this is a breeze
this.after(buildForm());
this.after('<div id="'+sMethodDisplayID+'"></div>');
Next Steps
So, now we have a much less obtrusive widget. Next time we’ll look at bringing the code into compliance with jQuery’s Authoring Conventions.