Yehuda Katz is a member of the Ember.js, Ruby on Rails and jQuery Core Teams; his 9-to-5 home is at the startup he founded, Tilde Inc.. There he works on Skylight, the smart profiler for Rails, and does Ember.js consulting. He is best known for his open source work, which also includes Thor and Handlebars. He travels the world doing open source evangelism and web standards work.

Archive for the ‘jQuery’ Category

Using SproutCore 2.0 with jQuery UI

One of the goals of SproutCore 2.0 is to make it trivial to integrate the tools you’re already using together with SproutCore.

One way that we do that is to make it possible to drop a SproutCore app into a small part of your existing page. Greg Moeck did a great job demonstrating this functionality on the SproutCore Blog a couple of weeks ago, and I’d definitely recommend checking it out if you’re interested in learning more about embedding SproutCore 2.0 in an existing app.

Another complementary approach is to make it easy to integrate SproutCore with existing JavaScript libraries and tools. Because SproutCore 2.0 uses templates as the primary way to build your application, it integrates well with the tools you’re already using. In this post, I’ll show you the hooks you need to integrate SproutCore with anything you want, and then show you how to do a general-purpose integration with jQuery UI.

Quick Refresh: Handlebars Templates

First of all, you can take any piece of HTML and attach it to a SproutCore view. You would typically do this in order to attach event handlers to the view or to define a function that computes how a particular value should be displayed. For instance, let’s say we have some HTML that shows a business card for a person:

<div class="card">
  <p class="name">{{salutation}} {{fullName}}</p>
  <p class="address">{{number}} {{street}}</p>
  <p class="region">{{city}}, {{state}} {{zip}}</p>
</div>

We can wrap this chunk of HTML in a SproutCore view, which will define the sources of each of the properties used in {{}}}.

