瀏覽代碼

Started working on initial Essay form

Markus Ochel 13 年之前
父節點
當前提交
f813505a85

+ 165 - 2
admin/controllers/essays.coffee

@@ -3,10 +3,158 @@ Spine       = require('spine/core')
 templates   = require('duality/templates')
 
 Essay       = require('models/essay')
+Author      = require('models/author')
+Collection  = require('models/collection')
+Sponsor     = require('models/sponsor')
+Site        = require('models/site')
 
 
-class Essays extends Spine.Controller
-  className: 'essays panel'
+class EssayForm extends Spine.Controller
+  className: 'essay 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'
+    'select[name=collections]': 'formCollections'
+    '.save-button':            'saveButton'
+    '.cancel-button':          'cancelButton'
+
+  events:
+    'submit form':              'preventSubmit'
+    'click .save-button':       'save'
+    'click .cancel-button':     'cancel'
+    'click .delete-button':     'destroy'
+    'change select[name=site]': 'siteChange'
+
+  constructor: ->
+    super
+    @active @render
+
+  render: (params) ->
+    @editing = params.id?
+    if @editing
+      @copying = params.id.split('-')[0] is 'copy'
+      if @copying
+        @title = 'Copy Essay'
+        @item = Essay.find(params.id.split('-')[1]).dup()
+      else
+        @item = Essay.find(params.id)
+        @title = @item.name
+    else
+      @title = 'New Essay'
+      @item = {}
+    
+    @item.sites = Site.all().sort(Site.nameSort)
+    @item.sponsors = Sponsor.all().sort(Sponsor.nameSort)
+    @html templates.render('essay-form.html', {}, @item)
+
+    @itemTitle.html @title
+    
+    # Set few initial form values
+    if @editing
+      @formSite.val(@item.site)
+      @formSponsorId.val(@item.sponsor_id)
+    else
+      @formSite.val(@stack.stack.filterBox.siteId)
+    @siteChange()
+
+  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)
+    @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)
+    @formCollections.empty()
+    for collection in collections
+      @formCollections.append "<option value=\"#{collection.id}\" data-slug=\"#{collection.slug}\">#{collection.name}</option>"
+    @formCollections.val (c.id for c in @item.collections)
+
+  save: (e) ->
+    e.preventDefault()
+    if @editing
+      @item.fromForm(@form)
+    else
+      @item = new Essay().fromForm(@form)
+
+    # Convert some boolean properties
+    @item.published = Boolean(@item.published)
+
+    # Pull all selected collections
+    collections = []
+    @formCollections.children('option:selected').each ->
+      $option = $(@)
+      id = $option.attr('value')
+      slug = $option.attr('data-slug')
+      if id and slug
+        collections.push id: id, slug: slug
+    @item.collections = collections
+    @log @item.collections
+
+    # Take care of some dates if need be
+    try
+      if @item.published_at
+        @item.published_at = new Date(@item.published_at).toJSON()
+      else
+        @item.published_at = new Date().toJSON()
+    catch error
+      @showError "Date format is wrong. Use this format: 'Feb 20 2012 6:30 PM'"
+    
+    # Save the item and make sure it validates
+    if @item.save()
+      @back()
+    else
+      msg = @item.validate()
+      @showError msg
+
+  showError: (msg) ->
+    @errorMessage.html(msg).show()
+    @el.scrollTop(0, 0)
+  
+  destroy: (e) ->
+    e.preventDefault()
+    if @item and confirm "Are you sure you want to delete this #{@item.constructor.name}?"
+      @item.destroy()
+      @back()
+
+  cancel: (e) ->
+    e.preventDefault
+    if @dirtyForm
+      if confirm "You may have some unsaved changes.\nAre you sure you want to cancel?"
+        @back()
+    else
+      @back()
+
+  back: ->
+    @navigate('/essays/list')
+
+  preventSubmit: (e) ->
+    e.preventDefault
+    
+  deactivate: ->
+    super
+    @el.scrollTop(0, 0)
+
+
+class EssayList extends Spine.Controller
+  className: 'essay list panel'
 
   constructor: ->
     super
@@ -24,4 +172,19 @@ class Essays extends Spine.Controller
     @render()
 
 
+class Essays extends Spine.Stack
+  className: 'essays panel'
+
+  controllers:
+    list: EssayList
+    form: EssayForm
+
+  default: 'list'
+
+  routes:
+    '/essays/list': 'list'
+    '/essay/new':   'form'
+    '/essay/:id':   'form'
+
+
 module.exports = Essays

