123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- Spine = require('spine/core')
- $ = Spine.$
- templates = require('duality/templates')
- utils = require('lib/utils')
- MultiSelectUI = require('controllers/ui/multi-select')
- FileUploadUI = require('controllers/ui/file-upload')
- PreviewUI = require('controllers/ui/preview')
- Scene = require('models/scene')
- Author = require('models/author')
- Collection = require('models/collection')
- Sponsor = require('models/sponsor')
- Site = require('models/site')
- class SceneForm extends Spine.Controller
- className: 'scene form panel'
- elements:
- '.item-title': 'itemTitle'
- '.error-message': 'errorMessage'
- 'form': 'form'
- 'select[name=site]': 'formSite'
- 'select[name=author_id]': 'formAuthorId'
- 'select[name=sponsor_id]': 'formSponsorId'
- 'input[name=title]': 'formTitle'
- 'input[name=published]': 'formPublished'
- 'textarea[name=body]': 'formBody'
- '.collections-list': 'collectionsList'
- '.upload-ui': 'fileUploadContainer'
- '.save-button': 'saveButton'
- '.cancel-button': 'cancelButton'
- 'button.fullscreen-button': 'fullscreenButton'
- events:
- 'submit form': 'preventSubmit'
- 'change *[name]': 'markAsDirty'
- 'keyup *[name]': 'markAsDirty'
- 'click .save-button': 'save'
- 'click .cancel-button': 'cancel'
- 'click .delete-button': 'destroy'
- 'change select[name=site]': 'siteChange'
- 'blur input[name=slug]': 'updateSlug'
- 'click .fullscreen-button': 'fullscreen'
- constructor: ->
- super
- @active @render
- render: (params) ->
- @dirtyForm = false
- @editing = params.id?
- if @editing
- @copying = params.id.split('-')[0] is 'copy'
- if @copying
- @title = 'Copy Scene'
- @item = Scene.find(params.id.split('-')[1]).dup()
- # Important to indicate that we are creating a new record
- @editing = false
- else
- @item = Scene.find(params.id)
- @title = @item.name
-
- # Fetch missing data if need be
- if not @item.body?
- @item.ajax().reload {},
- success: =>
- @formBody.val(@item.body)
- else
- @title = 'New Scene'
- @item = {}
- @item.collections ?= []
- @item._attachments ?= {}
-
- @item.sites = Site.all().sort(Site.alphaSort)
- @item.sponsors = Sponsor.all().sort(Sponsor.alphaSort)
- @html templates.render('scene-form.html', {}, @item)
- @itemTitle.html @title
-
- # Set few initial form values
- if @editing or @copying
- @formSite.val(@item.site)
- @formSponsorId.val(@item.sponsor_id)
- @formPublished.prop('checked', @item.published)
- else
- @formSite.val(@stack.stack.filterBox.siteId)
- # @formPublished.prop('checked', true)
- @siteChange()
- # Files upload area
- @fileUploadUI = new FileUploadUI
- docId: @item.id
- selectedFile: @item.photo
- attachments: @item._attachments
- changeCallback: @markAsDirty
- @fileUploadContainer.html @fileUploadUI.el
- return @
- siteChange: ->
- $siteSelected = @formSite.parents('.field').find('.site-selected')
- site = Site.exists(@formSite.val())
- if site
- $siteSelected.html "<div class=\"site-name theme-#{site.theme}\">#{site.name_html}</div>"
- @makeAuthorsList(site)
- @makeCollectionsList(site)
- else
- $siteSelected.html ""
- makeAuthorsList: (site) ->
- authors = Author.findAllByAttribute('site', site.id).sort(Author.alphaSort)
- @formAuthorId.empty()
- .append "<option value=\"\">Select an author...</option>"
- for author in authors
- @formAuthorId.append "<option value=\"#{author.id}\">#{author.name}</option>"
- @formAuthorId.val(@item.author_id)
-
- makeCollectionsList: (site) ->
- collections = Collection.findAllByAttribute('site', site.id).sort(Collection.alphaSort)
- @collectionSelectUI = new MultiSelectUI
- items: collections
- selectedItems: (c.id for c in @item.collections)
- valueFields: ['id','slug']
- changeCallback: @markAsDirty
- @collectionsList.html @collectionSelectUI.el
- updateSlug: (e) =>
- slug = $(e.currentTarget)
- unless slug.val()
- slug.val utils.cleanSlug(@formTitle.val())
- fullscreen: (e) =>
- e?.preventDefault()
- @fullscreenButtonText ?= @fullscreenButton.html()
- if @form.hasClass('fullscreen')
- @form.removeClass('fullscreen')
- @fullscreenButton.html @fullscreenButtonText
- @previewUI?.close()
- else
- @form.addClass('fullscreen')
- @fullscreenButton.html "Exit #{@fullscreenButtonText}"
- @previewUI = new PreviewUI field: @formBody
- save: (e) ->
- e.preventDefault()
- if not navigator.onLine
- alert "Can not save. You are OFFLINE."
- return
-
- if @editing
- @item.fromForm(@form)
- else
- @item = new Scene().fromForm(@form)
- @item.collections = @collectionSelectUI.selected()
- @item._attachments = @fileUploadUI.attachments
- # Take care of some boolean checkboxes
- @item.published = @formPublished.is(':checked')
-
- # Save the item and make sure it validates
- if @item.save()
- @back()
- else
- msg = @item.validate()
- @showError msg
- return @
- showError: (msg) ->
- @errorMessage.html(msg).show()
- @el.scrollTop(0)
-
- destroy: (e) ->
- e.preventDefault()
- if @item and confirm "Are you sure you want to delete this item?"
- @item.destroy()
- @back()
- markAsDirty: =>
- @dirtyForm = true
- @saveButton.addClass('glow')
- cancel: (e) ->
- e.preventDefault()
- if @dirtyForm
- if confirm "You may have some unsaved changes.\nAre you sure you want to proceed?"
- @back()
- else
- @back()
- back: ->
- @navigate('/scenes/list')
- preventSubmit: (e) ->
- e.preventDefault()
- return false
-
- deactivate: ->
- @el.scrollTop(0)
- super
- class SceneList extends Spine.Controller
- className: 'scene list panel fixed-header'
- events:
- 'click h1 .count': 'reload'
- constructor: ->
- super
- # @active @render
- Scene.bind 'change refresh', @render
- Spine.bind 'filterbox:change', @filter
- render: =>
- sortFunc = if @filterObj?.sortBy then Scene[@filterObj.sortBy] else Scene.dateSort
- context =
- scenes: Scene.filter(@filterObj).sort(sortFunc)
- @html templates.render('scenes.html', {}, context)
- filter: (@filterObj) =>
- @render()
- @el.scrollTop(0)
- reload: ->
- Scene.fetch()
- class Scenes extends Spine.Stack
- className: 'scenes panel'
- controllers:
- list: SceneList
- form: SceneForm
- default: 'list'
- routes:
- '/scenes/list': 'list'
- '/scene/new': 'form'
- '/scene/:id': 'form'
- constructor: ->
- super
- for k, v of @controllers
- @[k].active => @active()
- module.exports = Scenes
|