Formbuilder form in a FancyBox modal view

  Previous article Next article  

Formbuilder form in a FancyBox modal view

  Article optimized for CMSMS 2.x

  Author:
  Last tested in: CMSMS 2.1.4
  Last updated: 03-08-2016
  Comments: 3

In this tutorial I will show you how I implemented an Ajax based 'call-me-back' Form Builder form, that pops up in a FancyBox modal view.
What?!
Okay, I might need to explain it first :-)

'Call-me-back' form: a form which a website visitor can use to submit his name and phone number. The website owner will then call the visitor back as soon as possible.
FormBuilder is a very nice module for CMS Made Simple to build and handle forms. I would not know how to create a form in CMSMS without this module.
FancyBox: a Javascript 'tool' to display objects (in this case a webform) on top of the website.
The form also has a very basic and user friendly way of spam(bot) prevention.

The website owner wanted the 'call-me-back' form to be available on every webpage of his website. So on every page there will be a 'call me back!' - button.

  How to use

Step 1: Create the webform

Prerequisites - The FormBuilder module needs to be installed and for successful mail handling CMSMailer needs to be properly configured and tested

This form is just an example. Of course you can create other forms to suit your needs.

Extensions >> Form Builder >> 'Add New Form'

Main tab

Form Name: Call me back
Form Alias: call-me-back
Display form inline?: UNchecked (this is very important)

Form Submission tab

After form is submitted: Display "Submission Template"

Submission Template tab

<h3>Thank you</h3>
<p>We will call you as soon as possible on number<br />
<strong>{$your_phone_number}</strong></p>

Click the 'Add' button to create the form. Now we need to add some useful fields

  • Static Text field (optional):
    A field to display some descriptive text above the form.
  • Text Input:
    Name: Your name
    Require a response for this Field: checked
  • Text Input:
    Name: Your phone number (this name is referred to from the Submission Template)
    Require a response for this Field: checked
    Field Validation (optional): I use 'Match regular expression' but it depends on your country/location.
  • Text Input (we use this field for the spam prevention):
    Name: website
    Require a response for this Field: NOT(!) checked
    Field Validation: Doesn't match Regular Expression
    Advanced Settings tab:
    Field Alias and DOM id (CSS id) attribute: frm_website
    CSS Class for this field: website
    Validation Regex: /.+/
  • *Email Results to set Address(es):
    Name: sendto
    "From name" for email: choose an appropriate name for your website
    "From address" for email: choose an existing email address for your website domain
    Destination Email Address: add the email address of the website owner that needs to receive the webform contents.
    Advanced Settings tab:
    Create Sample Template (button)
    Email Template: remove the stuff for the 'website' field.

Save the form

Test the form by creating a new content page (you might want to hide that from the menu) and add {FormBuilder form='call-me-back'}.
Visit that page and check that it does not validate when anything is filled in 'website' field. Then fill in the other field and leave 'website' empty and check that the Submission template text is displayed and the form is received by the recipient supplied earlier. If tests are successful then you can delete the test-page.

Step 2: Add the form to your page template(s)

For the form to be present on every page I put it in the template. Initially it is hidden with some inline css. We only want to show the form when the 'Call me back!' button is used.
Just before the CLOSING </body> tag I put these lines:

<div id="callme_container" style="display: none;" class="frm_ajax">
  <div id="callme" class="frm_ajax_inner">{FormBuilder form='call-me-back'}</div>
</div>

It is important that the 'container' div has an id that is [id_of_child_div]_container.
So in this example the child div has id="callme" so it's parent has id="callme_container".
If this page template is actually used for some content page and you look at the html source of that webpage (frontend) then you should see the form is there just before the </body> tag.
The css "display: none;" hides it from the visitor.

Step 3: Create a button for showing the form

Somewhere in your page template you want to have a button or link so the website visitor will be able to 'call' the form. I just created a link and with some css made it look like a button. The styling is up to you, I'll just show you the code I used for the link:

<a href="#callme" id="inline" class="frm_fancybox">Call me!</a>

Note that the value of href ("#callme") refers to the id of the earlier created div (<div id="callme">). This is how FancyBox later knows what to show when the link is used.

Step 4: Integrate jQuery and FancyBox javascript

FancyBox is based on jQuery, so we first need to link to jQuery.

In the <head> section of your page template put (for example):

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Then download the FancyBox files from:
http://fancybox.googlecode.com/files/jquery.fancybox-1.3.4.zip

