inline_editor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 613a54ae2b2094b2b3f65bd09076ad440296cdc656ce4d9bce885f1da216a11d
4
+ data.tar.gz: bba7a5f528f10bda0a6bb0bfc9766c8bc62585931336a1916665ad97d3c79f9b
5
+ SHA512:
6
+ metadata.gz: d68aaf7a3982b5213fb9a142a84e3910efb0c5e28f00c1527b625c8804c09e024100aeaa68ad9c7153f545adc9544f9a9e135d14454c2ef9b310f65b14206980
7
+ data.tar.gz: 4ecf2664588d9e1443c1d4fb5b4ba4d7f13e48714317e74788cc2bdf285baf543587cddc1002042a7835c3074c86b560187ac2babca627cf559573f61f475784
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2019 ShevchukTania
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # InlineEditor
2
+ [![Build Status](https://travis-ci.com/ShevchukTania/inline_editor.svg?branch=master)](https://travis-ci.com/ShevchukTania/inline_editor)
3
+ [![Maintainability](https://api.codeclimate.com/v1/badges/8ad754e23e17a293dac2/maintainability)](https://codeclimate.com/github/ShevchukTania/inline_editor/maintainability)
4
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/8ad754e23e17a293dac2/test_coverage)](https://codeclimate.com/github/ShevchukTania/inline_editor/test_coverage)
5
+
6
+ Demo app https://inline-editor.herokuapp.com
7
+
8
+ ![](https://raw.githubusercontent.com/ShevchukTania/inline_editor/master/spec/dummy/app/assets/images/preview.gif)
9
+
10
+ ## Steps to install
11
+ 1. Add this line to your application's Gemfile:
12
+ ```ruby
13
+ gem 'inline_editor'
14
+ ```
15
+ 1. Import 'inline_editor' to your application.js
16
+
17
+ ```javascript
18
+ //= require inline_editor
19
+ ```
20
+ Also, you could add styles to your application.sccs for your inlne editor
21
+
22
+ ```scss
23
+ @import "inline_editor"
24
+ ```
25
+
26
+ 1. In your views you could use **inline_editor** helper which generate markup for clickable item and form
27
+
28
+ **Exampeles:**
29
+
30
+ ```ruby
31
+ <%= inline_editor as: :select, text: post.title, value: post.title, collection: Post::TITLE,
32
+ save_url: inline_update_post_path(post), include_blank: false, param: 'title'%>
33
+ ```
34
+
35
+ Also, insteed of plain text you could use any helper which generate HTML view
36
+
37
+ ```ruby
38
+ <%= inline_editor as: :select, text: your_helper(post.title), value: post.title, collection: Post::TITLE,
39
+ save_url: inline_update_post_path(post), include_blank: false, param: 'title'%>
40
+ ```
41
+ Option | Type | Example
42
+ ------------------ | -------------| -------------
43
+ as |symbol |as: :select. type of form tag you want to generate
44
+ text |string/HTML |text: post.title, text: your_text_helper(post.title), the value will
45
+ value |string |value: post.title
46
+ collection |array |collection: Post::TITLE
47
+ save_url |string |save_url: inline_update_post_path(post)
48
+ include_blank |boolean |include_blank: false
49
+ param |string |param: 'title', this is your model attribute you want to change
50
+
51
+ For now it is available two parameter for **as:**
52
+ * :select
53
+ * :grouped_select
54
+
55
+ 1. Create action responsible for inline update
56
+
57
+ It may look like this:
58
+
59
+ ```ruby
60
+ def inline_update
61
+ @post = Post.find(params[:id])
62
+ if @post.update(post_params)
63
+ render json: { html: helpers.inline_editor_text(value: post_params.values.first, option: post_params.keys.first)}
64
+ else
65
+ render json: { status: 'error', message: @post.errors.full_messages.to_sentence }
66
+ end
67
+ end
68
+ ```
69
+ 1. Also there are several custom JavaScript events you could use to achive extra behaviour
70
+
71
+ * **inlineEditError** - triggered if your responce contains { status: 'error' }
72
+ * **inlineEditSuccess** - triggered after controller respond without error status
73
+
74
+
75
+ ## Contributing
76
+ Contribution directions go here.
77
+
78
+ ## License
79
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'InlineEditor'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
18
+
19
+ require 'rake/testtask'
20
+
21
+ Rake::TestTask.new(:test) do |t|
22
+ t.libs << 'test'
23
+ t.pattern = 'test/**/*_test.rb'
24
+ t.verbose = false
25
+ end
26
+
27
+ task default: :test
@@ -0,0 +1,84 @@
1
+ document.addEventListener('DOMContentLoaded', function(){
2
+ document.querySelectorAll('.form select').forEach(select => {
3
+ select.addEventListener("change", function(e){
4
+ let data = {};
5
+ let target = e.currentTarget;
6
+ const url = target.dataset.url;
7
+ data[target.dataset.param] = target.querySelector('option:checked').text;
8
+
9
+ fetch(url, {
10
+ method: 'PUT',
11
+ body: JSON.stringify(data),
12
+ headers: { 'Content-Type': 'application/json' }
13
+ })
14
+ .then(response => {
15
+ return response.json();
16
+ })
17
+ .then(resultJson => {
18
+ const form = target.parentNode;
19
+ const hint = form.querySelector('span.inline-form-hint');
20
+ if (hint) {
21
+ hint.remove();
22
+ };
23
+
24
+ if (resultJson.status === 'error') {
25
+ form.dispatchEvent(createEvent('inlineEditError', resultJson));
26
+
27
+ form.classList.add('invalid-value');
28
+ if (resultJson.message) {
29
+ form.insertAdjacentHTML('beforeend',
30
+ "<span class='inline-form-hint'>" + resultJson.message + "</span>"
31
+ );
32
+ }
33
+ } else {
34
+ const container = form.parentNode;
35
+ let clicableItem = container.querySelector('.clickable-item');
36
+
37
+ form.dispatchEvent(createEvent('inlineEditSuccess', resultJson))
38
+
39
+ form.classList.remove('invalid-value');
40
+ clicableItem.innerHTML = '';
41
+ clicableItem.insertAdjacentHTML('beforeend', resultJson.html);
42
+ toggleVisibility(container);
43
+ }
44
+ })
45
+ .catch(function(error) {
46
+ console.log('Request failed', error)
47
+ });
48
+ });
49
+ });
50
+
51
+ document.querySelectorAll('.clickable-item').forEach(item => {
52
+ item.addEventListener("click", function(e){
53
+ const container = e.target.closest('.inline-editor-container');
54
+ toggleVisibility(container);
55
+ })
56
+
57
+ document.querySelector('body').addEventListener('click', function(e){
58
+ const activeForm = document.querySelector('.form.active');
59
+ const container = e.target.closest('.inline-editor-container')
60
+
61
+ if (activeForm && !(e.target.closest('.inline-editor-container'))) {
62
+ activeForm.classList.remove('active');
63
+ activeForm.classList.add('display-none');
64
+ activeForm.previousElementSibling.classList.remove('display-none');
65
+ }
66
+ });
67
+ });
68
+
69
+ function toggleVisibility(container) {
70
+ container.querySelectorAll('.clickable-item, .form').forEach(item => {
71
+ item.classList.toggle('display-none');
72
+ })
73
+
74
+ container.querySelector('.form').classList.toggle('active');
75
+ }
76
+
77
+ function createEvent(name, params) {
78
+ return event = new CustomEvent(name, {
79
+ detail: params,
80
+ bubbles: true,
81
+ cancelable: true
82
+ });
83
+ }
84
+ });
@@ -0,0 +1,69 @@
1
+ .inline-editor-container .display-none {
2
+ display: none;
3
+ }
4
+
5
+
6
+ .inline-editor-container .clickable-item {
7
+ cursor: pointer;
8
+ position: relative;
9
+ padding: 5px;
10
+ border: 2px solid transparent;
11
+ }
12
+
13
+ .inline-editor-container .clickable-item:after {
14
+ content: '';
15
+ background: url('icon-edit.svg') no-repeat 97% center;
16
+ display: block;
17
+ position: absolute;
18
+ width: 100%;
19
+ height: 100%;
20
+ right: 2px;
21
+ top: -2px;
22
+ padding: 1px;
23
+ border: 1px dashed #ccc;
24
+ visibility: hidden;
25
+ }
26
+
27
+ .inline-editor-container .clickable-item:hover:after {
28
+ visibility: visible;
29
+ }
30
+
31
+ .inline-editor-container .form {
32
+ width: 100%;
33
+ }
34
+
35
+ .inline-editor-container .clickable-item .with-label .label{
36
+ background: #1c9c14;
37
+ padding: 1px 3px;
38
+ border-radius: 3px;
39
+ font-size: 10px;
40
+ margin-left: 5px;
41
+ color: #fff;
42
+ }
43
+
44
+ .inline-editor-container .form.active.invalid-value * {
45
+ border-color: #ff0000;
46
+ }
47
+
48
+ .inline-editor-container .form.active.invalid-value span.inline-form-hint {
49
+ color: #ff0000;
50
+ font-size: 12px;
51
+ }
52
+
53
+ .inline-editor-container .form select {
54
+ width: 100%;
55
+ border: solid 2px #000;
56
+ padding: 5px 25px 5px 3px;
57
+ font-size: 16px;
58
+ font-family: "Times New Roman", Times, serif;
59
+ position: relative;
60
+ color: #000;
61
+ -webkit-appearance: none;
62
+ -moz-appearance: none;
63
+ -ms-appearance: none;
64
+ -o-appearance: none;
65
+ appearance: none;
66
+ box-shadow: none;
67
+ background: url('dropdown-arrow.svg') right no-repeat;
68
+ background-position: calc(100% - 5px) 50%;
69
+ }
@@ -0,0 +1,19 @@
1
+ <div class="inline-editor-container">
2
+ <div class='clickable-item'>
3
+ <%= raw text %>
4
+ </div>
5
+ <div class='form display-none'>
6
+
7
+ <%- if local_assigns[:as] == :select %>
8
+ <%= select_tag '', options_for_select(collection, value),
9
+ class: 'form-control select', include_blank: include_blank, data: { url: save_url, param: param }
10
+ %>
11
+ <% end %>
12
+
13
+ <%- if local_assigns[:as] == :grouped_select %>
14
+ <%= select_tag '', grouped_options_for_select(collection, value),
15
+ class: 'form-control select', include_blank: include_blank, data: { url: save_url, param: param }
16
+ %>
17
+ <% end %>
18
+ </div>
19
+ </div>
@@ -0,0 +1,21 @@
1
+ module InlineEditor
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ isolate_namespace InlineEditor
5
+
6
+ initializer 'inline_editor.assets_precompile', group: :all do |app|
7
+ app.config.assets.precompile += ['inline_editor/inline_editor.js', 'inline_editor/inline_editor.css']
8
+ end
9
+
10
+ initializer 'inline_editor.helpers' do
11
+ ActiveSupport.on_load :action_view do
12
+ ActionView::Base.send :include, InlineEditor::ApplicationHelper
13
+ end
14
+ end
15
+
16
+ config.generators do |g|
17
+ g.test_framework :rspec
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ module InlineEditor
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module InlineEditor
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,12 @@
1
+ require "inline_editor/engine"
2
+
3
+ module InlineEditor
4
+ module ApplicationHelper
5
+ def inline_editor(as: '', text: '', collection: '', value: '', include_blank: '', save_url: '', param: '', &block)
6
+ text = capture(&block) if block_given?
7
+
8
+ render 'inline_editor/inline_editor', as: as, text: text, collection: collection, value: value,
9
+ include_blank: include_blank, save_url: save_url, param: param
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :inline_editor do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inline_editor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ShevchukTania
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mini_racer
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 1.3.6
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '1.3'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.3.6
61
+ description: Simple inline editor for Rails applications
62
+ email:
63
+ - taniabeley@ukr.net
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - MIT-LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - app/assets/javascripts/inline_editor.js
72
+ - app/assets/stylesheets/inline_editor.css
73
+ - app/views/inline_editor/_inline_editor.erb
74
+ - lib/inline_editor.rb
75
+ - lib/inline_editor/engine.rb
76
+ - lib/inline_editor/railtie.rb
77
+ - lib/inline_editor/version.rb
78
+ - lib/tasks/inline_editor_tasks.rake
79
+ homepage: https://github.com/ShevchukTania/inline_editor
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubygems_version: 3.0.6
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Inline editor for Rails applications
102
+ test_files: []