Archives for category: Uncategorized

I just wanted to post a quick announcement about a special SproutCore meetup I’ll be giving on February 24th at Liberty Noodle in downtown Toronto. If you want to learn about what SproutCore is, how it works, and why you may want to think about using it for your next awesome project, then please come on out. There will even be demos of the framework used on real projects!

For more information, please check the meetup annoucement here.

-FC

A few days ago there was a post on the SproutCore Google Group by an individual asking if his code could be reviewed by people in the community. Given the request, I checked out the code from github and began to go through it. In a nutshell, I was reviewing a small SproutCore application that allows you to simply log in and log out of the application. The application makes use of Ki, a statechart framework, in order to keep track of what state the application is currently in. In addition, there are two custom views. One view represents a toolbar displaying whether you are logged in or logged out, and another view that represents a login form. The login form view also contains logic that will fake the log in procedure.

Read the rest of this entry »

I just wanted to send a quick thanks to everyone who swung by my lil’ old blog to read up on all things related to SproutCore. According to my WordPress year-end stats, my blog was visited 43,000 times in 2010. The most viewed post by far was my recent Why Does SproutCore Have a Run Loop and When Does It Execute? post. The next three most viewed posts were:

  1. Creating a Simple Custom View in SproutCore: Part 1
  2. Creating a Simple Custom View in SproutCore: Part 2
  3. Creating a Simple Custom List Item View: Part 1

So it would appear many of you are looking for information on how to create custom views and trying to understand SproutCore’s underlying mechanics. I’m certainly glad to help those out, and I hope to provide more information for 2011.

If you do have comments or questions, please feel free to e-mail me at frzncanuck@gmail.com.

Happy New Year!

-FC

Hey all. Well I must admit that it has been a while since I got around to writing a SproutCore tutorial. The last one I wrote was back on September 6th, and during that time the SproutCore framework has continued to mature and stabilize. So what was it that I last wrote about anyway? Oh, right. It was the first part of how to create a simple custom list item view. I figure since I left you all hanging with just the first part it would be helpful if I actually, you know, wrote the second part. Well overdue.

Before I even begin the second part of how to create a simple custom list item view, it’s probably best we do a quick re-cap of what we went over in the first part. Even I forgot!

In part 1 of how to create a simple list item view I wanted to start you off with a foundation that consisted of the following:

  • Building a list item view from scratch that can be rendered in a list view (SC.ListView)
  • That SproutCore already comes stock with a default list item view (SC.ListItemView) that you can extend yourself
  • A list view can make use of a custom list item view by assigning the item to the list view’s exampleView property
  • That there is a contract between the list item view you create and the collection view (SC.CollectionView) that ultimately manages all the list item views.
  • How to use the most fundamental properties provided to a list item view: content, isSelected, and isEnabled

Great. Now that I remember… er, I mean, rather that we remember, let’s move forward and see how we can do some more interesting things when creating a custom list item view. I’ll be going over the following with you:

  • Know what other properties are provided to a list item view by the collection view
  • How to add addition properties to a list item view through a collection view
  • How to go the extra mile and override the collection view’s createItemView method

Oh, and for those of you playing along at home (or in the office), we’ll be doing some code spelunking in SC.CollectionView. So you’ll probably want to open up the file collection.js that you can find in the SproutCore framework under the frameworks/desktop/views directory.

Part 2.1: Getting to Know Your Default Properties

As noted earlier, the collection view provides an item view with a suit of properties that the view can use as it sees fit. We’ve already learned about the basic properties, content, isSelected, and isEnabled, so let’s see what other default properties are provided. And to take out any mystery, let’s go to the source of where these properties are actually being assigned.

All item views are created by the SC.CollectionView via the itemViewForContentIndex method starting on line 945. I won’t go into all the details of the method for this tutorial, but we’ll focus our energy starting on line 977 where an attrs object is created as follows:


