diff --git a/dist/js/modularity-form-builder-front.0dfdbebf.js b/dist/js/modularity-form-builder-front.0dfdbebf.js deleted file mode 100644 index 85956cbf..00000000 --- a/dist/js/modularity-form-builder-front.0dfdbebf.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}({2:function(e,t,n){"use strict";n.r(t);var o;(function(e){function t(){this.init(),this.handleEvents()}t.prototype.init=function(){e(".mod-form-collapse").each((function(t){e(this).nextUntil(":not(.mod-form-field)").hide()}))},t.prototype.handleEvents=function(){e("button",".mod-form-collapse").click(function(t){t.preventDefault(),e(".mod-form-collapse__icon > i",t.target).toggleClass("pricon-plus-o pricon-minus-o"),e(t.target).parents(".mod-form-collapse").nextUntil(":not(.mod-form-field)").each((function(){e(this).fadeToggle("fast")}))}.bind(this))},new t})(jQuery),function(e){var t={street_number:{name:"street",addressType:"short_name"},route:{name:"street",addressType:"short_name"},locality:{name:"city",addressType:"long_name"},postal_code:{name:"postal-code",addressType:"long_name"}};function n(){var e=document.getElementById("form-get-location");navigator.geolocation&&null!==e&&this.handleEvents()}n.prototype.handleEvents=function(){e("#form-get-location").click(function(n){n.preventDefault(),$target=e(n.target).parents('[class*="mod-form"]'),e(n.target).find(".pricon").removeClass().addClass("spinner spinner-dark"),navigator.geolocation.getCurrentPosition((function(o){var r=o.coords.latitude,i=o.coords.longitude,a=new google.maps.LatLng(r,i);(new google.maps.Geocoder).geocode({latLng:a},(function(e,n){var o=[];if(n==google.maps.GeocoderStatus.OK&&e[0])for(var r=0;r '+formbuilder.something_went_wrong+"")}))}.bind(this))},new n}(jQuery),function(e){function t(){this.handleRequired(),this.handleEvents()}t.prototype.handleRequired=function(){var t=e('[class*="mod-form"]');e("[conditional-target]:hidden",t).find("[required]").prop("required",!1).attr("hidden-required",!0),e("[conditional-target]:visible",t).find("[hidden-required]").prop("required",!0)},t.prototype.handleEvents=function(){e("input[conditional]").change(function(t){$target=e(t.target).parents('[class*="mod-form"]');var n=e(t.target).attr("conditional");if(void 0!==n&&n.length>0){var o=JSON.parse(n);$target.find('div[conditional-target^=\'{"label":"'+o.label+"\",']").hide(),$target.find("div[conditional-target='"+n+"']").show()}this.handleRequired()}.bind(this))},new t}(jQuery),(o=jQuery)(document).ready((function(){window.setInterval((function(){o("#g-recaptcha-response").val()&&o(".captcha-warning").hide()}),1e3)})),function(e){function t(){e("form").submit(function(t){formbuilder.site_key?""===e(t.target).find(".g-recaptcha-response").val()?(t.preventDefault(),e(".captcha-warning").show()):this.handleEvents():this.handleEvents()}.bind(this))}t.prototype.handleEvents=function(){e('[class*="mod-form"]').submit(function(t){e(t.target).find('button[type="submit"]').html(' '+formbuilder.sending)}.bind(this))},new t}(jQuery)}}); \ No newline at end of file diff --git a/dist/js/modularity-form-builder-front.1fd6be58.js b/dist/js/modularity-form-builder-front.1fd6be58.js new file mode 100644 index 00000000..51637376 --- /dev/null +++ b/dist/js/modularity-form-builder-front.1fd6be58.js @@ -0,0 +1 @@ +!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}({2:function(e,t,n){"use strict";var o;function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}n.r(t);var i,a;(function(e){function t(){this.init(),this.handleEvents()}t.prototype.init=function(){e(".mod-form-collapse").each((function(t){e(this).nextUntil(":not(.mod-form-field)").hide()}))},t.prototype.handleEvents=function(){e("button",".mod-form-collapse").click(function(t){t.preventDefault(),e(".mod-form-collapse__icon > i",t.target).toggleClass("pricon-plus-o pricon-minus-o"),e(t.target).parents(".mod-form-collapse").nextUntil(":not(.mod-form-field)").each((function(){e(this).fadeToggle("fast")}))}.bind(this))},new t})(jQuery),function(e){var t={street_number:{name:"street",addressType:"short_name"},route:{name:"street",addressType:"short_name"},locality:{name:"city",addressType:"long_name"},postal_code:{name:"postal-code",addressType:"long_name"}};function n(){var e=document.getElementById("form-get-location");navigator.geolocation&&null!==e&&this.handleEvents()}n.prototype.handleEvents=function(){e("#form-get-location").click(function(n){n.preventDefault(),$target=e(n.target).parents('[class*="mod-form"]'),e(n.target).find(".pricon").removeClass().addClass("spinner spinner-dark"),navigator.geolocation.getCurrentPosition((function(o){var r=o.coords.latitude,i=o.coords.longitude,a=new google.maps.LatLng(r,i);(new google.maps.Geocoder).geocode({latLng:a},(function(e,n){var o=[];if(n==google.maps.GeocoderStatus.OK&&e[0])for(var r=0;r '+formbuilder.something_went_wrong+"")}))}.bind(this))},new n}(jQuery),function(e){function t(){this.handleRequired(),this.handleEvents()}t.prototype.handleRequired=function(){var t=e('[class*="mod-form"]');e("[conditional-target]:hidden",t).find("[required]").prop("required",!1).attr("hidden-required",!0),e("[conditional-target]:visible",t).find("[hidden-required]").prop("required",!0)},t.prototype.handleEvents=function(){e("input[conditional]").change(function(t){$target=e(t.target).parents('[class*="mod-form"]');var n=e(t.target).attr("conditional");if(void 0!==n&&n.length>0){var o=JSON.parse(n);$target.find('div[conditional-target^=\'{"label":"'+o.label+"\",']").hide(),$target.find("div[conditional-target='"+n+"']").show()}this.handleRequired()}.bind(this))},new t}(jQuery),(o=jQuery)(document).ready((function(){window.setInterval((function(){o("#g-recaptcha-response").val()&&o(".captcha-warning").hide()}),1e3)})),function(e){function t(){e("form").submit(function(t){formbuilder.site_key?""===e(t.target).find(".g-recaptcha-response").val()?(t.preventDefault(),e(".captcha-warning").show()):this.handleEvents():this.handleEvents()}.bind(this))}t.prototype.handleEvents=function(){e('[class*="mod-form"]').submit(function(t){e(t.target).find('button[type="submit"]').html(' '+formbuilder.sending)}.bind(this))},new t}(jQuery),i=function(e,t){var n=t.querySelectorAll('.required[type="checkbox"]:checked').length>0;return e.setCustomValidity(n?"":formbuilder.checkbox_required),n},a=function(e){var t=e.querySelectorAll('[type="checkbox"].required');if("object"===r(t)&&t.length>0)for(var n=0;n
Läs hela svaret här.." -#: source/php/Submission.php:405 +#: source/php/Submission.php:470 source/php/Submission.php:536 +msgid "Open file" +msgstr "" + +#: source/php/Submission.php:477 msgid "Referrer" msgstr "Förgående sida" -#: source/php/Submission.php:452 +#: source/php/Submission.php:522 msgid "Form submission copy" msgstr "Svarskopia" @@ -1101,6 +1128,247 @@ msgstr "Bygg formulär som kan visas i en modul" msgid "Kristoffer Svanmark, Sebastian Thulin" msgstr "Kristoffer Svanmark, Sebastian Thulin, Jonatan Hansson" +#~ msgid "Post types" +#~ msgstr "Posttyper" + +#~ msgid "Create post types that can be integrated with forms." +#~ msgstr "Skapa posttyper som kan kopplas ihop med formulär." + +#~ msgid "Singular name" +#~ msgstr "Namn i singular" + +#~ msgid "Plural name" +#~ msgstr "Namn i plural" + +#~ msgid "Form fields" +#~ msgstr "Formulärsfält" + +#~ msgid "Fields" +#~ msgstr "Fält" + +#~ msgid "Sender" +#~ msgstr "Avsändare" + +#~ msgid "Input" +#~ msgstr "Inmatning" + +#~ msgid "Radio" +#~ msgstr "Radiofält" + +#~ msgid "Checkbox" +#~ msgstr "Kryssruta" + +#~ msgid "Select" +#~ msgstr "Välj" + +#~ msgid "File upload" +#~ msgstr "Filuppladdning" + +#~ msgid "Custom content" +#~ msgstr "Eget innehåll" + +#~ msgid "Add form field" +#~ msgstr "Formulärsfält" + +#~ msgid "Submission" +#~ msgstr "Formulärsvar" + +#~ msgid "Text on submit button" +#~ msgstr "Text på skicka-knapp" + +#~ msgid "Send" +#~ msgstr "Skicka" + +#~ msgid "Submission notice" +#~ msgstr "Meddelande vid inskickning" + +#~ msgid "Text to display when form is submitted." +#~ msgstr "Text som visas när ett formulär skickats." + +#~ msgid "Notifications" +#~ msgstr "Notiser" + +#~ msgid "Notifications on form submission" +#~ msgstr "Notifikation när formulär skickas" + +#~ msgid "Notify email addresses" +#~ msgstr "Notifiera e-postadresser" + +#~ msgid "" +#~ "Notifications will be sent to below added email addresses when receiving " +#~ "a new form submission." +#~ msgstr "" +#~ "Ett mail skickas ut till nedanstående användare med innehållet i svaret." + +#~ msgid "Add email" +#~ msgstr "Lägg till e-postadress" + +#~ msgid "Email address" +#~ msgstr "E-postadress" + +#~ msgid "Condition" +#~ msgstr "Lägg till villkor" + +#~ msgid "Requirements" +#~ msgstr "Krav" + +#~ msgid "Only send when" +#~ msgstr "Skicka bara när" + +#~ msgid "Equals to" +#~ msgstr "Matchar" + +#~ msgid "Custom email subject" +#~ msgstr "Egen ämnesrad" + +#~ msgid "Check this box if you want to enter a custom email subject." +#~ msgstr "Kryssa i rutan för att ange egen ämnesrad." + +#~ msgid "Email subject" +#~ msgstr "Ämnesrad" + +#~ msgid "Enter custom email subject. Default is \"New form submission\"." +#~ msgstr "Ange egen ämnesrad. Standardvärde är “Nytt formulärsvar”." + +#~ msgid "Notification message" +#~ msgstr "Meddelande i notis" + +#~ msgid "Notification data" +#~ msgstr "Notisdata" + +#~ msgid "Show submission data in notice content" +#~ msgstr "Visa svarsdata i notisens innehåll" + +#~ msgid "Sender copy" +#~ msgstr "Svarskopia" + +#~ msgid "Allow sender copy" +#~ msgstr "Tillåt svarskopia" + +#~ msgid "Send copy of the submitted form data to the sender email." +#~ msgstr "Skicka en kopia av svaret till avsändarens e-postadress." + +#~ msgid "Yes, allow user to get a copy of the submission" +#~ msgstr "Ja, tillåt användare att få en svarskopia" + +#~ msgid "Custom email subject for submission copy" +#~ msgstr "Egen ämnesrad för svarskopia" + +#~ msgid "Enter custom email subject. Default is \"Form submission copy\"." +#~ msgstr "Ange egen ämnesrad. Standardvärde är “Svarskopia”." + +#~ msgid "Sender copy message" +#~ msgstr "Meddelande i svarskopia" + +#~ msgid "" +#~ "The message that will be sent to the user together with a list of the " +#~ "submitted data." +#~ msgstr "Meddelandet kommer att skickas tillsammans med svarsdatan." + +#~ msgid "Auto-reply" +#~ msgstr "Autosvar" + +#~ msgid "Send auto-reply on form submission" +#~ msgstr "Skicka autosvar när formuläret har skickats" + +#~ msgid "Auto-reply subject" +#~ msgstr "Ämne för autosvar" + +#~ msgid "Auto-reply content" +#~ msgstr "Meddelande för autosvar" + +#~ msgid "Advanced options" +#~ msgstr "Avancerade inställningar" + +#~ msgid "Save to post type" +#~ msgstr "Spara till posttyp" + +#~ msgid "Save form submissions to a custom post type." +#~ msgstr "Spara formulärsvar till en anpassad posttyp." + +#~ msgid "Post type" +#~ msgstr "Posttyp" + +#~ msgid "Select post type" +#~ msgstr "Välj posttyp" + +#~ msgid "Event" +#~ msgstr "Händelse" + +#~ msgid "Ticket" +#~ msgstr "Ärende" + +#~ msgid "Listing" +#~ msgstr "Lista" + +#~ msgid "Editable on front end" +#~ msgstr "Redigerbar för användaren" + +#~ msgid "Editable on back end" +#~ msgstr "Redigerbar för redaktör" + +#~ msgid "Public act notice" +#~ msgstr "Notis om allmän handling" + +#~ msgid "" +#~ "Adds a notice that informs the user that the submission will become a " +#~ "public act." +#~ msgstr "" +#~ "Lägger till ett meddelande som informerar användaren om att " +#~ "formulärsvaret blir en allmän handling." + +#~ msgid "Add public act notice" +#~ msgstr "Lägg till notis om allmän handling" + +#~ msgid "GDPR Complience notice" +#~ msgstr "GDPR komplience meddelande" + +#~ msgid "Contains information about how personal data is handled." +#~ msgstr "Innehåller information om hur personlig data hanteras." + +#~ msgid "" +#~ "Show a message (and checkbox) that is required to check to submit all " +#~ "forms." +#~ msgstr "" +#~ "Visa ett meddelande (och en checkbox) som är nödvändig för att posta " +#~ "formuläret." + +#~ msgid "GDPR complience notice content" +#~ msgstr "Innehåll för GDPR meddelande" + +#~ msgid "" +#~ "When you submit the form, we will process your personal information to " +#~ "perform the task that the form concerns. The data will not be used for " +#~ "any other purpose." +#~ msgstr "" +#~ "I det här formuläret samlar vi in personuppgifter om dig för att [det " +#~ "formuläret ska användas till]. Uppgifterna kommer inte att hanteras för " +#~ "något annat syfte, och kommer att raderas när [ärendet är avslutat]. Läs " +#~ "om hur Helsingborgs stad hanterar personuppgifter." + +#~ msgid "DB storage" +#~ msgstr "Databaslagring" + +#~ msgid "Don't store posted data in database" +#~ msgstr "Lagra inte postad data i databasen." + +#~ msgid "User Restriction" +#~ msgstr "Användarbegränsning" + +#~ msgid "Users" +#~ msgstr "Betrodda användare" + +#~ msgid "Add users who have access to the form data" +#~ msgstr "" +#~ "Lägg till betrodda användare som har access till det som postas från " +#~ "formulären" + +#~ msgid "Hello, you are not Superman, with full access?" +#~ msgstr "Hallååå! Du är ingen Superhjälte med full access" + +#~ msgid "Missing permissions" +#~ msgstr "Du saknar rättigheter för att se den här sidan" + #, fuzzy #~| msgid "Form submissions" #~ msgid "Form options" @@ -1111,17 +1379,6 @@ msgstr "Kristoffer Svanmark, Sebastian Thulin, Jonatan Hansson" #~ msgid "Custom post types" #~ msgstr "Anpassad posttyp för formulärsvar" -#~ msgid "GDPR & Confidentiality" -#~ msgstr "GDPR & Sekretess" - -#~ msgid "GDPR komplience meddelande" -#~ msgstr "GDRP meddelande" - -#~ msgid "" -#~ "Visa ett meddelande (och en checkbox) som är nödvändig för att posta " -#~ "formuläret." -#~ msgstr "Visa meddelande som beskriver hur vi hanterar användaruppgifter." - #~ msgctxt "modularity-form-builder" #~ msgid "Add New Form submission" #~ msgstr "Lägg till nytt formulärsvar" diff --git a/source/js/front/validation.js b/source/js/front/validation.js new file mode 100644 index 00000000..74e68382 --- /dev/null +++ b/source/js/front/validation.js @@ -0,0 +1,57 @@ +export default (() => { + const getValidity = (element, scope) => { + const checkedCheckboxes = scope.querySelectorAll('.required[type="checkbox"]:checked'); + const valid = checkedCheckboxes.length > 0; + + element.setCustomValidity(valid ? '' : formbuilder.checkbox_required); + + return valid; + }; + + const setHyperformValidation = scope => { + const requiredCheckboxes = scope.querySelectorAll('[type="checkbox"].required'); + + if (typeof requiredCheckboxes === 'object' && requiredCheckboxes.length > 0) { + for (let i = 0; i < requiredCheckboxes.length; i++) { + const checkbox = requiredCheckboxes[i]; + + hyperform.addValidator(checkbox, element => getValidity(element, scope)); + } + } + }; + + const setCheckboxValidationRules = modularityForm => { + const checkboxGroups = modularityForm.getElementsByClassName('checkbox-group'); + for (let i = 0; i < checkboxGroups.length; i++) { + const checkboxGroup = checkboxGroups.item(i); + setHyperformValidation(checkboxGroup); + } + }; + + /** + * Loop through forms and set custom validation rules to required checkboxes + */ + const init = () => { + const forms = document.getElementsByClassName('modularity-mod-form'); + + for (let i = 0; i < forms.length; i++) { + const form = forms.item(i); + setCheckboxValidationRules(form); + + /* Whenever a checkbox is clicked, revalidate all other checkboxes */ + let inputElements = form.getElementsByTagName('input'); + inputElements = Array.from(inputElements); + inputElements = inputElements.filter(elem => elem.type === 'checkbox'); + + for (let j = 0; j < inputElements.length; j++) { + inputElements[j].addEventListener('click', () => { + for (let k = 0; k < inputElements.length; k++) { + inputElements[k].reportValidity(); + } + }); + } + } + }; + + return init(); +})(); diff --git a/source/js/modularity-form-builder-front.js b/source/js/modularity-form-builder-front.js index 5dfb2f3e..c4dbf7a7 100644 --- a/source/js/modularity-form-builder-front.js +++ b/source/js/modularity-form-builder-front.js @@ -3,6 +3,7 @@ import GetLocation from './front/get-location'; import HandleConditions from './front/handle-conditions'; import RecaptchaWarning from './front/recaptcha-warning'; import SubmitHandler from './front/submit-handler'; +import Validation from './front/validation'; const FormBuilderFront = { Collapse, @@ -10,4 +11,5 @@ const FormBuilderFront = { HandleConditions, RecaptchaWarning, SubmitHandler, + Validation, }; diff --git a/source/php/Module/Form.php b/source/php/Module/Form.php index 1b3d26ba..7a4ae171 100644 --- a/source/php/Module/Form.php +++ b/source/php/Module/Form.php @@ -296,6 +296,7 @@ public function script() wp_localize_script('form-builder-js-front', 'formbuilder', array( 'site_key' => (defined('G_RECAPTCHA_KEY')) ? G_RECAPTCHA_KEY : '', 'sending' => __('Sending', 'modularity-form-builder'), + 'checkbox_required' => __('You must check at least one option', 'modularity-form-builder'), 'something_went_wrong' => __('Something went wrong', 'modularity-form-builder'), )); wp_enqueue_script('form-builder-js-front'); diff --git a/source/php/Module/views/fields/checkbox.blade.php b/source/php/Module/views/fields/checkbox.blade.php index 79f59fe0..194ffbf1 100644 --- a/source/php/Module/views/fields/checkbox.blade.php +++ b/source/php/Module/views/fields/checkbox.blade.php @@ -1,12 +1,12 @@
-
+
{!! !empty($field['description']) ? '
' . ModularityFormBuilder\Helper\SanitizeData::convertLinks($field['description']) . '
' : '' !!} @foreach ($field['values'] as $value) @endforeach