class Backbone.Poised.Textfield extends Backbone.View
className: 'poised textfield'
events:
'focusin input': 'clearInputValue'
'focusout input': 'readInput'
initialize: (options = {}) =>
throw new Error('Missing `model` option') unless options.model?
throw new Error('Missing `attribute` option') unless options.attribute?
@attribute = options.attribute
@options = _.chain(options)
.pick('type', 'placeholder', 'autofocus', 'clearOnFocus', 'stepSize', 'precision', 'minValue', 'maxValue', 'unit', 'validate')
.defaults
type: 'text'
autofocus: false
clearOnFocus: false
minValue: null
maxValue: null
validate: true
.value()
if @options.stepSize? and not @options.precision?
@options.precision = _.find([0..3], (i) =>
@options.stepSize * Math.pow(10, i) >= 1)
if _.isArray(options.range)
[@options.minValue, @options.maxValue] = options.range
@listenTo(@model, "change:#{@attribute}", @setValue)
limit: (val) ->
val = Math.max(val, @options.minValue) if @options.minValue?
val = Math.min(val, @options.maxValue) if @options.maxValue?
val
_updateValue: (value = @model.get(@attribute), options = {}) =>
if @options.type is 'number'
if typeof value is 'string'
if value.match(/^[+\-]?\d+(\.\d+)?$/i)?
value = @limit(parseFloat(value))
else
value = @model.get(@attribute)
if @options.precision
valueString = value.toFixed(@options.precision)
@$input.val(valueString or value)
unless options.updateModel is false
@model.set(@attribute, value)
if @model.validate? and @options.validate
@model.validate(@attribute)
setValue: ->
return if @$input.is(':focus')
@_updateValue(undefined, updateModel: false)
readInput: =>
@_updateValue(@$input.val())
clearInputValue: =>
@$input.val('') if @options.clearOnFocus
render: =>
@$el.empty()
inputAttributes =
class: 'poised'
name: @attribute
type: @options.type
placeholder: @options.placeholder
autofocus: @options.autofocus
if @options.type is 'number'
inputAttributes.min = @options.minValue
inputAttributes.max = @options.maxValue
inputAttributes.step = @options.stepSize or 'any'
@$input = $('', inputAttributes).appendTo(@$el)
@$el.append($('', text: @options.unit)) if @options.unit
@_updateValue()
this