// collect some other state
var attrs = this._TMP_ATTRS;
attrs.contentIndex = idx;
attrs.content      = item ;
attrs.owner        = attrs.displayDelegate = this;
attrs.parentView   = this.get('containerView') || this ;
attrs.page         = this.page ;
attrs.layerId      = this.layerIdFor(idx, item);
attrs.isEnabled    = del.contentIndexIsEnabled(this, content, idx);
attrs.isSelected   = del.contentIndexIsSelected(this, content, idx);
attrs.outlineLevel = del.contentIndexOutlineLevel(this, content, idx);
attrs.disclosureState = del.contentIndexDisclosureState(this, content, idx);
attrs.isGroupView  = isGroupView;
attrs.isVisibleInWindow = this.isVisibleInWindow;
if (isGroupView) attrs.classNames = this._GROUP_COLLECTION_CLASS_NAMES;
else attrs.classNames = this._COLLECTION_CLASS_NAMES;
    
layout = this.layoutForContentIndex(idx);
if (layout) {
  attrs.layout = layout;
} else {
  delete attrs.layout ;
}
    
ret = this.createItemView(E, idx, attrs);

The attrs object is what will be provided to the item view class to construct an instance of it. In the code above you’ll notice three familiar properties being assigned to attrs: content, isSelected, isEnabled. The other properties being assigned to attrs that are worth noting are:

  • contentIndex – The ordered index of the content provided to the item view
  • page – The SC.Page the collection view may belong to
  • parentView – The parent view of the item view
  • outlineLevel – The outline level at which the content belongs too. Used for tree like structures
  • disclosureState – Indicates if the item view is disclosing any item views that are children of it
  • isGroupView – Indicates if the item view groups other item views

Once all the properties are assigned to attrs the object is then passed to the createItemView method to finally construct the item view. (We’ll return to the createItemView method a bit later). How about we give one of the properties a try? Let’s use the contentIndex property. (The outlineLevel, disclosureState, and isGroupView are for more complex scenarios, but if you’d like to see how they are used then be sure to check out the code for SC.ListItemView).

If you recall in part 1 of this tutorial, I made you create a custom list item view to display in a list view that ended up looking like the following:

Notice that, aside from the text displayed, the look of each list item is the same. I’d like to change that so that the background colors alternate just to make them look a little more distinct and easier for the user to look at. Hmm. So how can we do that? Since the collection view provides our item view with the contentIndex property we can use it to our advantage. By using the modulus operator on the contentIndex we can determine if the index is odd or even, like so:

var isOdd = this.get('contentIndex') % 2

Very simple. So if the content index divides evenly by 2 then we’re even, otherwise the index is odd. Now let’s put our new found knowledge to practice and update our custom list item view’s render method like so (new lines in bold):


MyApp.CustomListItemView = SC.View.extend(SC.ContentDisplay, {

  classNames: ['custom-list-item-view'],

  displayProperties: 'isSelected isEnabled'.w(),

  contentDisplayProperties: 'fname lname company title',
  
  render: function(context, firstTime) {
  
    var content = this.get('content');
    var fname = content.get('fname');
    var lname = content.get('lname');
    var company = content.get('company');
    var title = content.get('title');
    var isSelected = this.get('isSelected');
    var isEnabled = this.get('isEnabled');
    var contentIndex = this.get('contentIndex');
    
    var isEven = contentIndex % 2 ? YES : NO;
    
    context = context.setClass({ 'odd': !isEven, 'even': isEven });
    
    var standard = isEnabled && !isSelected;
    var selected = isEnabled && isSelected;
    var disabled = !isEnabled;
    var classes = { 'standard': standard, 'selected': selected, 'disabled': disabled };
  
    context = context.begin().addClass('top').setClass(classes);
    context = context.begin('p').addClass('name').push('%@, %@'.fmt(lname, fname)).end();
    context = context.end(); // div.top
    
    context = context.begin().addClass('bottom').setClass(classes);
    context = context.begin('p').addClass('item').addClass('company');
    context = context.begin('span').addClass('label').push('Company:').end();
    context = context.begin('span').addClass('value').push(company).end();
    context = context.end(); // p.label.company
    context = context.begin('p').addClass('item').addClass('title');
    context = context.begin('span').addClass('label').push('Title:').end();
    context = context.begin('span').addClass('value').push(title).end();
    context = context.end(); // p.label.title
    context = context.end(); // div.bottom
    
    sc_super();
  }

});

