From e46e68cc22f5aa3a821af07e13c045d7d9115bdc Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sun, 12 Apr 2020 00:59:43 +0200 Subject: [PATCH 01/11] Add demo page The demo page shows a form and an embedded google sheet side by side. The form needs be be configured with a DEMO_FORM_ID environment variable. --- app/assets/config/manifest.js | 2 +- app/assets/stylesheets/application.css.scss | 17 +---- app/assets/stylesheets/demo.css.scss | 16 +++++ app/javascript/demo.js | 9 +++ app/javascript/packs/application.js | 2 + app/javascript/tinyforms.js | 51 ++++++++++++++ app/models/form.rb | 4 +- app/views/home/demo.html.erb | 77 +++++++++++++++++++++ config/initializers/demo.rb | 1 + config/routes.rb | 2 + 10 files changed, 163 insertions(+), 18 deletions(-) create mode 100644 app/assets/stylesheets/demo.css.scss create mode 100644 app/javascript/demo.js create mode 100644 app/javascript/tinyforms.js create mode 100644 app/views/home/demo.html.erb create mode 100644 config/initializers/demo.rb diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index 5918193..1f88c80 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -1,2 +1,2 @@ //= link_tree ../images -//= link_directory ../stylesheets .css +//= link application.css diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index 0045e6f..8ec56d8 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -1,18 +1,3 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's - * vendor/assets/stylesheets directory can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the bottom of the - * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS - * files in this directory. Styles in this file should be added after the last require_* statement. - * It is generally better to create a new file per style scope. - * - *= require_tree . - *= require_self - */ @import "bulma/sass/utilities/initial-variables"; @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400&family=Lobster&family=Comfortaa:wght@400;500;600;700&display=swap'); @import url('https://use.fontawesome.com/releases/v5.12.0/css/all.css'); @@ -40,6 +25,8 @@ $light: #fff; @import 'bulma/bulma'; +@import './demo'; + .is-font-logo { font-family: 'Lobster', cursive; } diff --git a/app/assets/stylesheets/demo.css.scss b/app/assets/stylesheets/demo.css.scss new file mode 100644 index 0000000..af052b0 --- /dev/null +++ b/app/assets/stylesheets/demo.css.scss @@ -0,0 +1,16 @@ +section.demo { + height: 90vh; + min-height: 600px; +} +.demo-form { + border: 1px solid $grey-light; + padding: 1em; + height: 100%; +} +section.demo .container, section.demo .columns, section.demo .column { + height: 100%; +} +#demo-success { + text-align: center; + padding-top: 1em; +} diff --git a/app/javascript/demo.js b/app/javascript/demo.js new file mode 100644 index 0000000..77a530b --- /dev/null +++ b/app/javascript/demo.js @@ -0,0 +1,9 @@ +document.addEventListener('DOMContentLoaded', function() { + var demoForm = document.getElementById('demo-form'); + demoForm.addEventListener('tinyforms:submitted', function() { + var demoFields = document.getElementById('demo-fields'); + var demoSucess = document.getElementById('demo-success'); + demoFields.style.display = 'none'; + demoSucess.style.display = 'block'; + }); +}); diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 80561d9..fb7f3ef 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -9,6 +9,8 @@ require("@rails/activestorage").start() require("channels") require('burger_menu'); +require('tinyforms'); +require('demo'); // Uncomment to copy all static images under ../images to the output folder and reference // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) diff --git a/app/javascript/tinyforms.js b/app/javascript/tinyforms.js new file mode 100644 index 0000000..bcb446d --- /dev/null +++ b/app/javascript/tinyforms.js @@ -0,0 +1,51 @@ +window.tinyforms = { + init: function() { + var forms = document.querySelectorAll('form[data-tinyforms]'); + forms.forEach(function(form) { + form.addEventListener('submit', tinyforms.onSubmit); + }); + }, + + submitForm: function(form) { + return new Promise(function(resolve, reject) { + var action = form.getAttribute('action'); + var formData = new FormData(form); + + var xhr = new XMLHttpRequest(); + xhr.open('POST', action, true); + xhr.setRequestHeader("Accept", "application/json"); + xhr.onload = function () { + var response; + try { + response = JSON.parse(xhr.responseText); + } catch (e) { + response = xhr.responseText; + } + if (xhr.status >= 200 && xhr.status < 300) { + resolve(response); + } else { + reject(response); + } + }; + xhr.onerror = function() { + reject(xhr.responseText) + }; + xhr.send(formData); + }); + }, + + onSubmit: function(e) { + e.preventDefault(); + return tinyforms.submitForm(this) + .then((response) => { + this.dispatchEvent(new CustomEvent('tinyforms:submitted', {detail: { response: response }})); + }) + .catch((response) => { + this.dispatchEvent(new CustomEvent('tinyforms:error', {detail: { response: response }})); + }); + } +}; + +document.addEventListener('DOMContentLoaded', function() { + tinyforms.init(); +}); diff --git a/app/models/form.rb b/app/models/form.rb index a1a13ca..b4fa31b 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -13,11 +13,11 @@ class Form < ApplicationRecord # TODO: use counter_cache option on association def submissions_count - submissions.count + @submissions_count ||= submissions.count end def last_submission_date - submissions.order(created_at: :desc).first&.created_at + @last_submission_date ||= submissions.order(created_at: :desc).first&.created_at end def deactivate!(reason = nil) diff --git a/app/views/home/demo.html.erb b/app/views/home/demo.html.erb new file mode 100644 index 0000000..c1a2114 --- /dev/null +++ b/app/views/home/demo.html.erb @@ -0,0 +1,77 @@ +
+
+
+
+
+

Demo

+

+ This short form is connected to the embedded document on the right.
+ Submit the form and see the update of the document. +

+ + + +
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+ diff --git a/config/initializers/demo.rb b/config/initializers/demo.rb new file mode 100644 index 0000000..915b94c --- /dev/null +++ b/config/initializers/demo.rb @@ -0,0 +1 @@ +DEMO_FORM = Form.find_by(id: ENV['DEMO_FORM_ID']) diff --git a/config/routes.rb b/config/routes.rb index 5bc2fc6..b83fe22 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,9 +13,11 @@ Rails.application.routes.draw do # short URL for form page get '/s/:id/form' => 'forms#form', as: :form_submitter + get '/signup' => 'sessions#new', as: :signup # TODO: add proper signup page get '/login' => 'sessions#new', as: :login get '/logout' => 'sessions#destroy', as: :logout get '/auth' => 'sessions#auth', as: :auth + get '/demo' => 'home#demo', as: :demo root 'home#index' end From 3723284f0d2025e78467da22a2aa5949c0448c2a Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sun, 12 Apr 2020 01:11:16 +0200 Subject: [PATCH 02/11] Move header into separate partial This makes the files a bit smaller and easier to read. Also remove some HTML nesting which should not be necessary. --- app/views/layouts/_header.html.erb | 30 ++++++++++++++++ app/views/layouts/application.html.erb | 47 +++----------------------- 2 files changed, 35 insertions(+), 42 deletions(-) create mode 100644 app/views/layouts/_header.html.erb diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb new file mode 100644 index 0000000..a9fdd12 --- /dev/null +++ b/app/views/layouts/_header.html.erb @@ -0,0 +1,30 @@ + diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index ff250d1..b001690 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -11,49 +11,12 @@ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> - - -
+ - -
-
-
- -
-
- -
- <%= yield %> -
-
+ <%= render 'layouts/header' %> +
+ <%= yield %> +
From b5027d9a07175e2b119ca17c49ccf1a280d51348 Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sun, 12 Apr 2020 01:29:23 +0200 Subject: [PATCH 03/11] Add file upload to demo --- app/views/home/demo.html.erb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/views/home/demo.html.erb b/app/views/home/demo.html.erb index c1a2114..b07ff24 100644 --- a/app/views/home/demo.html.erb +++ b/app/views/home/demo.html.erb @@ -21,14 +21,14 @@
- +
- +
@@ -59,6 +59,13 @@
+
+ +
+ +
+
+
From 8b15aed445e0b21861112f0e5f33ebaf8e6b9f67 Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sun, 12 Apr 2020 10:06:39 +0200 Subject: [PATCH 04/11] Add link to demo google document --- app/views/home/demo.html.erb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/home/demo.html.erb b/app/views/home/demo.html.erb index b07ff24..bb03df9 100644 --- a/app/views/home/demo.html.erb +++ b/app/views/home/demo.html.erb @@ -5,8 +5,8 @@

Demo

- This short form is connected to the embedded document on the right.
- Submit the form and see the update of the document. + This short form is connected to the embedded <%= link_to 'document', DEMO_FORM.google_spreadsheet_url %> on the right.
+ Submit the form and see the update of the document in realtime.

From dfa621d0bc0e5ddf040c58f04b26560ef142a53c Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sun, 12 Apr 2020 16:50:17 +0200 Subject: [PATCH 05/11] Add submission response to event details in tinyforms.js This makes the submitted data more easily accessible --- app/controllers/submissions_controller.rb | 2 +- app/javascript/tinyforms.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 518a3eb..9d801af 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -14,7 +14,7 @@ class SubmissionsController < ApplicationController respond_to do |format| if @submission.save format.html { redirect_to(@form.thank_you_url) if @form.thank_you_url.present? } - format.json { render(json: { success: true, data: @submission.data }) } + format.json { render(json: { success: true, submission: @submission.data }) } else format.html { redirect_to(@form.thank_you_url) if @form.thank_you_url.present? } format.json { render(json: { error: @submission.errors }, status: 422) } diff --git a/app/javascript/tinyforms.js b/app/javascript/tinyforms.js index bcb446d..c1e242c 100644 --- a/app/javascript/tinyforms.js +++ b/app/javascript/tinyforms.js @@ -38,10 +38,10 @@ window.tinyforms = { e.preventDefault(); return tinyforms.submitForm(this) .then((response) => { - this.dispatchEvent(new CustomEvent('tinyforms:submitted', {detail: { response: response }})); + this.dispatchEvent(new CustomEvent('tinyforms:submitted', {detail: { submission: response.submission, response: response }})); }) .catch((response) => { - this.dispatchEvent(new CustomEvent('tinyforms:error', {detail: { response: response }})); + this.dispatchEvent(new CustomEvent('tinyforms:error', {detail: { submission: response.submission, response: response }})); }); } }; From c26fd593de121bfcc3f50c9d1e6d94b10fb45563 Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sun, 12 Apr 2020 16:50:54 +0200 Subject: [PATCH 06/11] Personalize thank you message in demo --- app/javascript/demo.js | 10 +++++++++- app/views/home/demo.html.erb | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/javascript/demo.js b/app/javascript/demo.js index 77a530b..09fee25 100644 --- a/app/javascript/demo.js +++ b/app/javascript/demo.js @@ -1,9 +1,17 @@ document.addEventListener('DOMContentLoaded', function() { var demoForm = document.getElementById('demo-form'); - demoForm.addEventListener('tinyforms:submitted', function() { + if (!demoForm) { + return; + } + + demoForm.addEventListener('tinyforms:submitted', function(e) { + console.log(e); + console.log(e.detail); + var name = document.getElementById('demo-submission-name'); var demoFields = document.getElementById('demo-fields'); var demoSucess = document.getElementById('demo-success'); demoFields.style.display = 'none'; demoSucess.style.display = 'block'; + name.innerText = e.detail.submission.Name; }); }); diff --git a/app/views/home/demo.html.erb b/app/views/home/demo.html.erb index bb03df9..dfbdac7 100644 --- a/app/views/home/demo.html.erb +++ b/app/views/home/demo.html.erb @@ -11,7 +11,7 @@