SSbits - Home page
Site by Carbon Crayon
Submit a Post >

Tutorials - Big bits of code to help you do more

Embedding a contact form in a sidebar

In this tutorial we are going to add a form to a sidebar that can be included on any page on a website. You will be able to set whether to show the Form on a particular page via checkbox in the CMS. The work is based on the Working with SiteConfig and Creating a Simple Contact Form tutorials.

Decorating SiteConfig

We want to add fields to the site config for the email recipient of the form and the "thank you" text to be shown to the visitor after they have submitted the form.

Create a file called CustomSiteConfig.php in /mysite/code/ to hold the CustomSiteConfig class:

<?php

class CustomSiteConfig extends DataObjectDecorator {

function extraStatics() {
return array(
'db' => array(
'Mailto' => 'Varchar(100)',
'SubmitText' => 'Text',
)
);
}

public function updateCMSFields(FieldSet &$fields) {

$fields->addFieldToTab("Root.SideBar", new TextField('Mailto', 'Email submissions to'));
$fields->addFieldToTab("Root.SideBar", new TextareaField('SubmitText', 'Text on Submission'));
}
}

Extending the SiteConfig class with DataObjectDecorator is necessary and fairly straight forward. Here we have added fields to hold the email address that the form should be sent to (Mailto) and the text that should be shown to the visitor after they have submitted (SubmitText). We also need to explicitly tell SilverStripe to use this extension in /mysite/_config.php

//Extend the site config
DataObject::add_extension('SiteConfig', 'CustomSiteConfig');

Run a /dev/build/, flush the cache and view the site config panel in the admin area of your site by clicking on the Root of the page tree navigation - you should now see a Side Bar tab with the extra fields. Add your email address and the text you want visitors to see on submission of the form.

Create the form logic

Because the form used in the side bar could be included on any page its best to create the form in the Page_Controller. If your other page controllers extend Page_Controller then the form will be available on every page.

In my particular instance the form in the side bar was for visitors that wanted to sign up for a loyalty program but obviously the details of the form can be changed to suit:

<?php

// mysite/code/Page.php
class Page_Controller extends ContentController {

public static $allowed_actions = array (
);

public function init() {
parent::init();
}

function LoyaltyForm() {

// Create fields
$fields = new FieldSet(
new TextField('Name', 'Name'),
new TextField('Address', 'Address'),
new TextField('Phone', 'Phone'),
new EmailField('Email', 'Email')
);

// Create action
$actions = new FieldSet(
new FormAction('SendLoyaltyForm', 'Sign me up!')
);

// Create Validators
$validator = new RequiredFields('Name', 'Email');

$validator->setJavascriptValidationHandler('none');

return new Form($this, 'LoyaltyForm', $fields, $actions, $validator);
}

function SendLoyaltyForm($data) {

//Grab the site config
$siteConfig = $this->SiteConfig();

//Set data
$From = $data['Email'];
$Name = $data['Name'];
$To = $siteConfig->Mailto;

$Subject = "$Name has sent a request to sign up for the loyalty card";

$email = new Email($From, $To, $Subject);

//set template
$email->setTemplate('LoyaltyEmail');

//populate template
$email->populateTemplate($data);

//send mail
$success = $email->send();

//return to submitted message
Director::redirect(Director::baseURL(). $this->Link("/?loyaltyformsuccess=1"));
}

public function LoyaltyFormSuccess() {
return isset($_REQUEST['loyaltyformsuccess']) && $_REQUEST['loyaltyformsuccess'] == "1";
}
}

Here we have created the LoyaltyForm and the handler that will process the form and direct the request on to the correct page. This is very similar to the method used in Aram's tutorial for creating a simple contact form.

A notable difference is the method used to retrieve the email address we set in the SiteConfig panel earlier. The site config is accessible from the controller using:

$siteConfig = $this->SiteConfig();

Grabbing the Mailto field value is as easy as:

$To = $siteConfig->Mailto;

Controlling which pages show the Form

We need a way of including the side bar on any page which can be set in the CMS. The best way to achieve this is to add a boolean field to the Page class and a checkbox to control its value. In mysite/code/Page.php:

class Page extends SiteTree {

public static $db = array(
'ShowLoyaltyForm' => 'Boolean'
);

static $defaults = array(
'ShowLoyaltyForm' => false
);

function getCMSFields(){

$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Behaviour', new CheckboxField("ShowLoyaltyForm", "Show Loyalty form on this page?"));
return $fields;
}
}
.
.
.

 

Here we have added ShowLoyaltyForm as a boolean field, after running /dev/build/, clearing the cache and refreshing the SilverStripe admin area you should see a new checkbox on the Behaviour tab. By default this checkbox is set to false (unchecked) so the form is not inserted into every page by default.

