edit_mode 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/.gitignore +23 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +29 -0
  4. data/Guardfile +19 -0
  5. data/LICENSE +22 -0
  6. data/README.md +135 -0
  7. data/Rakefile +8 -0
  8. data/edit_mode.gemspec +31 -0
  9. data/lib/assets/javascripts/edit_mode/best_in_place.js.coffee +25 -0
  10. data/lib/assets/javascripts/edit_mode/best_in_place.js.coffee~ +26 -0
  11. data/lib/assets/javascripts/edit_mode/edit_mode_group.js.coffee +43 -0
  12. data/lib/assets/javascripts/edit_mode/initial_auto_hide.js.coffee +8 -0
  13. data/lib/assets/javascripts/edit_mode/make_modal.js.coffee +28 -0
  14. data/lib/assets/javascripts/edit_mode/show_only_in_edit_mode.js.coffee +22 -0
  15. data/lib/assets/javascripts/edit_mode/tool_buttons.js.coffee +21 -0
  16. data/lib/assets/javascripts/edit_mode.js +2 -0
  17. data/lib/assets/stylesheets/edit_mode/initial_auto_hide.css.sass +3 -0
  18. data/lib/assets/stylesheets/edit_mode/modal.css.sass +17 -0
  19. data/lib/assets/stylesheets/edit_mode.css +4 -0
  20. data/lib/assets/stylesheets/edit_mode.css~ +4 -0
  21. data/lib/edit_mode/engine.rb +7 -0
  22. data/lib/edit_mode/helper.rb +19 -0
  23. data/lib/edit_mode/railtie.rb +7 -0
  24. data/lib/edit_mode/version.rb +3 -0
  25. data/lib/edit_mode.rb +9 -0
  26. data/spec/helpers/edit_mode_helpers_spec.rb +26 -0
  27. data/spec/integration/buttons_spec.rb +69 -0
  28. data/spec/integration/show_only_in_edit_mode_spec.rb +24 -0
  29. data/spec/spec_helper.rb +22 -0
  30. data/test_app/.gitignore +15 -0
  31. data/test_app/Gemfile +56 -0
  32. data/test_app/README.md +135 -0
  33. data/test_app/Rakefile +7 -0
  34. data/test_app/app/assets/images/rails.png +0 -0
  35. data/test_app/app/assets/images/screenshot.png +0 -0
  36. data/test_app/app/assets/javascripts/activate_best_in_place.js +4 -0
  37. data/test_app/app/assets/javascripts/application.js +18 -0
  38. data/test_app/app/assets/stylesheets/#application.css# +14 -0
  39. data/test_app/app/assets/stylesheets/application.css +14 -0
  40. data/test_app/app/assets/stylesheets/modifications.css.sass +9 -0
  41. data/test_app/app/assets/stylesheets/nifty.css +79 -0
  42. data/test_app/app/controllers/application_controller.rb +3 -0
  43. data/test_app/app/controllers/root_controller.rb +11 -0
  44. data/test_app/app/controllers/users_controller.rb +44 -0
  45. data/test_app/app/helpers/application_helper.rb +2 -0
  46. data/test_app/app/helpers/error_messages_helper.rb +23 -0
  47. data/test_app/app/helpers/layout_helper.rb +22 -0
  48. data/test_app/app/helpers/users_helper.rb +2 -0
  49. data/test_app/app/mailers/.gitkeep +0 -0
  50. data/test_app/app/models/.gitkeep +0 -0
  51. data/test_app/app/models/user.rb +3 -0
  52. data/test_app/app/views/layouts/application.html.erb +19 -0
  53. data/test_app/app/views/users/_form.html.erb +16 -0
  54. data/test_app/app/views/users/edit.html.erb +8 -0
  55. data/test_app/app/views/users/index.html.erb +29 -0
  56. data/test_app/app/views/users/index.html.erb~ +21 -0
  57. data/test_app/app/views/users/new.html.erb +5 -0
  58. data/test_app/app/views/users/show.html.erb +54 -0
  59. data/test_app/app/views/users/show.html.erb~ +50 -0
  60. data/test_app/config/application.rb +59 -0
  61. data/test_app/config/boot.rb +6 -0
  62. data/test_app/config/database.yml +25 -0
  63. data/test_app/config/environment.rb +5 -0
  64. data/test_app/config/environments/development.rb +37 -0
  65. data/test_app/config/environments/production.rb +67 -0
  66. data/test_app/config/environments/test.rb +37 -0
  67. data/test_app/config/initializers/backtrace_silencers.rb +7 -0
  68. data/test_app/config/initializers/inflections.rb +15 -0
  69. data/test_app/config/initializers/mime_types.rb +5 -0
  70. data/test_app/config/initializers/secret_token.rb +7 -0
  71. data/test_app/config/initializers/session_store.rb +8 -0
  72. data/test_app/config/initializers/wrap_parameters.rb +14 -0
  73. data/test_app/config/locales/en.yml +5 -0
  74. data/test_app/config/routes.rb +62 -0
  75. data/test_app/config.ru +4 -0
  76. data/test_app/db/migrate/20120607231941_create_users.rb +14 -0
  77. data/test_app/db/schema.rb +24 -0
  78. data/test_app/db/seeds.rb +7 -0
  79. data/test_app/lib/assets/.gitkeep +0 -0
  80. data/test_app/lib/tasks/.gitkeep +0 -0
  81. data/test_app/public/404.html +26 -0
  82. data/test_app/public/422.html +26 -0
  83. data/test_app/public/500.html +25 -0
  84. data/test_app/public/favicon.ico +0 -0
  85. data/test_app/public/robots.txt +5 -0
  86. data/test_app/public/stylesheets/application.css +75 -0
  87. data/test_app/script/rails +6 -0
  88. data/test_app/test/fixtures/users.yml +9 -0
  89. data/test_app/test/functional/users_controller_test.rb +54 -0
  90. data/test_app/test/unit/user_test.rb +7 -0
  91. data/test_app/vendor/assets/javascripts/.gitkeep +0 -0
  92. data/test_app/vendor/assets/stylesheets/.gitkeep +0 -0
  93. data/test_app/vendor/plugins/.gitkeep +0 -0
  94. metadata +232 -0
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ Gemfile.lock
20
+ test_app/.bundle
21
+ test_app/db/*.sqlite3
22
+ test_app/log/*.log
23
+ test_app/tmp/**/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile ADDED
@@ -0,0 +1,29 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in edit_mode.gemspec
4
+ gemspec
5
+
6
+ group :test, :development do
7
+ gem 'rspec'
8
+ gem 'rspec-core'
9
+ gem 'rspec-expectations'
10
+ gem 'rspec-mocks'
11
+ gem 'nokogiri'
12
+ gem 'capybara'
13
+ gem 'execjs'
14
+ gem 'therubyracer', :platform => :ruby
15
+
16
+ gem 'guard', '1.0.1'
17
+ gem 'rspec-rails', '2.10.0'
18
+ gem 'guard-rspec', '0.5.5'
19
+
20
+ end
21
+
22
+ group :test do
23
+ gem 'best_in_place'
24
+ gem 'sass-rails'
25
+ end
26
+
27
+ gem 'jquery-rails'
28
+ gem 'coffee-rails'
29
+ gem 'sqlite3'
data/Guardfile ADDED
@@ -0,0 +1,19 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ require 'active_support/core_ext'
5
+
6
+ guard 'rspec', :version => 2, :all_after_pass => false do
7
+ watch(%r{^spec/.+_spec\.rb$})
8
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
9
+ watch('spec/spec_helper.rb') { "spec" }
10
+
11
+ # Rails example
12
+ # watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ # watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
14
+ # watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
15
+
16
+ # Capybara request specs
17
+ # watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
18
+ end
19
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Sebastian Fiedlschuster
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # EditMode
2
+
3
+ <img src="https://github.com/fiedl/edit_mode/raw/master/test_app/app/assets/images/screenshot.png" height="300" align="right" vspace="20" hspace="20" />
4
+
5
+ *edit_mode* is a *ruby on rails gem* that allows you to toggle an edit mode on a normal show view.
6
+ Think of it as a grouped in-place editing.
7
+ This also toggles [best_in_place](https://github.com/bernat/best_in_place) fields.
8
+
9
+ The edit mode is activated by pressing an 'edit' button on a show view. This shows additional editing tools
10
+ and switches on the best_in_place form fields. When editing is finished, use 'save' or 'cancel' buttons to
11
+ quit the edit mode and return to a normal show view.
12
+ Several editing groups per page are supported. Thus, you can have several 'boxes' to edit on a page.
13
+
14
+ ## Demo
15
+
16
+ You might want to have a look at [this demo app at heroku](http://edit-mode-test-app.herokuapp.com/).
17
+
18
+ The [code of this demo app can be found here](https://github.com/fiedl/edit_mode/tree/master/test_app).
19
+
20
+ ## Installation
21
+
22
+ THIS IS NOT READY, YET.
23
+
24
+ Add this line to your application's Gemfile:
25
+
26
+ gem 'edit_mode'
27
+
28
+ And then execute:
29
+
30
+ $ bundle
31
+
32
+ Or install it yourself as:
33
+
34
+ $ gem install edit_mode
35
+
36
+ TODO: Include css and js.
37
+
38
+ ### Include Assets
39
+
40
+ In `app/assets/javascripts/application.js`, add:
41
+
42
+ ```javascript
43
+ //= require edit_mode
44
+ ```
45
+
46
+ In `app/assets/stylesheets/application.css`, add:
47
+
48
+ ```css
49
+ /*
50
+ *...
51
+ *= require edit_mode
52
+ */
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ### Basic View
58
+
59
+ For a basic example, see: https://github.com/fiedl/edit_mode/blob/master/test_app/app/views/users/show.html.erb
60
+
61
+ ### edit_mode_group
62
+
63
+ The edit mode is toggled within a `<span class="edit_mode_group"></span>`. The buttons to 'edit', 'save' and 'cancel' should also be placed inside this span.
64
+
65
+ You can also have several edit_mode_group spans on a page, as shown in the demo app.
66
+
67
+ ### Tool Buttons
68
+
69
+ To enter and exit the edit mode, use buttons 'edit', 'save' and 'cancel'. These can be anchors, images, et cetera. They only have to have the correct css classes:
70
+
71
+ ```html
72
+ <span class="edit_mode_group">
73
+ <a class="edit_button" href="#">edit</a>
74
+ <a class="save_button" href="#">save</a>
75
+ <a class="cancel_button" href="#">cancel</a>
76
+ ...
77
+ </span>
78
+ ```
79
+
80
+ ### show_only_in_edit_mode
81
+
82
+ Within the edit_mode_group span, you may place certain elements that should only be shown when in edit mode. You can use this for 'add' buttons or 'destroy' buttons.
83
+
84
+ ```html
85
+ <span class="edit_mode_group">
86
+ ...
87
+ <span class="show_only_in_edit_mode">
88
+ <a href="#">add</a>
89
+ </span>
90
+ </span>
91
+ ```
92
+
93
+ The same, the other way round:
94
+
95
+ ```html
96
+ <span class="edit_mode_group">
97
+ ...
98
+ <span class="do_not_show_in_edit_mode">
99
+ <img src="..." alt="This picture is not shown in edit mode." />
100
+ </span>
101
+ </span>
102
+ ```
103
+
104
+ ### best_in_place
105
+
106
+ In the edit_mode_group span, all [best_in_place](https://github.com/bernat/best_in_place) elements are toggled as well.
107
+
108
+ ### '.editable' Triggers
109
+
110
+ If you need custom behaviour inside the edit_mode_group span, you can use these triggers: For all elements of the class `.editable`, the events `edit`, `save` and `cancel` are triggered, when entering or exiting edit mode.
111
+
112
+ ```html
113
+ <span class="edit_mode_group">
114
+ ...
115
+ <span class="editable custom_element">Test</span>
116
+ </span>
117
+ ```
118
+
119
+ Bind the event via JavaScript, e.g. with jQuery:
120
+
121
+ ```coffee
122
+ jQuery ->
123
+ $( ".custom_element" ).bind( "edit", ->
124
+ alert( "This element has just entered edit mode." )
125
+ )
126
+ ```
127
+
128
+ ## Contributing
129
+
130
+ 1. Fork it
131
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
132
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
133
+ 4. Push to the branch (`git push origin my-new-feature`)
134
+ 5. Create new Pull Request
135
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
data/edit_mode.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "edit_mode/version"
4
+ #require File.expand_path('../lib/edit_mode/version', __FILE__)
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "edit_mode"
8
+ gem.authors = ["Sebastian Fiedlschuster"]
9
+ gem.email = ["sebastian@fiedlschuster.de"]
10
+ gem.description = %q{The edit mode is activated by pressing an 'edit' button on a show view. This shows additional editing tools and switches on the best_in_place form fields. When editing is finished, use 'save' or 'cancel' buttons to quit the edit mode and return to a normal show view. Several editing groups per page are supported. Thus, you can have several 'boxes' to edit on a page.}
11
+ gem.summary = %q{Toggle an edit mode on a show view. Think of it as a grouped in-place editing.}
12
+ gem.homepage = "https://github.com/fiedl/edit_mode"
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.name = "edit_mode"
18
+ gem.require_paths = ["lib"]
19
+ gem.version = EditMode::VERSION
20
+
21
+
22
+ # gem.add_dependency "railties"
23
+
24
+ gem.add_dependency "rails", ">= 3.2"
25
+ gem.add_dependency "jquery-rails"
26
+
27
+ gem.add_development_dependency "rspec-rails", ">= 2.8.0"
28
+ gem.add_development_dependency "nokogiri", ">= 1.5.0"
29
+ gem.add_development_dependency "capybara"
30
+
31
+ end
@@ -0,0 +1,25 @@
1
+
2
+ jQuery ->
3
+ $( ".best_in_place" ).best_in_place()
4
+ .addClass( "editable ")
5
+ .bind( "edit", ->
6
+ $( this ).data( 'bestInPlaceEditor' ).activate()
7
+ $( this ).find( "*" ).unbind( 'blur' )
8
+ .unbind( 'click' )
9
+ .unbind( 'keyup' )
10
+ .unbind( 'submit' )
11
+ .bind( 'keyup', keyUpHandler )
12
+ )
13
+ .bind( "cancel", ->
14
+ $( this ).data( 'bestInPlaceEditor' ).abort()
15
+ )
16
+ .bind( "save", ->
17
+ $( this ).data( 'bestInPlaceEditor' ).update()
18
+ )
19
+
20
+ keyUpHandler = (event) ->
21
+ if event.keyCode == 27
22
+ $( this ).closest( ".edit_mode_group" ).trigger( "cancel" )
23
+ if event.keyCode == 13
24
+ unless $( event.target ).is( "textarea" )
25
+ $( this ).closest( ".edit_mode_group" ).trigger( "save" )
@@ -0,0 +1,26 @@
1
+
2
+ jQuery ->
3
+ $( ".best_in_place" ).best_in_place()
4
+ .addClass( "editable ")
5
+ .bind( "edit", ->
6
+ alert( "activated" )
7
+ $( this ).data( 'bestInPlaceEditor' ).activate()
8
+ $( this ).find( "*" ).unbind( 'blur' )
9
+ .unbind( 'click' )
10
+ .unbind( 'keyup' )
11
+ .unbind( 'submit' )
12
+ .bind( 'keyup', keyUpHandler )
13
+ )
14
+ .bind( "cancel", ->
15
+ $( this ).data( 'bestInPlaceEditor' ).abort()
16
+ )
17
+ .bind( "save", ->
18
+ $( this ).data( 'bestInPlaceEditor' ).update()
19
+ )
20
+
21
+ keyUpHandler = (event) ->
22
+ if event.keyCode == 27
23
+ $( this ).closest( ".edit_mode_group" ).trigger( "cancel" )
24
+ if event.keyCode == 13
25
+ unless $( event.target ).is( "textarea" )
26
+ $( this ).closest( ".edit_mode_group" ).trigger( "save" )
@@ -0,0 +1,43 @@
1
+
2
+ jQuery ->
3
+
4
+ # The <span class="edit_mode_group"></span> elements receive 'edit', 'save' and 'cancel' events,
5
+ # when the user clicks the corresponding buttons '.edit_button', '.save_button' or '.cancel_button'.
6
+ # The edit_mode_group has to pass these events down to the contained .editable elements.
7
+ $( ".edit_mode_group" ).bind( "edit", ->
8
+
9
+ unless $( this ).hasClass( "currently_in_edit_mode" )
10
+ $( this ).addClass( "currently_in_edit_mode" )
11
+
12
+ $( $( this ).find( ".editable" ).get().reverse() ).each ->
13
+ $( this ).trigger( "edit" )
14
+ )
15
+
16
+ $( ".edit_mode_group" ).bind( "save", ->
17
+
18
+ if $( this ).hasClass( "currently_in_edit_mode" )
19
+ $( this ).removeClass( "currently_in_edit_mode" )
20
+
21
+ edit_mode_group = $( this )
22
+ button_effect( $( this ).find( ".save_button" ), ->
23
+ edit_mode_group.find( ".editable" ).trigger( "save" )
24
+ )
25
+
26
+ )
27
+
28
+ $( ".edit_mode_group" ).bind( "cancel", ->
29
+
30
+ if $( this ).hasClass( "currently_in_edit_mode" )
31
+ $( this ).removeClass( "currently_in_edit_mode" )
32
+
33
+ edit_mode_group = $( this )
34
+ button_effect( $( this ).find( ".cancel_button" ), ->
35
+ edit_mode_group.find( ".editable" ).trigger( "cancel" )
36
+ )
37
+
38
+ )
39
+
40
+
41
+
42
+ button_effect = ( button, callback ) ->
43
+ button.effect( "pulsate", { times: 2 }, "fast", callback )
@@ -0,0 +1,8 @@
1
+
2
+ jQuery ->
3
+
4
+ # The tool buttons and the .show_only_in_edit_mode elements first are hidden via css (in case JavaScript does not work).
5
+ # In order to use .hide() and .show() of jQuery, we need to restore the display css property
6
+ # and hide the elements via jQuery.
7
+ $( ".save_button,.cancel_button,.show_only_in_edit_mode" ).css( "display", "inline-block" ).hide()
8
+
@@ -0,0 +1,28 @@
1
+
2
+ jQuery ->
3
+
4
+ # The <span class="edit_mode_group"></span> elements should be modal when in edit mode.
5
+ # That means that everything else should be greyed out.
6
+ # If the user clicks on the shaded (grey) area outside, the edit_mode_group is saved.
7
+
8
+ $( ".edit_mode_group" ).bind( "edit", ->
9
+ unless $( this ).hasClass( "modal" )
10
+ modal_edit_mode_group = $( this )
11
+ $( this ).addClass( "modal" )
12
+ $( "body" ).append( "<div class='modal_bg'></div>" )
13
+ $( "div.modal_bg" ).hide().fadeIn().click( ->
14
+ modal_edit_mode_group.trigger( "save" )
15
+ )
16
+ )
17
+
18
+ $( ".edit_mode_group" ).bind( "save cancel", ->
19
+ if $( this ).hasClass( "modal" )
20
+ unless $( this ).hasClass( "animating" )
21
+ $( this ).addClass( "animating" )
22
+ setTimeout( ->
23
+ $( "div.modal_bg" ).fadeOut( ->
24
+ $( this ).remove()
25
+ $( ".modal" ).removeClass( "modal animating" )
26
+ )
27
+ , 300 )
28
+ )
@@ -0,0 +1,22 @@
1
+
2
+ jQuery ->
3
+
4
+ # When edit mode is entered, on all included '.editable' elements the 'edit' event is triggered.
5
+ # When edit mode is left, the events 'save' or 'cancel' are triggered.
6
+ # For <span class="show_only_in_edit_mode"></span> tags, these events are rather simple:
7
+ # Just show or hide these spans!
8
+ $( ".show_only_in_edit_mode" ).live( "edit", ->
9
+ $( this ).show()
10
+ ).live( "save cancel", ->
11
+ $( this ).hide()
12
+ )
13
+
14
+ # And just the opposite for <span class="do_not_show_in_edit_mode"></span>.
15
+ $( ".do_not_show_in_edit_mode" ).live( "edit", ->
16
+ $( this ).hide()
17
+ ).live( "save cancel", ->
18
+ $( this ).show()
19
+ )
20
+
21
+ # In order to receive these events, the .show_only_in_edit_mode elements have to be .editable as well.
22
+ $( ".show_only_in_edit_mode,.do_not_show_in_edit_mode" ).addClass( "editable" )
@@ -0,0 +1,21 @@
1
+
2
+ jQuery ->
3
+
4
+ # The 'save' and the 'cancel' button are only to be shown in edit mode.
5
+ # In order to receive the proper 'edit', 'save', 'cancel' events, they also have to be .editable.
6
+ $( ".save_button,.cancel_button" ).addClass( "show_only_in_edit_mode editable" )
7
+
8
+ # The 'edit' button is only to be shown when not in edit mode.
9
+ $( ".edit_button" ).addClass( "do_not_show_in_edit_mode editable" )
10
+
11
+ # The buttons trigger the correspondig events of the surrounding edit_mode_group.
12
+ $( ".edit_button" ).click ( ->
13
+ $( this ).closest( ".edit_mode_group" ).trigger( "edit" )
14
+ )
15
+ $( ".save_button" ).click( ->
16
+ $( this ).closest( ".edit_mode_group" ).trigger( "save" )
17
+ )
18
+ $( ".cancel_button" ).click( ->
19
+ $( this ).closest( ".edit_mode_group" ).trigger( "cancel" )
20
+ )
21
+
@@ -0,0 +1,2 @@
1
+ //
2
+ //= require_tree ./edit_mode
@@ -0,0 +1,3 @@
1
+
2
+ .show_only_in_edit_mode, .save_button, .cancel_button
3
+ display: none
@@ -0,0 +1,17 @@
1
+ .modal
2
+ position: relative
3
+ z-index: 3005
4
+
5
+ .modal_bg
6
+ top: 0px
7
+ left: 0px
8
+ position: fixed
9
+ width: 100%
10
+ height: 100%
11
+ background-color: #000000
12
+ filter: alpha(opacity = 60)
13
+ opacity: 0.6
14
+ -moz-opacity: 0.6
15
+ z-index: 3000
16
+ text-align: center
17
+ vertical-align: middle
@@ -0,0 +1,4 @@
1
+
2
+ /*
3
+ *= require_tree ./edit_mode
4
+ */
@@ -0,0 +1,4 @@
1
+
2
+ /*
3
+ *= require_tree .
4
+ */
@@ -0,0 +1,7 @@
1
+ module EditMode
2
+ class Engine < Rails::Engine
3
+ initializer "setup for rails" do
4
+ ActionView::Base.send( :include, EditMode::EditModeHelpers )
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ module EditMode
2
+ module EditModeHelpers
3
+
4
+ # Returns a span tag which is only shown in edit mode.
5
+ def show_only_in_edit_mode_span( &block )
6
+ content_tag :span, :class => 'show_only_in_edit_mode' do
7
+ yield
8
+ end
9
+ end
10
+
11
+ # Returns a span tag which is only shown when *not* in edit mode.
12
+ def do_not_show_in_edit_mode_span( &block )
13
+ content_tag :span, :class => 'do_not_show_in_edit_mode' do
14
+ yield
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ module EditMode
2
+ class Railtie < Rails::Railtie
3
+ initializer "set view helpers" do
4
+ EditMode::ViewHelpers = ActionView::Base.new
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module EditMode
2
+ VERSION = "0.0.1"
3
+ end
data/lib/edit_mode.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "edit_mode/version"
2
+ require "edit_mode/helper"
3
+ require "edit_mode/engine"
4
+ require "edit_mode/railtie"
5
+ require "action_view"
6
+
7
+ module EditMode
8
+ # Your code goes here...
9
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ describe EditMode::EditModeHelpers do
4
+
5
+ describe "#show_only_in_edit_mode_span" do
6
+
7
+ it "should generate the corresponding span" do
8
+ nokogiri = Nokogiri::HTML.parse( show_only_in_edit_mode_span { "<p>This text is shown only in edit mode.</p>" } )
9
+ span = nokogiri.css( "span" )
10
+ span.text.should == "<p>This text is shown only in edit mode.</p>"
11
+ end
12
+
13
+ end
14
+
15
+ describe "#do_not_show_in_edit_mode_span" do
16
+
17
+ it "should generate the corresponding span" do
18
+ nokogiri = Nokogiri::HTML.parse( do_not_show_in_edit_mode_span { "<p>This text is shown only when not in edit mode.</p>" } )
19
+ span = nokogiri.css( "span" )
20
+ span.text.should == "<p>This text is shown only when not in edit mode.</p>"
21
+ end
22
+
23
+ end
24
+
25
+
26
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe "button behaviour", js: true do
4
+
5
+ before do
6
+ @user = User.new( first_name: "John", last_name: "Doe", date_of_birth: "1995-12-21" )
7
+ @user.save
8
+ visit user_path( @user )
9
+ end
10
+
11
+ describe "edit button" do
12
+
13
+ it "should be visible outside and invisible in edit mode" do
14
+ page.should have_selector( ".edit_button", visible: true, count: 2 )
15
+ click_on 'edit'
16
+ page.should have_selector( ".edit_button", visible: true, count: 1 )
17
+ page.should_not have_selector( ".edit_button", visible: true, count: 2 )
18
+ click_on 'cancel'
19
+ page.should have_selector( ".edit_button", visible: true, count: 2 )
20
+ end
21
+
22
+ it "should activate the edit mode" do
23
+ page.should_not have_selector( ".edit_mode_group.currently_in_edit_mode" )
24
+ click_on 'edit'
25
+ page.should have_selector( ".edit_mode_group.currently_in_edit_mode" )
26
+ end
27
+
28
+ it "should activate the edit mode only for the own edit_mode_group" do
29
+ click_on 'edit'
30
+ page.should have_field( 'first_name' )
31
+ page.should_not have_field( 'date_of_birth' )
32
+ end
33
+
34
+ end
35
+
36
+ describe "save button" do
37
+ it "should be visible only in edit mode" do
38
+ page.should_not have_selector( ".save_button", visible: true )
39
+ click_on 'edit'
40
+ page.should have_selector( ".save_button", visible: true )
41
+ end
42
+
43
+ it "should save the best_in_place fields" do
44
+ click_on 'edit'
45
+ fill_in 'first_name', with: 'Jane'
46
+ click_on 'save'
47
+ page.should_not have_content( "First Name: John" )
48
+ page.should have_content( "First Name: Jane" )
49
+ end
50
+ end
51
+
52
+ describe "cancel button" do
53
+ it "should be visible only in edit mode" do
54
+ page.should_not have_selector( ".cancel_button", visible: true )
55
+ click_on 'edit'
56
+ page.should have_selector( ".cancel_button", visible: true )
57
+ end
58
+
59
+ it "should *not* save the best_in_place fields" do
60
+ click_on 'edit'
61
+ fill_in 'first_name', with: 'Jane'
62
+ click_on 'cancel'
63
+ page.should have_content( "First Name: John" )
64
+ page.should_not have_content( "First Name: Jane" )
65
+ end
66
+ end
67
+
68
+
69
+ end