<script type="text/html">
{{#view Yehuda.BusinessCard contentBinding="Yehuda.businessContent"}}
  <div class="card">
    <p class="name">{{content.salutation}} {{fullName}}</p>
    <p class="address">{{content.streetNumber}} {{content.street}}</p>
    <p class="region">{{content.city}}, {{content.state}} {{content.zip}}</p>
  </div>
{{/view}}
</script>

Wrapping the HTML snippet in a <script> tag tells SproutCore to render it using its template engine. You’d normally get the {{}} properties from a controller or other data source, but let’s define a view with the values baked in for now:

Yehuda.BusinessCard = SC.View.extend({
  // fill in the content in the template with contentBinding
  content: null,
 
  fullName: function() {
    return this.get('firstName') + ' ' + this.get('lastName');
  }.property('content.firstName', 'content.lastName')
});
 
Yehuda.businessContent = SC.Object.create({
  firstName: "Yehuda",
  lastName: "Katz",
  salutation: "Mr.",
  streetNumber: 300,
  street: "Brannan",
  city: "San Francisco",
  state: "CA",
  zip: "94107"
});

If we reload the page, we will see a static business card with my information in it. If we update my content with Yehuda.businessContent.set(key, value), SproutCore will automatically update the HTML for you. If you update any property, including firstName or lastName, which are used only as dependencies of fullName, SproutCore will automatically handle updating the HTML for you.

didCreateElement

You can also define some code to run every time an element is rendered. You can use this hook to wire up any JavaScript library to the element that SproutCore has created. For instance, let’s say we want to zebra stripe the three lines in our business card once it has been create (note: you probably would not use JS to zebra stripe in real life).

Let’s extend our view:

Yehuda.BusinessCard = SC.View.extend({
  // fill in the content in the template with contentBinding
  content: null,
 
  fullName: function() {
    return this.get('firstName') + ' ' + this.get('lastName');
  }.property('content.firstName', 'content.lastName'),
 
  didCreateElement: function() {
    this._super();
    this.$("p:even").addClass("even");
  }
});

First of all, you will want to call super, to ensure that any hooks in parent classes get called. Second, all SproutCore views have a $ function, which is the normal jQuery function, scoped to the current element. You can also call this.$() to get back a jQuery object wrapping the element itself.

You can use this hook to do anything you want, allowing you to hook in any library you want. You would use this hook a lot like you’d use a jQuery(document).ready hook, but scoped to the view being created.

SproutCore also provides a willDestroyElement hook, which you can use to tear things down that you set up when the element was created. This is relatively rare, and is mostly used when interfacing with another toolkit that requires a teardown, or to tear down custom SproutCore observers.

jQuery UI

We can use these hooks to build some basic integration with jQuery UI. I’ve written a demo that shows how to connect SproutCore bindings to jQuery options at http://sc20-jqui.strobeapp.com/. You can also check out the annotated source code.

The most important thing to look at is the JQ.Widget mixin, which can be mixed into view classes to attach jQuery UI options and events to SproutCore’s binding and event system.

You can get started with the SproutCore 2.0 developer preview by downloading the starter kit.

Until next time!

jQuery 1.4 and Malformed JSON

Today, we released jQuery 1.4, a mostly backward compatible release with a few minor quirks. One of these quirks is that jQuery now uses the native JSON parser where available, rejecting malformed JSON.

This probably sounds fine, except that by malformed JSON, we mostly mean:

{foo: "bar"}

Because this is valid JavaScript, people have long assumed it was valid JSON, and a lot of hand-coded JSON is written like this. Thankfully, JSON automatically generated by Rails does not have this problem, so most of you guys should not have an issue here.

If you have server-side JSON that can’t be quickly fixed in the transition to jQuery 1.4, you can use the compatibility plugin, which tries to patch a number of small incompatibilities, or you can use this workaround:

$.ajax({url: "/url", 
  dataType: "json",
  success: function(json) {
    // do something with json
  }
});
 
// becomes
 
$.ajax({url: "/url",
  dataType: "text",
  success: function(text) {
    json = eval("(" + text + ")");
    // do something with JSON
  }
});

Essentially, this is what jQuery used to do to evaluate JSON, so with these small changes you can get the old behavior.

Again, though, you should probably be modifying your busted server-side code to stop sending malformed JSON!

Files from my talk at @media

I have uploaded the files that I will use for my demonstration at @media. The slides will come later today after my talk. The easiest way to browse the files are via github. You can either browse the files online, get them via git, or download a tarball of the entire thing.

If you’re at @media, feel free to download the files and follow along.

RailsConf Europe Slides

Hey guys!

My RailsConf Europe slides are up :)

http://yehudakatz.com/wp-content/uploads/2008/09/rce-jquery.pdf

If you were at my talk, please log into your account at O’reilly and rate it. Thanks!

jQuery Selector Refcardz

Bear Bibeault (my co-author on jQuery in Action) and I have put together a neat reference card for jQuery selectors that you can get from DZone.

Here’s a blurb they provided:

This reference card puts the power of jQuery selectors at your very fingertips. Written by Bear Bibeault and Yehuda Katz, co-authors of jQuery in Action (Manning Publications), jQuery selectors are one of the most important aspects of the jQuery library. These selectors use familiar CSS syntax to allow page authors to quickly and easily identify any set of page elements to operate upon with the jQuery library methods. Understanding jQuery selectors is the key to using the jQuery library most effectively.

RailsConf Slides

Hey guys,

My talks at RailsConf were a ton of fun. The first night I did talks on Merb and jQuery which were completely packed, and the first day of the conference I did a talk on DataMapper which seemed to be well received as well.

While it was nice to hear that so many people wanted to see the DataMapper talk that some people were turned away, it sucks that some people got turned away. Without further ado, go check out my Merb and DataMapper slides at Slideshare:

I’ll try and get up the jQuery slides shortly as well. Enjoy!

Almost There: 30% Off jQuery in Action!

As you might know, I’m putting the final touches on jQuery in Action, an introductory book on all things jQuery for Manning Publications. I’ve spent the last half a year diligently plugging away at it, along with my co-author Bear Bibeault, and we’re finally hitting the home stretch.

It’s taken a lot of time, and focus, and while it’s been a great experience, I’m also looking forward to being able to once again put my full energy into the various Open Source projects I’m involved in (including jQuery, of course). We’re reviewing typeset PDF’s of what looks to be just about ready to print — there’s light at the end of this tunnel!

The book is set to print in early to mid-January; as a final push before publication, Manning is offering 30% off until December 31st, with the code JQM30. Though the book is also available on Amazon.com, among other places, Manning is the only place you can also get the e-book, which at least for me, is really important.

Thanks to everyone who’s been there for me in this crazy busy time, and for everyone who’s had to grin and bear it while my focus was split. I’m almost done!

Conferences, etc.

As some of you may know, I was at The Ajax Experience conference last week, along with the one-day mini-conference, jQueryCamp.

This was my third The Ajax Experience, and there were a lot of great people to see. Even more exciting though, was jQueryCamp, despite forgetting my t-shirt in Boston.. The accommodations were especially wonderful ;) (that’s code for… I crashed on John‘s couch. Thanks John!)..