Adding the form to the Template

The last step is to add the Sidebar to our Page template. TWe do this by creating an Include file which we can then use in any of our templates, but more specifically in this example in the Sidebar.ss template. So in themes/myTheme/templates/Includes/LoyaltyForm.ss add the following:

<% if ShowLoyaltyForm %>			
<% if LoyaltyFormSuccess %>

<h2 class="white">Thanks!</h2>
<p class="success">$SiteConfig.SubmitText</p>

<% else %>

<h2 class="white">Sign up for our Loyalty Program!</h2>

$LoyaltyForm

<% end_if %>
<% end_if %>

This template is fairly straight forward, if the page is set to show the form (i.e. ShowLoyaltyForm = true) then if the form has been submitted and the LoyaltyFormSuccess() method in Page_Controller returns true then we retrieve the text we set earlier for this occassion in the SiteConfig panel. Accessing the SubmitText data from the SiteConfig is easily achieved using $SiteConfig.SubmitText. If the form has not been submitted then display the form itself calling $LoyaltyForm.

Now all we need to do is inculde this template in the sidebar by adding <% include LoyaltyForm %> to our themes/myTheme/templates/Layout/Page.ss file:

    <div id="sidebar">
<p>Sidebar content</p>
<% include LoyaltyForm %>
</div>

<div id="content" class="typography">

<h1>$Title</h1>
$Content
$Form

</div>

 

Because we used the <% if ShowLoyaltyForm %> in the LoyaltyForm include template we don't need to worry about anything other than including it in our main template. You could add this include anywhere you like, even inside another include such as Sidebar.ss.

Lastly the template for the email sent by the form is held in themes/myTheme/templates/Emails/LoyaltyEmail.ss could look something like this:

 

<p>$Name has requested to sign up to the loyalty program, 
you may respond to $Name by replying to this email.</p>

<dl>
<dt>Name:</dt>
<dd>$Name</dd>
<dt>Address:</dt>
<dd>$Address</dd>
<dt>Phone:</dt>
<dd>$Phone</dd>
<dt>Email:</dt>
<dd>$Email</dd>
</dl>

All that remains is to add the side bar to a few pages in the SilverStripe CMS and test the form by submitting it. Big thanks to SSBits tutorials that paved the way for this work.

Special Thanks

Special thanks go to Aram Balakjian for their contributions to this post.

Frank Mullenger avatar

Frank Mullenger

Frank is a freelance web developer who is recently back in New Zealand after a few years contracting in London, UK.

  • Marcus Dalgren
    29/10/2010 8:42am (4 years ago)

    Really nice use of SiteConfig and the Contact form. I've been working on something similar where custom forms can be activated for pretty much any page but I haven't used SiteConfig as the central config.

  • robert
    20/01/2011 9:49pm (4 years ago)

    Great tutorial. However, there seems to be a tiny, yet crucial mistake with the part used to check what page you want the form on. It took me a while to figure out why the check box field wouldn't stay ticked after i saved my page. It seems that "s" in showLoyaltyForm is not capitalized which was causing the problem.

  • Encho
    24/01/2011 11:11am (4 years ago)

    Love this website, unfortunately the above did not work for me. Form never appears. Could be that I pasted it wrong, will investigate. Anyone else had success with this one?

  • Frank Mullenger
    24/01/2011 8:06pm (4 years ago)

    If you are having trouble getting the $LoyaltyForm to display maybe try running a ?flush=1 in case your sidebar template is not being included, or try putting the $LoyatlyForm on the page template directly to test that it returns html for the form, if that does not work maybe you need to add LoyaltyForm to the $allowed_actions array for that controller but I don't think you would need to.

    The important thing is that you have a function called LoyaltyForm() in your Page_Controller and that the current page you are viewing extends the Page_Controller class so that it can inherit it.

  • Terry Apodaca
    28/01/2011 12:49am (4 years ago)

    [code]$this->redirect($this->Link("?..."));[/code]

    is all you need...

    [code]Director::redirect(); [/code]

    is depricated

Post a comment ...

You cannot post comments until you have logged in. Login Here.

Advertisement

Site of the Month

Find SSbits on

Top Contributers

Rank Avatar Name
1 article image Aram Balakjian
2 article image Daniel Hensby
3 article image Marcus Dalgren
4 article image Hamish Campbell
5 article image Ty Barho
6 article image Martijn van Nieuwenhoven
7 article image Darren-Lee
8 article image Roman Schmid
9 article image Matt Clegg
10 article image dalesaurus

View full leaderboard


Advertisement