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

  • Work with all your cloud files (Drive, Dropbox, and Slack and Gmail attachments) and documents (Google Docs, Sheets, and Notion) in one place. Try Dokkio (from the makers of PBworks) for free. Now available on the web, Mac, Windows, and as a Chrome extension!


Todos - Alternate 6 ObjectController, SplitView

Page history last edited by Aleksandr 11 years, 2 months ago

It would be good to expand this GUI a bit further. Let's add a form view. When the user selects a Todo item in the list view, lets display the details of the Todo item in the form view.


(There is a video screencast that describes this step. You can find it here on vimeo.com: http://www.vimeo.com/14602725 or you can find it on screencast.com: http://bit.ly/cQzxS5. Note that there is some difference in controller names between this tutorial and screencast.)


To accomplish this, we will add a split view so that the list view that displays the Todos are on the left and the Todo details are editable to the right.


Then later, we can add some additional fields with different types to the Todo model object and perhaps some relationships as well.


Before we add the formview, let's just add a split view and a object controller. The array controller works with the list view. The object controller will work with the formview (and for now just the view to the right).


We are going to do the following steps as part of this Alternate 6:




  1. Add splitter pane with a view that has just a label
    • Left side of splitter pane has list view
    • Right side of splitter pane has label
  2. Add ObjectController
    • Add binding to array controller 
  3. Show information about the current Todo task in the new view
    • Add binding to content of Object controller





Add splitter pane with a view that has just a label


"A split view is used to show views that the user can resize or collapse. To use a split view you need to set a topLeftView, a bottomRightView and, optionally, a splitDividerView. You can also set various other properties to control the minimum and maximum thickness allowed for the flexible views".


Put the Todos list on the left, i.e., make it the topLeftView of the split view. Then just put the label to the right, i.e., make it the bottomRightView of the split view



Let's just add a split view to start off with. Open up ./apps/todos/resources/main_page.js.


Add a split view by replacing the middleView of the mainPane (Todos.mainPage.mainPane) with a SC.SplitView as follows:


    middleView: SC.SplitView.design({

        layout: { left: 0, top: 36, right: 0, bottom: 32 },

        layoutDirection: SC.LAYOUT_HORIZONTAL,

        autoresizeBehavior: SC.RESIZE_TOP_LEFT,

        defaultThickness: 0.8,

        //The list view is nested into the scrollview which is now in the splitview.

        topLeftView: SC.ScrollView.design({

          hasHorizontalScroller: NO,

          layout: { top: 36, bottom: 32, left: 0, right: 0 },

          backgroundColor: 'white',

          //Here is the original list view, which is bound to the tasksController

          contentView: SC.ListView.design({

            contentBinding: 'Todos.tasksController.arrangedObjects',

            selectionBinding: 'Todos.tasksController.selection',

            contentValueKey: "description",

            contentCheckboxKey: "isDone",

            rowHeight: 21,

            canEditContent: YES,

            canDeleteContent: YES,


            target: "Todos.tasksController",

            action: "toggleDone"



        topLeftMinThickness: 150,

        topLeftMaxThickness: 250,

        dividerView: SC.SplitDividerView.design({

            layout: {}


        //This view shows up on the right. It is a placeholder, later we will use a formview.

        bottomRightView: SC.LabelView.design({

            textAlign: SC.ALIGN_CENTER,

            valueBinding: "Todos.tasksController.summary"




At this point the bottomRightView is just a place holder for a form view which we will add in the next tutorial.


We also have to change one line in tasks.js (controller file). Change line


var list = Todos.mainPage.getPath('mainPane.middleView.contentView');

to look like this:

var list = Todos.mainPage.getPath('mainPane.middleView.topLeftView.contentView');



At this point, you can run this. The label will show up on the right. The todos list view will be on the left.


It should look like this:


Add ObjectController


According to the SproutCore documentation: "An ObjectController gives you a simple way to manage the editing state of an object. You can use an ObjectController instance as a 'proxy' for your model objects. Any properties you get or set on the object controller, will be passed through to its content object. This allows you to setup bindings to your object controller one time for all of your views and then swap out the content as needed."



We want to bind the current selection from the array controller into the object controller.  Naturally, we would like to call our object controller taskController, but it would be only one letter off from the array controller name, i.e., tasksController (a maintenance nightmare). Therefore rename the array controller to tasksArrayController.



To do this we edit. ./apps/controllers/tasks.js as follows:


    Todos.taskController = SC.ObjectController.create({

         contentBinding: SC.Binding.single('Todos.tasksController.selection'),




You may wonder why we use SC.Binding.single('Todos.tasksController.selection') since we did not need to use SC.Binding before. It is because the user can select more than one item in the list; therefore, the selection is an array, but we need it to be single object. SC.Binding has transform methods to adapt a binding to an object more appropriate to its receiver. The single function will create a binding that transforms the selection array into a single object that the ObjectController manages.


Show information about the current Todo task in the new view


Now we just need to update the label that we added before to the right side of the split pane to bind to the object controller as follows:


        bottomRightView: SC.LabelView.design({

            textAlign: SC.ALIGN_CENTER,

            valueBinding: "Todos.taskController.description"



Now every time you select the a task in the list view, its description will display on the right hand side as the following screen capture shows:



You can find the source for this at http://github.com/RichardHightower/todo-sproutcore-tut/tree/master/todo-6/.


In the next alternate path lesson, we create a form and do some validation.

Continue to next step: Todos - Alternate Path Step 7 - Forms and Validationยป



Comments (1)

Ido Ran said

at 3:10 pm on Oct 17, 2010

Very good addition to the tutorial.
One thing that did work as I expect is that when I select multiple items in the list, the taskController.content is not one of the tasks (I expect it to be the first) but it is "@@MULT@@".
If you can explain about it that will be great.

Thank you,

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