I met most of my fellow core team members, which I’d really been looking forward to, along with a slew of jQuery geeks and gurus. Karl, Jörn, Bradley, Marc, Paul, Rey, Richard — just to name a few. I hope to post more about jQuery camp — the talks, etc. — when things get a bit calmer… if ever they do.

(As a side bonus, there were a few Merb folks around — what more could I ask for?!)

There was a pleasantly enthusiastic response to jQuery in Action; lots of people with comments, reading the Early Access version, and lots of people looking forward to it. I’m feeling good about it!

I’ll be at RubyConf in NC this weekend. There are a lot of people I’m looking forward to meeting there, and talks of some Merb hacking.

There’s nothing like putting faces to the IRC folks I talk to every day, the blogs I read, etc. There are also some old friends I’m looking forward to seeing again. Stephen Bristol, ReinH, Evan Phoenix, Jeremy McAnally, Ezra Zygmuntowicz, Dr Nic Williams, and so on. Leah (the wife) will be joining me at RubyConf too, so that’s always a bonus — and I know there are lots of people she’s looking forward to seeing too.

Do drop me a line, or comment, if you’ll be around. Would love to see everyone. Safe travels!

jQuery in Action (w00t)

Some of you might know that I’m writing a jQuery book for Manning called jQuery in Action. It’s pretty awesome, and includes a bunch of labs and exercises that are unique to it. My coauthor is Bear Bibeault (pronounced Bee-Bo), who coauthored Ajax in Practice (and hilariously enough, Prototype and Scriptaculous in Action).

It’s intended for people who already know some JavaScript, but still have questions about jQuery. It’s thorough, while going beyond the typical API runthrough (there are excellent examples; in later chapters, especially Ajax, the examples run through the entire chapter and show you how to complete a fairly detailed, yet typical project using jQuery).

Anyhow, check it out. If you buy now, you get the early-access chapters, which is the equivalent of the PragProgs’ beta book stuff. We’ve already released betas of chapters 1-8 (of 9), so there’s a lot there.

Event Normalization in jQuery 1.1.3

A loooong time ago, I wrote a bunch of event normalization code as a plugin to jQuery. In essence, the goal was the get events as close as possible to the DOM specification while retaining a sane file-size and backwards compatibility with existing code.

I wanted to add support for:
* relatedTarget, which, on mouse movement, returns the element that the mouse was previously on when moving onto or off of an element
* “which” for key events, which would return a normalized keyCode
* metaKey, which would return the Apple key on OSX, and the ctrl key in Windows (allowing stuff like apple-B to render something bold in OSX, but ctrl-B to do the same in Windows… the expected behavior)
* And a biggie: “which” support for buttons (1 for left-click, 2 for middle-click, and 3 for right-click).

I originally had some more grandiose plans, like supporting offsetX across browsers and getting keyCode to be the same cross-browser on keypresses, but those ended up either requiring unacceptable dependencies or requiring lots of messy code to get working.

Today, jQuery merged relatedTarget, which (for keys and buttons), and metaKey into the core jQuery distribution, and we did it without adding a single byte to the current 20k cap on jQuery’s filesize. We also added a whole slew of new features, without sacrificing our current cap. I say it’s incredible, and thanks to the hard, tireless work of the jQuery Core Team. The speed improvements, which are the work of jQuery’s maintainer, John Resig, also happened, sort of unexpectedly, without busting the 20k.

Amazing.

Back to the event normalization, I think you’ll find that between the old normalization that was present since the early days (event.target and event.pageX/pageY), and this new code, you’ll be able to do all sorts of neat tricks without having to put much thought into browser compatibility issues.

Enjoy!

Archives

Categories

Meta