Lanes.Components.Form || = {} Lanes.Components.Form.FieldMixin = { bindDataEvents: -> model: "change:#{@props.name} remote-update:#{@props.name} invalid-fields invalid-field:#{@getInvalidFieldName()}" mixins: [ Lanes.React.Mixins.Access Lanes.React.Mixins.ReadEditingState Lanes.React.Mixins.FieldErrors ] pubsub: false propTypes: model: Lanes.PropTypes.State.isRequired name: React.PropTypes.string.isRequired unlabeled: React.PropTypes.bool fieldOnly: React.PropTypes.bool onChange: React.PropTypes.func unstyled: React.PropTypes.bool getValue: React.PropTypes.func setValue: React.PropTypes.func align: React.PropTypes.oneOf([ 'right', 'left', 'center' ]) label: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.element ]) fieldMixinSetValue: (ev) -> if @props.onChange @props.onChange(ev) unless true is ev.isDefaultPrevented?() @model[@props.name] = ev.target.value componentWillUnmount: -> clearTimeout(@state.pendingChangeSetDelay) if @state.pendingChangeSetDelay _unsetChangeSet: -> @setState(displayChangeset: false, pendingChangeSetDelay: null) setDataState: (state, evname) -> displayChangeset = @model.updatingFromChangeset and @model.changedAttributes()[@props.name] if displayChangeset and not @state.pendingChangeSetDelay pendingChangeSetDelay = _.delay(@_unsetChangeSet, 2000) @setState(_.extend( state, {pendingChangeSetDelay, displayChangeset})) _fieldMixinGetLabelValue: -> @getLabelValue?() || @props.label || _.titleize _.humanize @props.name fieldMixinGetValue: -> value = if @props.getValue @props.getValue.call(@model, @props) else if @props.value? @props.value else if @getValue @getValue() else @model[@props.name] if _.isBlank(value) '' else value _fieldMixinRenderFormGroup: (child, props, options) -> if (invalidMsg = @fieldInvalidValueMessage()) msg = {invalidMsg} unless @props.unlabeled label = {@_fieldMixinGetLabelValue()} {label} {child} {msg} _fieldMixinRenderEdit: (props) -> _fieldMixinRenderDisplay: (props) -> value = @fieldMixinGetValue() value = value.toString() if _.isObject(value) {value} _fieldMixinRenderNone: (props) -> renderType: -> if @isEditingRecord() if @hasWriteAccess() ['edit', 'Edit'] else if @hasReadAccess() ['read-only', 'Display'] else ['none', 'None'] else if @hasReadAccess() ['display', 'Display'] else ['none', 'None'] statics: cleanColumnProps: (props) -> _.omit props, 'model', 'label', 'name', 'unlabeled', 'fieldOnly', 'placeholder', 'type' renderEmptyColumn: (props = @props) -> props = @cleanColumnProps(props) render: -> [type, method] = @renderType() options = {} hasError = @isFieldValueInvalid() options.validationState = 'warning' if hasError props = LC.Form.FieldMixin.statics.cleanColumnProps(@props) props.className = _.classnames( _.result(this, 'fieldClassName'), 'lanes-field', type, props.className, ( if @props.align then "align-#{@props.align}" else null), { changeset: @state.displayChangeset 'has-error': hasError } ) field = (@[ "render#{method}" ] || @["_fieldMixinRender#{method}"])( if @props.fieldOnly then props else _.omit(props, 'className') ) if @props.fieldOnly field else ( @['renderFormGroup'] || @['_fieldMixinRenderFormGroup'] )(field, props, options) }