+ 2 - 0
admin/models/essay.coffee

@@ -17,6 +17,8 @@ class Essay extends BaseModel
   @queryOn: ['title','slug']
     
   validate: ->
+    @updated_at = new Date().toJSON()
+    @published_at = new Date().toJSON() unless @published_at
     return 'Site is required' unless @site
     return 'Slug is required' unless @slug
     return 'Title is required' unless @title

+ 1 - 1
admin/templates/collection-form.html

@@ -24,7 +24,7 @@
   </div>
   <div class="field required">
     <label>Slug</label>
-    <input type="text" name="slug" value="{{slug}}" placeholder="Choose a lug — all lowercase and hyphens but and NO spaces">
+    <input type="text" name="slug" value="{{slug}}" placeholder="All lowercase and hyphens but and NO spaces">
   </div>
   <div class="field">
     <label>Intro MD/HTML</label>

+ 81 - 0
admin/templates/essay-form.html

@@ -0,0 +1,81 @@
+<div class="buttons">
+  <button class="save-button">Save</button>
+  <button class="cancel-button plain">Cancel</button>
+</div>
+<h1>Essay</h1>
+<h3 class="item-title">{{title}}</h3>
+
+<form class="essay">
+  <div class="error-message"></div>
+
+  <div class="field required">
+    <label>Site</label>
+    <select name="site">
+      <option value="" disabled>Choose a site...</option>
+      {{#each sites}}
+      <option value="{{id}}">{{name}} &mdash; {{id}}</option>
+      {{/each}}
+    </select>
+    <div class="site-selected"></div>
+  </div>
+  <div class="field required">
+    <label>Title</label>
+    <input type="text" name="title" value="{{title}}" placeholder="Write a smart title">
+  </div>
+  <div class="field">
+    <div class="field-left required">
+      <label>Slug</label>
+      <input type="text" name="slug" value="{{slug}}" placeholder="All lowercase and hyphens but and NO spaces">
+    </div>
+    <div class="field-right">
+      <label>Author</label>
+      <select name="author_id"></select>
+    </div>
+  </div>
+  <div class="field">
+    <label>Intro MD/HTML</label>
+    <textarea name="intro" placeholder="Provide an essay introduction text as Markdown/HTML">{{intro}}</textarea>
+  </div>
+  <div class="field">
+    <label>Body MD/HTML</label>
+    <textarea name="body" placeholder="Write your essay content as Markdown/HTML">{{body}}</textarea>
+  </div>
+  <div class="field">
+    <label>Collections</label>
+    <select name="collections" multiple></select>
+  </div>
+  <div class="field">
+    <div class="field-left">
+      <label>Published</label>
+      <input type="checkbox" name="published" {{#if published}}checked{{/if}}>
+    </div>
+    <div class="field-right">
+      <label>Published At</label>
+      <input type="text" name="published_at" value="{{published_at}}" placeholder="ex. Feb 20 2012 6:30 PM or leave blank">
+    </div>
+  </div>
+
+  <h3 class="heading">Sponsorship</h3>
+  <div class="field">
+    <div class="field-left">
+      <label>Sponsor</label>
+      <select name="sponsor_id">
+        <option value="">Select a sponsor...</option>
+        {{#each sponsors}}
+        <option value="{{id}}">{{name}}</option>
+        {{/each}}
+      </select>
+    </div>
+    <div class="field-right">
+      <label>Start</label>
+      <input type="text" name="sponsor_start" value="{{sponsor_start}}" placeholder="ex. Feb 20 2012 6:30 PM">
+      <br class="clearfix">
+      <label>End</label>
+      <input type="text" name="sponsor_end" value="{{sponsor_end}}" placeholder="ex. Feb 20 2012 6:30 PM">
+    </div>
+  </div>
+</form>
+
+{{#if id}}
+<button class="delete-button plain">Delete {{type}}</button>
+{{/if}}

+ 1 - 1
site/templates/essay.html

@@ -63,7 +63,7 @@
       <div class="bio">{{{author.bio}}}</div>
       <ul class="links">
         {{#each author.links}}
-        <li><a href="{{link}}" target="_blank">{{label}}</a></li>
+        <li><a href="{{url}}" target="_blank">{{label}}</a></li>
         {{/each}}
       </ul>
     </div>