Yehuda Katz is a member of the Ember.js, Ruby on Rails and jQuery Core Teams; he spends his daytime hours at the startup he founded, Tilde Inc.. Yehuda is co-author of best-selling jQuery in Action and Rails 3 in Action. He spends most of his time hacking on open source—his main projects, like Thor, Handlebars and Janus—or traveling the world doing evangelism work. He can be found on Twitter as @wycats and on Github.

Archive for the ‘SproutCore’ 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!

Archives

Categories

Meta