The FormView should take a configuration and automatically generate forms to edit various properties on the form view. It uses a set of configuration methods, just like SC.Record.attr() so you can setup the form view. Here is an example of how the API would work :
from a main_page.js:
myForm: SC.FormView.design({
layout: { top: 0, left: 0, right: 0, bottom: 40 },
fields: 'name gender'.w(), // Fields. RowView is really just a sub
// form as it works identically in most ways.
contentBinding: "MyApp.fooController",
// if row gets a class as a first argument, it conveniently sets it up
// like the following, but with only one field.
name: SC.FormView.row({
fields: "firstName lastName".w(),
fieldLabel: "Name:",
firstName: SC.FormView.field(SC.TextFieldView, { fieldKey: "first_name" }),
lastName: SC.FormView.field(SC.TextFieldView, { fieldKey: "last_name"})
}),
// with that optional first argument:
gender: SC.FormView.row(SC.RadioView, {
layout: { width: 100 },
items: 'male female'.w(),
fieldKey: 'contactGender',
fieldLabel: "Gender:",
}
});
This would create a form with three fields: firstName, lastName, and gender. By default these will generate fields preceded by a label using the key name (i.e. firstName, lastName) as the key on the content object and a humanized form of the key name (i.e. First Name:, Last Name:) as the label.
You can override these defaults using the 'fieldKey' and 'fieldTitle' properties in the second hash. Any other properties named in the hash will be applied to the generated view.
The 'fields' property—by the way—is not required. It just allows you to control the order in which the fields will be displayed. Otherwise it will display the fields in the order they are defined here.
Fields would usually be created using the "row" function. The API for a row is identical to the API for a form, except that rows have an additional property: fieldLabel. In fact, rows are actually subclasses of FormView (groups and other form features may also be implemented as form subclasses).
Note: the following discusses many settings, but it should be noted that the defaults should make a very nice form to begin with; tweaks should not be necessary except for customization to a theme.
A few extra features may be wanted from controls or fields in a form. These can be implemented in a set of Form controls or fields, which are, of course, not rewrites of the existing controls, but encapsulate them.
Many forms have an editable and non editable state. The non-editable state might show only the fields that hold information, or may show textual values instead of the normal UI controls. The FormView needs to be able to call beginEdit and endEdit and have fields automatically hide or show themselves and switch from being controls to labels or whatever as necessary.
If you look in Address Book.app on Mac, the first and last name fields change width as you type. This would be a nice feature to have in the Form's specialized text field view. It may also be a nice feature to have in other views (checkboxes, etc.). However, it would impact performance more significantly than other features, so should be opt-in.
Would be interesting (though perhaps a very bad idea) if the text fields could update the values they were bound to, live (but without necessarily committing the underlying data to the server—just intra-app).
Animation should be possible through a FormView animation mixin. This mixin will automatically propagate itself through all child forms it knows how to connect to.
Example usage:
myFormView: SC.FormView.design(SC.AnimatableForm, { /* My form stuff */ })
This allows automatic animation of anything animatable, without inserting any animation logic directly into FormView itself.
Parts of this stink a bit, but is there a workaround? The FormView and FormRowViews handle the positioning of the rows, labels, and fields; but how do they do this positioning? Unfortunately, they have to take parameters to make it somewhat flexible, and they remind one a bit too much of HTML tables. It would be really nice to have a better idea on how to do this:
Currently, the size of the label is calculated so that all labels can be sized to one size (the maximum label width). However, this involves creating and destroying a DOM node—for each calculation. Perhaps performance could be improved by:
The measurement occurs every time the label's layout or contents change—somewhat (but not terribly) often; primarily focused around initial creation of the form.
FormViews could also have a isAutoconfigured: YES option. If turned on, then instead of looking for fields defined on the view itself, the form view would look at the fields defined on the content object. Based on the fields found, it would generate defaults fields for the UI.
In this case, any fields defined on the FormView (i.e. firstName, lastName, etc above) would be used only if the content object itself had a field with the same property name.