• If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • You already know Dokkio is an AI-powered assistant to organize & manage your digital files & messages. Very soon, Dokkio will support Outlook as well as One Drive. Check it out today!

View
 

Hello World Tutorial

Page history last edited by Charles Jolley 13 years, 3 months ago Saved with comment

1. Getting started:

I thought I'd start by trying to get through the original Hello World tutorial and document the differences that I come across, since it seems obvious you won't get very far trying to follow at it is.  I'll note what I had to do for each step as I can.

  1. First off, you'll need to follow the instructions for setting up Abbot.  Make sure you have run git submodule update --init after you check out.
  2. It seems the sproutcore command from abbot doesn't work, but running sc-init hello_world is what you want to do.
  3. Now, cd into hello_world.  Run <path_to_abbot>/bin/sc-server.  You should now be able to hit your application on the server at the URL - "http://localhost:4020/hello_world".

 

You will see the text "Hello World" in the middle of the screen.

 

The source of this text lies in the file main_page.js in the directory english.lproj. In main_page.js, you can see the source as below:

 

    labelView: SC.LabelView.design({
      layout: { centerX: 0, centerY: 0, width: 100, height: 18 },
      tagName: "h1", value: "Hello World"
    })

 

This is the code which is responsible for getting our "Hello World" on the screen.

Now, change the value attribute of the label view to "I am changing!". Go back to the browser and refresh the screen. You can see the new text on the screen.

 

2. Adding a controller:

OK, now we move on to add our first controller to the "hello world" application. Type the following command at the terminal to generate the controller:

 

<path_to_abbot>/bin/sc-gen controller HelloWorld.appController

 

This will create a controller for the application under the directory "controllers". The code in the controller would look like:

 

HeloWorld.appController = SC.Object.create(
/** @scope HeloWorld.app.prototype */ {

  // TODO: Add your own code here.

}) ;

 

 

The create method on the Object class is creating new instance of Object. Now, we will be adding some code to our controller. Replace the line with TODO with the line below:

greeting: "Hello World!"

 

3. Adding the binding:

Now switch back to main_page.js and replace the text value: "Hello World" with the below text:

valueBinding: 'HelloWorld.appController.greeting'

If you refresh the page in the browser, you will see "Hello World" again. But now the text of the label is coming from the property of the controller. It is live binding of the text of the label to the property of the controller. This can be verified by typing the below line in the FireBug console:

HelloWorld.appController.set('greeting', 'I am changing again!!!')

You will see that the text will change to the value set by you above.

 

4. Adding button:

Now we move on to the next step. We will add a button to our page. But before that, we will add a function to our controller which will look like:

 

  toggleGreeting: function() {
    var currentGreeting = this.get('greeting');
    var newGreeting = (currentGreeting === 'Hello World!') ?

                        'I am on SproutCore!' :

                        'Hello World!' ;
    this.set('greeting', newGreeting);
  }

 

This function is to toggle the greeting message. If the current greeting message is "Hello World", it will change it to "I am SproutCore!" and vice versa. This function can be tested by calling it on the FireBug console as:

HelloWorld.appController.toggleGreeting()

 

Now we add a button on click of which we can call this finction. For this we need to add the below code to main_page.js, just below the labelView:

 

    buttonView: SC.ButtonView.design({
      layout: { centerX: 0, centerY: -50, width: 100, height: 18 },
      title: "Change Title",
      action: "toggleGreeting",
      target: "HelloWorld.appController"
    })

 

Make sure that a comma is present after labelView design. Otherwise you'll get an error in your browser when you refresh. Now refresh the page in the browser. But where is our button :-(

Oh.. we forgot to add it the childViews array. Add it as below:

 

childViews: 'labelView buttonView'.w(),

 

w() is a function provided by SproutCore. If we have a string of substrings delimited by whitespaces, this function can convert such a string to an array of given substrings.

 

Now refresh the page. Good! Now we can see the button. Now click the button and see if the label text changes. :-)

Cool!

 

5. Observers:

One more key concept in SproutCore is observers. Observers are normal functions which observe the value of a specified property and execute the statements of the function whenever the property changes.

Above, we used button to toggle the text of the label. Now, we will implement something similar using a checkbox, where we can see a status as on or off.

In the app controller, just after the function, add the below property and the observer:

 

isClockShowing: NO,

 

isClockShowingObserver: function() {

var isClockShowing = this.get('isClockShowing') ;

var newGreeting = (isClockShowing) ? 'CLOCK!' : 'Hello World!' ;

this.set('greeting', newGreeting) ;

}.observes('isClockShowing') 

 

In SproutCore, we use YES or NO alternatively for true or false. There is no difference between the two, but we use it this way as a convention.

Here, note that isClockShowingObserver is an observer which is like a normal function. By just adding .observes function it becomes an observer which will observe the value of isClockShowing.

