ldx-widgets
Version:
widgets
225 lines (177 loc) • 6.43 kB
text/coffeescript
React = require 'react'
PropTypes = require 'prop-types'
createClass = require 'create-react-class'
ReactDOM = require 'react-dom'
Spinner = React.createFactory(require './spinner')
InputMixin = require '../mixins/input_mixin'
{makeGuid, synthesizeMouseEvent} = require '../utils'
{ENTER} = require '../constants/keyboard'
{div, select, label, option} = require 'react-dom-factories'
###&
Select Props
@props.value - REQUIRED - [String]
The value of the input
w/ out this props, the input will not work
@props.name - OPTIONAL - [String]
The name of the input
@props.options - REQUIRED - [Array/Collection]
An array of objects w/ a value and label property or an array of objects w/ any values
@props.selectText - [String]
text for the default option
@props.labelField - [String] - REQUIRED
w/ arbitrary option array (ie no label/value properties)
The attribute name from the collection of objects to be used as the select label
@props.valueField - [String] - REQUIRED
w/ arbittrary option array (ie no label/value properties)
The attribute value from the collection of objects to be used as the select value
@props.returnFullObjects - [Boolean] - Optional
Get value will return a full object instead of just the value
@props.onChange - REQUIRED - [Function]
method that will change the value of the input prop
gets passed a single param that is the new value of the input
w/ out this method, the input will not update
@props.className - OPTIONAL - [String] - default 'select-input'
optional class to be added the select element itself
@props.id - OPTIONAL - [String] - default null
optional id to be added the input element itself
@props.wrapperClass - OPTIONAL - [String] default null
class to be added to the wrapper div
@props.wrapperLabel - OPTIONAL - [String]
text for wrapping label element
@props.loading - OPTIONAL - [Boolean]
indicator to determine that the input is loading a value from the server
@props.tabIndex - OPTIONAL - [Number]
tab index for the input
@props.onEnterKey/onBlur/onFocus - Optional - [Function]
optional handlers for various events
@props.disabled - OPTIONAL - [Boolean]
disabled state of the input
@props.validation - OPTIONAL - [Function]
a method that takes the value and returns an arry of validation objects
always return an empty array for a valid value
see the validation store for more documentation on validation objects
@props.isInPopover - OPTIONAL - [Boolean]
set this to yes if the form is inside a popover or modal, forces the
validation to display above the popover/modal layer
Inconsequential if validation is not being used
@props.delayedActionOnChange - OPTIONAL - [Object]
Takes action and interval parameters, will fire the action after the set interval everytime the data changes
@props.openOnMount - [Boolean] - Optional
opens the drop down when it mounts
@props.tabId - OPTIONAL - [String]
If this input is within a tab, this id will be used for validation errors in the store
@props.returnNull - REQUIRED - [Boolean]
When the default or 'placeholder' value is selected, instead of returning empty string, return null
&###
SelectInput2 = createClass
displayName: 'SelectInput2'
mixins: [InputMixin]
contextTypes:
clearValidationError: PropTypes.func
addValidationError: PropTypes.func
getValidationStatus: PropTypes.func
toggleValidationError: PropTypes.func
propTypes:
name: PropTypes.string
onChange: PropTypes.func.isRequired
options: PropTypes.array.isRequired
tabId: PropTypes.oneOfType([
PropTypes.string
PropTypes.number
])
returnNull: PropTypes.bool.isRequired
getDefaultProps: ->
{
className: 'select-menu'
id: null
name: null
wrapperClass: null
wrapperLabel: null
loading: no
tabIndex: null
onKeyDown: null
onKeyPress: null
onFocus: null
onBlur: null
onKeyUp: null
onEnterKey: null
onChange: null
disabled: no
validation: off
isInPopover: no
delayedActionOnChange: null
openOnMount: no
returnFullObjects: no
valueField: null
labelField: null
selectText: null
returnNull: no
}
render: ->
{value, name, options, tabIndex, className, loading, onKeyDown, onKeyPress, onBlur, onFocus,
wrapperClass, wrapperLabel, id, disabled, validation, valueField, labelField, returnFullObjects, selectText} = @props
{valueHasChanged} = @state
{error, forceShowAllErrors} = @context.getValidationStatus(@inputId)
{valueHasChanged} = @state
isValid = not error?
outerClass = 'field-wrap'
outerClass += " #{wrapperClass}" if wrapperClass?
outerClass += ' invalid shrink' if not isValid and (valueHasChanged or forceShowAllErrors)
valueField = valueField or 'value'
labelField = labelField or 'label'
optionEls = (option {
key: "#{item[valueField]}_#{index}"
value: item[valueField]
disabled: item.disabled
}, item[labelField] for item, index in options)
if selectText?
optionEls.unshift option {
key: "default"
value: ''
}, selectText
# When returnFullObjects is on, then overwrite the value (which will be ab object),
# with it's 'valueField' attribute
if returnFullObjects and value? then value = value[valueField]
input = select {
ref: 'input'
key: 'selectMenu'
name: name
onChange: @handleChange
onKeyUp: @handleKeyUp
value: value or ''
className
id
tabIndex
onFocus
onBlur
onKeyDown
onKeyPress
disabled
}, optionEls
# Add a wrapper label element if label prop is present
if wrapperLabel
input = label {
key: 'textInputLabel'
}, [wrapperLabel, input]
div {
className: "#{outerClass}"
}, [
input
div({
key: 'input-spinner'
className: 'input-spinner'
}, Spinner {length: 3}) if loading
div {
className: 'field-errors-show'
key: 'textInputErrorsShow'
ref: 'errorAnchor'
onMouseOver: @handleErrorMouseOver
onMouseOut: @handleErrorMouseOut
}
]
componentDidMount: ->
if @props.openOnMount
setTimeout =>
synthesizeMouseEvent @refs.input, 'mousedown'
, 15
module.exports = SelectInput2