That’s it! By just adding three simple lines we have now modified how the item views should be displayed. Now, if you’ve been reading any of my tutorials I’m sure you realize there’s still something left we have to do… which is? Update the CSS to take advantage of the added class tags. So in your style.css file located in the resources directory (Remember: There is no more english.lproj directory), add the following:


div.custom-list-item-view.even div.top.standard {
  background-color: #808080;
}

div.custom-list-item-view.even div.bottom.standard {
  background-color: #a3a3a3;
  border-bottom-color: black;
  border-bottom-width: 3px;
  border-bottom-style: solid;
}

Now if you start up your app using sc-server, you should get something like the following:

Good job! You’ve now taken advantage of another property supplied to you by the SC.CollectionView.

Part 2.2: But I Want to Use My Own Properties

We’ve taken advantage of the properties provided to our list item view by the SC.CollectionView. Great. But since we’ve gone out of our way to create our custom list item view, wouldn’t it be nice if we could assign some of our own properties to the list item view? Sure would! But how do we do it? One way, as I’m sure some of you will note, is to simply assign properties to the content like you can do with a typical custom view. We can already witness this with the given content’s firstName and lastName properties. But what about properties that are not part of the content? Well, this means we have to add properties to the list item view itself, just like the isSelected property. The question then becomes just how do you assign those properties that the collection view does not know about? To understand let’s first go look at the code in our application that creates the list view in the main_page.js file:


list: SC.ScrollView.design({
  layout: { top: 10, bottom: 30, left: 10, right: 10 },
  contentView: SC.ListView.design({
    layout: { top: 0, bottom: 0, left: 0, right: 0 }, 
    contentBinding: 'MyApp.testController',
    exampleView: MyApp.CustomListItemView,
    rowHeight: 54,
    rowSpacing: 0
  })
}),

From the code above we have two options to assign additional properties to the custom list item view. The first option is to simply extend the list item view with your specific properties, like so:


list: SC.ScrollView.design({
  layout: { top: 10, bottom: 30, left: 10, right: 10 },
  contentView: SC.ListView.design({
    layout: { top: 0, bottom: 0, left: 0, right: 0 }, 
    contentBinding: 'MyApp.testController',
    exampleView: MyApp.CustomListItemView.extend({
      foo: 100,
      bar: 200
    }),
    rowHeight: 54,
    rowSpacing: 0
  })
}),

The second approach is to do the following:


list: SC.ScrollView.design({
  layout: { top: 10, bottom: 30, left: 10, right: 10 },
  contentView: SC.ListView.design({
    layout: { top: 0, bottom: 0, left: 0, right: 0 }, 
    contentBinding: 'MyApp.testController',
    exampleView: MyApp.CustomListItemView,
    rowHeight: 54,
    rowSpacing: 0,
    foo: 100,
    bar: 200
  })
}),

The first approach seems the most obvious since we just extend the custom list item view and assign the values directly. We could even use binding if we so choose. The second approach seems, well, odd. It’s looks like you’re assigning the properties foo and bar directly to the list view itself. But the list view, and by extension the collection view, don’t understand what foo and bar are. So how do they make their way over to the list item view? For that we go back to the attrs object in the collection view’s itemViewForContentIndex method.

Two properties that I didn’t mention earlier that are also assigned to the attrs object are the owner and displayDelegate properties, both of which happen to reference the collection view object:


attrs.owner        = attrs.displayDelegate = this;

