From 97ed3186965b8d89dae48e5aa072038499523ac7 Mon Sep 17 00:00:00 2001 From: Torsten Date: Fri, 9 Dec 2022 17:16:26 +0200 Subject: [PATCH] forms as sections with cards, error and app handling --- app/controllers/merged/form_controller.rb | 66 ++++++++++++++++++++ app/helpers/merged/merged_helper.rb | 2 +- app/views/merged/form/form.haml | 9 +++ app/views/merged/view/_form_section.haml | 11 +++- app/views/merged/view/cards/_form_field.haml | 4 +- config/merged/option.yaml | 14 ++++- config/merged/section_style.yaml | 2 + config/routes.rb | 2 + 8 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 app/controllers/merged/form_controller.rb create mode 100644 app/views/merged/form/form.haml diff --git a/app/controllers/merged/form_controller.rb b/app/controllers/merged/form_controller.rb new file mode 100644 index 0000000..62f8bed --- /dev/null +++ b/app/controllers/merged/form_controller.rb @@ -0,0 +1,66 @@ +module Merged + class FormController < MergedController + + def sendit + @section = Section.find( params[:section_id] ) + @errors = { } + return if bot_alert + check_maths + verify_data + if( @errors.length > 0) + render :form + else + dispatch_form_data( ) + redirect_to main_app.root_url , notice: @section.option("ok_message") + end + end + + private + + def dispatch_form_data + puts "Dispatch data" + data = {} + @section.cards.each do |card| + data[card.header] = params[card.header] + end + if(@section.has_option?("handler") ) + puts "Sending data" + @section.option("handler").constantize.new.handle_form(@section, data) + end + end + + def verify_data + @section.cards.each do |card| + check_option( card , params[card.header]) + end + end + def check_option(card , value) + return unless value.blank? + puts "Checking #{card.header} #{value}" + compulsory = card.option("compulsory") == "yes" + return unless compulsory + # check different types + @errors[card.header] = "May not be blank" + end + + def check_maths + key = params[:bot_fudder].to_i / 2 + if( (2*key + 1).to_s != params[:challenge]) + @errors[:challenge] = "Check the maths #{key.to_i} #{params[:challenge]}" + end + end + + def bot_alert + if @section.nil? + head :ok + return true + end + key = params[:bot_fudder] + if key.to_i.to_s != key + head :ok + return true + end + return false + end + end +end diff --git a/app/helpers/merged/merged_helper.rb b/app/helpers/merged/merged_helper.rb index e9e6697..ad38690 100644 --- a/app/helpers/merged/merged_helper.rb +++ b/app/helpers/merged/merged_helper.rb @@ -3,7 +3,7 @@ require "redcarpet" module Merged module MergedHelper @@renderer = nil - + def renderer return @@renderer unless @@renderer.nil? options = {hard_wrap: true , autolink: true, no_intra_emphasis: true , diff --git a/app/views/merged/form/form.haml b/app/views/merged/form/form.haml new file mode 100644 index 0000000..2681d61 --- /dev/null +++ b/app/views/merged/form/form.haml @@ -0,0 +1,9 @@ +.flex.flex-col.m-20 + .flex.items-center.justify-center.flex-1 + - @errors.each do |name , message| + .m-5.rounded.border-l-4.border-green-500.bg-red-50.p-4 + %strong.font-medium.text-red-700= name.capitalize + .mt-2.text-sm.text-red-700= message + +- template = find_template(@section) += render( template , section: @section) diff --git a/app/views/merged/view/_form_section.haml b/app/views/merged/view/_form_section.haml index 0d90c81..1e6a452 100644 --- a/app/views/merged/view/_form_section.haml +++ b/app/views/merged/view/_form_section.haml @@ -6,9 +6,16 @@ = markdown(section) .flex.items-center.justify-start.bg-white .mx-auto.w-full.max-w-4xl{class: "max-w-[50%]"} - %form.mt-10{:action => "https://api.web3forms.com/submit"} + = form_tag( form_sendit_path , {class: "mt-10" }) do + - challenge = rand(8) + = hidden_field_tag :section_id , section.id + = hidden_field_tag :bot_fudder , "#{challenge*2}" .grid.gap-6.md:grid-cols-2 - template = "merged/view/cards/" + section.card_template - section.cards.each do |card| = render( template , card: card) - %button.mt-5.rounded-md.bg-cyan-700.px-10.py-2.text-white{:type => "submit"} Send + .grid.gap-6.md:grid-cols-2 + .relative.z-0.mt-10 + %input.peer.block.w-full.appearance-none.border-0.border-b.border-gray-500.bg-transparent.px-0.text-sm.text-gray-900.focus:border-blue-600.focus:outline-none.focus:ring-0{:class => "py-2.5", :name => "challenge", :placeholder => " ", :type => "text"} + %label.absolute.top-3.-z-10.-translate-y-6.scale-75.transform.text-sm.text-gray-500.duration-300.peer-placeholder-shown:translate-y-0.peer-placeholder-shown:scale-100.peer-focus:left-0.peer-focus:-translate-y-6.peer-focus:scale-75.peer-focus:text-blue-600.peer-focus:dark:text-blue-500{:class => "origin-[0]"}Anti bot question: #{challenge} + #{challenge + 1} is + %button.mt-10.rounded-md.bg-cyan-700.px-20.py-2.text-white{:type => "submit"} Send diff --git a/app/views/merged/view/cards/_form_field.haml b/app/views/merged/view/cards/_form_field.haml index 2c4f343..830917f 100644 --- a/app/views/merged/view/cards/_form_field.haml +++ b/app/views/merged/view/cards/_form_field.haml @@ -1,8 +1,8 @@ -if card.option("form_type") == "message" .relative.z-0.col-span-2 - %textarea.peer.block.w-full.appearance-none.border-0.border-b.border-gray-500.bg-transparent.px-0.text-sm.text-gray-900.focus:border-blue-600.focus:outline-none.focus:ring-0{:class => "py-2.5", :name => "message", :placeholder => " ", :rows => "5"} + %textarea.peer.block.w-full.appearance-none.border-0.border-b.border-gray-500.bg-transparent.px-0.text-sm.text-gray-900.focus:border-blue-600.focus:outline-none.focus:ring-0{:class => "py-2.5", :name => card.header, :placeholder => " ", :rows => "5"}=params[card.header] %label.absolute.top-3.-z-10.-translate-y-6.scale-75.transform.text-sm.text-gray-500.duration-300.peer-placeholder-shown:translate-y-0.peer-placeholder-shown:scale-100.peer-focus:left-0.peer-focus:-translate-y-6.peer-focus:scale-75.peer-focus:text-blue-600.peer-focus:dark:text-blue-500{:class => "origin-[0]"}= card.header -else .relative.z-0 - %input.peer.block.w-full.appearance-none.border-0.border-b.border-gray-500.bg-transparent.px-0.text-sm.text-gray-900.focus:border-blue-600.focus:outline-none.focus:ring-0{:class => "py-2.5", :name => "email", :placeholder => " ", :type => "text"} + %input.peer.block.w-full.appearance-none.border-0.border-b.border-gray-500.bg-transparent.px-0.text-sm.text-gray-900.focus:border-blue-600.focus:outline-none.focus:ring-0{:class => "py-2.5", :name => card.header, :placeholder => " " , "value" => params[card.header], :type => "text"} %label.absolute.top-3.-z-10.-translate-y-6.scale-75.transform.text-sm.text-gray-500.duration-300.peer-placeholder-shown:translate-y-0.peer-placeholder-shown:scale-100.peer-focus:left-0.peer-focus:-translate-y-6.peer-focus:scale-75.peer-focus:text-blue-600.peer-focus:dark:text-blue-500{:class => "origin-[0]"}= card.header diff --git a/config/merged/option.yaml b/config/merged/option.yaml index 81c945e..ab39d6c 100644 --- a/config/merged/option.yaml +++ b/config/merged/option.yaml @@ -70,11 +70,21 @@ - name: compulsory desciption: Form fields may be compulsory or not. By default they are. - values: on off - default: off + values: yes no + default: yes - name: form_type desciption: Form fields may have a type for special handling. The default is text but message would be a longer text, and email checked to be a name. values: text message email phone date default: text +- name: ok_message + desciption: + Message shown to the user when a form was submitted + values: + default: +- name: handler + desciption: + Form handler + values: FormHandler + default: FormHandler diff --git a/config/merged/section_style.yaml b/config/merged/section_style.yaml index ca7682f..6835013 100644 --- a/config/merged/section_style.yaml +++ b/config/merged/section_style.yaml @@ -82,5 +82,7 @@ - header - text options: + - ok_message + - handler - background - color diff --git a/config/routes.rb b/config/routes.rb index cdeef69..8849894 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,6 +4,8 @@ Merged::Engine.routes.draw do post 'changes/commit' get "styles/index" + post 'form/sendit' + resources :pages , except: [:show , :new] , shallow: true do resources :sections do get :select_image