From 9e9fe49ccf90ceafd880c75ccccbb15d4a74914c Mon Sep 17 00:00:00 2001 From: did Date: Thu, 2 Feb 2012 16:53:26 +0100 Subject: [PATCH] the has_many ui component is done --- .../images/locomotive/list/icons/pencil.png | Bin 0 -> 352 bytes .../locomotive/list/icons/pencil_off.png | Bin 0 -> 350 bytes .../images/locomotive/list/icons/popup.png | Bin 0 -> 347 bytes .../locomotive/list/icons/popup_off.png | Bin 0 -> 351 bytes .../utils/tinymce_settings.js.coffee | 19 +++- .../{_form.js.coffee => _form_view.js.coffee} | 20 ++++- .../_popup_form_view.js.coffee | 77 ++++++++++++++++ .../{edit.js.coffee => edit_view.js.coffee} | 0 .../{index.js.coffee => index_view.js.coffee} | 0 .../{new.js.coffee => new_view.js.coffee} | 0 .../views/shared/fields/file_view.js.coffee | 9 +- .../shared/fields/has_many_view.js.coffee | 65 ++++++++++++-- .../views/shared/form_view.js.coffee | 3 +- .../backoffice/dialog_changes.css.scss | 20 ++++- .../backoffice/formtastic_changes.css.scss | 9 +- app/helpers/locomotive/base_helper.rb | 2 +- .../locomotive/content_entries_helper.rb | 6 +- app/models/locomotive/content_type.rb | 20 +++++ .../locomotive/content_entry_presenter.rb | 1 - .../content_entries/_form.html.haml | 2 +- .../locomotive/content_types/_form.html.haml | 6 +- .../locomotive/current_site/_form.html.haml | 3 +- .../locomotive/custom_fields/_form.html.haml | 2 +- .../custom_fields/types/_boolean.html.haml | 2 +- .../custom_fields/types/_has_many.html.haml | 72 +++++++-------- .../custom_fields/types/_has_one.html.haml | 14 --- .../custom_fields/types/_string.html.haml | 2 +- .../locomotive/layouts/application.html.haml | 4 +- .../locomotive/my_account/edit.html.haml | 2 +- app/views/locomotive/pages/_form.html.haml | 2 +- app/views/locomotive/shared/_head.html.haml | 2 +- app/views/locomotive/snippets/_form.html.haml | 2 +- .../locomotive/theme_assets/_form.html.haml | 2 +- .../locomotive/theme_assets/index.html.haml | 12 ++- config/locales/admin_ui.en.yml | 4 +- doc/TODO | 2 +- lib/locomotive/custom_fields.rb | 4 + .../locomotive/backbone.modelbinding.js | 5 +- .../assets/javascripts/locomotive/toggle.js | 83 +++++++++++------- 39 files changed, 343 insertions(+), 135 deletions(-) create mode 100644 app/assets/images/locomotive/list/icons/pencil.png create mode 100644 app/assets/images/locomotive/list/icons/pencil_off.png create mode 100644 app/assets/images/locomotive/list/icons/popup.png create mode 100644 app/assets/images/locomotive/list/icons/popup_off.png rename app/assets/javascripts/locomotive/views/content_entries/{_form.js.coffee => _form_view.js.coffee} (65%) create mode 100644 app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee rename app/assets/javascripts/locomotive/views/content_entries/{edit.js.coffee => edit_view.js.coffee} (100%) rename app/assets/javascripts/locomotive/views/content_entries/{index.js.coffee => index_view.js.coffee} (100%) rename app/assets/javascripts/locomotive/views/content_entries/{new.js.coffee => new_view.js.coffee} (100%) delete mode 100644 app/views/locomotive/custom_fields/types/_has_one.html.haml diff --git a/app/assets/images/locomotive/list/icons/pencil.png b/app/assets/images/locomotive/list/icons/pencil.png new file mode 100644 index 0000000000000000000000000000000000000000..915192633ba561095ba1f743ac9104e92ffce9f0 GIT binary patch literal 352 zcmV-m0iXVfP)gWc5 zoVp!|br}c)U8q_iWCL1&SP_>FF5^AuLW)p542-})1ex?4>VLeNznyhKmI8%?B*+C$ z#AwFC2kCKQ!sT=<&PI0u*eguX=phKOXa+|u$bd)KY)00ALo*0Gf(7C$SlnYX00#iM zT#N~tOlJ`j2511J=N%(7FNi`@m>dIf0OV~$kO8oS^cslWfcP>InlD4uzC+IoH-Xp$ yh+A>Q%wMRS2~;fuEG6R0&Z0;z#G0J}0t^7BjYcUUqo&jV0000 zDFjat(2IBpNyI`-5WImGu@G_syHvJmg@COP@J*P&GH%=qe8uk0dpr9xUY_U55_7Ny zK93u42XC1;72_E=fE}2KwHBPg5q$bdZ6rkC0WynN@m$6^ku;!EZy;9gh&k6c4Nf2& zQlx1rr$W|r2IRDLi7h6i@yQ_J%X985#-vH~Q0bN(RZ$c_N74K|&ajBPrzL~hwzDZ1 z5L47-P|7MylRsk8l$yWkb<7=zAWh?OF9iI<7HVA3v6p1ff20@KfNF%e;@n2|!V|1O wKJYRvudO)O+Ktp@dvM`)4vY$|?feyB0K3~mzG3gy?*IS*07*qoM6N<$g2+vhiU0rr literal 0 HcmV?d00001 diff --git a/app/assets/images/locomotive/list/icons/popup.png b/app/assets/images/locomotive/list/icons/popup.png new file mode 100644 index 0000000000000000000000000000000000000000..8280b78029613b6cc2bad7e4cb37b702f25e4815 GIT binary patch literal 347 zcmV-h0i^zkP)gX;2 zIdwai@g7A69N^no7Z_6)q!x%xKwg6x&;rDYXbRx~XfV2vB2-Tn6V&!(20Q?pp-??S zAQw161CNlc=mvuHI5EMTP9{)ffkqF}PDgXuUyutP5$kj;;1S3L`=G91#t~S!07%b1 zCTKF9MTY-pA*X|SAod1gIU>CS@^%e~!HATZK*@78G^ODKmw`AGh;O3jg`3di*@`1( t{zBzUV4BfgfGsZ`uF=002ovPDHLkV1ifDg|z?x literal 0 HcmV?d00001 diff --git a/app/assets/images/locomotive/list/icons/popup_off.png b/app/assets/images/locomotive/list/icons/popup_off.png new file mode 100644 index 0000000000000000000000000000000000000000..d3d3e322aaa1177af5abbb6b79c4683cd5c5d0ee GIT binary patch literal 351 zcmV-l0igbgP)u=qAO%UST$6QI=Tx$ zPTgKrRi(&)1GKfZ!I-)rwLokF@*2#579dtcQwRq@gVBW)p?b2IptdJ7-~reSh3XLk zxxfh;c!X?4HxQ)9i3#R(GJzrsG+Z x%wMRS2~;iC-1rOXv~Fm27DaL)*6a)rU;x0tKv5FRPiFuC002ovPDHLkV1gdGh - @model = new Locomotive.Models.ContentEntry(@options.content_entry) + @model ||= new Locomotive.Models.ContentEntry(@options.content_entry) window.foo = @model @@ -45,7 +45,7 @@ class Locomotive.Views.ContentEntries.FormView extends Locomotive.Views.Shared.F enable_richtexteditor: -> _.each @$('li.input.rte textarea.html'), (textarea) => - settings = _.extend {}, window.Locomotive.tinyMCE.defaultSettings, + settings = _.extend {}, @tinyMCE_settings(), onchange_callback: (editor) => $(textarea).val(editor.getBody().innerHTML).trigger('change') @@ -62,7 +62,8 @@ class Locomotive.Views.ContentEntries.FormView extends Locomotive.Views.Shared.F enable_has_many_fields: -> _.each @model.get('_has_many_fields'), (field) => name = field[0]; inverse_of = field[1] - view = new Locomotive.Views.Shared.Fields.HasManyView model: @model, name: name, inverse_of: inverse_of + new_entry = new Locomotive.Models.ContentEntry(@options["#{name}_new_entry"]) + view = new Locomotive.Views.Shared.Fields.HasManyView model: @model, name: name, new_entry: new_entry, inverse_of: inverse_of @_has_many_field_views.push(view) @@ -74,8 +75,21 @@ class Locomotive.Views.ContentEntries.FormView extends Locomotive.Views.Shared.F refresh_file_fields: -> _.each @_file_field_views, (view) => view.refresh() + refresh: -> + @$('li.input.toggle input[type=checkbox]').checkToggle('sync') + _.each @_file_field_views, (view) => view.refresh() + + reset: -> + @$('li.input.string input[type=text], li.input.text textarea, li.input.date input[type=text]').val('').trigger('change') + _.each @$('li.input.rte textarea.html'), (textarea) => $(textarea).tinymce().setContent(''); $(textarea).trigger('change') + _.each @_file_field_views, (view) => view.reset() + @$('li.input.toggle input[type=checkbox]').checkToggle('sync') + remove: -> _.each @_file_field_views, (view) => view.remove() _.each @_has_many_field_views, (view) => view.remove() super + tinyMCE_settings: -> + window.Locomotive.tinyMCE.defaultSettings + diff --git a/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee b/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee new file mode 100644 index 00000000..985159d9 --- /dev/null +++ b/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee @@ -0,0 +1,77 @@ +#= require ../shared/form_view + +Locomotive.Views.ContentEntries ||= {} + +class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.ContentEntries.FormView + + initialize: -> + @create_dialog() + + super() + + render: -> + super() + + return @ + + save: (event) -> + @save_in_ajax event, + headers: { 'X-Flash': true } + on_success: (response, xhr) => + entry = new Locomotive.Models.ContentEntry(response) + @options.parent_view.insert_or_update_entry(entry) + @close() + on_error: => + @shake() + + create_dialog: -> + @dialog = $(@el).dialog + autoOpen: false + modal: true + zIndex: 998 + width: 770, + create: (event, ui) => + $('.ui-widget-overlay').bind 'click', => @close() + + $(@el).prev().find('.ui-dialog-title').html(@$('h2').html()) + @$('h2').remove() + actions = @$('.dialog-actions').appendTo($(@el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix') + + actions.find('#close-link').click (event) => @close(event) + actions.find('input[type=submit]').click (event) => @save(event) + + open: (event, ui, extra) => + # nothing to do + + open: -> + parent_el = $(@el).parent() + if @model.isNew() + parent_el.find('.edit-section').hide() + parent_el.find('.new-section').show() + else + parent_el.find('.new-section').hide() + parent_el.find('.edit-section').show() + + $(@el).dialog('open') + + close: (event) -> + event.stopPropagation() & event.preventDefault() if event? + $(@el).dialog('close') + + shake: -> + $(@el).parents('.ui-dialog').effect('shake', { times: 4 }, 100) + + center: -> + $(@el).dialog('option', 'position', 'center') + + reset: (entry) => + @model.set entry.attributes + + if entry.isNew() + @model.id = null + super() + else + @refresh() + + tinyMCE_settings: -> + window.Locomotive.tinyMCE.popupSettings diff --git a/app/assets/javascripts/locomotive/views/content_entries/edit.js.coffee b/app/assets/javascripts/locomotive/views/content_entries/edit_view.js.coffee similarity index 100% rename from app/assets/javascripts/locomotive/views/content_entries/edit.js.coffee rename to app/assets/javascripts/locomotive/views/content_entries/edit_view.js.coffee diff --git a/app/assets/javascripts/locomotive/views/content_entries/index.js.coffee b/app/assets/javascripts/locomotive/views/content_entries/index_view.js.coffee similarity index 100% rename from app/assets/javascripts/locomotive/views/content_entries/index.js.coffee rename to app/assets/javascripts/locomotive/views/content_entries/index_view.js.coffee diff --git a/app/assets/javascripts/locomotive/views/content_entries/new.js.coffee b/app/assets/javascripts/locomotive/views/content_entries/new_view.js.coffee similarity index 100% rename from app/assets/javascripts/locomotive/views/content_entries/new.js.coffee rename to app/assets/javascripts/locomotive/views/content_entries/new_view.js.coffee diff --git a/app/assets/javascripts/locomotive/views/shared/fields/file_view.js.coffee b/app/assets/javascripts/locomotive/views/shared/fields/file_view.js.coffee index da6e6bb8..8070be4f 100644 --- a/app/assets/javascripts/locomotive/views/shared/fields/file_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/shared/fields/file_view.js.coffee @@ -39,13 +39,14 @@ class Locomotive.Views.Shared.Fields.FileView extends Backbone.View return @ refresh: -> - # @remove() @$('input[type=file]').unbind 'change' @states = { 'change': false, 'delete': false } @render() - # @$('input[type=file]').unbind 'change' - # @states = { 'change': false, 'delete': false } - # @render() + + reset: -> + @model.set_attribute @options.name, null + @model.set_attribute "#{@options.name}_url", null + @refresh() toggle_change: (event) -> @_toggle event, 'change', diff --git a/app/assets/javascripts/locomotive/views/shared/fields/has_many_view.js.coffee b/app/assets/javascripts/locomotive/views/shared/fields/has_many_view.js.coffee index bd89b64a..a6b19b5c 100644 --- a/app/assets/javascripts/locomotive/views/shared/fields/has_many_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/shared/fields/has_many_view.js.coffee @@ -8,6 +8,8 @@ class Locomotive.Views.Shared.Fields.HasManyView extends Backbone.View className: 'list' events: + 'click p.actions a.add': 'open_new_entry_view' + 'click ul span.actions a.edit': 'edit_entry' 'click ul span.actions a.remove': 'remove_entry' template: -> @@ -21,8 +23,7 @@ class Locomotive.Views.Shared.Fields.HasManyView extends Backbone.View @collection = @model.get(@options.name) - window.model = @model - window.bar = @collection + @build_target_entry_view() render: -> $(@el).html(@template()()) @@ -40,9 +41,12 @@ class Locomotive.Views.Shared.Fields.HasManyView extends Backbone.View @$('.empty').show() insert_entry: (entry) -> + unless @collection.get(entry.get('_id'))? + @collection.add(entry) + @$('.empty').hide() entry_html = $(@entry_template()(label: entry.get('_label'))) - entry_html.data('data-entry-cid', entry.cid) + entry_html.data('data-entry-id', entry.id) @$('> ul').append(entry_html) make_entries_sortable: -> @@ -54,20 +58,63 @@ class Locomotive.Views.Shared.Fields.HasManyView extends Backbone.View refresh_position_entries: -> @$('> ul > li').each (index, entry_html) => - cid = $(entry_html).data('data-entry-cid') - entry = @collection.getByCid(cid) + id = $(entry_html).data('data-entry-id') + entry = @collection.get(id) entry.set_attribute "position_in_#{@options.inverse_of}", index + build_target_entry_view: -> + @target_entry_view = new Locomotive.Views.ContentEntries.PopupFormView + el: $("##{@options.name}-template-entry") + parent_view: @ + model: @options.new_entry.clone() # by default, it does not matter + + @target_entry_view.render() + + edit_entry: (event) -> + event.stopPropagation() & event.preventDefault() + + entry = @get_entry_from_element($(event.target)) + + @target_entry_view.reset(entry) + @target_entry_view.open() + + update_entry: (entry) -> + entry_html = $(_.detect @$('> ul > li'), (_entry_html) -> $(_entry_html).data('data-entry-id') == entry.id) + + new_entry_html = $(@entry_template()(label: entry.get('_label'))) + new_entry_html.data('data-entry-id', entry.id) + + entry_html.replaceWith(new_entry_html) + + insert_or_update_entry: (entry) -> + if @collection.get(entry.id)? + @update_entry(entry) + else + @insert_entry(entry) + remove_entry: (event) -> event.stopPropagation() & event.preventDefault() if confirm($(event.target).attr('data-confirm')) - entry_html = $(event.target).closest('li') - cid = $(entry_html).data('data-entry-cid') - entry = @collection.getByCid(cid) + entry = @get_entry_from_element($(event.target)) entry.set _destroy: true - entry_html.remove() + $(event.target).closest('li').remove() @$('.empty').show() if @$('> ul > li').size() == 0 @refresh_position_entries() + open_new_entry_view: (event) -> + event.stopPropagation() & event.preventDefault() + + @target_entry_view.reset(@options.new_entry.clone()) + @target_entry_view.open() + + get_entry_from_element: (element) => + entry_html = $(element).closest('li') + id = $(entry_html).data('data-entry-id') + @collection.get(id) + + + + + diff --git a/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee b/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee index dd1bb558..48bcd499 100644 --- a/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee @@ -23,11 +23,12 @@ class Locomotive.Views.Shared.FormView extends Backbone.View @clear_errors() - options ||= { on_success: null, on_error: null } + options ||= { headers: {}, on_success: null, on_error: null } previous_attributes = _.clone @model.attributes @model.save {}, + headers: options.headers success: (model, response, xhr) => model.attributes = previous_attributes diff --git a/app/assets/stylesheets/locomotive/backoffice/dialog_changes.css.scss b/app/assets/stylesheets/locomotive/backoffice/dialog_changes.css.scss index 3115af59..c400569d 100644 --- a/app/assets/stylesheets/locomotive/backoffice/dialog_changes.css.scss +++ b/app/assets/stylesheets/locomotive/backoffice/dialog_changes.css.scss @@ -60,7 +60,7 @@ .ui-dialog-content { position: relative; - z-index: 101; + z-index: 999; text-align: left; @@ -71,6 +71,22 @@ overflow: auto; height: 360px; } + + form.formtastic { + fieldset { + legend, ol { + width: 748px; + } + + ol { + li.string { + input[type=text] { + width: 530px; + } + } // li.string + } + } + } // .form.formtastic } // .ui-dialog-content @@ -104,7 +120,7 @@ z-index: 1003; - a { + a, input[type=submit] { @include light-button; } diff --git a/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.scss b/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.scss index 36e53687..ed2ea297 100644 --- a/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.scss +++ b/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.scss @@ -127,7 +127,7 @@ form.formtastic { padding-left: 10px; } - a.remove, a.toggle, a.drag { + a.edit, a.remove, a.toggle, a.drag { display: inline-block; width: 16px; height: 16px; @@ -138,6 +138,13 @@ form.formtastic { outline: none; text-indent: -9999px; + &.edit { + background: transparent image-url("locomotive/list/icons/pencil_off.png") repeat 0 0; + &:hover { + background-image: image-url("locomotive/list/icons/pencil.png"); + } + } + &.remove { background: transparent image-url("locomotive/list/icons/trash_off.png") repeat 0 0; &:hover { diff --git a/app/helpers/locomotive/base_helper.rb b/app/helpers/locomotive/base_helper.rb index 3b765e4e..5b674fd1 100644 --- a/app/helpers/locomotive/base_helper.rb +++ b/app/helpers/locomotive/base_helper.rb @@ -59,7 +59,7 @@ module Locomotive::BaseHelper end def backbone_view_data - content_for?(:backbone_view_data) ? content_for(:backbone_view_data) : 'null' + content_for?(:backbone_view_data) ? content_for(:backbone_view_data) : '' end def nocoffee_tag diff --git a/app/helpers/locomotive/content_entries_helper.rb b/app/helpers/locomotive/content_entries_helper.rb index 5b142495..05d6e848 100644 --- a/app/helpers/locomotive/content_entries_helper.rb +++ b/app/helpers/locomotive/content_entries_helper.rb @@ -1,11 +1,7 @@ module Locomotive::ContentEntriesHelper def options_for_belongs_to_custom_field(class_name) - content_type = nil - - if class_name =~ /^Locomotive::Entry(.*)/ - content_type = current_site.content_types.find($1) - end + content_type = Locomotive::ContentType.class_name_to_content_type(class_name, current_site) if content_type content_type.ordered_entries.map { |entry| [entry._label, entry._id] } diff --git a/app/models/locomotive/content_type.rb b/app/models/locomotive/content_type.rb index 71e58c83..493f6166 100644 --- a/app/models/locomotive/content_type.rb +++ b/app/models/locomotive/content_type.rb @@ -74,6 +74,26 @@ module Locomotive end end + def class_name_to_content_type(class_name) + self.class.class_name_to_content_type(class_name, self.site) + end + + # Retrieve from a class name the associated content type within the scope of a site. + # If no content type is found, the method returns nil + # + # @param [ String ] class_name The class name + # @param [ Locomotive::Site ] site The Locomotive site + # + # @return [ Locomotive::ContentType ] The content type matching the class_name + # + def self.class_name_to_content_type(class_name, site) + if class_name =~ /^Locomotive::Entry(.*)/ + site.content_types.find($1) + else + nil + end + end + def to_presenter Locomotive::ContentTypePresenter.new(self) end diff --git a/app/presenters/locomotive/content_entry_presenter.rb b/app/presenters/locomotive/content_entry_presenter.rb index 9e7ddbc9..046d17c2 100644 --- a/app/presenters/locomotive/content_entry_presenter.rb +++ b/app/presenters/locomotive/content_entry_presenter.rb @@ -86,7 +86,6 @@ module Locomotive when :date then "formatted_#{name}" when :file then "#{name}_url" when :belongs_to then "#{name}_id" - # when :has_many then nil else name end diff --git a/app/views/locomotive/content_entries/_form.html.haml b/app/views/locomotive/content_entries/_form.html.haml index c6791016..a74e0c45 100644 --- a/app/views/locomotive/content_entries/_form.html.haml +++ b/app/views/locomotive/content_entries/_form.html.haml @@ -3,7 +3,7 @@ - content_for :backbone_view_data do :plain - { content_entry: #{@content_entry.to_json} } + content_entry: #{@content_entry.to_json} = f.inputs :name => :attributes do - @content_type.ordered_entries_custom_fields.each_with_index do |field, index| diff --git a/app/views/locomotive/content_types/_form.html.haml b/app/views/locomotive/content_types/_form.html.haml index 821948d2..c8f15b5d 100644 --- a/app/views/locomotive/content_types/_form.html.haml +++ b/app/views/locomotive/content_types/_form.html.haml @@ -3,10 +3,8 @@ - content_for :backbone_view_data do :plain - { - content_type: #{@content_type.persisted? ? @content_type.to_json : 'null'}, - inverse_of_list: #{options_for_content_type_inverse_of.to_json} - } + content_type: #{@content_type.persisted? ? @content_type.to_json : 'null'}, + inverse_of_list: #{options_for_content_type_inverse_of.to_json} = f.inputs :name => :information do diff --git a/app/views/locomotive/current_site/_form.html.haml b/app/views/locomotive/current_site/_form.html.haml index 1c910782..503c2741 100644 --- a/app/views/locomotive/current_site/_form.html.haml +++ b/app/views/locomotive/current_site/_form.html.haml @@ -4,7 +4,8 @@ - content_for :backbone_view_data do :plain - { site: #{@site.to_json(:current_account => current_locomotive_account, :current_site => current_site)}, errors: #{@site.errors.to_json} } + site: #{@site.to_json(:current_account => current_locomotive_account, :current_site => current_site)}, + errors: #{@site.errors.to_json} = f.inputs :name => :information do = f.input :name, :wrapper_html => { :style => 'display: none' } diff --git a/app/views/locomotive/custom_fields/_form.html.haml b/app/views/locomotive/custom_fields/_form.html.haml index 3c195810..44c7afaa 100644 --- a/app/views/locomotive/custom_fields/_form.html.haml +++ b/app/views/locomotive/custom_fields/_form.html.haml @@ -38,7 +38,7 @@ = g.input :hint, :input_html => { :class => 'hint' } - = g.input :localized, :as => :'Locomotive::Toggle', :wrapper_html => { :class => 'extra localized' }, :input_html => { :class => 'localized' } + = g.input :localized, :as => :'Locomotive::Toggle', :wrapper_html => { :class => 'localized' }, :input_html => { :class => 'localized' } = g.input :select_options, :as => :'Locomotive::Empty', :wrapper_html => { :class => 'extra select-options', :style => 'display: none' } diff --git a/app/views/locomotive/custom_fields/types/_boolean.html.haml b/app/views/locomotive/custom_fields/types/_boolean.html.haml index 11159f00..911ea783 100644 --- a/app/views/locomotive/custom_fields/types/_boolean.html.haml +++ b/app/views/locomotive/custom_fields/types/_boolean.html.haml @@ -1,4 +1,4 @@ = f.input name, :label => field.label, :hint => field.hint, - :as => :'Locomotive::Toggle' \ No newline at end of file + :as => :'Locomotive::Toggle' diff --git a/app/views/locomotive/custom_fields/types/_has_many.html.haml b/app/views/locomotive/custom_fields/types/_has_many.html.haml index 8b9ff89d..b405ee3e 100644 --- a/app/views/locomotive/custom_fields/types/_has_many.html.haml +++ b/app/views/locomotive/custom_fields/types/_has_many.html.haml @@ -1,5 +1,8 @@ - if !f.object.new_record? && field.ui_enabled? + - target_content_type = Locomotive::ContentType.class_name_to_content_type(field.class_name, current_site) + - new_target_content_entry = target_content_type.entries.build(field.inverse_of => f.object) + = f.input name.to_sym, :label => field.label, :hint => field.hint, @@ -16,8 +19,8 @@ %hr - %p - = link_to t('.new_entry'), '#' + %p.actions + = link_to t('.new_entry'), '#', :class => 'add' %script{ :type => 'text/html', :id => "#{name}_entry" } %li @@ -28,43 +31,40 @@ {{label}} %span.actions + = link_to 'e', '#', :class => 'edit' = link_to 'x', '#', :class => 'remove', :confirm => t('locomotive.messages.confirm') - / - collection = f.object.send(name.to_sym) + - content_for :backbone_view_data do + :plain + , #{name}_new_entry: #{new_target_content_entry.to_json} + + - content_for :foot do + + %div{ :id => "#{name}-template-entry", :style => 'display: none' } + + %h2 + %span.new-section= t('locomotive.content_entries.new.title', :type => name.capitalize).html_safe + %span.edit-section= t('locomotive.content_entries.edit.title', :type => name.capitalize).html_safe + + = semantic_form_for new_target_content_entry, :as => :content_entry, :url => content_entries_url(target_content_type.slug), :html => { :multipart => true } do |form| + + = form.inputs :name => :attributes do + - target_content_type.ordered_entries_custom_fields.each_with_index do |_field, index| + + - next if _field.name == field.inverse_of || _field.type == 'has_many' + + = render "locomotive/custom_fields/types/#{_field.type}", + :f => form, + :name => _field.name.to_sym, + :field => _field, + :highlighted => _field._id == target_content_type.label_field_id + .dialog-actions + = link_to t('locomotive.buttons.close'), '#', :id => 'close-link' + + .button-wrapper + %span.new-section= submit_tag t('locomotive.shared.form_actions.create') + %span.edit-section= submit_tag t('locomotive.shared.form_actions.update') -/ = form.custom_input field._alias.to_sym, :label => field.label, :hint => field.hint, :css => 'has-many', :required => required do -/ -/ .has-many-selector -/ -/ %p{ :style => form.object.send(field._alias.to_sym).empty? ? '' : 'display: none' } -/ = t('.empty') -/ -/ %ul -/ -/ %script{ :type => 'text/x-mustache-template', :name => 'template', :'data-base-input-name' => "content[#{field._alias.to_sym}]" } -/ %li{ :class => "item {{behaviour_flag}}" } -/ %span.handle -/ = image_tag 'admin/form/icons/drag.png' -/ -/ {{^if_template}} -/ %input{ :name => '{{base_name}}[]', :value => '{{{id}}}', :type => 'hidden', :'data-field' => 'id' } -/ {{/if_template}} -/ -/ %strong {{label}} -/ -/ {{#if_template}} -/ = select_tag 'label', '' -/ {{/if_template}} -/ -/ %span.actions -/ - if field.reverse_lookup? -/ = link_to image_tag('admin/form/pen.png'), '#', :class => 'edit first' -/ = link_to image_tag('admin/form/icons/trash.png'), '#', :class => 'remove' -/ %button{ :class => 'button light mini add', :type => 'button' } -/ %span!= t('locomotive.buttons.new_item') -/ -/ %script{ :type => 'text/javascript', :name => 'data' } -/ != has_many_data_to_js(field, form.object) \ No newline at end of file diff --git a/app/views/locomotive/custom_fields/types/_has_one.html.haml b/app/views/locomotive/custom_fields/types/_has_one.html.haml deleted file mode 100644 index 141a3193..00000000 --- a/app/views/locomotive/custom_fields/types/_has_one.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -- field.target.constantize.reload_parent! # to make sure all the contents from the parent are loaded - -- if breadcrumb_root && params[:breadcrumb_alias] == field._alias - - = form.hidden_field field._name.to_sym - - = hidden_field_tag 'breadcrumb_alias', field._alias - -- else - - - selected_id = form.object.send(field._alias.to_sym).try(:_id) - - = form.input field._alias.to_sym, :label => field.label, :hint => field.hint, :input_html => { :class => 'has_one' }, :as => :select, :collection => options_for_has_one(field, selected_id), :selected => selected_id, :required => required - diff --git a/app/views/locomotive/custom_fields/types/_string.html.haml b/app/views/locomotive/custom_fields/types/_string.html.haml index 0fc160a9..80306567 100644 --- a/app/views/locomotive/custom_fields/types/_string.html.haml +++ b/app/views/locomotive/custom_fields/types/_string.html.haml @@ -1,4 +1,4 @@ = f.input name, :label => field.label, :hint => field.hint, - :wrapper_html => { :class => "#{'highlighted' if highlighted}" } \ No newline at end of file + :wrapper_html => { :class => "#{'highlighted' if highlighted}" } diff --git a/app/views/locomotive/layouts/application.html.haml b/app/views/locomotive/layouts/application.html.haml index 87503f32..03f01f4f 100644 --- a/app/views/locomotive/layouts/application.html.haml +++ b/app/views/locomotive/layouts/application.html.haml @@ -29,4 +29,6 @@ = yield #footer - = render 'locomotive/shared/footer' \ No newline at end of file + = render 'locomotive/shared/footer' + + = yield :foot \ No newline at end of file diff --git a/app/views/locomotive/my_account/edit.html.haml b/app/views/locomotive/my_account/edit.html.haml index d816800c..8db6f987 100644 --- a/app/views/locomotive/my_account/edit.html.haml +++ b/app/views/locomotive/my_account/edit.html.haml @@ -2,7 +2,7 @@ - content_for :backbone_view_data do :plain - { account: #{@account.to_json} } + account: #{@account.to_json} - content_for :submenu do = render_cell 'locomotive/settings_menu', :show diff --git a/app/views/locomotive/pages/_form.html.haml b/app/views/locomotive/pages/_form.html.haml index f51bdc78..37489003 100644 --- a/app/views/locomotive/pages/_form.html.haml +++ b/app/views/locomotive/pages/_form.html.haml @@ -5,7 +5,7 @@ - content_for :backbone_view_data do :plain - { page: #{@page.to_presenter.as_json_for_html_view.to_json} } + page: #{@page.to_presenter.as_json_for_html_view.to_json} - if can?(:manage, @page) diff --git a/app/views/locomotive/shared/_head.html.haml b/app/views/locomotive/shared/_head.html.haml index b3498c2b..a4253462 100644 --- a/app/views/locomotive/shared/_head.html.haml +++ b/app/views/locomotive/shared/_head.html.haml @@ -23,7 +23,7 @@ window.application_view = new Locomotive.Views.ApplicationView({ flash: #{flash.to_json}, view: #{backbone_view_class_name}, - view_data: #{backbone_view_data} + view_data: { #{backbone_view_data} } }); window.application_view.render(); diff --git a/app/views/locomotive/snippets/_form.html.haml b/app/views/locomotive/snippets/_form.html.haml index a46c89c0..b2e3b3eb 100644 --- a/app/views/locomotive/snippets/_form.html.haml +++ b/app/views/locomotive/snippets/_form.html.haml @@ -3,7 +3,7 @@ - content_for :backbone_view_data do :plain - { snippet: #{@snippet.persisted? ? @snippet.to_presenter.as_json_for_html_view.to_json : 'null'} } + snippet: #{@snippet.persisted? ? @snippet.to_presenter.as_json_for_html_view.to_json : 'null'} = f.inputs :name => :information do = f.input :name, :wrapper_html => { :class => 'highlighted' } diff --git a/app/views/locomotive/theme_assets/_form.html.haml b/app/views/locomotive/theme_assets/_form.html.haml index d33449e3..8a07a300 100644 --- a/app/views/locomotive/theme_assets/_form.html.haml +++ b/app/views/locomotive/theme_assets/_form.html.haml @@ -3,7 +3,7 @@ - content_for :backbone_view_data do :plain - { theme_asset: #{@theme_asset.persisted? ? @theme_asset.to_json : 'null'} } + theme_asset: #{@theme_asset.persisted? ? @theme_asset.to_json : 'null'} = f.hidden_field :performing_plain_text diff --git a/app/views/locomotive/theme_assets/index.html.haml b/app/views/locomotive/theme_assets/index.html.haml index 242baf4e..9ca159e5 100644 --- a/app/views/locomotive/theme_assets/index.html.haml +++ b/app/views/locomotive/theme_assets/index.html.haml @@ -16,13 +16,11 @@ - content_for :backbone_view_data do :plain - { - snippets: #{can?(:manage, Locomotive::Snippet) ? @snippets.to_json : 'null'}, - images: #{@assets[:images].to_json}, - media: #{@assets[:media].to_json}, - js_and_css_assets: #{can?(:manage, Locomotive::ThemeAsset) ? @js_and_css_assets.to_json : 'null'}, - fonts: #{can?(:manage, Locomotive::ThemeAsset) ? @assets[:fonts].to_json : 'null'} - } + snippets: #{can?(:manage, Locomotive::Snippet) ? @snippets.to_json : 'null'}, + images: #{@assets[:images].to_json}, + media: #{@assets[:media].to_json}, + js_and_css_assets: #{can?(:manage, Locomotive::ThemeAsset) ? @js_and_css_assets.to_json : 'null'}, + fonts: #{can?(:manage, Locomotive::ThemeAsset) ? @assets[:fonts].to_json : 'null'} - content_for :submenu do = render_cell 'locomotive/settings_menu', :show diff --git a/config/locales/admin_ui.en.yml b/config/locales/admin_ui.en.yml index 24530bb4..c8dbbf5e 100644 --- a/config/locales/admin_ui.en.yml +++ b/config/locales/admin_ui.en.yml @@ -80,7 +80,9 @@ en: file: delete_file: Delete file has_many: - empty: Empty + empty: The list is empty + new_entry: + Add a new entry + form: required: Required optional: Optional diff --git a/doc/TODO b/doc/TODO index b786d330..bddc1838 100644 --- a/doc/TODO +++ b/doc/TODO @@ -107,7 +107,7 @@ x script to migrate existing site - upgrade to rails 3.2 (https://github.com/locomotivecms/engine/pull/281/files) - missing custom_fields x belongs_to - - has_many + x has_many - many_to_many - heroku module for locomotive - refactoring diff --git a/lib/locomotive/custom_fields.rb b/lib/locomotive/custom_fields.rb index 72dca76d..3d12c6db 100644 --- a/lib/locomotive/custom_fields.rb +++ b/lib/locomotive/custom_fields.rb @@ -8,6 +8,10 @@ module CustomFields class Field field :ui_enabled, :type => Boolean, :default => true + def class_name_to_content_type + self._parent.send :class_name_to_content_type, self.class_name + end + protected def ensure_class_name_security diff --git a/vendor/assets/javascripts/locomotive/backbone.modelbinding.js b/vendor/assets/javascripts/locomotive/backbone.modelbinding.js index 7ab93404..80b6b869 100644 --- a/vendor/assets/javascripts/locomotive/backbone.modelbinding.js +++ b/vendor/assets/javascripts/locomotive/backbone.modelbinding.js @@ -183,7 +183,10 @@ Backbone.ModelBinding = (function(Backbone, _, $){ } // console.log(attribute_name); - var modelChange = function(changed_model, val){ element.val(val); }; + var modelChange = function(changed_model, val){ + val = val == null ? '' : val; + element.val(val); + }; var setModelValue = function(attr_name, value){ var data = {}; diff --git a/vendor/assets/javascripts/locomotive/toggle.js b/vendor/assets/javascripts/locomotive/toggle.js index 1efa8d27..85c2666a 100644 --- a/vendor/assets/javascripts/locomotive/toggle.js +++ b/vendor/assets/javascripts/locomotive/toggle.js @@ -26,7 +26,12 @@ * @param Bool settings[bypass_skin] Flags whether to bypass the inclusion of the skin.css file. Used if you've included the skin styles somewhere else already. */ - $.fn.checkToggle = function(settings) { + $.fn.checkToggle = function(action, settings) { + + if (typeof(action) == 'object' || typeof(action) == 'undefined') { + settings = action || {}; + action = 'initialize'; + } settings = $.extend({ on_label : 'Yes', @@ -48,14 +53,24 @@ settings.off_label = 'Non'; } - // append the skin styles - // if(settings.bypass_skin == false){ - // $("head").append(''); - // } + function showUncheckedState(element) { + element.parent().prev().css("color",settings.off_label_color); + element.parent().next().css("color",settings.on_label_color); + element.parent().css("background-color", settings.off_bg_color).removeClass('on'); + element.parent().parent().prev().removeAttr("checked").trigger('change'); + element.removeClass("left").addClass("right"); + } + + function showCheckedState(element) { + element.parent().prev().css("color",settings.on_label_color); + element.parent().next().css("color",settings.off_label_color); + element.parent().css("background-color", settings.on_bg_color).addClass('on'); + element.parent().parent().prev().attr("checked", "checked").trigger('change'); + element.removeClass("right").addClass("left"); + } function toggle(element){ - - var checked = $(element).parent().parent().prev().attr("checked"); + var checked = $(element).parent().parent().prev().is(':checked'); // if it's set to on if(checked){ @@ -64,11 +79,7 @@ // callback function function(){ - $(element).parent().prev().css("color",settings.off_label_color); - $(element).parent().next().css("color",settings.on_label_color); - $(element).parent().css("background-color", settings.off_bg_color).removeClass('on'); - $(element).parent().parent().prev().removeAttr("checked").trigger('change'); - $(element).removeClass("left").addClass("right"); + showUncheckedState($(element)); if (typeof $.fn.publish != 'undefined') $.publish('toggle.' + $(element).parent().parent().prev().attr('id') + '.unchecked', []); @@ -76,48 +87,56 @@ settings.off_callback(); }); - }else{ - + } else { $(element).animate({marginLeft: '15px'}, 100, // callback function function(){ - $(element).parent().prev().css("color",settings.on_label_color); - $(element).parent().next().css("color",settings.off_label_color); - $(element).parent().css("background-color", settings.on_bg_color).addClass('on'); - $(element).parent().parent().prev().attr("checked", "checked").trigger('change'); - $(element).removeClass("right").addClass("left"); + showCheckedState($(element)); if (typeof $.fn.publish != 'undefined') $.publish('toggle.' + $(element).parent().parent().prev().attr('id') + '.checked', []); settings.on_callback(); }); - } }; return this.each(function () { - if ($(this).hasClass('simple')) return; + if (action == 'initialize') {// initialize the UI element - // hide the checkbox - $(this).css('display','none'); + if ($(this).hasClass('simple')) return; - // insert the new toggle markup - if($(this).attr("checked") == "checked" || $(this).attr("checked") == true){ - $(this).after('
'+settings.on_label+'<\/span>
<\/span><\/div>'+settings.off_label+'<\/span><\/div>'); - }else{ - $(this).after('
'+settings.on_label+'<\/span>
<\/span><\/div>'+settings.off_label+'<\/span><\/div>'); + // hide the checkbox + $(this).css('display','none'); + + // insert the new toggle markup + if($(this).attr("checked") == "checked" || $(this).attr("checked") == true){ + $(this).after('
'+settings.on_label+'<\/span>
<\/span><\/div>'+settings.off_label+'<\/span><\/div>'); + }else{ + $(this).after('
'+settings.on_label+'<\/span>
<\/span><\/div>'+settings.off_label+'<\/span><\/div>'); + } + + // Bind the switchHandle click events to the internal toggle function + $(this).next().find('div.switchArea').bind("click", function () { + toggle($(this).find('.switchHandle')); + }) + + } else if (action == 'sync') { + element = $(this).next().find('.switchHandle'); + + if ($(this).is(':checked')) + showCheckedState(element); + else + showUncheckedState(element); + } else { + console.log('unknown action for the checkToggle plugin') } - // Bind the switchHandle click events to the internal toggle function - $(this).next().find('div.switchArea').bind("click", function () { - toggle($(this).find('.switchHandle')); }) }); - }; })(jQuery); \ No newline at end of file