As you may suspect, in order for our custom list item view to acquire the values assigned to foo and bar the item view has to access either the given owner or displayDelegate properties first, like so:


var foo = this.getPath('owner.foo');

Not too bad. The limitation with going through either the owner or displayDelegate properties is that you then lose the ability to use bindings on those properties, which may or may not be of concern depending on what you are trying to accomplish. It depends on if you know the values will be statically assigned and not change or will change during the course of the application’s execution. In either case, the approach you choose will dictate how to code your custom list item view, so make sure to comment your code as such. Also make note that the properties you assign to your item views will not effect the list view or its parent collection view. They both remain oblivious to what is going on.

So now that we have an idea of how to add our own properties to the list item views, let take them for a spin. For both approaches we want to add additional property that will simply toggle the visibility of the person’s title. We’ll start with the first approach by simply extending our custom list item view. First update your list item view to be the following:


MyApp.CustomListItemView = SC.View.extend(SC.ContentDisplay, {

  classNames: ['custom-list-item-view'],
  
  isTitleVisible: YES,

  displayProperties: 'isSelected isEnabled'.w(),

  contentDisplayProperties: 'fname lname company title',
  
  render: function(context, firstTime) {
  
    var content = this.get('content');
    var fname = content.get('fname');
    var lname = content.get('lname');
    var company = content.get('company');
    var title = content.get('title');
    var isSelected = this.get('isSelected');
    var isEnabled = this.get('isEnabled');
    var contentIndex = this.get('contentIndex');
    var isTitleVisible = this.get('isTitleVisible');
    
    var isEven = contentIndex % 2 ? YES : NO;
    
    context = context.setClass({ 'odd': !isEven, 'even': isEven });
    
    var standard = isEnabled && !isSelected;
    var selected = isEnabled && isSelected;
    var disabled = !isEnabled;
    var classes = { 'standard': standard, 'selected': selected, 'disabled': disabled };
  
    context = context.begin().addClass('top').setClass(classes);
    context = context.begin('p').addClass('name').push('%@, %@'.fmt(lname, fname)).end();
    context = context.end(); // div.top
    
    context = context.begin().addClass('bottom').setClass(classes);
    context = context.begin('p').addClass('item').addClass('company');
    context = context.begin('span').addClass('label').push('Company:').end();
    context = context.begin('span').addClass('value').push(company).end();
    context = context.end(); // p.label.company
    
    if (isTitleVisible) {
      context = context.begin('p').addClass('item').addClass('title');
      context = context.begin('span').addClass('label').push('Title:').end();
      context = context.begin('span').addClass('value').push(title).end();
      context = context.end(); // p.label.title
    }
    
    context = context.end(); // div.bottom
    
    sc_super();
  }

});

If your app is started and loaded into a browser, go ahead and refresh. Everything should appear as it did before. Good. So now we want to change the list items so that they don’t show the person’s title. We’ll do this be updating the list item view supplied to the list view in the main_page.js file, like so:


list: SC.ScrollView.design({
  layout: { top: 10, bottom: 30, left: 10, right: 10 },
  contentView: SC.ListView.design({
    layout: { top: 0, bottom: 0, left: 0, right: 0 }, 
    contentBinding: 'MyApp.testController',
    exampleView: MyApp.CustomListItemView.extend({
      isTitleVisible: NO
    }),
    rowHeight: 54,
    rowSpacing: 0
  })
}),

Like before, refresh your browser. You should see the following:

Awesome! Now the title of the people listed is no longer visible. Again, notice how the changes to the view above is just the same thing you would do if making a typical custom view.

Alright. Now let’s try the second approach by passing the properties through the displayDelegate provided by the collection view. Let’s go back and change the code in the custom list item view:


MyApp.CustomListItemView = SC.View.extend(SC.ContentDisplay, {

  classNames: ['custom-list-item-view'],

  displayProperties: 'isSelected isEnabled'.w(),

  contentDisplayProperties: 'fname lname company title',
  
  render: function(context, firstTime) {
    ..
    var isTitleVisible = this.getPath('displayDelegate.isTitleVisible');
    
    ...
    
    if (isTitleVisible) {
      context = context.begin('p').addClass('item').addClass('title');
      context = context.begin('span').addClass('label').push('Title:').end();
      context = context.begin('span').addClass('value').push(title).end();
      context = context.end(); // p.label.title
    }
    
    ...
  }

});

In the code above we removed the isTitleVisible property from the view. In addition, we updated the render method to acquire the property's value through the displayDelegate. Now let's update the list view again in the main_page.js file:


list: SC.ScrollView.design({
  layout: { top: 10, bottom: 30, left: 10, right: 10 },
  contentView: SC.ListView.design({
    layout: { top: 0, bottom: 0, left: 0, right: 0 }, 
    contentBinding: 'MyApp.testController',
    exampleView: MyApp.CustomListItemView,
    rowHeight: 54,
    rowSpacing: 0,
    isTitleVisible: YES
  })
}),

The isTitleVisible property is now applied directly to the list view instead of the custom list item view. Go ahead and refresh your browser. If all checks out you should see the title being displayed for all the people listed. If you change the value of isTitleVisible to NO and refresh you will no longer see the titles being displayed. So the display delegate worked! Cool.

Part 2.3: Assigning Properties to a Specific List Item

Going over the last part of this tutorial, you were able to apply your own custom properties to the list items. However, did you feel something... lacking? In the example you went through, when you change a property what gets those changes? All of the items, not just a specific one. So what if you have the scenario where you don't want to show the title of a specific item in the list? Hmm. This is where things get admittedly a bit more complicated, but its still achievable. Remember how I mentioned a method in the collection view called createItemView? Well it comes back to that method. Here is what the method looks like in the collection view (collection.js) on line 971:


createItemView: function(exampleClass, idx, attrs) {
    return exampleClass.create(attrs);
}

Very trivial by default. The collection view just uses it to create an instance of the example view by providing it with the attrs hash.

I'll come back to how to target properties against specific item in part 3 of this tutorial. I know, I know: boo-erns to me ;-). But it'll be worth it as you get a lot more bang for the buck, and then you can tell people about it at parties you attend... very, very nerdy parties.

Till then, have fun programming in SproutCore

-FC

I received an interesting e-mail from a person who is currently trying to test a SproutCore app he built using the Selenium framework. For those not familiar with Selenium, it is an open source test automation framework for web-based applications. Selenium has tools that allow you to record or program a set of actions that can be replayed in most of the popular browsers either through a Mozilla IDE plug-in or using a remote control framework. In any case, Selenium is great for automated feature and integration testing and can be extended for your own needs.

The issue raised by the gentleman was that he got quickly stuck when trying to perform a simple click action. If you are familiar with typical JavaScript programming in a web browser, you know that there is a set of standard events that can be invoked on a given DOM element, such as onclick, onmousedown, onmouseup and so on. You can also programmatically invoke those events using JavaScript. In the case of Selenium, when you want to click something, the framework is invoking those common events. So if you want to click on a DIV element, then that element’s click method will be invoked.

So why does the standard clicking not work in a SproutCore application? Because clicking is actually two actions: mouse down and then mouse up. Why? It’s because of the way SproutCore likes to handle events, and in order to do things like double clicking and dragging, SproutCore has to be aware of when the user first moused down and then moused up. That is why when you create a new view (custom or extended) and you want to handle events on that view, there is no click method that you can override, but you can override mouseUp and mouseDown.

Currently I’m starting to use the Selenium framework to do a lot of automated testing on a large, complex application. Because there are things that SproutCore likes to do that don’t follow the normal course of action in a typical web-based app, I’ll be capturing those hurdles and write posts about it as I go along.

In the mean time, have fun programming in SproutCore!

-FC

