Created
January 15, 2016 13:40
-
-
Save isralduke/d75194b1d02d90ce4ef6 to your computer and use it in GitHub Desktop.
Raven + AJAX + Happy JS Validation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{ raven:form formset="contact" attr="id:contact-form|class:contact-form" }} | |
<div class="row"> | |
<div class="col-xs-12 col-sm-4"> | |
<div class="form-group"> | |
<label for="">{{ theme:partial src="reqd" }} Name</label> | |
<input type="text" class="form-control" name="name" id="name" placeholder="What is your name?"> | |
</div> | |
</div> | |
<div class="col-xs-12 col-sm-4"> | |
<div class="form-group"> | |
<label for="">{{ theme:partial src="reqd" }} Email</label> | |
<input type="email" class="form-control" name="email" id="email" placeholder="What is your email address?"> | |
</div> | |
</div> | |
<div class="col-xs-12 col-sm-4"> | |
<div class="form-group"> | |
<label for="">{{ theme:partial src="reqd" }} Phone</label> | |
<input type="tel" class="form-control" name="phone" id="phone" placeholder="What is your phone number?"> | |
</div> | |
</div> | |
<div class="col-xs-12 website"> | |
<div class="form-group"> | |
<label for="website">{{ theme:partial src="reqd" }} Website</label> | |
<input type="url" class="form-control" name="website" id="website" placeholder="What is your website url?"> | |
</div> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col-xs-12 col-sm-4"> | |
<div class="form-group"> | |
<label>Select a Location</label> | |
</div> | |
<div class="form-group"> | |
<select class="form-control" name="location" id="location"> | |
<option value="North Blvd">North Blvd</option> | |
<option value="Highland Road">Highland Road</option> | |
<option value="Silverside Drive">Silverside Drive</option> | |
<option value="Congress Drive">Congress Drive</option> | |
</select> | |
</div> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col-xs-12 col-sm-6"> | |
<div class="form-group"> | |
<label for="">{{ theme:partial src="reqd" }} Message</label> | |
<textarea name="message" id="message" cols="30" rows="10" class="form-control" placeholder="What would you like to ask us?"></textarea> | |
</div> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col-xs-12 col-sm-2"> | |
<button class="btn btn-primary btn-block" type="submit" id="submit">Send</button> | |
</div> | |
</div> | |
{{ /raven:form }} | |
<div class="row"> | |
<div class="col-xs-12 col-sm-4"> | |
<p class="successMessage"> | |
Thanks! We’ll be in touch soon. | |
</p> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Location (from root) to save form submissions | |
submission_save_path: _forms/contact/ | |
# Fields allowed to be submitted in the form, automatically | |
# purging anything and everything else | |
allowed: | |
- name | |
- phone | |
- location | |
- message | |
honeypot: website | |
# You are not required to require fields, but once you do, any missing | |
# from the POST will squash this submission and send a list of | |
# missing fields to your {{ raven:errors }} tagpair | |
required: | |
- name | |
- message | |
submission_save_extension: yaml | |
# Configure notification email | |
email: | |
to: [email protected] | |
from: "{{ email }}" | |
subject: CDS Website Form Message | |
automagic: true | |
html_template: email | |
# text_template: text_email | |
datestamp_format: "Y F d" | |
control_panel: | |
fields: | |
- name | |
- phone | |
- location | |
metrics: | |
- | |
type: count | |
field: email | |
label: Total Submissions Received |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*global $*/ | |
(function happyJS($) { | |
$.fn.isHappy = function isHappy(config) { | |
var fields = [], item; | |
var pauseMessages = false; | |
function isFunction(obj) { | |
return typeof obj === 'function'; | |
} | |
function defaultError(error) { //Default error template | |
var msgErrorClass = config.classes && config.classes.message || 'unhappyMessage'; | |
return $('<span id="' + error.id + '" class="' + msgErrorClass + '" role="alert">' + error.message + '</span>'); | |
} | |
function getError(error) { //Generate error html from either config or default | |
if (isFunction(config.errorTemplate)) { | |
return config.errorTemplate(error); | |
} | |
return defaultError(error); | |
} | |
function handleSubmit(e) { | |
var i, l; | |
var errors = false; | |
if (config.testMode) { | |
e.preventDefault(); | |
} | |
for (i = 0, l = fields.length; i < l; i += 1) { | |
if (!fields[i].testValid(true)) { | |
errors = true; | |
} | |
} | |
if (errors) { | |
if (isFunction(config.unHappy)) config.unHappy(e); | |
return false; | |
} else if (config.testMode) { | |
if (window.console) console.warn('would have submitted'); | |
if (isFunction(config.happy)) return config.happy(e); | |
} | |
if (isFunction(config.happy)) return config.happy(e); | |
} | |
function handleMouseUp() { | |
pauseMessages = false; | |
} | |
function handleMouseDown() { | |
pauseMessages = true; | |
} | |
function processField(opts, selector) { | |
var field = $(selector); | |
if (!field.length) return; | |
selector = field.prop('id') || field.prop('name').replace(['[',']'], ''); | |
var error = { | |
message: opts.message || '', | |
id: selector + '_unhappy' | |
}; | |
var errorEl = $(error.id).length > 0 ? $(error.id) : getError(error); | |
var handleBlur = function handleBlur() { | |
if (!pauseMessages) { | |
field.testValid(); | |
} else { | |
$(window).one('mouseup', field.testValid); | |
} | |
}; | |
fields.push(field); | |
field.testValid = function testValid(submit) { | |
var val, temp; | |
var required = field.prop('required') || opts.required; | |
var password = field.attr('type') === 'password'; | |
var arg = isFunction(opts.arg) ? opts.arg() : opts.arg; | |
var errorTarget = (opts.errorTarget && $(opts.errorTarget)) || field; | |
var fieldErrorClass = config.classes && config.classes.field || 'unhappy'; | |
var testResult = errorTarget.hasClass(fieldErrorClass); | |
var oldMessage = error.message; | |
// handle control groups (checkboxes, radio) | |
if (field.length > 1) { | |
val = []; | |
field.each(function(i,obj) { | |
val.push($(obj).val()); | |
}); | |
val = val.join(','); | |
} else { | |
// clean it or trim it | |
if (isFunction(opts.clean)) { | |
val = opts.clean(field.val()); | |
} else if (!password && typeof opts.trim === 'undefined' || opts.trim) { | |
val = $.trim(field.val()); | |
} else { | |
val = field.val(); | |
} | |
// write it back to the field | |
field.val(val); | |
} | |
// check if we've got an error on our hands | |
if (submit === true && required === true) { | |
testResult = !val.length; | |
} | |
if ((val.length > 0 || required === 'sometimes') && opts.test) { | |
if (isFunction(opts.test)) { | |
testResult = opts.test(val, arg); | |
} | |
else if (typeof opts.test === 'object') { | |
$.each(opts.test, function (i, test) { | |
if (isFunction(test)) { | |
testResult = test(val, arg); | |
if (testResult !== true) { | |
return false; | |
} | |
} | |
}); | |
} | |
if (testResult instanceof Error) { | |
error.message = testResult.message; | |
} | |
else { | |
testResult = !testResult; | |
error.message = opts.message || ''; | |
} | |
} | |
// only rebuild the error if necessary | |
if (!oldMessage !== error.message) { | |
temp = getError(error); | |
errorEl.replaceWith(temp); | |
errorEl = temp; | |
} | |
if (testResult) { | |
errorTarget.addClass(fieldErrorClass).after(errorEl); | |
return false; | |
} else { | |
errorEl.remove(); | |
errorTarget.removeClass(fieldErrorClass); | |
return true; | |
} | |
}; | |
field.on(opts.when || config.when || 'blur', handleBlur); | |
} | |
for (item in config.fields) { | |
if (config.fields.hasOwnProperty(item)) { | |
processField(config.fields[item], item); | |
} | |
} | |
$(config.submitButton || this).on('mousedown', handleMouseDown); | |
$(window).on('mouseup', handleMouseUp); | |
if (config.submitButton) { | |
$(config.submitButton).click(handleSubmit); | |
} else { | |
this.on('submit', handleSubmit); | |
} | |
return this; | |
}; | |
})(this.jQuery || this.Zepto); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="//malsup.github.com/min/jquery.form.min.js"></script> | |
{{ theme:js tag="true" src="bootstrap.min" }} | |
{{ theme:js tag="true" src="happy" }} | |
{{ theme:js tag="true" }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(document).ready(function() { | |
function formend() { | |
$('#contact-form').slideUp(350); | |
$("#contact-form")[0].reset(); | |
$('.successMessage').slideDown(350); | |
} | |
$('#contact-form').isHappy( | |
{ | |
fields: { | |
'#name': { required: true, message:'We need your name!'}, | |
'#email': { required: true, message:'Give us your email!'}, | |
'#phone': { required: true, message:'Can we have your phone number?'}, | |
'#message': { required: true, message:'Be sure to send a message to us.'} | |
} | |
}); | |
$('#submit').click(function() { | |
$('#contact-form').ajaxForm(function() { | |
formend(); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment