alchemy-ajax-form 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +310 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/config/alchemy_ajax_form_manifest.js +3 -0
  6. data/app/assets/images/ajax_form.png +0 -0
  7. data/app/assets/images/alchemy/ajax_form.png +0 -0
  8. data/app/assets/javascripts/ajax_forms.js.erb +185 -0
  9. data/app/controllers/alchemy/admin/ajax_forms_controller.rb +53 -0
  10. data/app/controllers/alchemy/ajax_forms_controller.rb +34 -0
  11. data/app/mailers/alchemy/ajax_forms_mailer.rb +42 -0
  12. data/app/models/alchemy/ajax_form.rb +68 -0
  13. data/app/models/alchemy/ajax_form_ability.rb +22 -0
  14. data/app/views/alchemy/admin/ajax_forms/_table.html.erb +22 -0
  15. data/app/views/alchemy/ajax_forms/create.json.jbuilder +6 -0
  16. data/app/views/alchemy/ajax_forms_mailer/mjml_notify_message.mjml.erb +1 -0
  17. data/app/views/alchemy/ajax_forms_mailer/mjml_notify_user_message.mjml.erb +1 -0
  18. data/app/views/alchemy/ajax_forms_mailer/notify_message.html.erb +1 -0
  19. data/app/views/alchemy/ajax_forms_mailer/notify_user_message.html.erb +1 -0
  20. data/app/views/layouts/alchemy/base_mailer.html.erb +323 -0
  21. data/app/views/layouts/alchemy/mjml_base_mailer.mjml +23 -0
  22. data/config/initializer/assets.rb +1 -0
  23. data/config/locales/it.yml +56 -0
  24. data/config/routes.rb +4 -0
  25. data/lib/alchemy/ajax/form.rb +18 -0
  26. data/lib/alchemy/ajax/form/engine.rb +21 -0
  27. data/lib/alchemy/ajax/form/version.rb +7 -0
  28. data/lib/alchemy/ajax_form_resource.rb +45 -0
  29. data/lib/generators/custom_form/USAGE +8 -0
  30. data/lib/generators/custom_form/custom_form_generator.rb +191 -0
  31. data/lib/generators/custom_form/templates/app/controllers/admin/generic_controller.rb.tt +3 -0
  32. data/lib/generators/custom_form/templates/app/controllers/generic_controller.rb.tt +3 -0
  33. data/lib/generators/custom_form/templates/app/lib/generic_resource.rb.tt +4 -0
  34. data/lib/generators/custom_form/templates/app/model/generic_ability.rb.tt +18 -0
  35. data/lib/generators/custom_form/templates/app/model/generic_form.rb.tt +15 -0
  36. data/lib/generators/custom_form/templates/app/views/alchemy/ajax_forms_mailer/_generic_form.html.erb.tt +38 -0
  37. data/lib/generators/custom_form/templates/app/views/alchemy/ajax_forms_mailer/_generic_user_form.html.erb.tt +39 -0
  38. data/lib/generators/custom_form/templates/app/views/alchemy/elements/_generic_ajax_form_view.html.erb.tt +50 -0
  39. data/lib/generators/custom_form/templates/config/initializers/alchemy_ajax_forms.rb.tt +26 -0
  40. data/lib/generators/custom_form/templates/db/migrate/generic_migration.rb.tt +12 -0
  41. data/lib/tasks/alchemy/ajax/form_tasks.rake +4 -0
  42. metadata +182 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 45ab672b66d4ffa39f450d9a4ad2eb4f1e1b8534
4
+ data.tar.gz: cca6ea5eb17fac0519450621a80d96b2b4148d1d
5
+ SHA512:
6
+ metadata.gz: 11917022577519167aca018ce66bd2c0192bd67dfdbd92643f6ed9986b377f77e51478d7ba16444df88468dc07829b9dde9b919ed63f47b51190995735b4d2f4
7
+ data.tar.gz: ccc002dd2b745626230d24a148a62bef65d8481a0c33d2af53d135e8ad1b3a8dcfd438425c1273b7fa97b7dbbdb81025cbf238183399ed2a6ddfc2a796fef771
@@ -0,0 +1,20 @@
1
+ Copyright 2018 Alessandro Baccanelli
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.
@@ -0,0 +1,310 @@
1
+ # Alchemy::Ajax::Form
2
+ A gem for semplify form creations in alchemy.
3
+
4
+ ## Installation
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'alchemy-ajax-form', github: "ArchimediaZerogroup/alchemy-ajax-form"
9
+ ```
10
+
11
+ And then execute:
12
+ ```bash
13
+ $ bundle install
14
+ ```
15
+
16
+ Or install it yourself as:
17
+ ```bash
18
+ $ gem install alchemy-ajax-form
19
+ ```
20
+
21
+ install mjml 4.1.0 with npm globally (with sudo if necessary)
22
+ ```bash
23
+ $ npm install mjml@4.1.0 -g
24
+ ```
25
+
26
+
27
+ ## Usage
28
+ Launch the generator with this command:
29
+ ```bash
30
+ $ bin/rails generate custom_form name_of_form param:type
31
+ ```
32
+ example:
33
+ ```bash
34
+ $ bin/rails generate custom_form contact_form email:string firstname:string lastname:string message:text
35
+ ```
36
+
37
+ Ansawer to the questions step by step
38
+
39
+ Configure element in layoutpage
40
+
41
+ Restart Server
42
+
43
+ ### How use without generator
44
+ If you don't wont use the generator you have to follow these steps:
45
+
46
+ Let's assume we want to create the form "ContactForm"
47
+
48
+ #### Create Admin Controller
49
+
50
+ Create Admin::ContactFormsController (/app/controllers/admin/contact_forms_controller.rb)
51
+
52
+ ```ruby
53
+ class Admin::ContactFormsController < Alchemy::Admin::AjaxFormsController
54
+
55
+ end
56
+ ```
57
+
58
+ #### Create Controller
59
+ Create ContactFormsController (/app/controllers/admin/contact_forms_controller.rb)
60
+
61
+ ```ruby
62
+ class ContactFormsController < Alchemy::AjaxFormsController
63
+
64
+ end
65
+ ```
66
+
67
+ #### Create Resource
68
+ Create ContactFormResource (app/lib/contact_form_resource.rb)
69
+
70
+ ```ruby
71
+ class ContactFormResource < Alchemy::AjaxFormResource
72
+
73
+ end
74
+ ```
75
+
76
+ #### Create Model
77
+ Create ContactForm (app/models/contact_form.rb)
78
+
79
+ ```ruby
80
+ class ContactForm < Alchemy::AjaxForm
81
+
82
+ validates :check_privacy, inclusion: [true, '1']
83
+
84
+
85
+ def notify_subject
86
+ I18n.translate(:contact_form_notify, scope: [:ajax_form_mailer, :subjects])
87
+ end
88
+
89
+ def notify_user_subject
90
+ I18n.translate(:contact_form_user_notify, scope: [:ajax_form_mailer, :subjects])
91
+ end
92
+
93
+
94
+ end
95
+ ```
96
+
97
+ #### Create Ability
98
+ Create ContactFormAbility (app/models/contact_form_ability.rb)
99
+
100
+ ```ruby
101
+ class ContactFormAbility
102
+ include CanCan::Ability
103
+
104
+ def initialize(user)
105
+ if user.present? && user.is_admin?
106
+ can :manage, ContactForm
107
+ cannot :create, ContactForm
108
+ cannot :update, ContactForm
109
+ can :manage, :admin_contact_forms
110
+ cannot :create, :admin_contact_forms
111
+ cannot :update, :admin_contact_forms
112
+ end
113
+ end
114
+
115
+ end
116
+ ```
117
+
118
+ #### Create Migration
119
+ Create CreateContactForm (db/migrate/%Y%m%d%H%M%Screate_contact_form.rb)
120
+
121
+ ```ruby
122
+ class CreateContactForm < ActiveRecord::Migration[5.2]
123
+ def change
124
+ create_table :contact_forms do |t|
125
+
126
+ # insert all form fields
127
+
128
+ t.boolean :check_privacy
129
+ t.references :language, index: true
130
+ t.timestamps
131
+ end
132
+ end
133
+ end
134
+ ```
135
+
136
+ #### Create Element Configuration
137
+ Insert into file "config/alchemy/elements.yml"
138
+
139
+ ```yaml
140
+ - name: contact_form
141
+ hint: false
142
+ contents:
143
+ - name: privacy_page
144
+ type: EssenceText
145
+ settings:
146
+ linkable: true
147
+ - name: recipient_notification
148
+ type: EssenceText
149
+ default: "example@example.it"
150
+ - name: send_only
151
+ type: EssenceBoolean
152
+ - name: send_staff
153
+ type: EssenceBoolean
154
+ - name: send_user
155
+ type: EssenceBoolean\n
156
+
157
+ ```
158
+
159
+ #### Create Element View
160
+ Create contact form view "app/views/alchemy/elements/_contact_form_view.html.erb"
161
+
162
+ ```erbruby
163
+ <% cache(element) do %>
164
+ <%= element_view_for(element) do |el| -%>
165
+
166
+
167
+ <%
168
+ privacy_link = element.content_by_name(:privacy_page).essence.link
169
+ privacy_title = element.content_by_name(:privacy_page).essence.body
170
+ @contact_form = ContactForm.new
171
+ @contact_form.alcm_element = element.id
172
+ %>
173
+
174
+
175
+ <div class="messages"></div>
176
+
177
+
178
+ <%= form_for(@contact_form, url: main_app.contact_forms_path, method: :post, remote: true, multipart: true,html:{class: "ajax_forms"}) do |f| %>
179
+ <%= f.hidden_field :alcm_element %>
180
+ <div class="row">
181
+ #list of attributes
182
+ </div>
183
+
184
+ <% if !privacy_title.blank? %>
185
+ <div class="privacy">
186
+ <div class="single_privacy">
187
+ <%= f.check_box :check_privacy %>
188
+ <%= link_to privacy_link do %>
189
+ <label><%= privacy_title %></label>
190
+ <% end %>
191
+ </div>
192
+ </div>
193
+ <% else %>
194
+ <%= f.check_box :check_privacy %>
195
+ <% end %>
196
+
197
+
198
+ <div class="submit">
199
+ <%= f.submit t(:submit) %>
200
+ </div>
201
+
202
+ <% end %>
203
+
204
+
205
+
206
+ <%- end -%>
207
+ <%- end -%>
208
+ ```
209
+
210
+ #### Create or add entry to initializer
211
+
212
+ Create or edit alchemy_ahax_forms initializer ( config/initializers/alchemy_ajax_forms.rb)
213
+
214
+ ```ruby
215
+ Alchemy::Modules.register_module({
216
+ name: 'alchemy_ajax_forms',
217
+ order: 1,
218
+ navigation: {
219
+ name: 'modules.contact_forms',
220
+ controller: '/admin/contact_forms',
221
+ action: 'index',
222
+ image: 'alchemy/ajax_form.png',
223
+ sub_navigation: [
224
+ {
225
+ name: 'modules.contact_forms',
226
+ controller: '/admin/contact_forms',
227
+ action: 'index'
228
+ },
229
+ ]
230
+ }
231
+ })
232
+
233
+ Alchemy.register_ability(ContactFormAbility)
234
+
235
+ module Alchemy
236
+
237
+ EMAIL_NOTIFY= "example@example.it"
238
+ EMAIL_NOTIFY_FROM = "no-reply@example.it"
239
+
240
+ end
241
+ ```
242
+
243
+ If you add multiple form add only:
244
+ ```ruby
245
+ {
246
+ name: 'modules.contact_forms',
247
+ controller: '/admin/contact_forms',
248
+ action: 'index'
249
+ }
250
+ ```
251
+ and ability
252
+ ```ruby
253
+ Alchemy.register_ability(ContactFormAbility)
254
+ ```
255
+
256
+ #### Create Mail Template
257
+
258
+ Create email template ()app/views/alchemy/ajax_forms_mailer/_contact_form.mjml)
259
+ Create email template for user notification ()app/views/alchemy/ajax_forms_mailer/_contact_form_user.mjml)
260
+
261
+ ```ruby
262
+ <mj-column>
263
+ <mj-text align="left" color="#55575d" font-family="Arial, sans-serif" font-size="13px" line-height="22px" padding-bottom="0px" padding-top="5px" padding="10px 25px">
264
+ <p style="line-height: 16px; text-align: center; margin: 10px 0;font-size:12px;color:#000;font-family:'Times New Roman',Helvetica,Arial,sans-serif">
265
+ <span><b>attribute name:</b></span>
266
+ <span><%= rec.attribute_name %></span>
267
+ </p>
268
+ </mj-text>
269
+ </mj-column>
270
+ ```
271
+
272
+ #### Add Routes
273
+ Add right routes
274
+
275
+ ```ruby
276
+ namespace :admin do
277
+ resources :contact_forms
278
+
279
+ end
280
+ resources :contact_forms , only: [:create]
281
+ ```
282
+
283
+ #### Require assets
284
+ Add to app/assets/javascripts/application.js
285
+
286
+ ```ruby
287
+ //= require jquery3
288
+ //= require ajax_forms
289
+ ```
290
+
291
+ ### Run Migration
292
+ Run migration with rake task
293
+
294
+ ```bash
295
+ $ bin/rake db:migrate
296
+ ```
297
+
298
+ Configure element in layoutpage
299
+
300
+ Restart Server
301
+
302
+ ## Translations
303
+ Remember to check translations
304
+
305
+
306
+ ## Contributing
307
+ Contribution directions go here.
308
+
309
+ ## License
310
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,36 @@
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 = 'Alchemy::Ajax::Form'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ require 'bundler/gem_tasks'
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'test'
31
+ t.pattern = 'test/**/*_test.rb'
32
+ t.verbose = false
33
+ end
34
+
35
+
36
+ task default: :test
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
@@ -0,0 +1,185 @@
1
+ (function ($) {
2
+
3
+ var recaptha_disabled = <%= Recaptcha.configuration.skip_verify_env.include?(Rails.env.to_s ) %>
4
+
5
+
6
+ var print_results = function (element, result) {
7
+ if (result instanceof Array) {
8
+ var resp = "";
9
+
10
+ $.each(result, function (index, value) {
11
+
12
+ resp += "<span>" + value + "</span>";
13
+
14
+ });
15
+
16
+ } else {
17
+ resp = result
18
+ }
19
+
20
+ resp = '<div class="default_message">' + resp + '</div>';
21
+ $(element).append(resp);
22
+
23
+ };
24
+
25
+ var add_errors = function (form, errors) {
26
+
27
+ $.each(errors, function (name, value) {
28
+
29
+ var input = $(form).find("[name*='" + name + "']");
30
+
31
+
32
+ $(input).addClass("invalid");
33
+
34
+ if ($(input).parent().children('.error-message').length == 0) {
35
+ $(input).parent().append("<span class='error-message'>" + value + "</span>");
36
+ } else {
37
+ $('.error-message').show();
38
+ }
39
+
40
+ });
41
+ };
42
+
43
+
44
+ var clear_deafult_message = function (form) {
45
+ var message_box = $(form).parent().find(".messages")[0];
46
+ var default_message = $(message_box).find(".default_message");
47
+ var custom_message = $(message_box).find(".custom_message");
48
+ if ($(default_message).length > 0) {
49
+ $(default_message).remove();
50
+ }
51
+
52
+ if ($(custom_message).length == 0) {
53
+ $(message_box).html("");
54
+ }
55
+ }
56
+
57
+
58
+ var add_loader = function (form) {
59
+ if ($(form).children('.ajax_forms_loader').length == 0) {
60
+ $(form).append('<div class="ajax_forms_loader"> <i class="fa fa-circle-o-notch fa-spin"></i> </div>');
61
+ } else {
62
+ $(form).children('.ajax_forms_loader').fadeIn();
63
+ }
64
+ }
65
+
66
+ var hide_loader = function (form) {
67
+ $(form).children('.ajax_forms_loader').fadeOut();
68
+ }
69
+
70
+ var submit_function = function (form, method, action) {
71
+ $(form).trigger("submitted");
72
+ add_loader(form);
73
+
74
+ if ($(form).find("[name='_dontcare']").length < 1) {
75
+ $(form).append("<input type=\"hidden\" name=\"_dontcare\">")
76
+ }
77
+
78
+ var formdata = new FormData($(form)[0])
79
+ $.ajax({
80
+ method: method,
81
+ url: action,
82
+ dataType: "json",
83
+ data: formdata,
84
+ contentType: false,
85
+ processData: false,
86
+ success: function (response, status, xhr) {
87
+
88
+ clear_deafult_message(form);
89
+ var message_box = $(form).parent().find(".messages")[0];
90
+ if (!$(message_box).find(".custom_message").length > 0) {
91
+ print_results(message_box, response.messages);
92
+ }
93
+
94
+ $(form).trigger("successed");
95
+ $(message_box).addClass('ok');
96
+ $(form).trigger("reset");
97
+
98
+ },
99
+ error: function (xhr, status, errorThrown) {
100
+ var response = JSON.parse(xhr.responseText);
101
+ var message_box = $(form).parent().find(".messages")[0];
102
+ clear_deafult_message(form);
103
+ print_results(message_box, response.messages);
104
+ $(form).trigger("failed", [xhr, status, errorThrown]);
105
+ $(message_box).addClass('ko');
106
+ add_errors(form, response.errors);
107
+
108
+ },
109
+ complete: function () {
110
+ if (!recaptha_disabled) {
111
+ grecaptcha.reset();
112
+ }
113
+ $(form).find("input[type='submit']").attr("disabled", false);
114
+ hide_loader(form);
115
+ }
116
+ });
117
+ }
118
+
119
+ load_invisible_recaptcha = function () {
120
+
121
+
122
+ $(document).ready(function () {
123
+
124
+
125
+
126
+ $(".ajax_forms").each(function (element, index) {
127
+
128
+ var form = this;
129
+ var action = $(this).attr("action");
130
+ var method = $(this).attr("method");
131
+ var submit_button = $(form).find(".submit").last();
132
+
133
+
134
+ if (!recaptha_disabled) {
135
+ var container_div = $('<div class="invisible_recaptcha_container"></div>');
136
+ $(submit_button).before(container_div);
137
+
138
+ var widget_id = grecaptcha.render(container_div[0], {
139
+ 'sitekey': '<%= Recaptcha.configuration.site_key! %>',
140
+ 'badge': 'inline',
141
+ 'size': 'invisible',
142
+ 'callback': function () {
143
+ submit_function(form, method, action);
144
+ }
145
+ });
146
+
147
+ $(form).data("widget-id",widget_id)
148
+
149
+ }
150
+
151
+ $(form).children('.ajax_forms_loader').fadeOut();
152
+ });
153
+
154
+ $(document).on("submit", ".ajax_forms", function (event) {
155
+
156
+ event.preventDefault ? event.preventDefault() : (event.returnValue = false);
157
+
158
+ var form = $(event.target);//.closest("form");
159
+ var action = $(form).attr("action");
160
+ var method = $(form).attr("method");
161
+ var widget_id = $(form).data("widget-id");
162
+ // disable all submit buttons
163
+ $(form).find("input[type='submit']").attr("disabled", true)
164
+
165
+
166
+ if (!recaptha_disabled) {
167
+ grecaptcha.execute(widget_id)
168
+ } else {
169
+ submit_function(form, method, action);
170
+ }
171
+
172
+
173
+ });
174
+
175
+ $('.ajax_forms').on('change', '.invalid', function () {
176
+ $(this).removeClass("invalid");
177
+ $(this).parent().children('.error-message').hide();
178
+ });
179
+
180
+ });
181
+ };
182
+ $.getScript("//www.google.com/recaptcha/api.js?onload=load_invisible_recaptcha&render=explicit")
183
+
184
+
185
+ })(jQuery);