Silverstripe Version:
4.5.1
Question:
I’m looking to build a contact form which submits the content through ajax. I’ve not done this before using SilverStripe.
I’ve had a look at the tutorial on general ajax loading, but not sure how to tie this in with form submission.
Is anyone aware of a tutorial on this, or can offer general advice on where to start, please?
Thanks in advance!
Hopefully this will get you pointed in the right direction. This is what I generally recycle for my contact forms. I add this to PageController.php so I can add a contact form on any page.
public function ContactForm() {
Requirements::javascript('themes/yourtheme/javascript/jquery/jquery-3.3.1.min.js');
Requirements::javascript('themes/yourtheme/javascript/ajax.js');
$fields = new FieldList(
TextField::create('FirstName'),
TextField::create('LastName'),
EmailField::create('Email'),
TextField::create('Phone'),
TextareaField::create('Message'),
NocaptchaField::create('Captcha')
);
$actions = new FieldList(
FormAction::create('doSubmission', 'Submit')
);
$validator = new RequiredFields('FirstName', 'LastName', 'Email', 'Message');
$form = new Form($this, 'ContactForm', $fields, $actions, $validator);
$form->AddExtraClass('js-ajax-form');
// Load the form with previously sent data
$request = Controller::curr()->getRequest();
$session = $request->getSession();
if(is_array($session->get('ContactFormData'))) {
// $form->sessionMessage('There was a problem submitting the form. Please review the errors below and try again.','error');
$previous_data = $session->get("ContactFormData");
$session->clear("ContactFormData");
$form->loadDataFrom($previous_data);
}
return $form;
}
public function doSubmission($data, $form) {
$form->clearMessage();
$siteconfig = SiteConfig::current_site_config();
$email = new Email();
$email->setTo($siteconfig->AdministratorEmail); //replace this with To Email
$email->setFrom($siteconfig->AdministratorEmail);
if($data['Email']) {
$email->setReplyTo($data['Email']);
}
$email->setSubject("New Enquiry from Website : Contact Message from " . $data["FirstName"] . " " . $data["LastName"] );
$messageBody = "
<p><strong>Name:</strong> {$data['FirstName']} {$data['LastName']}</p>
<p><strong>Email:</strong> {$data['Email']}</p>
<p><strong>Phone:</strong> {$data['Phone']}</p>
<p><strong>Message:</strong> {$data['Message']}</p>
<p><strong>IP Address:</strong> ". $_SERVER['REMOTE_ADDR'] . "</p>
<p><strong>Page URL:</strong> ". $this->AbsoluteLink() . "</p>
";
$email->setBody($messageBody);
$email->send();
$this->redirect($this->Link("success"));
}
ajax.js
$(function(){
var frm = $('form.js-ajax-form');
frm.submit(function (e) {
var $form = $(this);
var formData = $form.serialize();
var formAction = $form.prop('action');
var formMethod = $form.prop('method');
var encType = $form.prop('enctype');
e.preventDefault();
$.ajax({
beforeSend: function(jqXHR,settings) {
if ($form.prop('isSending')) {
return false;
}
$form.prop('isSending',true);
$form.addClass('uk-loading');
},
complete: function(jqXHR,textStatus) {
$form.prop('isSending',false);
$form.removeClass('uk-loading');
},
contentType: encType,
data: formData,
error: function(jqXHR, textStatus, errorThrown) {
console.log('An error occurred.');
window.location = window.location;
},
success: function(data, textStatus, jqXHR) {
var $holder = $form.parent();
$holder.fadeOut('normal',function() {
$holder.html(data).fadeIn();
});
},
type: formMethod,
url: formAction
});
});
});
1 Like
Thanks @Jellygnite - That’s really helpful!
I’ve adapted this to make it suitable for the site I’m working on, and it works a treat.
Have a great weekend!
This won’t work for forms with multiple submit options as it doesn’t include the action in the post body. If anyone needs multiple submit options, replace
var formData = $form.serialize();
with
var formData = $form.serializeArray();
formData.push({name: e.originalEvent.submitter.name, value: e.originalEvent.submitter.value});
1 Like