multi-select.coffee 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. Spine = require('spine/core')
  2. $ = Spine.$
  3. class MultiSelectUI extends Spine.Controller
  4. tag: 'ul'
  5. className: 'ui-multi-select'
  6. tagClass: ''
  7. itemTag: 'li'
  8. itemClass: ''
  9. items: []
  10. selectedItems: []
  11. keyField: 'id'
  12. nameField: 'name'
  13. valueField: 'id'
  14. valueFields: null
  15. emptyText: 'Nothing to select here.'
  16. jumpToFirst: true
  17. changeCallback: null
  18. constructor: ->
  19. super
  20. @el.addClass(@tagClass) if @tagClass
  21. @render()
  22. @bind 'change', @changeCallback
  23. render: =>
  24. @el.html $("<#{@itemTag}/>").html(@emptyText) unless @items
  25. # create and render all options in the list
  26. for item in @items
  27. # create a list option item
  28. $option = $("<#{@itemTag}/>")
  29. $option.html item[@nameField]
  30. $option.attr("data-#{@keyField}", item[@keyField])
  31. if @valueFields
  32. for field in @valueFields
  33. $option.attr("data-#{field}", item[field])
  34. else
  35. $option.attr("data-#{@valueField}", item[@valueField])
  36. # add some needed classes
  37. $option.addClass(@itemClass) if @itemClass
  38. $option.addClass('selected') if item[@keyField] in @selectedItems
  39. # setup a selection toggle
  40. $option.on 'click', (e) =>
  41. e.preventDefault()
  42. $(e.currentTarget).toggleClass('selected')
  43. # Trigger change event
  44. @trigger 'change'
  45. # add the created option to the list
  46. @el.append $option
  47. @delay(@scrollToSelected, 1000) if @jumpToFirst
  48. @
  49. selected: =>
  50. cls = @
  51. items = []
  52. @el.children('.selected').each ->
  53. $option = $(@)
  54. if cls.valueFields
  55. obj = {}
  56. for field in cls.valueFields
  57. obj[field] = $option.attr("data-#{field}")
  58. items.push obj
  59. else
  60. items.push $option.attr("data-#{cls.valueField}")
  61. return items
  62. scrollToSelected: =>
  63. position = @el.find('.selected:first')?.position()
  64. @el.scrollTop(position?.top - 12) if position
  65. module.exports = MultiSelectUI