Posts

Showing posts with the label sproutcore

Book review: Sproutcore Web Application Development

Image
TL;DR:  Sproutcore is a huge framework, and this book will save you a lot of time (and headaches). Buy it. Disclaimer : this is a review of a free copy that Packt kindly sent me. Win a free copy of this book, scroll down to know how to participate! If only I had this book 3 years ago! 3 years ago I started developing a Sproutcore app as a learning experience and, in all honesty, the path has been rough. Sproutcore is a massive  framework with lots of features: some are well documented, some mentioned casually in the guides, some others...well you don't know they are there until you start reading the code or chat with one of the more knowledgeable devs in IRC.

Easy animations with Sproutcore 1.10

The release of Sproutcore 1.10  marks an important step in the life of this very popular framework. Lots of new features make developing applications on the Sproutcore framework even easier and fun. One improvement that I am sure will catch your eye (pun intended) is  view animations . Coding view animations was rather easy also on previous versions, but with 1.10 animations are now first class citizens bolted into the core rendering subsystem. For an example of what is available out of the box see this  demo . So how would you use this goodness in an actual Sproutcore application? And how much code would it take? As an example I have put together a very basic Sproutcore app ( source , demo ) which has two states: an authentication form and a main screen. Logging in transitions the app from the login form to the main screen and logging out returns the app to the login screen. Pretty simple.

Developing Sproutcore apps on c9.io

Image
The Cloud9 online IDE running on Chrome/Mac. Today I was looking for a way to quickly edit a pull request to the Sproutcore project without booting up my laptop, but using the MacMini in the living room instead, which is always on, being our main entertainment system. Turns out it's quite easy if you do not mind signing in into another online service: the  Cloud9 online IDE .

SC.outlet

