app/assets/javascripts/components/editLayers.js.coffee
DataForm = ->
template: JST['templates/layerData']
_params: ['name', 'visible', 'fill_color', 'stroke_color', 'rule']
init: (opts) ->
@index = opts.index
@el = $ @template(opts)
@findFields()
@bindEvents()
@status = "active"
this
show: ->
@el.slideDown('fast')
@status = "active"
hide: ->
@el.slideUp('fast')
@status = "hidden"
toggle: ->
if @status is 'hidden' then @show() else @hide()
findFields: ->
@fields = {}
_.each ['name', 'visible', 'fill_color', 'stroke_color', 'tags'], (key) =>
@fields[key] = @el.find(".data_#{key}")
onChange: ->
App.mediator.publish 'layerData:changed', @index
getValue: ->
vals = {}
_.each @_params, (key) =>
if key == 'rule'
vals['rule'] = @_getRule()
else if @fields[key].attr('type') is 'checkbox'
vals[key] = @fields[key].prop('checked')
else
vals[key] = @fields[key].val()
vals
setValue: (entry) ->
_.each @_params, (key) =>
if key == 'rule'
return @_setRule(entry[key])
else if @fields[key].attr('type') is 'checkbox'
@fields[key].prop('checked', entry[key])
else
@fields[key].val(entry[key])
@fields[key].setComponentValue(entry[key])
bindEvents: ->
_.each @fields, (el, key) =>
el.change _.debounce(@onChange.bind(this), 100)
_getRule: ->
tags = @fields['tags'].val()
if tags.length > 0
{
operator: 'has'
property: 'tags'
value: tags.split(',')
}
else
null
_setRule: (rule) ->
if rule? and rule.operator == 'has' and rule.property == 'tags' and rule.value?
value = JSON.parse(rule.value).join(',')
@fields['tags'].setComponentValue('tags', value)
LayerItem = ->
template: JST['templates/layerItem']
init: (@opts) ->
@index = @opts.index
@el = $ @template(@opts)
@addDataForm(@opts)
@findElements()
@bindEvents()
@update()
this
addDataForm: (opts) ->
@data = DataForm().init(opts)
@el.find('.data-container').append @data.el
findElements: ->
@namePreviewEl = @el.find('.layer-name-preview')
@idEl = @el.find('.layer_id')
@colorPreviewEl = @el.find('.layer-color-preview')
onRemove: (evt) ->
evt.preventDefault()
@el.fadeOut 200, =>
App.mediator.publish 'layerItem:removed', @index
@el.remove()
getId: ->
if @idEl.val().length > 0 then @idEl.val() else null
getPosition: ->
@el.index()
getValue: ->
dataValue = @data.getValue()
_.extend {id: @getId(), position: @getPosition()}, dataValue
validateValue: ->
value = @getValue()
value.name.length > 0 && value.rule?
setValue: (entry)->
@idEl.val(entry.id)
@data.setValue(
name: _.result entry, 'name'
visible: _.result entry, 'visible'
fill_color: _.result entry, 'fill_color'
stroke_color: _.result entry, 'stroke_color'
rule: _.result entry, 'rule'
)
@update()
update: ->
value = @getValue()
@namePreviewEl.text(value.name || @opts.unnamed_layer)
@colorPreviewEl.css
'background-color': value.fill_color
'border-color': value.stroke_color
this
onChange: ->
@update()
App.mediator.publish 'layerItem:changed' if @getValue()
dataChanged: (evt, index) ->
@onChange() if index is @index
toggleData: (evt)->
evt.preventDefault()
@data.toggle()
this
showData: ->
@data.show()
this
hideData: ->
@data.hide()
this
bindEvents: ->
@el.find('.list-item-remove-btn').click @onRemove.bind(this)
@el.find('.list-item-metadata-btn').click @toggleData.bind(this)
App.mediator.subscribe 'layerData:changed', @dataChanged.bind(this)
App.components.editLayers = ->
itemDefaultValue:
visible: true
fill_color: () -> '#'+Math.floor(Math.random()*16777215).toString(16)
stroke_color: () -> '#'+Math.floor(Math.random()*16777215).toString(16)
attributes: ->
itemsContainer: @container.find('.layers-list')
addButton : @container.find('.add-new-btn')
layersInput : @container.find('.layers-value')
items : []
counter : 0
initialize: ->
layers = @attr.layersInput.val()
if layers.length > 0 && layers isnt '[]'
@loadData()
else
@addItem() # show an empty new entry
@listen()
loadData: ->
entries = _.sortBy JSON.parse(@attr.layersInput.val()), 'position'
_.each entries, (entry) =>
item = @addItem(entry)
addItem: (entry) ->
item = LayerItem().init _.extend({}, @attr.data, {index: @attr.counter++})
item.setValue @itemDefaultValue
@attr.items.push item
@attr.itemsContainer.append(item.el)
App.mediator.publish 'components:start', item.el
if entry?
item.setValue(entry).hideData()
item
listen: ->
@on @attr.addButton, 'click', @onAdd
@on @attr.itemsContainer, 'sortupdate', @onChange.bind(this)
App.mediator.subscribe 'layerItem:removed', @onRemove.bind(this)
App.mediator.subscribe 'layerItem:changed', @onChange.bind(this)
onAdd: (evt) ->
evt.preventDefault()
@addItem()
onRemove: (evt, index) ->
@attr.items[index] = null
@onChange()
onChange: ->
vals = []
_.each @attr.items, (item) ->
vals.push item.getValue() if item && item.validateValue()
@attr.layersInput.val JSON.stringify(vals)