I use version 1 because version 2 is not free for commercial use. But version 1 is not compatible with jQuery 1.9+. Therefor I needed a patched version which I downloaded from:
http://www.picssel.com/playground/jquery/fancybox/jquery.fancybox-1.3.4_patch.zip

More information on StackOverflow:
http://stackoverflow.com/questions/14344289/fancybox-doesnt-work-with-jquery-v1-9-0-f-browser-is-undefined-cannot-read

I uploaded the original FancyBox files including the patch to the web server:
/uploads/template/js/fancybox

Then I linked to the patched js file; just below the jQuery include put:

<script type="text/javascript" src="{uploads_url}/template/js/fancybox/jquery.fancybox-1.3.4_patch.js"></script>

A2 Webhosting CMS Made Simple

Step 5: Some custom javascript to put things together

Now we need to do some stuff:

  • make the link/button activate a FancyBox
  • make the submit button of the form use Ajax in stead of a normal POST
  • make sure the form is available after the FancyBox is closed

I've created a 'prepareForm' function. It finds the form(s) and sets the onSubmit handlers of it so the form uses ajax to submit the data and retrieve the output.

Then in the 'document ready' function the link/button is FancyBoxed. The onStart event is used to store the original contents (the form) to a variable. FancyBox seems to move the form to it's 'Fancybox div' but when it closes, the content is gone. So a subsequent call for the form would fail as it does not exist anymore. The onClosed event is used to restore the original form to its original location.

Put this code below the earlier included jQuery and FancyBox in your page template:

<script type="text/javascript">
function prepareForm() {
/*
Used to set onSubmit handler. Needs to be done after every ajax request because the old form object is overwritten
*/

  $('.frm_ajax_inner form.cms_form').on( "submit", function( event ) {
    event.preventDefault();
    var posturl = $(this).attr("action") + "?showtemplate=false";  
    var postdata = $(this).serialize();
    var frm_container = $(this).parent();
    /* ajax */
    $.post(posturl,postdata,function(data) {
      /* overwrite form's parent div with new html and prepare form again */
      frm_container.html(data);
      prepareForm(); } );
      } );
    }

/*
Variable to get original form content. Used to be able to show a clean form after modal box is closed while form was submitted but not valid
*/

var org_content;

$(document).ready(function() {
  $('a.frm_fancybox').fancybox( {  
    onStart : function (links, index) { /* save original form contents */
    var currentlink = $(links[index]);
    var linktargetparent =  $(currentlink.attr("href") + '_container');
    org_content = linktargetparent.html(); } , // save original content to variable
    onClosed :  function(links, index) { /* restore original hidden form and prepare it */
      var currentlink = $(links[index]);
      var linktargetparent =  $(currentlink.attr("href") + '_container');
      linktargetparent.html(org_content);
      org_content = '';
      prepareForm();}
    } );
  prepareForm();
} );
</script>

And we need some styling, so add a call to the Fancybox style in the head of your HTML template:

<link media="screen" type="text/css" href="{uploads_url}/template/js/fancybox/jquery.fancybox-1.3.4.css" rel="stylesheet">

Step 6: Test it

If everything works out well you should now have a working form that shows in a Fancybox and does NOT make your page reload when submitted.

Step 7: Hide the website field (spam prevention)

Use some css to hide the 'website' field from the website visitor. The idea is that automated web bots only look for the form fields and can't resist to add some information. As the specific field is hidden from real, human visitors you know it should never contain anything.
Somewhere in your stylesheet put:

div.website, div.website * {
  display: none !important;
}

The website field should now not be visible anymore.

Tip

  Working example



A2 Webhosting CMS Made Simple

  Comments

  Click here to leave a comment






This is a captcha-picture. It is used to prevent mass-access by robots. (see: www.captcha.net)
  « Enter the CAPTCHA code (lower case)

Your IP address will be stored on submit. I reserve the right to change or delete your response without notice!
In case of abuse your IP address will be blocked!


Can I have your attention for a moment?

Did this tutorial help you solving a problem at your (clients) website and it saved you many hours of work? Great!!
Consider buying Rolf a cup of coffee in return! [ Click here ]


  3 Comments

CMS Made Simple 2.2.2 - Tutorials, tips and tricks - CMSMS 2.2.2

Formbuilder form in a FancyBox modal view

  Article optimized for CMSMS 2.x

  Author:
  Last tested in: CMSMS 2.1.4
  Last updated: 03-08-2016
  Comments: 3

A2 Webhosting CMS Made Simple