Whenever in a Sproutcore app a controller or a state needs to reference a view which is deeply nested in the ui tree there is a good case to use SC.outlet . The outlet creates a layer of indirection between the view and the other layers leaving to the view the responsibility to provide shortcuts to its inner objects, decoupling the layout from the application logic. An example of SC.outlet usage is shown in the todos application described in the Getting Started guides. Without outlet: ... TodosThree.mainPage = SC.Page.design({ // conventional design // https://github.com/sproutcore/getting-started/blob/master/apps/todos_three/resources/main_page.js#L4 ... TodosThree.SHOWING_APP = SC.State.design({ enterState: function() { TodosThree.mainPage.get('mainPane').append(); TodosThree.mainPage.mainPane.newTodoField.field.becomeFirstResponder(); }, Notice how the view design trickles down to the state layer (a part of the controller layer, which should be pre...

Guide to searching (and finding) help on Sproutcore

Image
Make no mistake: Sproutcore IS a huge framework. Also not all of it is documented equally well and that's the reason why a casual observer or someone picking it up for the first time might find it difficult to perceive its full power (and extent). My first acquaintance with Sproutcore goes back to fall 2009 when a series of articles began to appear on the web about this new framework created at Apple by Charles Jolley. Since then a lot of things have changed and it's not always been clear what was driving those changes. This post is an attempt to write down and share my experiences and the resources that I used in learning Sproutcore in the hope that they may be useful to others. A little bit of history First of all a little bit of history: Sproutcore was started by Charles Jolley while working on the MobileMe platform at Apple. From there the framework spun off into an Open Source MIT licensed version (originally hosted on GitHub under the sproutit account). Tha...

Installing Sproutcore on Windows (with Screenshots)

Image
Most Sproutcore developers working on Windows are used to the installer, which is also the default choice on the download page. Since lately the installer seems to be a little unreliable I decided to try the manual way and screenshot the whole process so that it might be of help to others. The first thing to do is install Ruby for Windows, which can be conveniently fetched from  http://rubyinstaller.org/ . I recommend you pick version 1.9.2 which, at the moment, I believe is the version used by most of the Sproutcore developers. Installing is a breeze, just remember to tick the 'Add Ruby to your path'  box so that you don't have to do it yourself later. If you have other ruby versions installed and you DO care about which version is selected by default than it's up to you whether or not to tick the box. If unsure just tick the box. When the installer is done open a command prompt (just type cmd in the run box on the Start menu and select the black icon ...

A case for manipulating the DOM outside the Sproutcore RunLoop

KVO is one of Sproutcore coolest features. At the core of it there is the RunLoop in which events and notifications are efficiently processed, dispatched to their destination(s) and views modify the DOM to reflect the new application state. Sproutcore developers are consequently told not to manipulate directly the DOM. When out-of-band events, like an ajax call returning from a third-party library or a WebSocket receiving a new message happen it is possible to trigger the RunLoop manually by calling  SC.RunLoop.begin() ... SC.RunLoop.end() . Sometimes though it is not only necessary, but recommended, to bypass the RunLoop and manipulate directly the DOM to either provide UI refreshes as fast as the browser allows or avoid the expensive computations implicated in the RunLoop. These concepts were incidentally discussed on IRC just when I needed to implement a progress bar to provide feedback on the loading state of a particularly slow datasource and I am writing them dow...

Tweak OpenLayers to get parse GetCapabilities working in IE

It happened to me recently that I needed OpenLayers (version 2.11) to parse a GetCapabilities response from Geoserver to present the user a list of layers to pick from. The capabilites request is made through a Sproutcore request, which is basically a jQuery ajax object in disguise. This of course works beautifully in every browser with the notable execption of ... IE (IE9 included). The cause is that IE will helpfully xml-parse a response whose content-type is text/xml , but will refuse to parse a document whose content-type is  application/vnd.ogc.request+xml . To add comedy to the drama the responseXML attribute of response is not null, as one would expect, but is instead set to reference an empty dom. The workaround is to put a giant browser-sniffing if in your javascript to handle IE differently. The code is like the following and please note that it is Sproutcore code, so browser sniffing and other amenities are peculiar to Sproutcore: // God mess IE if(SC.$.bro...

Installing Sproutcore (stable and dev) on Linux

This is just a note-to-self kind of post. Official instruction, available here , do not explain how to setup the development version (which currently is 1.7.1.beta). This is the full list of command (ran and tested on Ubuntu Lucid Lynx 10.04), just need to type the occasional yes . For those cases when bundle fails (happened to me) to create the bin directory with the beta version of sc-* tools just type the longer variant: bundle exec sc-server

SC.ContentDisplay

I'm writing this post just to share an interesting conversation that popped up on #sproutcore this week. Sproutcore is a huge framework and there is no amount of documentation that will explain it all, that's why I suggest you hang out in IRC . Even if you don't have questions to ask you'll learn a lot from others'. In this case the question was: how do I make my custom view update whenever one of the content object properties change? The perfect case for this, I think, would be if we were writing a custom  SC.ListItemView . In my case, prior to discovering SC.ContentDisplay I used the following configuration in a custom ListItemView: Maps.OpenLayersLayer = SC.View.extend({ content: null, displayProperties: ["content", "content.order", "content.visible", "content.opacity", "content.cql_filter"], [...] While it works (it was, I quote, described as funny  though) this is the recommended way to do it: Maps.O...

JTS processing Grails servlet

Sometimes it is convenient to make certain topological operations available in a web-based gis. For a gis that makes heavy use of Javascript (like OpenLayers-based ones) it might be worth looking at jSTS , a Javascript port of JTS. For all the rest and for those who don't want to load yet another library in the browser you can always write a Grails controller that encapsulates common JTS operations like buffer, intersection, union, etc. Assuming you are familiar with Grails the steps are as follows: drop the jts jar in the lib directory create a controller and define the relevant methods define a url mapping to prettify the calls Step 1 is trivial, so we'll go straight to 2. Create a controller and call it JtsController , then open the source file and paste this code: import com.vividsolutions.jts.geom.* import com.vividsolutions.jts.io.* import com.vividsolutions.jts.operation.overlay.snap.* import grails.converters.JSON import grails.plugins.springsecuri...

SC.Menu dynamic positioning with OpenLayers

In one app I needed to allow the user to CTRL-click on an OpenLayers map to popup a tool menu. Since all the rest of the app is Sproutcore based I also wanted the menu to have the same look&feel. Sproutcore already has a menu view which is called SC.MenuPane . Unfortunately SC.MenuPane can be positioned only relatively to another SC.View, but what if I want to position the menu exactly where I clicked on the map? The solution turns out to be pretty simple and requires us to override only one MenuPane method. The method is positionPane and can be overridden at definition time by adding it to the mixin as done below (gotta love javascript, huh?): Maps.openLayersController.menuPane: SC.MenuPane.create({ layout: {width: 120}, itemHeight: 25, items: [ { title: '_geocode'.loc(), icon: 'http://maps.gstatic.com/favicon.ico', action: "geocode" }, { title: '_streetview'.loc(), icon: 'icon-streetview-16', action: "streetview...

Using a separate settings file with Abbot and Sproutcore 1.6

In some cases it is practical in an application to have a single global settings file where all configuration is stored. Most often this configuration file varies between a deployment and another, depending on customer requirements, licensed features, backend technology, etc. When developing an application with Sproutcore 1.x (1.6 is assumed) it is not immediately clear how to do it, not because it is not possible but just because documentation on Abbot , SC's build tool is, to use an euphemism, well, scarce. So what do we want to do exactly? We want to have a single config.js file that is included before any other application file and, most importantly, must not be minified and packed so that on-the-fly editing or inspection is still conveniently possible. The file should be kept small anyway so that packing and minifying it is not going to be necessary. To do this we need to create a new .js file and place it wherever we like in the application tree. A sensible choice wou...

Improve OpenLayers performance in a Sproutcore app

When using OpenLayers embedded in a Sproutcore app you will want to set the following option on the OpenLayers.Map constructor: fallThrough  : false to avoid double handling events (once in OpenLayers and once in Sproutcore). Map dragging should improve and feel much smoother. Although deprecated this wiki page explains very clearly Sproutcore event handling.

Grails ajax login from a Sproutcore app

Image
Warning : this post is a work in progress. Full source code for both Sproutcore and Grails  parts can be found at my github account  https://github.com/unicolet . All the Sproutcore examples that I've found so far only show how to fetch data from different backends, but there is unfortunately very little material on authentication. In my case I'm hooking up to a Java backend written in  Grails  with authentication being provided by by Spring Security . The grails spring-security-core plugin documentation already incorporates  Ajax logins so the server-side code is already in place. We only have to apply one small tweak to make it work with Sproutcore. Prerequisites: Grails, Sproutcore > 1.6 with Statecharts. The statechart in the figure illustrates the states and transitions we plan to handle. Authentication Let's start with authenticating the user. We will deal with reconnecting the session later. Assuming you have a basic Grails ...

Adding Google Web Fonts to a Sproutcore app

Yesterday I was playing with the Hubbub   Sproutcore app that is just plain beautiful (and useful, if anyone used it over here in stodgy Italy). Anyway I noticed that the beautiful texts on the home page are not images, but actual text with fonts. I did not know I had such great fonts on my computer and in fact I don't. Those fonts come from Google Web Fonts  and you can use them too, right away in any of your web apps or sites. Since I am working on a Sproutcore app that could use some beauty I decided to style the app name with this font. Now, if only I knew how to add the css link to the html generated by abbot... [/me is gtfw & source browsing for a good 30 mins...] The solution turns out to be pretty simple and elegant (as everything in SC world, wink wink). Open the Buildfile in your favourite editor and add a stylesheet_libs option to the project config as follows: config :all do |c| c[:javascript_libs] = ['http://maps.google.com/maps/api/js?v=...

Adding Sproutcore KVO to OpenLayers - More Automation - Part 3

I have showed in the previous post how to add KVO to OpenLayers objects and then connect these objects to inputs, etc. The approach was unfortunately troublesome because each OpenLayers object had to be programmatically augmented through a SC.mixin call. In this post I will show how the OpenLayers source can be patched to make the augmentation process built-in. The only modification that needs be done is in Class.js where the OpenLayers.Class function must be modified as follows: OpenLayers.Class = function() {     var len = arguments.length;     var P = arguments[0];     var F = arguments[len-1];     var C=null;     if(typeof F.initialize == "function") {         if (!F.__my_init) {             F.__my_init = F.initialize             F.initialize = function() {                       ...

Adding Sproutcore KVO to OpenLayers - Part 2

Image
You can also  Read Part 1   or   Read Part 3 In the previous post of this series I have showed how easily an OpenLayers object can be extended with Sproutcore KVO . The main driver behind integrating KVO into OL is that of beauty and simplicity. When KVO is available texfields, checkboxes, layers, features, you name it can all have their state transparently and continuosly synchronized without writing any code at all. The first post was more of a proof of concept. In this post instead I am going to show a more practical use and rewrite one the OpenLayers examples (from the dev examples). The original example shows how to create and add features to a map from javascript. With the help of KVO I am going to expand the original and also make the features editable. As we will see the changes will propagate immediately into the map. The full source is available on github . To run the example simply download/clone/fetch the repo and open index.html with a browser. The...

Adding Sproutcore KVO to OpenLayers - Part 1

The truth is that after you start using Sproutcore KVO you become addicted to its beauty and simplicity. Where in other frameworks you spent most time keeping each part of the app in sync, in Sproutcore you get it for free. Sure Sproutcore isn't perfect and is not for all, but KVO is simply automagical! In this post I will show how easy it is to implement KVO on top of OpenLayers and take advantage of KVO to bind features, wfs queries and UI controls to otherwise stubborn Openlayers objects. In this example we will create a Vector layer, add KVo to it and then verify KVO bindings by manually adding an observer. I have run all this code from Google Chrome console and you can do it too. First thing to do is to create a scratch SC project: sc-init kvool then let's edit the Buildfile and add the following lines at the end so that the OpenLayers library is loaded with the app: config :all do |c| c[:javascript_libs] = ['http://www.openlayers.org/api/OpenLaye...

Sproutcore closable Mixin

Image
I've been working with sproutcore in my spare time for almost 6 months now and along the path I came up with some nice (I think) components. This one is a tiny unintrusive mixin that can be applied to panette panes and adds a close button on the top right corner. I have tried to make it work on panel panes too, but without success so far. That is probably because panel panes, being modal, grab all events before the events reach the mixin. Fetch from my github account: https://github.com/unicolet/stuff-I-m-proud-of P.S.: I also have a functional OpenLayers view, but it requires some refactoring before I can make it public.