The newspaper industry is doomed! No one wants to pay for quality journalism anymore. Profits can’t be made from just Internet advertising to compensate for free articles. The future is blogs to get information; no one wants to read dusty old newspapers. Government should grant tax breaks to keep the newspapers alive. Newspaper should go non-profit so people can donate them money…

… And so on, and so on, and so on.

If you’ve been watching the news channels, reading the papers and skimming through blogs often enough over the last few years, I’m sure you’ve come across one or more of these passages all summing up that the newspapers of today can not survive in the age of Internet. After all, It’s just too difficult. There is no real solution to free. I for one am a person getting tired of hearing this hyperbolic rhetoric over and over again.

I am someone who reads the newspapers, albeit, I often read them online simply because its more convenient. I do want quality journalism. I think professional journalist play an important and necessary role in informing our society. And journalists should indeed be compensated for their work. But how in this day in age of the Internet when newspapers give away most, if not all, of their content away for free can anyone make a profit, let alone get paid? If you are to listen to the experts, they seem to claim one of two solutions.

One solution is that you use clever online advertising to get people to look at and click on. However, time and time again, reports come out that online advertising still does not bring in the money to compensate for the free online content.

The other solution is that instead of giving your content away for free and depend on online advertising, you instead require that the reader has to buy a monthly or year subscription. And in most cases, those subscriptions are an all or nothing plan. You pay a fee to get everything or you don’t get nothing at all.

A couple of newspapers and magazines tried to do this subscription approach a few years ago and most failed. The New York Times (nytimes.com) tried it, among many others, and soon they were back to providing free online content. Turns out that most people did not want to pay the high yearly cost for the entire paper. I remember even e-mailing The New York Times asking them if I could just pay for certain sections of the paper online. Their response: They did not offer an a la carte service. The very few exceptions to this rule happen to be the Financial Times (ft.com) and The Wall Street Journal (wsj.com), both of which focus on a specific niche markets that will pay for the entire paper, but, again, they are the exception rather than the rule.

And as for what once was a big revenue stream, the classified ads, forget it. Sites like craigslist.org and such have essentially eroded whatever profit was left from that segment of the newspaper.

The problem with the pure online advertising approach and the paid subscription approach is that they are at the extreme ends of the solutions scale in order to make some kind of income and make the online paper profitable. This is sad. In some respects, it feels like many in the newspaper industry have all but listened to Chris Anderson, the editor at large at Wired magazine, and accepted his view of the future were everything is free. This, in my view, is nonsense. The problem isn’t that people won’t pay for articles written by paid professionals, but, rather, the problem is that the most in the newspaper industry have not paid attention to the idea of choice.

Perhaps you remember all the crying the music industry made back when everyone and their grandmother were using software like Napster and such to download free music. Why pay when its all free online! The music industry got angry and began to sue, but as hard as they try, they couldn’t stop the onslaught of people continuing to download free music. Profits were being lost. No one wanted to buy music made buy professional musicians. Yada, yada, yada. The real problem was that the music industry was stuck in their old ways. They wanted people to buy a whole CD for a high marked-up price. And if you wanted the singles, well, that would still cost you something like five bucks. They kept groaning but never listening to what people were actually complaining about — Choice!

When Apple came out with the iTunes store, so came a simple idea: Let the people download the songs that they just want at a reasonable price and do it within a simple to use portal. And guess what. People bought the songs. Yes. People were willing to pay for something so long as you listened to them. Now others have jumped on the bandwagon, such as Amazon.com, allowing you to download individual tracks. Even better, the music industry has continued to listened and drop the digital rights management so that customers don’t have silly restrictions.

Looking back as the music industry, maybe the newspaper industry can learn something here. Many people are willing to pay for professional content, but there are a few fundamental principles to follow in the age of the Internet.

To start, provide real choice to the consumer buy letting them pay for just the articles they want to read. I know this is a real shocker to the newspaper industry, but most people do not read the entire paper, which is why the full subscription pay model falls flat on its face.

