EditMode

The EditMode desktop sample demonstrate using the "edit mode" feature of DADataTable which enables a two phase approach to locally changing data in a table row rather than directly changing the contents. In "edit mode" the row will store its current values, including any pending changes made previously, until either the changes are discarded or posted; discarding changes made while in "edit mode" will revert the row back to the exact state (including pending changes to be applied to the server) it was in before. "Edit Mode" is particularly useful when you want to implement a UI for editing a row's data that is separate from the UI to display the data; for instance an edit sheet.

Getting Started

The sample is typically located in /Developer/RemObjects Software/Samples/Data Abstract/Desktop/EditMode, though you may have installed the Data Abstract for Cocoa and it's samples in another location.

To build it, you will of course need Xcode, and like all the samples provided with Data Abstract for Cocoa you will need to be running the Relativity Server with the DASamples Domain and the Simple Schema available.

Running the Sample

This sample allows you to see the results of using "edit mode" when adding a new row or editing a row. It uses the Clients table located in the Simple schema in an instance of Relativity Server.

The UI is comprised of 5 buttons, a table and a popup. The "Load" button retrieves the Clients table and displays it in the table. The "Add" button adds a new row to the table and opens the new row in an edit sheet. The "Edit" button opens the selected row in an edit sheet. The "Remove" button removes the selected row from the table. The "Apply" button sends the changes to the server. Lastly the "Servers" popup contains a list of available servers discovered by the Zeroconf discovery system. When the sample is run, it starts a Zeroconf discovery service that looks for instances of Relativity Server running on the local network. Any discovered servers will be added to the popup, if no servers are discovered then the dropbox on the toolbar will be empty. You can specify a server address yourself by clicking on the popup and then clicking on "Specify custom URL...".

There are two types of "Edit Mode" that can be seen in this sample:

  • The first occurs when adding a new row to the table, the new row is added invisibly to the table and an edit sheet displayed with some basic values. If you save the changes the row is added properly to the table, if the edit is cancelled then the row is removed completely from the table.
  • The second use of edit mode occurs when choosing a row to edit, the old values and pending changes are stored internally in the row. Changes are only committed when those values are posted, otherwise the original values and pending changes are returned.

Examining the Code

The code for creating the connection to the server and handling logging in is covered by other samples. In this section we shall focus solely on how "edit mode" is activated for a new row, and how it is activated when editing a row.

NOTE If the table name, or the field names do not exist then an ROException will be raised and should be handled appropriately.

App Structure

The sample is built around five classes; AppDelegate, DataAccess, ServiceAccess, RegisterServerWindowController and EditorWindowController.

The DataAccess class handles everything related to interacting with the Data Abstract SDK; including retrieving data from an instance of Relativity Server and applying changes back to the server.

The ServiceAccess class handles the discovery of any instances of Relativity Server that are available on the local network using ROZeroConf which is a feature available with the Remoting SDK that Data Abstract is built upon. ServiceAccess sets up a ROZeroConfBrowser Class object which searches for any servers that broadcast a value matching the value defined for RELATIVITY_SERVICE_NAME. When a service is found, or indeed disappears, the server list is updated and the popup with the list of available servers is also updated. It also handles the registration of custom server addresses. To explore further the ServiceAccess class and Zeroconf discovery see the article: The ServiceAccess Class and Zeroconf discovery.

The RegisterServerWindowController class is a subclass of NSWindowController which handles the UI aspects of a user manually adding a server url.

The EditorWindowController handles populating the UI with the selected row's data, activating edit mode, and either posting or discarding the changes depending on whether the "Save" or "Cancel" buttons are pressed.

Lastly the AppDelegate class handles the primary setup of the application, registers that it will listen for notifications broadcast by the ServiceAccess and DataAccess classes, and acts as a delegate to the EditorWindowController, RegisterServiceWindowController, DataAccess and NSTableView classes. It handles the actions for all of the buttons.

Adding a Row in Edit Mode

To add a new row in edit mode, you need to call DADataTable's addNewRowInEditMode: method. This creates a brand new row and sets the new row's rowState to rsAddedInEditMode as well as adding it to an internal list of edited rows and calling the row's edit method to activate its edit mode. The new row is not visible when the table is displayed in an NSTableView until the changes are committed using the row's post method. If you call the row's discard method then all of the changes are discarded and the row removed from the table.

If you passed NO to addNewRowInEditMode: and pressed the "Add", the edit form is opened and when you press the "Cancel" button the default form of the row is still in the table.

Below a new row is created by passing "YES" to addNewRowInEditMode:, and three of the fields assigned some default values.

//DataAccess.m
- (DADataTableRow *)addClient {
    DADataTableRow * addedRow = [self.clientsTable addNewRowInEditMode:YES];
    addedRow[FIELD_NAME] = @"[new client]";
    addedRow[FIELD_EMAIL] = @"temp";
    addedRow[FIELD_PASSWORD] = @"123";
    return addedRow;
}

Editing a row in Edit mode

To put a DADataTableRow into edit mode you need to call its edit method. While in edit mode any changes you make will not be visible until the post is called. To throw away the changes made, the discard method should instead be called.

In this sample when the "Edit" button is pressed, the selected row is put into "Edit Mode" (in EditorWindowController's showSheetWithData:forWindow) and its original contents used to fill in the edit form. When the "Cancel" button on the form is pressed it calls EditorWindowController's cancelAction: method which then calls discardWork (see below) which in turn calls the row's discard method. When the "Save" button is pressed, it calls okAction: which in turn calls the postWork method which calls the post method of the row.

//EditorWindowController.m
-(void)showSheetWithData:(DADataTableRow *)row forWindow:(NSWindow *)parentWindow {

    self.row = row;
    [self.row edit];

    ...
}
//EditorWindowController.m
-(void)postWork {
    [self.row post];
}
//EditorWindowController.m
-(void)discardWork {
    [self.row discard];
}