This can be tested by typing the below statement in FireBug:

 

HelloWorld.appController.set('isClockShowing', YES)

 

Next, we create a checkbox in our view. We replace the buttonView code with the following code:

checkbox: SC.CheckboxView.design({

      layout: { top: 50, left: 50, width: 20, height: 20 },

      valueBinding: "HelloWorld.appController.isClockShowing"

}),

checkBoxLabel: SC.LabelView.design({

     layout: {top: 50, left: 75, height: 20, width: 200},

     value: "Show Clock"

})

 

and add the above views to child views

 

childViews: 'labelView checkbox checkBoxLabel'.w(),

 

The checkbox’ value property is now bound to the isClockShowing property, which means whenever you click the checkbox, the isClockShowing property will update causing your observer to fire which will change the greeting property and update the label. It all works like magic we hope. Refresh the web browser and try it out.

 

Finally, we add the clock functionality. We will add some functions in the controller and use the SproutCore Timers and date formatting functions. Add the below functions to the controller. Again, do not miss the comma after the previous property or function. This small miss can lead you to error on your page.

tick: function() {

this.set('greeting', this.now()) ;

},

 

now: function() {

return new Date().format('hh:mm:ss');

}

 

Modify the isClockShowingObserver observer as below:

isClockShowingObserver: function() {

var isClockShowing = this.get('isClockShowing') ;

 

// create a timer if it does not exist already

if (!this._timer) this._timer = SC.Timer.schedule({

target: this, action: 'tick', repeats: YES,

    interval: 1000

});

 

// pause the timer unless the clock is showing

this._timer.set('isPaused', !isClockShowing) ;

 

// update right now

var newGreeting = (isClockShowing) ? this.now() : 'Hello World';

this.set('greeting', newGreeting) ;

}.observes('isClockShowing'),

 

Ok, done! Refresh the page and your clock should be ticking.

 

6. Localization:

Now, lets talk about localization i.e. customizing your application to work in languages other than English.  

 

To activate localization in your application, you just need to add a language folder for each language you want to support.  A language folder ends in the ".lproj" extension and contains all of the resources for your application that you want to appear localized.  Let's add your first language to the HelloWorld app.  On the command line, from the project directory type:

 

sc-gen language HelloWorld en

 

You should now find a new directory called "en.lproj" in your application with a string.js file in it.  In these string.js files we put the language specific strings. For our "Hello World" application, we can modify the strings.js file as:

 

SC.stringsFor('en',{
  "_HelloWorld.ShowClock": "Show Clock"
}) ;

 

To use these strings, you just need to tell SproutCore which strings you want to location.  Modify your main_page.js file like so:

 

checkBoxLabel: SC.LabelView.design({

     layout: {top: 50, left: 75, height: 20, width: 200},

 

     value: "Show Clock" "_HelloWorld.ShowClock".loc()

})

 

So, we see that the application is actually language independent. If the application has to be deployed in some other locality, we just need to add strings.js file to the specific language's ".lproj" directory and add the property "_HelloWorld.ShowClock" in the file. The value of the property will be the language specific string in that language meaning, "Show Clock".

 

Note:

Statements executed with light green background are to be executed on FireBug console.

Comments (7)

Charles Jolley said

at 9:57 pm on Apr 19, 2009

We've started updating Hello World. Please check it out and contribute there!

http://github.com/sproutit/samples-hello-world/tree/master

Chris Nelson said

at 9:42 am on Apr 20, 2009

That's great, Charles. Thanks for help. I mean this page to be a step by step tutorial as before. Finished code is great, but knowing how to produce it is what I want also :)

tymofi said

at 7:03 am on May 8, 2009

In step 2, does "<path_to_abbot>/bin/sc-gen controller hello_world/app" need to be "<path_to_abbot>/bin/sc-gen controller HelloWorld.AppController?"

Cory Loken said

at 3:45 pm on May 8, 2009

I fixed a spelling error. Fixed an error in the example code. Changed quotes to a more friendly quote for copy/paste of example code into projects.

Charles Jolley said

at 10:50 am on May 10, 2009

@tymofi: it should be "sc-gen controller HelloWorld.appController" (or HelloWorld.app in the example given here.)

The older sc-gen accepted a filename. The new one does also but it also takes a simple class name, which is much easier to remember and therefore now recommended.

tymofi said

at 6:48 am on May 11, 2009

@Charles Jolley: Great! Thanks for clarifying. I guess the only thing is that in "Abbot Spec sc-gen" specs instead of "sc-gen model|view|controller AppName.ClassName...," it should be "sc-gen model|view|controller AppName.className..."

Erich Ocean said

at 12:51 pm on May 11, 2009

Actually, it would be sc-gen model|view AppName.ClassName, and sc-gen controller AppName.instanceName.

You don't have permission to comment on this page.