refactor code (wip) + fix bugs (wip) + tweak ui + save an existing page in ajax (HTML5 + FormData) + create a new page in ajax (wip)
This commit is contained in:
parent
a50df5ad8e
commit
47625dfa17
@ -10,7 +10,6 @@
|
||||
//= require underscore
|
||||
//= require handlebars
|
||||
//= require backbone
|
||||
//= require backbone_rails_sync
|
||||
//= require uploadify
|
||||
//= require codemirror
|
||||
//= require tinymce-jquery
|
||||
|
@ -1,8 +1,14 @@
|
||||
class Locomotive.Models.EditableElement extends Backbone.Model
|
||||
|
||||
toJSONForSave: ->
|
||||
_.tap {}, (hash) =>
|
||||
for key, value of @.toJSON()
|
||||
hash[key] = value if _.include(['id', 'source', 'content', 'remove_source'], key)
|
||||
|
||||
class Locomotive.Models.EditableElementsCollection extends Backbone.Collection
|
||||
|
||||
model: Locomotive.Models.EditableElement
|
||||
|
||||
blocks: ->
|
||||
names = _.uniq(@map (editable, index) -> editable.get('block_name'))
|
||||
_.tap [], (list) =>
|
||||
@ -11,3 +17,6 @@ class Locomotive.Models.EditableElementsCollection extends Backbone.Collection
|
||||
|
||||
by_block: (name) ->
|
||||
@filter (editable) -> editable.get('block_name') == name
|
||||
|
||||
toJSONForSave: ->
|
||||
@map (model) => model.toJSONForSave()
|
||||
|
@ -1,7 +1,37 @@
|
||||
class Locomotive.Models.Page extends Backbone.Model
|
||||
|
||||
paramRoot: 'page'
|
||||
|
||||
urlRoot: "#{Locomotive.mount_on}/pages"
|
||||
|
||||
initialize: ->
|
||||
@_normalize()
|
||||
|
||||
_normalize: ->
|
||||
@set
|
||||
editable_elements: new Locomotive.Models.EditableElementsCollection(@get('editable_elements'))
|
||||
|
||||
|
||||
# unless _.isArray @get('editable_elements')
|
||||
# console.log('already a collection')
|
||||
# return
|
||||
#
|
||||
# previous_collection = @previous('editable_elements')
|
||||
#
|
||||
# console.log(previous_collection)
|
||||
#
|
||||
# if _.isArray collection
|
||||
# collection = new Locomotive.Models.EditableElementsCollection(@get('editable_elements'))
|
||||
# else
|
||||
# collection.fetch(@get('editable_elements'))
|
||||
#
|
||||
# @set(editable_elements: collection)
|
||||
|
||||
# @set
|
||||
# editable_elements: new Locomotive.Models.EditableElementsCollection(@get('editable_elements'))
|
||||
|
||||
toJSON: ->
|
||||
_.tap super, (hash) =>
|
||||
hash.editable_elements = @get('editable_elements').toJSONForSave() if @get('editable_elements')
|
||||
|
||||
class Locomotive.Models.PagesCollection extends Backbone.Collection
|
@ -9,6 +9,8 @@ class Locomotive.Views.EditableElements.EditAllView extends Backbone.View
|
||||
_editable_elements_views: []
|
||||
|
||||
render: ->
|
||||
window.bar = @
|
||||
|
||||
if @collection.isEmpty()
|
||||
$(@el).hide()
|
||||
else
|
||||
@ -22,6 +24,16 @@ class Locomotive.Views.EditableElements.EditAllView extends Backbone.View
|
||||
|
||||
return @
|
||||
|
||||
after_render: ->
|
||||
_.each @_editable_elements_views, (view) => view.after_render()
|
||||
|
||||
refresh: ->
|
||||
_.each @_editable_elements_views, (view) =>
|
||||
foo = @collection.get(view.model.get('id'))
|
||||
console.log(foo.cid)
|
||||
view.model = @collection.get(view.model.get('id'))
|
||||
view.refresh()
|
||||
|
||||
render_elements: ->
|
||||
index = 0
|
||||
|
||||
@ -60,4 +72,10 @@ class Locomotive.Views.EditableElements.EditAllView extends Backbone.View
|
||||
_hide_last_separator: ->
|
||||
_.each @$('fieldset'), (fieldset) =>
|
||||
$(fieldset).find('li.last').removeClass('last')
|
||||
$(_.last($(fieldset).find('li.input:visible'))).addClass('last')
|
||||
$(_.last($(fieldset).find('li.input:visible'))).addClass('last')
|
||||
|
||||
remove: ->
|
||||
_.each @_editable_elements_views, (view) => view.remove()
|
||||
@_editable_elements_views.length = 0
|
||||
super
|
||||
|
||||
|
@ -17,8 +17,22 @@ class Locomotive.Views.EditableElements.FileView extends Backbone.View
|
||||
render: ->
|
||||
$(@el).html(ich.editable_file_input(@model.toJSON()))
|
||||
|
||||
# only in HTML 5
|
||||
@$('input[type=file]').bind 'change', (event) =>
|
||||
input = $(event.target)[0]
|
||||
if input.files?
|
||||
@model.set(source: input.files[0])
|
||||
|
||||
return @
|
||||
|
||||
after_render: ->
|
||||
# do nothing
|
||||
|
||||
refresh: ->
|
||||
@$('input[type=file]').unbind 'change'
|
||||
@states = { 'change': false, 'delete': false }
|
||||
@render()
|
||||
|
||||
toggle_change: (event) ->
|
||||
@_toggle event, 'change',
|
||||
on_change: =>
|
||||
@ -31,9 +45,11 @@ class Locomotive.Views.EditableElements.FileView extends Backbone.View
|
||||
on_change: =>
|
||||
@$('a:first').addClass('deleted') & @$('a.change').hide()
|
||||
@$('input[type=hidden].remove-flag').val('1')
|
||||
@model.set('remove_source': true)
|
||||
on_cancel: =>
|
||||
@$('a:first').removeClass('deleted') & @$('a.change').show()
|
||||
@$('input[type=hidden].remove-flag').val('0')
|
||||
@model.set('remove_source': false)
|
||||
|
||||
_toggle: (event, state, options) ->
|
||||
event.stopPropagation() & event.preventDefault()
|
||||
@ -52,20 +68,6 @@ class Locomotive.Views.EditableElements.FileView extends Backbone.View
|
||||
|
||||
@states[state] = !@states[state]
|
||||
|
||||
|
||||
# toggle_change: (event) ->
|
||||
# event.stopPropagation() & event.preventDefault()
|
||||
#
|
||||
# button = $(event.target)
|
||||
# label = button.attr('data-cancel-label')
|
||||
#
|
||||
# unless @changing
|
||||
# @$('a:first').hide() & @$('input[type=file]').show() & @$('a.delete').hide()
|
||||
# else
|
||||
# @$('a:first').show() & @$('input[type=file]').hide() & @$('a.delete').show()
|
||||
#
|
||||
# button.attr('data-alt-label', button.html())
|
||||
#
|
||||
# button.html(label)
|
||||
#
|
||||
# @changing = !@changing
|
||||
remove: ->
|
||||
@$('input[type=file]').unbind 'change'
|
||||
super
|
||||
|
@ -1,14 +1,8 @@
|
||||
#= require ./short_text_view
|
||||
|
||||
Locomotive.Views.EditableElements ||= {}
|
||||
|
||||
class Locomotive.Views.EditableElements.LongTextView extends Backbone.View
|
||||
class Locomotive.Views.EditableElements.LongTextView extends Locomotive.Views.EditableElements.ShortTextView
|
||||
|
||||
tagName: 'li'
|
||||
|
||||
className: 'text input html'
|
||||
|
||||
render: ->
|
||||
$(@el).html(ich.editable_text_input(@model.toJSON()))
|
||||
|
||||
@$('textarea').tinymce window.Locomotive.tinyMCE.defaultSettings
|
||||
|
||||
return @
|
||||
tinymce_settings: ->
|
||||
window.Locomotive.tinyMCE.defaultSettings
|
@ -9,6 +9,28 @@ class Locomotive.Views.EditableElements.ShortTextView extends Backbone.View
|
||||
render: ->
|
||||
$(@el).html(ich.editable_text_input(@model.toJSON()))
|
||||
|
||||
@$('textarea').tinymce window.Locomotive.tinyMCE.minimalSettings
|
||||
return @
|
||||
|
||||
return @
|
||||
after_render: ->
|
||||
settings = _.extend {}, @tinymce_settings(),
|
||||
onchange_callback: (editor) =>
|
||||
console.log('content changed !!!! (' + @model.cid + '), ' + editor.getBody().innerHTML)
|
||||
console.log(@model)
|
||||
@model.set(content: editor.getBody().innerHTML)
|
||||
|
||||
console.log('here ?')
|
||||
|
||||
window.a = @$('textarea')
|
||||
window.b = settings
|
||||
|
||||
@$('textarea').tinymce(settings)
|
||||
|
||||
tinymce_settings: ->
|
||||
window.Locomotive.tinyMCE.minimalSettings
|
||||
|
||||
refresh: ->
|
||||
# do nothing
|
||||
|
||||
remove: ->
|
||||
@$('textarea').tinymce().destroy()
|
||||
super
|
@ -16,16 +16,18 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||
initialize: ->
|
||||
_.bindAll(@, 'insert_image')
|
||||
|
||||
@page = new Locomotive.Models.Page(@options.page)
|
||||
@model = new Locomotive.Models.Page(@options.page)
|
||||
|
||||
window.page = @page
|
||||
window.foo = @model
|
||||
|
||||
@filled_slug = @touched_url = false
|
||||
@image_picker_view = new Locomotive.Views.ThemeAssets.ImagePickerView
|
||||
collection: new Locomotive.Models.ThemeAssetsCollection()
|
||||
on_select: @insert_image
|
||||
|
||||
@editable_elements_view = new Locomotive.Views.EditableElements.EditAllView(collection: @page.get('editable_elements'))
|
||||
Backbone.ModelBinding.bind @
|
||||
|
||||
@editable_elements_view = new Locomotive.Views.EditableElements.EditAllView(collection: @model.get('editable_elements'))
|
||||
|
||||
render: ->
|
||||
super()
|
||||
@ -45,7 +47,6 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||
|
||||
# editable elements
|
||||
@render_editable_elements()
|
||||
# @enable_editable_elements_nav()
|
||||
|
||||
return @
|
||||
|
||||
@ -60,19 +61,41 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||
@image_picker_view.close()
|
||||
|
||||
enable_liquid_editing: ->
|
||||
@editor = CodeMirror.fromTextArea @$('#page_raw_template').get()[0],
|
||||
input = @$('#page_raw_template')
|
||||
@editor = CodeMirror.fromTextArea input.get()[0],
|
||||
mode: 'liquid'
|
||||
autoMatchParens: false
|
||||
lineNumbers: false
|
||||
passDelay: 50
|
||||
tabMode: 'shift'
|
||||
theme: 'default'
|
||||
onChange: (editor) => @model.set(raw_template: editor.getValue())
|
||||
|
||||
after_inputs_fold: ->
|
||||
@editor.refresh()
|
||||
|
||||
show_error: (attribute, message, html) ->
|
||||
switch attribute
|
||||
when 'raw_template'
|
||||
@$("#page_raw_template_input .CodeMirror").after(html)
|
||||
else super
|
||||
|
||||
render_editable_elements: ->
|
||||
@$('.formtastic fieldset.inputs:first').before(@editable_elements_view.render().el)
|
||||
@editable_elements_view.after_render()
|
||||
|
||||
# Remove the editable elements and rebuild them
|
||||
reset_editable_elements: ->
|
||||
console.log('reset_editable_elements')
|
||||
@editable_elements_view.remove()
|
||||
# @editable_elements_view = new Locomotive.Views.EditableElements.EditAllView(collection: @model.get('editable_elements'))
|
||||
@editable_elements_view.collection = @model.get('editable_elements')
|
||||
@render_editable_elements()
|
||||
|
||||
# Just re-connect the model and the views (+ rebuild the files)
|
||||
refresh_editable_elements: ->
|
||||
@editable_elements_view.collection = @model.get('editable_elements')
|
||||
@editable_elements_view.refresh()
|
||||
|
||||
fill_default_slug: (event) ->
|
||||
unless @filled_slug
|
||||
|
@ -3,4 +3,37 @@ Locomotive.Views.Pages ||= {}
|
||||
class Locomotive.Views.Pages.EditView extends Locomotive.Views.Pages.FormView
|
||||
|
||||
save: (event) ->
|
||||
console.log('saving')
|
||||
event.stopPropagation() & event.preventDefault()
|
||||
|
||||
@clear_errors()
|
||||
|
||||
console.log('saving')
|
||||
|
||||
@model.save {},
|
||||
success: (model, response, xhr) =>
|
||||
console.log('success')
|
||||
model._normalize()
|
||||
|
||||
$.growl('success', xhr.getResponseHeader('X-Message'))
|
||||
|
||||
if model.get('template_changed') == true
|
||||
@reset_editable_elements()
|
||||
else
|
||||
@refresh_editable_elements()
|
||||
|
||||
error: (model, xhr) =>
|
||||
console.log('error')
|
||||
# window.model = model
|
||||
window.model = model
|
||||
window.xhr = xhr
|
||||
|
||||
# probably restore the previous attributes
|
||||
|
||||
errors = JSON.parse(xhr.responseText)
|
||||
|
||||
@show_errors errors
|
||||
|
||||
$.growl('error', xhr.getResponseHeader('X-Message'))
|
||||
|
||||
|
||||
|
||||
|
@ -35,8 +35,7 @@ class Locomotive.Views.Pages.ListView extends Backbone.View
|
||||
|
||||
# on_sort: (data) ->
|
||||
on_successful_sort: (data, status, xhr) ->
|
||||
window.foo = xhr
|
||||
$.growl('success', xhr.getResponseHeader('Flash'));
|
||||
$.growl('success', xhr.getResponseHeader('X-Message'))
|
||||
|
||||
on_failed_sort: (data, status, xhr) ->
|
||||
$.growl('error', xhr.getResponseHeader('Flash'));
|
||||
$.growl('error', xhr.getResponseHeader('X-Message'))
|
||||
|
@ -1,3 +1,33 @@
|
||||
Locomotive.Views.Pages ||= {}
|
||||
|
||||
class Locomotive.Views.Pages.NewView extends Locomotive.Views.Pages.FormView
|
||||
|
||||
save: (event) ->
|
||||
event.stopPropagation() & event.preventDefault()
|
||||
|
||||
@clear_errors()
|
||||
|
||||
console.log('saving')
|
||||
|
||||
@model.save {},
|
||||
success: (model, response, xhr) =>
|
||||
console.log('success')
|
||||
model._normalize()
|
||||
|
||||
$.growl('success', xhr.getResponseHeader('X-Message'))
|
||||
|
||||
if model.get('template_changed') == true
|
||||
@reset_editable_elements()
|
||||
else
|
||||
@refresh_editable_elements()
|
||||
|
||||
error: (model, xhr) =>
|
||||
console.log('error')
|
||||
|
||||
window.xhr = xhr
|
||||
|
||||
errors = JSON.parse(xhr.responseText)
|
||||
|
||||
@show_errors errors
|
||||
|
||||
$.growl('error', xhr.getResponseHeader('X-Message'))
|
@ -30,7 +30,7 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
|
||||
newValue = prompt(title.attr('title'), title.html());
|
||||
if newValue && newValue != ''
|
||||
title.html(newValue)
|
||||
target.val(newValue)
|
||||
target.val(newValue).trigger('change')
|
||||
|
||||
make_inputs_foldable: ->
|
||||
self = @
|
||||
@ -49,6 +49,18 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
|
||||
after_inputs_fold: ->
|
||||
# overide this method if necessary
|
||||
|
||||
clear_errors: ->
|
||||
@$('div.inline-errors').remove()
|
||||
|
||||
show_errors: (errors) ->
|
||||
for attribute, message of errors
|
||||
html = $("<div class=\"inline-errors\"><p>#{message[0]}</p></div>")
|
||||
@show_error attribute, message[0], html
|
||||
|
||||
show_error: (attribute, message, html) ->
|
||||
input = @$("##{@model.paramRoot}_#{attribute}")
|
||||
input.after(html) if input.size() > 0
|
||||
|
||||
_enable_checkbox: (name, options) ->
|
||||
@$('li#page_' + name + '_input input[type=checkbox]').checkToggle
|
||||
on_callback: =>
|
||||
|
@ -15,8 +15,10 @@ ul.content-assets {
|
||||
|
||||
margin: 0 10px 10px 0;
|
||||
|
||||
border: 1px solid #ccced7;
|
||||
|
||||
@include border-radius(8px);
|
||||
@include box-shadow(rgba(0, 0, 0, 0.2) 0px 1px 0px 0px);
|
||||
@include box-shadow(rgba(0, 0, 0, 0.4) 0px 1px 0px 0px);
|
||||
background: #ebedf4;
|
||||
|
||||
&.last {
|
||||
|
@ -9,10 +9,11 @@
|
||||
|
||||
.nav {
|
||||
display: block;
|
||||
width: 100%;
|
||||
width: 918px;
|
||||
height: 31px;
|
||||
|
||||
border-bottom: 1px solid #ccced7;
|
||||
border: 1px solid #ccced7;
|
||||
border-bottom: 0px;
|
||||
|
||||
@include border-top-radius(8px);
|
||||
@include background-image(linear-gradient(#ebedf4, #d7dbe7));
|
||||
@ -20,6 +21,7 @@
|
||||
a {
|
||||
float: left;
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
line-height: 31px;
|
||||
padding: 0px 20px 0 20px;
|
||||
@ -35,30 +37,38 @@
|
||||
&.on {
|
||||
@include background-image(linear-gradient(#d9dde9, #ebedf4));
|
||||
|
||||
height: 32px;
|
||||
height: 31px;
|
||||
|
||||
z-index: 999;
|
||||
|
||||
color: #1e1f26;
|
||||
font-weight: bold;
|
||||
|
||||
border-right: 1px solid #f8f9fb;
|
||||
border-left: 1px solid #f8f9fb;
|
||||
border-right: 1px solid #ccced7;
|
||||
border-left: 1px solid #ccced7;
|
||||
|
||||
@include box-shadow(rgba(193, 197, 207, 0.4) -1px 0px 0px 0px inset, rgba(193, 197, 207, 0.4) -1px 0px 0px 0px);
|
||||
@include box-shadow(#EBEDF4 0 1px 0 0, rgba(255, 255, 255, 0.4) 0 1px 0 0 inset, rgba(255, 255, 255, 0.4) -1px 0 0 0 inset, rgba(255, 255, 255, 0.4) 1px 0 0 0 inset);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
&.on {
|
||||
@include border-top-left-radius(8px);
|
||||
border-left: none;
|
||||
@include box-shadow(rgba(193, 197, 207, 0.4) -1px 0px 0px 0px inset);
|
||||
@include box-shadow(#EBEDF4 0 1px 0 0, rgba(255, 255, 255, 0.4) 0 1px 0 0 inset, rgba(255, 255, 255, 0.4) -1px 0 0 0 inset);
|
||||
}
|
||||
}
|
||||
} // a
|
||||
} // .nav
|
||||
|
||||
.wrapper {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
clear: both;
|
||||
|
||||
ol {
|
||||
border-top: none;
|
||||
|
||||
li.file {
|
||||
span.file {
|
||||
|
@ -10,15 +10,18 @@ form.formtastic {
|
||||
margin-bottom: 20px;
|
||||
|
||||
@include border-bottom-radius(8px);
|
||||
@include box-shadow(rgba(0, 0, 0, 0.2) 0px 1px 0px 0px);
|
||||
@include box-shadow(rgba(0, 0, 0, 0.4) 0px 1px 0px 0px);
|
||||
background: #ebedf4;
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
width: 918px;
|
||||
|
||||
padding: 5px 0px;
|
||||
|
||||
border: 1px solid #ccced7;
|
||||
border-bottom: 0px;
|
||||
|
||||
@include border-top-radius(8px);
|
||||
@include background-image(linear-gradient(#ebedf4, #d7dbe7));
|
||||
|
||||
@ -58,7 +61,9 @@ form.formtastic {
|
||||
margin-bottom: 0px;
|
||||
padding: 0px;
|
||||
|
||||
border-top: 1px solid #ccced7;
|
||||
border: 1px solid #ccced7;
|
||||
border-bottom: 0px;
|
||||
@include box-shadow(rgba(255, 255, 255, 0.5) 0 1px 0 0 inset);
|
||||
|
||||
> li.input {
|
||||
margin: 0;
|
||||
|
@ -3,7 +3,7 @@ module Locomotive
|
||||
|
||||
sections 'contents'
|
||||
|
||||
respond_to :json, :only => [:show, :update, :sort, :get_path]
|
||||
respond_to :json, :only => [:show, :create, :update, :sort, :get_path]
|
||||
|
||||
def index
|
||||
@pages = current_site.all_pages_in_once
|
||||
@ -33,17 +33,7 @@ module Locomotive
|
||||
def update
|
||||
@page = current_site.pages.find(params[:id])
|
||||
@page.update_attributes(params[:page])
|
||||
puts @page.errors.inspect
|
||||
respond_with @page, :location => edit_page_url(@page._id)
|
||||
# do |format|
|
||||
# format.json do
|
||||
# render :json => {
|
||||
# :notice => t('flash.locomotive.pages.update.notice'),
|
||||
# :editable_elements => @page.template_changed ?
|
||||
# render_to_string(:partial => 'locomotive/pages/editable_elements.html.haml') : ''
|
||||
# }
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
@ -4,7 +4,7 @@ module Locomotive
|
||||
delegate :title, :slug, :fullpath, :raw_template, :published, :template_changed, :cache_strategy, :to => :source
|
||||
|
||||
def editable_elements
|
||||
self.source.enabled_editable_elements
|
||||
self.source.enabled_editable_elements.collect(&:as_json)
|
||||
end
|
||||
|
||||
def included_methods
|
||||
|
@ -49,42 +49,4 @@
|
||||
%p.inline-hints {{hint}}
|
||||
{{/if}}
|
||||
|
||||
= hidden_field_tag 'page[editable_elements_attributes][{{index}}][id]', '{{id}}', :id => 'page_editable_elements_attributes_{{index}}_id'
|
||||
|
||||
|
||||
/ - grouped_editable_elements = @page.editable_elements_grouped_by_blocks
|
||||
/
|
||||
/ = semantic_fields_for(@page) do |f|
|
||||
/ - unless grouped_editable_elements.empty?
|
||||
/ #editable-elements
|
||||
/ .nav
|
||||
/ - grouped_editable_elements.keys.each_with_index do |name, index|
|
||||
/ = link_to (name.try(:humanize) || t('locomotive.pages.form.default_block')).gsub('\'', ''), "#block-#{index}", :id => "block-nav-#{index}", :class => "#{'on' if index == 0}"
|
||||
/ .clear
|
||||
/
|
||||
/ .wrapper
|
||||
/ %ul{ :id => "blocks" }
|
||||
/ - grouped_editable_elements.keys.each_with_index do |name, index|
|
||||
/ - elements = grouped_editable_elements[name]
|
||||
/ %li{ :id => "block-#{index}", :class => 'block', :style => "display: #{index == 0 ? 'block' : 'none' }" }
|
||||
/ %fieldset.inputs
|
||||
/ %ol
|
||||
/ - elements.each do |el|
|
||||
/ = f.fields_for 'editable_elements', el, :child_index => el._index do |g|
|
||||
/ - case el
|
||||
/ - when ::Locomotive::EditableLongText
|
||||
/ = g.input :content, :label => el.slug.humanize, :hint => el.hint, :as => :text, :input_html => { :class => 'html' }
|
||||
/ - when ::Locomotive::EditableShortText
|
||||
/ = g.input :content, :label => el.slug.humanize, :hint => el.hint
|
||||
/ - when ::Locomotive::EditableFile
|
||||
/ = g.input :source, :label => el.slug.humanize, :hint => el.hint, :css => 'file'
|
||||
/ / do
|
||||
/ / = g.file_field :source
|
||||
/ / - if el.source?
|
||||
/ / %p.remove
|
||||
/ / %strong
|
||||
/ / = link_to File.basename(el.source.url), el.source.url
|
||||
/ / %span
|
||||
/ / /
|
||||
/ / != t('locomotive.pages.form.delete_file')
|
||||
/ / = g.check_box :remove_source
|
||||
= hidden_field_tag 'page[editable_elements_attributes][{{index}}][id]', '{{id}}', :id => 'page_editable_elements_attributes_{{index}}_id'
|
@ -279,7 +279,6 @@ es:
|
||||
site: Información del Sitio
|
||||
content_types: Modelos
|
||||
assets: Contenido multi-media
|
||||
asset_collections: Colecciones
|
||||
snippets: Fragmentos
|
||||
pages: Páginas
|
||||
messages:
|
||||
|
@ -262,7 +262,6 @@ nl:
|
||||
site: Website informatie
|
||||
content_types: aangepaste content typen
|
||||
assets: Thema bestanden
|
||||
asset_collections: Bronbestand verzamelingen
|
||||
snippets: Fragmenten
|
||||
pages: Pagina's'
|
||||
messages:
|
||||
|
@ -71,9 +71,6 @@ es:
|
||||
highlighted_field_name: Campo destacado
|
||||
group_by_field_name: Champ para agrupar
|
||||
api_enabled: API activada
|
||||
asset_collection:
|
||||
name: Nombre
|
||||
slug: Enlace
|
||||
asset:
|
||||
name: Nombre
|
||||
source: Fichero
|
||||
|
@ -73,16 +73,6 @@ es:
|
||||
alert: "La afiliaciónMember no se pudo crear."
|
||||
already_created: "La cuenta ya estaba añadida al sitio web actual."
|
||||
|
||||
asset_collections:
|
||||
create:
|
||||
notice: "Colección creada con éxito."
|
||||
alert: "La colección no se pudo crear."
|
||||
update:
|
||||
notice: "Colección actualizada con éxito."
|
||||
alert: "La colección no se pudo actualizar."
|
||||
destroy:
|
||||
notice: "Colección eliminada con éxito."
|
||||
|
||||
assets:
|
||||
create:
|
||||
notice: "Contenido multi-media creado con éxito."
|
||||
|
@ -73,16 +73,6 @@ nl:
|
||||
alert: "Lidmaatschap is niet gemaakt."
|
||||
already_created: "Lidmaatschap is al gemaakt voor de website."
|
||||
|
||||
asset_collection:
|
||||
create:
|
||||
notice: "Verzameling is gemaakt."
|
||||
alert: "Verzameling is niet gemaakt."
|
||||
update:
|
||||
notice: "Verzameling is gewijzigd."
|
||||
alert: "Verzameling is niet gewijzigd."
|
||||
destroy:
|
||||
notice: "Verzameling is verwijderd."
|
||||
|
||||
assets:
|
||||
create:
|
||||
notice: "Bronbestand is gemaakt."
|
||||
|
5
doc/TODO
5
doc/TODO
@ -11,14 +11,17 @@ x editable_short_text => tinymce
|
||||
- editable_file =>
|
||||
x backbone / handlebar
|
||||
- new formtastic inputs
|
||||
- menu / submenu in full css3 (no images)
|
||||
x menu / submenu in full css3 (no images)
|
||||
- create/edit page in ajax
|
||||
x edit
|
||||
- create
|
||||
- fix other sections
|
||||
- content types
|
||||
- edit my account
|
||||
- create a new site
|
||||
- edit my site
|
||||
- theme assets
|
||||
- fix css in firefox
|
||||
|
||||
|
||||
BACKLOG:
|
||||
|
@ -1,18 +0,0 @@
|
||||
require 'locomotive/liquid/drops/contents'
|
||||
|
||||
module Locomotive
|
||||
module Liquid
|
||||
module Drops
|
||||
|
||||
class AssetCollections < Contents
|
||||
|
||||
def before_method(meth)
|
||||
Rails.logger.warn "\n[WARNING] asset_collections is deprecated and will be removed in the next commits. Please, use contents.<slug> instead.\n\n"
|
||||
super(meth)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
@ -61,7 +61,6 @@ module Locomotive
|
||||
assigns = {
|
||||
'site' => current_site,
|
||||
'page' => @page,
|
||||
'asset_collections' => Locomotive::Liquid::Drops::AssetCollections.new, # deprecated, will be removed shortly
|
||||
'contents' => Locomotive::Liquid::Drops::Contents.new,
|
||||
'current_page' => self.params[:page],
|
||||
'params' => self.params,
|
||||
|
@ -12,7 +12,8 @@ module Locomotive
|
||||
if get?
|
||||
display resource
|
||||
elsif has_errors?
|
||||
with_flash_message(:error) do |message|
|
||||
Rails.logger.debug "--> ERRORS #{resource.errors.inspect}" # FIXME: debug purpose
|
||||
with_flash_message(:alert) do |message|
|
||||
display resource.errors, :status => :unprocessable_entity
|
||||
end
|
||||
elsif post?
|
||||
@ -38,7 +39,8 @@ module Locomotive
|
||||
set_flash_message!
|
||||
message = controller.flash[type]
|
||||
|
||||
controller.headers[:flash] = message
|
||||
controller.headers['X-Message'] = message
|
||||
controller.headers['X-Message-Type'] = type
|
||||
|
||||
yield(message) if block_given?
|
||||
|
||||
|
529
vendor/assets/javascripts/backbone.modelbinding.js
vendored
Normal file
529
vendor/assets/javascripts/backbone.modelbinding.js
vendored
Normal file
@ -0,0 +1,529 @@
|
||||
// Backbone.ModelBinding v0.4.1
|
||||
//
|
||||
// Copyright (C)2011 Derick Bailey, Muted Solutions, LLC
|
||||
// Distributed Under MIT Liscene
|
||||
//
|
||||
// WARNING: Modified by Didier Lafforgue for LocomotiveCMS
|
||||
//
|
||||
// Documentation and Full Licence Availabe at:
|
||||
// http://github.com/derickbailey/backbone.modelbinding
|
||||
|
||||
// ----------------------------
|
||||
// Backbone.ModelBinding
|
||||
// ----------------------------
|
||||
|
||||
Backbone.ModelBinding = (function(Backbone, _, $){
|
||||
modelBinding = {
|
||||
version: "0.4.1",
|
||||
|
||||
bind: function(view, options){
|
||||
view.modelBinder = new ModelBinder(view, options);
|
||||
view.modelBinder.bind();
|
||||
},
|
||||
|
||||
unbind: function(view){
|
||||
if (view.modelBinder){
|
||||
view.modelBinder.unbind()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ModelBinder = function(view, options){
|
||||
this.config = new modelBinding.Configuration(options);
|
||||
this.modelBindings = [];
|
||||
this.elementBindings = [];
|
||||
|
||||
this.bind = function(){
|
||||
var conventions = modelBinding.Conventions;
|
||||
for (var conventionName in conventions){
|
||||
if (conventions.hasOwnProperty(conventionName)){
|
||||
var conventionElement = conventions[conventionName];
|
||||
var handler = conventionElement.handler;
|
||||
var conventionSelector = conventionElement.selector;
|
||||
handler.bind.call(this, conventionSelector, view, view.model, this.config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.unbind = function(){
|
||||
// unbind the html element bindings
|
||||
_.each(this.elementBindings, function(binding){
|
||||
binding.element.unbind(binding.eventName, binding.callback);
|
||||
});
|
||||
|
||||
// unbind the model bindings
|
||||
_.each(this.modelBindings, function(binding){
|
||||
binding.model.unbind(binding.eventName, binding.callback);
|
||||
});
|
||||
}
|
||||
|
||||
this.registerModelBinding = function(model, attribute_name, callback){
|
||||
// bind the model changes to the form elements
|
||||
var eventName = "change:" + attribute_name;
|
||||
model.bind(eventName, callback);
|
||||
this.modelBindings.push({model: model, eventName: eventName, callback: callback});
|
||||
}
|
||||
|
||||
this.registerElementBinding = function(element, callback){
|
||||
// bind the form changes to the model
|
||||
element.bind("change", callback);
|
||||
this.elementBindings.push({element: element, eventName: "change", callback: callback});
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// Model Binding Configuration
|
||||
// ----------------------------
|
||||
modelBinding.Configuration = function(options){
|
||||
this.bindingAttrConfig = {};
|
||||
|
||||
_.extend(this.bindingAttrConfig,
|
||||
modelBinding.Configuration.bindindAttrConfig,
|
||||
options
|
||||
);
|
||||
|
||||
if (this.bindingAttrConfig.all){
|
||||
var attr = this.bindingAttrConfig.all;
|
||||
delete this.bindingAttrConfig.all;
|
||||
for (var inputType in this.bindingAttrConfig){
|
||||
if (this.bindingAttrConfig.hasOwnProperty(inputType)){
|
||||
this.bindingAttrConfig[inputType] = attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.getBindingAttr = function(type){
|
||||
return this.bindingAttrConfig[type];
|
||||
};
|
||||
|
||||
this.getBindingValue = function(element, type){
|
||||
var bindingAttr = this.getBindingAttr(type);
|
||||
return element.attr(bindingAttr);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
modelBinding.Configuration.bindindAttrConfig = {
|
||||
text: "id",
|
||||
textarea: "id",
|
||||
password: "id",
|
||||
radio: "name",
|
||||
checkbox: "id",
|
||||
select: "id",
|
||||
number: "id",
|
||||
range: "id",
|
||||
tel: "id",
|
||||
search: "id",
|
||||
url: "id",
|
||||
email: "id"
|
||||
|
||||
};
|
||||
|
||||
modelBinding.Configuration.store = function(){
|
||||
modelBinding.Configuration.originalConfig = _.clone(modelBinding.Configuration.bindindAttrConfig);
|
||||
};
|
||||
|
||||
modelBinding.Configuration.restore = function(){
|
||||
modelBinding.Configuration.bindindAttrConfig = modelBinding.Configuration.originalConfig;
|
||||
};
|
||||
|
||||
modelBinding.Configuration.configureBindingAttributes = function(options){
|
||||
if (options.all){
|
||||
this.configureAllBindingAttributes(options.all);
|
||||
delete options.all;
|
||||
}
|
||||
_.extend(modelBinding.Configuration.bindindAttrConfig, options);
|
||||
};
|
||||
|
||||
modelBinding.Configuration.configureAllBindingAttributes = function(attribute){
|
||||
var config = modelBinding.Configuration.bindindAttrConfig;
|
||||
config.text = attribute;
|
||||
config.textarea = attribute;
|
||||
config.password = attribute;
|
||||
config.radio = attribute;
|
||||
config.checkbox = attribute;
|
||||
config.select = attribute;
|
||||
config.number = attribute;
|
||||
config.range = attribute;
|
||||
config.tel = attribute;
|
||||
config.search = attribute;
|
||||
config.url = attribute;
|
||||
config.email = attribute;
|
||||
};
|
||||
|
||||
// ----------------------------
|
||||
// Text, Textarea, and Password Bi-Directional Binding Methods
|
||||
// ----------------------------
|
||||
StandardBinding = (function(Backbone){
|
||||
var methods = {};
|
||||
|
||||
var _getElementType = function(element) {
|
||||
var type = element[0].tagName.toLowerCase();
|
||||
if (type == "input"){
|
||||
type = element.attr("type");
|
||||
if (type == undefined || type == ''){
|
||||
type = 'text';
|
||||
}
|
||||
}
|
||||
return type;
|
||||
};
|
||||
|
||||
methods.bind = function(selector, view, model, config){
|
||||
var modelBinder = this;
|
||||
|
||||
view.$(selector).each(function(index){
|
||||
var element = view.$(this);
|
||||
var elementType = _getElementType(element);
|
||||
var attribute_name = config.getBindingValue(element, elementType);
|
||||
|
||||
// HACK (Did)
|
||||
if (model.paramRoot) {
|
||||
regexp = new RegExp('^' + model.paramRoot + '_')
|
||||
attribute_name = attribute_name.replace(regexp, '')
|
||||
}
|
||||
// console.log(attribute_name);
|
||||
|
||||
var modelChange = function(changed_model, val){ element.val(val); };
|
||||
|
||||
var setModelValue = function(attr_name, value){
|
||||
var data = {};
|
||||
data[attr_name] = value;
|
||||
model.set(data);
|
||||
};
|
||||
|
||||
var elementChange = function(ev){
|
||||
setModelValue(attribute_name, view.$(ev.target).val());
|
||||
};
|
||||
|
||||
modelBinder.registerModelBinding(model, attribute_name, modelChange);
|
||||
modelBinder.registerElementBinding(element, elementChange);
|
||||
|
||||
// set the default value on the form, from the model
|
||||
var attr_value = model.get(attribute_name);
|
||||
if (typeof attr_value !== "undefined" && attr_value !== null) {
|
||||
element.val(attr_value);
|
||||
} else {
|
||||
var elVal = element.val();
|
||||
if (elVal){
|
||||
setModelValue(attribute_name, elVal);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return methods;
|
||||
})(Backbone);
|
||||
|
||||
// ----------------------------
|
||||
// Select Box Bi-Directional Binding Methods
|
||||
// ----------------------------
|
||||
SelectBoxBinding = (function(Backbone){
|
||||
var methods = {};
|
||||
|
||||
methods.bind = function(selector, view, model, config){
|
||||
var modelBinder = this;
|
||||
|
||||
view.$(selector).each(function(index){
|
||||
var element = view.$(this);
|
||||
var attribute_name = config.getBindingValue(element, 'select');
|
||||
|
||||
// HACK (Did)
|
||||
if (model.paramRoot) {
|
||||
regexp = new RegExp('^' + model.paramRoot + '_')
|
||||
attribute_name = attribute_name.replace(regexp, '')
|
||||
}
|
||||
// console.log(attribute_name);
|
||||
|
||||
var modelChange = function(changed_model, val){ element.val(val); };
|
||||
|
||||
var setModelValue = function(attr, val, text){
|
||||
var data = {};
|
||||
data[attr] = val;
|
||||
data[attr + "_text"] = text;
|
||||
model.set(data);
|
||||
};
|
||||
|
||||
var elementChange = function(ev){
|
||||
var targetEl = view.$(ev.target);
|
||||
var value = targetEl.val();
|
||||
var text = targetEl.find(":selected").text();
|
||||
setModelValue(attribute_name, value, text);
|
||||
};
|
||||
|
||||
modelBinder.registerModelBinding(model, attribute_name, modelChange);
|
||||
modelBinder.registerElementBinding(element, elementChange);
|
||||
|
||||
// set the default value on the form, from the model
|
||||
var attr_value = model.get(attribute_name);
|
||||
if (typeof attr_value !== "undefined" && attr_value !== null) {
|
||||
element.val(attr_value);
|
||||
}
|
||||
|
||||
// set the model to the form's value if there is no model value
|
||||
if (element.val() != attr_value) {
|
||||
var value = element.val();
|
||||
var text = element.find(":selected").text();
|
||||
setModelValue(attribute_name, value, text);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return methods;
|
||||
})(Backbone);
|
||||
|
||||
// ----------------------------
|
||||
// Radio Button Group Bi-Directional Binding Methods
|
||||
// ----------------------------
|
||||
RadioGroupBinding = (function(Backbone){
|
||||
var methods = {};
|
||||
|
||||
methods.bind = function(selector, view, model, config){
|
||||
var modelBinder = this;
|
||||
|
||||
var foundElements = [];
|
||||
view.$(selector).each(function(index){
|
||||
var element = view.$(this);
|
||||
|
||||
var group_name = config.getBindingValue(element, 'radio');
|
||||
if (!foundElements[group_name]) {
|
||||
foundElements[group_name] = true;
|
||||
var bindingAttr = config.getBindingAttr('radio');
|
||||
|
||||
var modelChange = function(model, val){
|
||||
var value_selector = "input[type=radio][" + bindingAttr + "=" + group_name + "][value=" + val + "]";
|
||||
view.$(value_selector).attr("checked", "checked");
|
||||
};
|
||||
modelBinder.registerModelBinding(model, group_name, modelChange);
|
||||
|
||||
var setModelValue = function(attr, val){
|
||||
var data = {};
|
||||
data[attr] = val;
|
||||
model.set(data);
|
||||
};
|
||||
|
||||
// bind the form changes to the model
|
||||
var elementChange = function(ev){
|
||||
var element = view.$(ev.currentTarget);
|
||||
if (element.is(":checked")){
|
||||
setModelValue(group_name, element.val());
|
||||
}
|
||||
};
|
||||
|
||||
var group_selector = "input[type=radio][" + bindingAttr + "=" + group_name + "]";
|
||||
view.$(group_selector).each(function(){
|
||||
var groupEl = $(this);
|
||||
modelBinder.registerElementBinding(groupEl, elementChange);
|
||||
});
|
||||
|
||||
var attr_value = model.get(group_name);
|
||||
if (typeof attr_value !== "undefined" && attr_value !== null) {
|
||||
// set the default value on the form, from the model
|
||||
var value_selector = "input[type=radio][" + bindingAttr + "=" + group_name + "][value=" + attr_value + "]";
|
||||
view.$(value_selector).attr("checked", "checked");
|
||||
} else {
|
||||
// set the model to the currently selected radio button
|
||||
var value_selector = "input[type=radio][" + bindingAttr + "=" + group_name + "]:checked";
|
||||
var value = view.$(value_selector).val();
|
||||
setModelValue(group_name, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return methods;
|
||||
})(Backbone);
|
||||
|
||||
// ----------------------------
|
||||
// Checkbox Bi-Directional Binding Methods
|
||||
// ----------------------------
|
||||
CheckboxBinding = (function(Backbone){
|
||||
var methods = {};
|
||||
|
||||
methods.bind = function(selector, view, model, config){
|
||||
var modelBinder = this;
|
||||
|
||||
view.$(selector).each(function(index){
|
||||
var element = view.$(this);
|
||||
var bindingAttr = config.getBindingAttr('checkbox');
|
||||
var attribute_name = config.getBindingValue(element, 'checkbox');
|
||||
|
||||
// HACK (Did)
|
||||
if (model.paramRoot) {
|
||||
regexp = new RegExp('^' + model.paramRoot + '_')
|
||||
attribute_name = attribute_name.replace(regexp, '')
|
||||
}
|
||||
// console.log(attribute_name);
|
||||
|
||||
var modelChange = function(model, val){
|
||||
if (val){
|
||||
element.attr("checked", "checked");
|
||||
}
|
||||
else{
|
||||
element.removeAttr("checked");
|
||||
}
|
||||
};
|
||||
|
||||
var setModelValue = function(attr_name, value){
|
||||
var data = {};
|
||||
data[attr_name] = value;
|
||||
model.set(data);
|
||||
};
|
||||
|
||||
var elementChange = function(ev){
|
||||
// console.log('[SELECT] elementChange');
|
||||
var changedElement = view.$(ev.target);
|
||||
var checked = changedElement.is(":checked")? true : false;
|
||||
setModelValue(attribute_name, checked);
|
||||
};
|
||||
|
||||
modelBinder.registerModelBinding(model, attribute_name, modelChange);
|
||||
modelBinder.registerElementBinding(element, elementChange);
|
||||
|
||||
var attr_exists = model.attributes.hasOwnProperty(attribute_name);
|
||||
if (attr_exists) {
|
||||
// set the default value on the form, from the model
|
||||
var attr_value = model.get(attribute_name);
|
||||
if (typeof attr_value !== "undefined" && attr_value !== null && attr_value != false) {
|
||||
element.attr("checked", "checked");
|
||||
}
|
||||
else{
|
||||
element.removeAttr("checked");
|
||||
}
|
||||
} else {
|
||||
// bind the form's value to the model
|
||||
var checked = element.is(":checked")? true : false;
|
||||
setModelValue(attribute_name, checked);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return methods;
|
||||
})(Backbone);
|
||||
|
||||
// ----------------------------
|
||||
// Data-Bind Binding Methods
|
||||
// ----------------------------
|
||||
DataBindBinding = (function(Backbone, _, $){
|
||||
var dataBindSubstConfig = {
|
||||
"default": ""
|
||||
};
|
||||
|
||||
modelBinding.Configuration.dataBindSubst = function(config){
|
||||
this.storeDataBindSubstConfig();
|
||||
_.extend(dataBindSubstConfig, config);
|
||||
};
|
||||
|
||||
modelBinding.Configuration.storeDataBindSubstConfig = function(){
|
||||
modelBinding.Configuration._dataBindSubstConfig = _.clone(dataBindSubstConfig);
|
||||
};
|
||||
|
||||
modelBinding.Configuration.restoreDataBindSubstConfig = function(){
|
||||
if (modelBinding.Configuration._dataBindSubstConfig){
|
||||
dataBindSubstConfig = modelBinding.Configuration._dataBindSubstConfig;
|
||||
delete modelBinding.Configuration._dataBindSubstConfig;
|
||||
}
|
||||
};
|
||||
|
||||
modelBinding.Configuration.getDataBindSubst = function(elementType, value){
|
||||
var returnValue = value;
|
||||
if (value === undefined){
|
||||
if (dataBindSubstConfig.hasOwnProperty(elementType)){
|
||||
returnValue = dataBindSubstConfig[elementType];
|
||||
} else {
|
||||
returnValue = dataBindSubstConfig["default"];
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
setOnElement = function(element, attr, val){
|
||||
var valBefore = val;
|
||||
val = modelBinding.Configuration.getDataBindSubst(attr, val);
|
||||
switch(attr){
|
||||
case "html":
|
||||
element.html(val);
|
||||
break;
|
||||
case "text":
|
||||
element.text(val);
|
||||
break;
|
||||
case "enabled":
|
||||
element.attr("disabled", !val);
|
||||
break;
|
||||
case "displayed":
|
||||
element[val? "show" : "hide"]();
|
||||
break;
|
||||
case "hidden":
|
||||
element[val? "hide" : "show"]();
|
||||
break;
|
||||
default:
|
||||
element.attr(attr, val);
|
||||
}
|
||||
};
|
||||
|
||||
splitBindingAttr = function(element)
|
||||
{
|
||||
var dataBindConfigList = [];
|
||||
var databindList = element.attr("data-bind").split(";");
|
||||
_.each(databindList, function(attrbind){
|
||||
var databind = $.trim(attrbind).split(" ");
|
||||
|
||||
// make the default special case "text" if none specified
|
||||
if( databind.length == 1 ) databind.unshift("text");
|
||||
|
||||
dataBindConfigList.push({
|
||||
elementAttr: databind[0],
|
||||
modelAttr: databind[1]
|
||||
});
|
||||
});
|
||||
return dataBindConfigList;
|
||||
};
|
||||
|
||||
var methods = {};
|
||||
|
||||
methods.bind = function(selector, view, model, config){
|
||||
var modelBinder = this;
|
||||
|
||||
view.$(selector).each(function(index){
|
||||
var element = view.$(this);
|
||||
var databindList = splitBindingAttr(element);
|
||||
|
||||
_.each(databindList, function(databind){
|
||||
var modelChange = function(model, val){
|
||||
setOnElement(element, databind.elementAttr, val);
|
||||
};
|
||||
|
||||
modelBinder.registerModelBinding(model, databind.modelAttr, modelChange);
|
||||
|
||||
// set default on data-bind element
|
||||
setOnElement(element, databind.elementAttr, model.get(databind.modelAttr));
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
return methods;
|
||||
})(Backbone, _, $);
|
||||
|
||||
|
||||
// ----------------------------
|
||||
// Binding Conventions
|
||||
// ----------------------------
|
||||
modelBinding.Conventions = {
|
||||
text: {selector: "input:text", handler: StandardBinding},
|
||||
textarea: {selector: "textarea", handler: StandardBinding},
|
||||
password: {selector: "input:password", handler: StandardBinding},
|
||||
radio: {selector: "input:radio", handler: RadioGroupBinding},
|
||||
checkbox: {selector: "input:checkbox", handler: CheckboxBinding},
|
||||
select: {selector: "select", handler: SelectBoxBinding},
|
||||
databind: { selector: "*[data-bind]", handler: DataBindBinding},
|
||||
// HTML5 input
|
||||
number: {selector: "input[type=number]", handler: StandardBinding},
|
||||
range: {selector: "input[type=range]", handler: StandardBinding},
|
||||
tel: {selector: "input[type=tel]", handler: StandardBinding},
|
||||
search: {selector: "input[type=search]", handler: StandardBinding},
|
||||
url: {selector: "input[type=url]", handler: StandardBinding},
|
||||
email: {selector: "input[type=email]", handler: StandardBinding}
|
||||
};
|
||||
|
||||
return modelBinding;
|
||||
})(Backbone, _, jQuery);
|
93
vendor/assets/javascripts/backbone.sync.js
vendored
Normal file
93
vendor/assets/javascripts/backbone.sync.js
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
(function() {
|
||||
var methodMap = {
|
||||
'create': 'POST',
|
||||
'update': 'PUT',
|
||||
'delete': 'DELETE',
|
||||
'read' : 'GET'
|
||||
};
|
||||
|
||||
var getUrl = function(object) {
|
||||
if (!(object && object.url)) return null;
|
||||
return _.isFunction(object.url) ? object.url() : object.url;
|
||||
};
|
||||
|
||||
var urlError = function() {
|
||||
throw new Error("A 'url' property or function must be specified");
|
||||
};
|
||||
|
||||
Backbone.sync = function(method, model, options) {
|
||||
var type = methodMap[method];
|
||||
|
||||
// Default JSON-request options.
|
||||
var params = _.extend({
|
||||
type: type,
|
||||
dataType: 'json',
|
||||
beforeSend: function( xhr ) {
|
||||
var token = $('meta[name="csrf-token"]').attr('content');
|
||||
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
|
||||
}
|
||||
}, options);
|
||||
|
||||
if (!params.url) {
|
||||
params.url = getUrl(model) || urlError();
|
||||
}
|
||||
|
||||
// Ensure that we have the appropriate request data.
|
||||
if (!params.data && model && (method == 'create' || method == 'update')) {
|
||||
params.contentType = 'application/json';
|
||||
|
||||
var data = {}
|
||||
|
||||
if(model.paramRoot) {
|
||||
data[model.paramRoot] = model.toJSON();
|
||||
} else {
|
||||
data = model.toJSON();
|
||||
}
|
||||
|
||||
if (typeof(FormData) != 'undefined') { // XHR2
|
||||
var formData = new FormData();
|
||||
|
||||
var _buildParams = function(prefix, obj, fn) { // code grabbed from jquery
|
||||
if (jQuery.isArray(obj)) {
|
||||
jQuery.each(obj, function(i, v) {
|
||||
if (/\[\]$/.test(prefix)) { // rbracket
|
||||
fn(prefix, v);
|
||||
} else {
|
||||
_buildParams(prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, fn);
|
||||
}
|
||||
});
|
||||
} else if (obj != null && typeof obj === "object" && !(obj instanceof File)) {
|
||||
for (var name in obj) {
|
||||
_buildParams(prefix + "[" + name + "]", obj[name], fn);
|
||||
}
|
||||
} else {
|
||||
fn(prefix, obj);
|
||||
}
|
||||
}
|
||||
|
||||
for (var prefix in data) {
|
||||
_buildParams(prefix, data[prefix], function(key, value) {
|
||||
// console.log('append ' + key + ', ' + value);
|
||||
if (value != null)
|
||||
formData.append(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
params.data = formData;
|
||||
params.processData = false;
|
||||
params.contentType = false;
|
||||
} else {
|
||||
params.data = JSON.stringify(data);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't process data on a non-GET request.
|
||||
if (params.type !== 'GET') {
|
||||
params.processData = false;
|
||||
}
|
||||
|
||||
// Make the request.
|
||||
return $.ajax(params);
|
||||
}
|
||||
|
||||
}).call(this);
|
4
vendor/assets/javascripts/toggle.js
vendored
4
vendor/assets/javascripts/toggle.js
vendored
@ -64,7 +64,7 @@
|
||||
$(element).parent().prev().css("color","#cccccc");
|
||||
$(element).parent().next().css("color","#333333");
|
||||
$(element).parent().css("background-color", settings.off_bg_color).removeClass('on');
|
||||
$(element).parent().parent().prev().removeAttr("checked");
|
||||
$(element).parent().parent().prev().removeAttr("checked").trigger('change');
|
||||
$(element).removeClass("left").addClass("right");
|
||||
|
||||
if (typeof $.fn.publish != 'undefined')
|
||||
@ -82,7 +82,7 @@
|
||||
$(element).parent().prev().css("color","#333333");
|
||||
$(element).parent().next().css("color","#cccccc");
|
||||
$(element).parent().css("background-color", settings.on_bg_color).addClass('on');
|
||||
$(element).parent().parent().prev().attr("checked","checked");
|
||||
$(element).parent().parent().prev().attr("checked", "checked").trigger('change');
|
||||
$(element).removeClass("right").addClass("left");
|
||||
|
||||
if (typeof $.fn.publish != 'undefined')
|
||||
|
Loading…
Reference in New Issue
Block a user