authors.coffee 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. Spine = require('spine/core')
  2. $ = Spine.$
  3. templates = require('duality/templates')
  4. Author = require('models/author')
  5. Site = require('models/site')
  6. class AuthorForm extends Spine.Controller
  7. className: 'author form panel'
  8. elements:
  9. '.item-title': 'itemTitle'
  10. '.error-message': 'errorMessage'
  11. 'form': 'form'
  12. 'select[name=site]': 'formSite'
  13. 'textarea[name=bio]': 'formBio'
  14. '.links-list': 'linksList'
  15. '.save-button': 'saveButton'
  16. '.cancel-button': 'cancelButton'
  17. events:
  18. 'submit form': 'preventSubmit'
  19. 'change *[name]': 'markAsDirty'
  20. 'keyup *[name]': 'markAsDirty'
  21. 'click .save-button': 'save'
  22. 'click .cancel-button': 'cancel'
  23. 'click .delete-button': 'destroy'
  24. 'change select[name=site]': 'siteChange'
  25. 'click .add-link': 'addLink'
  26. constructor: ->
  27. super
  28. @active @render
  29. render: (params) ->
  30. @dirtyForm = false
  31. @editing = params.id?
  32. if @editing
  33. @copying = params.id.split('-')[0] is 'copy'
  34. if @copying
  35. @title = 'Copy Author'
  36. @item = Author.find(params.id.split('-')[1]).dup()
  37. # Important to indicate that we are creating a new record
  38. @editing = false
  39. else
  40. @item = Author.find(params.id)
  41. @title = @item.name
  42. # Fetch missing data if need be
  43. if not @item.bio?
  44. @item.ajax().reload {},
  45. success: =>
  46. @formBio.val(@item.bio)
  47. else
  48. @title = 'New Author'
  49. @item = {}
  50. @item.sites = Site.all().sort(Site.alphaSort)
  51. @html templates.render('author-form.html', {}, @item)
  52. @itemTitle.html @title
  53. # Set few initial form values
  54. if @editing or @copying
  55. @formSite.val(@item.site)
  56. else
  57. @formSite.val(@stack.stack.filterBox.siteId)
  58. @addLink()
  59. @siteChange()
  60. return @
  61. siteChange: ->
  62. $siteSelected = @formSite.parents('.field').find('.site-selected')
  63. site = Site.exists(@formSite.val())
  64. if site
  65. $siteSelected.html "<div class=\"site-name theme-#{site.theme}\">#{site.name_html}</div>"
  66. else
  67. $siteSelected.html ""
  68. addLink: (e) ->
  69. e?.preventDefault()
  70. @linksList.append templates.render('partials/link-form.html', {}, {})
  71. save: (e) ->
  72. e.preventDefault()
  73. if not navigator.onLine
  74. alert "Can not save. You are OFFLINE."
  75. return
  76. if @editing
  77. @item.fromForm(@form)
  78. else
  79. @item = new Author().fromForm(@form)
  80. # Construct the links list object
  81. links = []
  82. @linksList.find('.link-form').each ->
  83. label = $.trim $(@).find('input[name=link_label]').val()
  84. url = $.trim $(@).find('input[name=link_url]').val()
  85. code = $.trim $(@).find('input[name=link_code]').val()
  86. if label and url
  87. links.push label: label, url: url, code: code
  88. @item.links = links
  89. # Save the item and make sure it validates
  90. if @item.save()
  91. @back()
  92. else
  93. msg = @item.validate()
  94. @showError msg
  95. return @
  96. showError: (msg) ->
  97. @errorMessage.html(msg).show()
  98. @el.scrollTop(0)
  99. destroy: (e) ->
  100. e.preventDefault()
  101. if @item and confirm "Are you sure you want to delete this item?"
  102. @item.destroy()
  103. @back()
  104. markAsDirty: =>
  105. @dirtyForm = true
  106. @saveButton.addClass('glow')
  107. cancel: (e) ->
  108. e.preventDefault()
  109. if @dirtyForm
  110. if confirm "You may have some unsaved changes.\nAre you sure you want to proceed?"
  111. @back()
  112. else
  113. @back()
  114. back: ->
  115. @navigate('/authors/list')
  116. preventSubmit: (e) ->
  117. e.preventDefault()
  118. return false
  119. deactivate: ->
  120. @el.scrollTop(0)
  121. super
  122. class AuthorList extends Spine.Controller
  123. className: 'author list panel fixed-header'
  124. events:
  125. 'click h1 .count': 'reload'
  126. constructor: ->
  127. super
  128. # @active @render
  129. Author.bind 'change refresh', @render
  130. Spine.bind 'filterbox:change', @filter
  131. render: =>
  132. context =
  133. authors: Author.filter(@filterObj).sort(Author.alphaSort)
  134. @html templates.render('authors.html', {}, context)
  135. filter: (@filterObj) =>
  136. @render()
  137. @el.scrollTop(0)
  138. reload: ->
  139. Author.fetch()
  140. class Authors extends Spine.Stack
  141. className: 'authors panel'
  142. controllers:
  143. list: AuthorList
  144. form: AuthorForm
  145. default: 'list'
  146. routes:
  147. '/authors/list': 'list'
  148. '/author/new': 'form'
  149. '/author/:id': 'form'
  150. constructor: ->
  151. super
  152. for k, v of @controllers
  153. @[k].active => @active()
  154. module.exports = Authors