With the ability to pay for individual articles, this brings the second principle to follow: Provide the articles at a reasonable price. What’s a reasonable price? I guess it depends, but I would imagine there were be some kind of variable cost depending on the type and length of the article. So, for instance, a full front-page story could cost 10 cents, whereas a full multi-page article would be more; anywhere from 15 cents or more. In addition to paying for an article, once it has been paid for, the user can always go back to the article to read it again, whether its months or years after the article was bought by that person.

But to pay for individual articles that costs pennies, how would you charge a credit card for that? Instead of performing a payment transaction on each article you instead charge a user a minimum account balance and pull from it until the balance has been reached. The paper can be set up so that either once the balance has been depleted it can be automatically replenished by charging the minimum account balance again or notify the user about the depletion and letting them decide if they want to renew again.

Finally we come to the third principle: Providing easy access to the articles to purchase. The format most of the online newspaper follow is fine. They would just need to be updated to allow the user to easily click on a button to says purchase and then they’re off reading the article. The only limitation is that going directly to the newspaper’s site creates a walled off environment from other sites where you can also purchase individual articles, and that can become tedious for the consumer. It would be preferable if the newspapers opened up so that articles can be viewed, selected and purchased in a single marketplace. To do this the newspapers would just have to create publicly accessible services that software can access to query for articles and perform purchase transactions against a registered account. These services would not only be handy to the consumer but would possibly open up a whole new area of software development.

So to repeat, I believe that the newspapers can make an income, a good income, in this day for professionally written content, but there are three simple but fundamental principles to follow: 1) Give the custom real choice by letting the buy individual articles; 2) charge a reasonable but fair price for each article; and 3) make it easy to access the articles for purchase.

As a final note, to entice people to purchase individual articles, newspapers could set up their site so that if you register you are allowed to select any three to five articles and read them for free in a thirty day period, but you can not read them again unless purchased. After each thirty days, the user can again select another three or five articles and so on. This is something that the Financial Times has done to good effect.

If the music industry can change so can the newspaper industry, and for the better.

(… and just to be sure, this concept equally applies to the magazine industry as much as it does to the newspaper industry)

Hey all,

If you’ve been following my blog and have been waiting around for the second part of my last post on how to create a custom list item view, know that it is coming. Unfortunately I’ve been so backed up with work at my real job that I had to postpone writing new posts. Priorities, priorities :).

In other related news, for the last two posts I wrote, I created shortcut links to jump to different sections in each post. However, I made the mistake of naming the anchor links the same thing, so the shortcut links don’t work. I’ll fix that soon.

-FC

If you use Twitter and follow the #SproutCore channel, you might notice some really useful quick tips and tricks tweeted by others who use the SproutCore framework. Instead of just letting these useful tweets fade away into Twitter history, I decided to capture them so that others can find and learn from them too.

You can find all these useful tweets on my SproutCore page. I’ll make sure to update the page as I come across more quick tips and tricks via Twitter. And for anyone who does create these tweets, I’ll make sure they are properly acknowledged :)

– FC

With lots to do at my real job, there has been a little less time for me to make posts discussing the SproutCore framework. However, I have some stuff in the pipeline that I’m working on and will be posting shortly (within the next week or two). Here’s what’s coming up soon:

  • How to Make a Custom List Item View for SC.ListView: Part 1
  • How to Make a Custom List Item View for SC.ListView: Part 2
  • Unit Testing Custom Views in SproutCore

I’ll try to keep the posts shorter compared to the last post I did on KVO and bindings :).

In the mean time, if you want to see a good, working open source SproutCore application that you can learn from, definitely check out Suvajit Gupta’s Tasks application that is on GitHub. You’ll need Git if you don’t already have it.

Have fun coding in SproutCore!

Whoa. I just created a blog. This is a bit scary. Okay, so that being said, what’s this blog all about? Well, I think I’ll just keep it focused on technology that I’m working with and other interesting development issues I run into. So ya. Nothing about my cat Mittens here ;).