Todos - Alternate 6 ObjectController, SplitView


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
  2. Add ObjectController
  3. Show information about the current Todo task in the new view

 

 

 

 

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ยป