Controls make up the primary interface components for defining and manipulating query conditions. They are composed of two main components for defining a condition, the operator and value inputs. Depending on the data, the operator may be implied or simplified to a checkbox for inclusion or exclusion of the values (e.g. IN vs. NOT IN).

Input types are type-independent and focus on how a user can define their value. These include:

  • TextInput - text box for typing in a value
  • SelectInput - select box for choosing from a list of pre-define values
  • TypeaheadInput - text box which support auto-completing values client or server-side

Control types are type-aware and present inputs in a way appropriate for the type of data and the supported operators. These roughly map the simple types that Harvest defines:

  • StringControl
  • NumberControl
  • BooleanControl

Interface

The base Control class has support for the following options. Each object-based option will be extended not replaced.

Options

attrNames: ['id', 'operator', 'value', 'nulls']

An array of attribute names that may be used by the control. The default is id, operator, value, and nulls.

dataAttrs:
    id: 'data-id'
    operator: 'data-operator'
    value: 'data-value'
    nulls: 'data-nulls'

An object of attribute names and their HTML attribute which holds a static value. This is currently only used for getting/setting static values for the attribute when the target element is not a form element. Read more about static values below.

dataSelectors:
    id: '[data-id]'
    operator: '[data-operator]'
    value: '[data-value]'
    nulls: '[data-nulls]'

An object of attribute names and their element selector for getting/setting the attribute value. If the selector resolves in a form element including input,select,textarea, the value will be extracted from the field's value, otherwise it will fallback to the dataAttrs means.

regions:
    operator: '.control-operator'
    value: '.control-value'
    nulls: '.control-nulls'

Control is a subclass of Marionette.Layout and thus supports regions. This is an object of attribute names and the selector within the class' template where the input will be rendered.

regionViews:
    operator: c.ui.OperatorInput
    value: c.ui.TextInput
    nulls: c.ui.BooleanInput

An object of attribute names and the control input class that will be rendered in the corresponding region.

regionOptions: {}

An object of attribute names and options to be used when initialize a region view instance.

attrGetters:
    id: 'getId'
    operator: 'getOperator'
    value: 'getValue'
    nulls: 'getNulls'

An object attribute names and method names on this that are used to get the value from the corresponding element.

attrSetters:
    id: 'setId'
    operator: 'setOperator'
    value: 'setValue'
    nulls: 'setNulls'

An object attribute names and method names on this that are used to set the value to the corresponding element.

The above getters/setters are pre-defined on the Control class, but are no-ops.

Usage

# Get some field
field = c.data.fields.at(0)

# Get the context for the field (assuming it's defined)
context = c.data.contexts.getSession().fetch(field: field.id)

# Initialize with model and with any overrides/extensions of the
# above options
control = new c.ui.FieldControl
    model: field
    ...

# The control supports both the 'get' and 'set' methods for
# convenience. A single attribute name can be passed or an object.
# This enables setting the initial state of the control
control.set(context.get())

# The view that depends on this control, such as a FieldForm can bind
# to the control's change event which enables updating the context
# as the control is manipulated
control.on 'change', (control, attrs) ->
    context.set(attrs)

# To set up a bi-directional sync, the control can _listenTo_ the
# context
control.listenTo context, 'change', (model) ->
    control.set(context.changedAttributes())

Static Values

A static value is typically used when one of the attributes needs to remain constant or the user should not have/need the ability to edit the value. For example, the control operator could be kept static to limit the kind of operation to be applied for the query condition. This could be a text box and the operator may always be a iregex for performing case-insensitive regular expressions.