NIHVIVO-3538 implemented a jquery plus java captcha on the contact form page
This commit is contained in:
parent
06fbfcbb87
commit
5fea873ed2
5 changed files with 277 additions and 51 deletions
|
@ -49,6 +49,7 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
private final static String TEMPLATE_EMAIL = "contactForm-email.ftl";
|
private final static String TEMPLATE_EMAIL = "contactForm-email.ftl";
|
||||||
private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl";
|
private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl";
|
||||||
private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
|
private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
|
||||||
|
private final static String TEMPLATE_FORM = "contactForm-form.ftl";
|
||||||
|
|
||||||
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home.directory";
|
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home.directory";
|
||||||
private static final String EMAIL_JOURNAL_FILE_DIR = "emailJournal";
|
private static final String EMAIL_JOURNAL_FILE_DIR = "emailJournal";
|
||||||
|
@ -75,9 +76,13 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
String webuseremail = nonNullAndTrim(vreq, WEB_USEREMAIL_PARAM);
|
String webuseremail = nonNullAndTrim(vreq, WEB_USEREMAIL_PARAM);
|
||||||
String comments = nonNullAndTrim(vreq, COMMENTS_PARAM);
|
String comments = nonNullAndTrim(vreq, COMMENTS_PARAM);
|
||||||
String formType = nonNullAndTrim(vreq, "DeliveryType");
|
String formType = nonNullAndTrim(vreq, "DeliveryType");
|
||||||
|
String captchaInput = nonNullAndTrim(vreq, "defaultReal");
|
||||||
|
String captchaDisplay = nonNullAndTrim(vreq, "defaultRealHash");
|
||||||
|
|
||||||
if (validateInput(webusername, webuseremail, comments) != null) {
|
String errorMsg = validateInput(webusername, webuseremail, comments, captchaInput, captchaDisplay);
|
||||||
return errorParametersNotValid();
|
|
||||||
|
if ( errorMsg != null) {
|
||||||
|
return errorParametersNotValid(errorMsg, webusername, webuseremail, comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
String spamReason = checkForSpam(comments, formType);
|
String spamReason = checkForSpam(comments, formType);
|
||||||
|
@ -302,18 +307,26 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String validateInput(String webusername, String webuseremail,
|
private String validateInput(String webusername, String webuseremail,
|
||||||
String comments) {
|
String comments, String captchaInput, String captchaDisplay) {
|
||||||
|
|
||||||
if( webusername.isEmpty() ){
|
if( webusername.isEmpty() ){
|
||||||
return "A proper webusername field was not found in the form submitted.";
|
return "Please enter a value in the Full name field.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if( webuseremail.isEmpty() ){
|
if( webuseremail.isEmpty() ){
|
||||||
return "A proper webuser email field was not found in the form submitted.";
|
return "Please enter a valid email address.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comments.isEmpty()) {
|
if (comments.isEmpty()) {
|
||||||
return "The proper comments field was not found in the form submitted.";
|
return "Please enter your comments or questions in the space provided.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (captchaInput.isEmpty()) {
|
||||||
|
return "Please enter the contents of the gray box in the security field provided.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !captchaHash(captchaInput).equals(captchaDisplay) ) {
|
||||||
|
return "The value you entered in the security field did not match the letters displayed in the gray box.";
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -347,6 +360,15 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String captchaHash(String value) {
|
||||||
|
int hash = 5381;
|
||||||
|
value = value.toUpperCase();
|
||||||
|
for(int i = 0; i < value.length(); i++) {
|
||||||
|
hash = ((hash << 5) + hash) + value.charAt(i);
|
||||||
|
}
|
||||||
|
return String.valueOf(hash);
|
||||||
|
}
|
||||||
|
|
||||||
private ResponseValues errorNoSmtpServer() {
|
private ResponseValues errorNoSmtpServer() {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("errorMessage",
|
body.put("errorMessage",
|
||||||
|
@ -363,11 +385,14 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
return new TemplateResponseValues(TEMPLATE_ERROR, body);
|
return new TemplateResponseValues(TEMPLATE_ERROR, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseValues errorParametersNotValid() {
|
private ResponseValues errorParametersNotValid(String errorMsg, String webusername, String webuseremail, String comments) {
|
||||||
// rjy7 We should reload the form, not go to the error page!
|
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("errorMessage", "Invalid submission");
|
body.put("errorMessage", errorMsg);
|
||||||
return new TemplateResponseValues(TEMPLATE_ERROR, body);
|
body.put("formAction", "submitFeedback");
|
||||||
|
body.put("webusername", webusername);
|
||||||
|
body.put("webuseremail", webuseremail);
|
||||||
|
body.put("comments", comments);
|
||||||
|
return new TemplateResponseValues(TEMPLATE_FORM, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseValues errorSpam() {
|
private ResponseValues errorSpam() {
|
||||||
|
|
31
webapp/web/css/jquery_plugins/jquery.realperson.css
Normal file
31
webapp/web/css/jquery_plugins/jquery.realperson.css
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* Real Person jQuery plugin styles v1.0.1. */
|
||||||
|
.realperson-challenge {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #ddd;
|
||||||
|
width: 150px;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
.realperson-text {
|
||||||
|
font-family: "Courier New",monospace;
|
||||||
|
font-size: 6px;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
line-height: 3px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.realperson-regen {
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-right: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.realpersonLabel {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#defaultReal {
|
||||||
|
margin-left: 20px;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
|
@ -6,41 +6,9 @@ function ValidateForm(formName) {
|
||||||
errors = false;
|
errors = false;
|
||||||
var errorList;
|
var errorList;
|
||||||
|
|
||||||
if (document.forms[formName].RequiredFields) {
|
|
||||||
errorList = 'Please fill out the following required fields:\n';
|
|
||||||
// build array of required fields
|
|
||||||
reqStr = document.forms[formName].RequiredFields.value;
|
|
||||||
requiredFields = reqStr.split(',');
|
|
||||||
// build array holding the names of required fields as
|
|
||||||
// displayed in error box
|
|
||||||
if (document.forms[formName].RequiredFieldsNames) {
|
|
||||||
reqNameStr = document.forms[formName].RequiredFieldsNames.value;
|
|
||||||
} else {
|
|
||||||
reqNameStr = document.forms[formName].RequiredFields.value;
|
|
||||||
}
|
|
||||||
requiredNames = reqNameStr.split(',');
|
|
||||||
// Loop through form elements, checking for required fields
|
|
||||||
while ((x < document.forms[formName].elements.length)) {
|
|
||||||
if (document.forms[formName].elements[x].name == requiredFields[y]) {
|
|
||||||
if (document.forms[formName].elements[x].value == '') {
|
|
||||||
errorList += requiredNames[y] + '\n';
|
|
||||||
errors = true;
|
|
||||||
}
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
if (errors) {
|
|
||||||
alert(errorList);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for Email formatting
|
// Check for Email formatting
|
||||||
if (document.forms[formName].EmailFields) {
|
if (document.forms[formName].EmailFields) {
|
||||||
errorList = 'Please format your e-mail address as: \"userid@institution.edu\" or enter another complete email address';
|
errorList = '\nPlease format your e-mail address as:\n \"userid@institution.edu\" or enter another complete and valid email address';
|
||||||
// build array of required fields
|
// build array of required fields
|
||||||
emailStr = document.forms[formName].EmailFields.value;
|
emailStr = document.forms[formName].EmailFields.value;
|
||||||
emailFields = emailStr.split(',');
|
emailFields = emailStr.split(',');
|
||||||
|
|
183
webapp/web/js/jquery_plugins/jquery.realperson.js
Normal file
183
webapp/web/js/jquery_plugins/jquery.realperson.js
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
/* http://keith-wood.name/realPerson.html
|
||||||
|
Real Person Form Submission for jQuery v1.0.1.
|
||||||
|
Written by Keith Wood (kwood{at}iinet.com.au) June 2009.
|
||||||
|
Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
|
||||||
|
MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
|
||||||
|
Please attribute the author if you use it. */
|
||||||
|
|
||||||
|
(function($) { // Hide scope, no $ conflict
|
||||||
|
|
||||||
|
var PROP_NAME = 'realPerson';
|
||||||
|
|
||||||
|
/* Real person manager. */
|
||||||
|
function RealPerson() {
|
||||||
|
this._defaults = {
|
||||||
|
length: 6, // Number of characters to use
|
||||||
|
includeNumbers: false, // True to use numbers as well as letters
|
||||||
|
regenerate: 'Click to change', // Instruction text to regenerate
|
||||||
|
hashName: '{n}Hash' // Name of the hash value field to compare with,
|
||||||
|
// use {n} to substitute with the original field name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||||
|
var DOTS = [
|
||||||
|
[' * ', ' * * ', ' * * ', ' * * ', ' ***** ', '* *', '* *'],
|
||||||
|
['****** ', '* *', '* *', '****** ', '* *', '* *', '****** '],
|
||||||
|
[' ***** ', '* *', '* ', '* ', '* ', '* *', ' ***** '],
|
||||||
|
['****** ', '* *', '* *', '* *', '* *', '* *', '****** '],
|
||||||
|
['*******', '* ', '* ', '**** ', '* ', '* ', '*******'],
|
||||||
|
['*******', '* ', '* ', '**** ', '* ', '* ', '* '],
|
||||||
|
[' ***** ', '* *', '* ', '* ', '* ***', '* *', ' ***** '],
|
||||||
|
['* *', '* *', '* *', '*******', '* *', '* *', '* *'],
|
||||||
|
['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '*******'],
|
||||||
|
[' *', ' *', ' *', ' *', ' *', '* *', ' ***** '],
|
||||||
|
['* *', '* ** ', '* ** ', '** ', '* ** ', '* ** ', '* *'],
|
||||||
|
['* ', '* ', '* ', '* ', '* ', '* ', '*******'],
|
||||||
|
['* *', '** **', '* * * *', '* * *', '* *', '* *', '* *'],
|
||||||
|
['* *', '** *', '* * *', '* * *', '* * *', '* **', '* *'],
|
||||||
|
[' ***** ', '* *', '* *', '* *', '* *', '* *', ' ***** '],
|
||||||
|
['****** ', '* *', '* *', '****** ', '* ', '* ', '* '],
|
||||||
|
[' ***** ', '* *', '* *', '* *', '* * *', '* * ', ' **** *'],
|
||||||
|
['****** ', '* *', '* *', '****** ', '* * ', '* * ', '* *'],
|
||||||
|
[' ***** ', '* *', '* ', ' ***** ', ' *', '* *', ' ***** '],
|
||||||
|
['*******', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
|
||||||
|
['* *', '* *', '* *', '* *', '* *', '* *', ' ***** '],
|
||||||
|
['* *', '* *', ' * * ', ' * * ', ' * * ', ' * * ', ' * '],
|
||||||
|
['* *', '* *', '* *', '* * *', '* * * *', '** **', '* *'],
|
||||||
|
['* *', ' * * ', ' * * ', ' * ', ' * * ', ' * * ', '* *'],
|
||||||
|
['* *', ' * * ', ' * * ', ' * ', ' * ', ' * ', ' * '],
|
||||||
|
['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '*******'],
|
||||||
|
[' *** ', ' * * ', '* *', '* *', '* *', ' * * ', ' *** '],
|
||||||
|
[' * ', ' ** ', ' * * ', ' * ', ' * ', ' * ', '*******'],
|
||||||
|
[' ***** ', '* *', ' *', ' * ', ' ** ', ' ** ', '*******'],
|
||||||
|
[' ***** ', '* *', ' *', ' ** ', ' *', '* *', ' ***** '],
|
||||||
|
[' * ', ' ** ', ' * * ', ' * * ', '*******', ' * ', ' * '],
|
||||||
|
['*******', '* ', '****** ', ' *', ' *', '* *', ' ***** '],
|
||||||
|
[' **** ', ' * ', '* ', '****** ', '* *', '* *', ' ***** '],
|
||||||
|
['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '* '],
|
||||||
|
[' ***** ', '* *', '* *', ' ***** ', '* *', '* *', ' ***** '],
|
||||||
|
[' ***** ', '* *', '* *', ' ******', ' *', ' * ', ' **** ']];
|
||||||
|
|
||||||
|
$.extend(RealPerson.prototype, {
|
||||||
|
/* Class name added to elements to indicate already configured with real person. */
|
||||||
|
markerClassName: 'hasRealPerson',
|
||||||
|
|
||||||
|
/* Override the default settings for all real person instances.
|
||||||
|
@param settings (object) the new settings to use as defaults
|
||||||
|
@return (RealPerson) this object */
|
||||||
|
setDefaults: function(settings) {
|
||||||
|
$.extend(this._defaults, settings || {});
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Attach the real person functionality to an input field.
|
||||||
|
@param target (element) the control to affect
|
||||||
|
@param settings (object) the custom options for this instance */
|
||||||
|
_attachRealPerson: function(target, settings) {
|
||||||
|
target = $(target);
|
||||||
|
if (target.hasClass(this.markerClassName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target.addClass(this.markerClassName);
|
||||||
|
var inst = {settings: $.extend({}, this._defaults)};
|
||||||
|
$.data(target[0], PROP_NAME, inst);
|
||||||
|
this._changeRealPerson(target, settings);
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Reconfigure the settings for a real person control.
|
||||||
|
@param target (element) the control to affect
|
||||||
|
@param settings (object) the new options for this instance or
|
||||||
|
(string) an individual property name
|
||||||
|
@param value (any) the individual property value (omit if settings is an object) */
|
||||||
|
_changeRealPerson: function(target, settings, value) {
|
||||||
|
target = $(target);
|
||||||
|
if (!target.hasClass(this.markerClassName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
settings = settings || {};
|
||||||
|
if (typeof settings == 'string') {
|
||||||
|
var name = settings;
|
||||||
|
settings = {};
|
||||||
|
settings[name] = value;
|
||||||
|
}
|
||||||
|
var inst = $.data(target[0], PROP_NAME);
|
||||||
|
$.extend(inst.settings, settings);
|
||||||
|
target.prevAll('.realperson-challenge,.realperson-hash').remove().end().
|
||||||
|
before(this._generateHTML(target, inst));
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Generate the additional content for this control.
|
||||||
|
@param target (jQuery) the input field
|
||||||
|
@param inst (object) the current instance settings
|
||||||
|
@return (string) the additional content */
|
||||||
|
_generateHTML: function(target, inst) {
|
||||||
|
var text = '';
|
||||||
|
for (var i = 0; i < inst.settings.length; i++) {
|
||||||
|
text += CHARS.charAt(Math.floor(Math.random() *
|
||||||
|
(inst.settings.includeNumbers ? 36 : 26)));
|
||||||
|
}
|
||||||
|
var html = '<div class="realperson-challenge"><div class="realperson-text">';
|
||||||
|
for (var i = 0; i < DOTS[0].length; i++) {
|
||||||
|
for (var j = 0; j < text.length; j++) {
|
||||||
|
html += DOTS[CHARS.indexOf(text.charAt(j))][i].replace(/ /g, ' ') +
|
||||||
|
' ';
|
||||||
|
}
|
||||||
|
html += '<br>';
|
||||||
|
}
|
||||||
|
html += '</div><div class="realperson-regen">' + inst.settings.regenerate +
|
||||||
|
'</div></div><input type="hidden" class="realperson-hash" name="' +
|
||||||
|
inst.settings.hashName.replace(/\{n\}/, target.attr('name')) +
|
||||||
|
'" value="' + this._hash(text) + '">';
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Remove the real person functionality from a control.
|
||||||
|
@param target (element) the control to affect */
|
||||||
|
_destroyRealPerson: function(target) {
|
||||||
|
target = $(target);
|
||||||
|
if (!target.hasClass(this.markerClassName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target.removeClass(this.markerClassName).
|
||||||
|
prevAll('.realperson-challenge,.realperson-hash').remove();
|
||||||
|
$.removeData(target[0], PROP_NAME);
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Compute a hash value for the given text.
|
||||||
|
@param value (string) the text to hash
|
||||||
|
@return the corresponding hash value */
|
||||||
|
_hash: function(value) {
|
||||||
|
var hash = 5381;
|
||||||
|
for (var i = 0; i < value.length; i++) {
|
||||||
|
hash = ((hash << 5) + hash) + value.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Attach the real person functionality to a jQuery selection.
|
||||||
|
@param command (string) the command to run (optional, default 'attach')
|
||||||
|
@param options (object) the new settings to use for these instances (optional)
|
||||||
|
@return (jQuery) for chaining further calls */
|
||||||
|
$.fn.realperson = function(options) {
|
||||||
|
var otherArgs = Array.prototype.slice.call(arguments, 1);
|
||||||
|
return this.each(function() {
|
||||||
|
if (typeof options == 'string') {
|
||||||
|
$.realperson['_' + options + 'RealPerson'].
|
||||||
|
apply($.realperson, [this].concat(otherArgs));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$.realperson._attachRealPerson(this, options || {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialise the real person functionality. */
|
||||||
|
$.realperson = new RealPerson(); // singleton instance
|
||||||
|
|
||||||
|
$('.realperson-challenge').live('click', function() {
|
||||||
|
$(this).next().next().realperson('change');
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
|
@ -5,11 +5,17 @@
|
||||||
<section class="staticPageBackground feedbackForm" role="region">
|
<section class="staticPageBackground feedbackForm" role="region">
|
||||||
<h2>${title}</h2>
|
<h2>${title}</h2>
|
||||||
|
|
||||||
|
<#if errorMessage?has_content>
|
||||||
|
<section id="error-alert"><img src="${urls.images}/iconAlert.png" role="error alert"/>
|
||||||
|
<p>${errorMessage}</p>
|
||||||
|
</section>
|
||||||
|
</#if>
|
||||||
|
|
||||||
<p>Thank you for your interest in ${siteName}.
|
<p>Thank you for your interest in ${siteName}.
|
||||||
Please submit this form with questions, comments, or feedback about the content of this site.
|
Please submit this form with questions, comments, or feedback about the content of this site.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form name="contact_form" id="contact_form" class="customForm" action="${formAction}" method="post" onsubmit="return ValidateForm('contact_form');" role="contact form">
|
<form name="contact_form" id="contact_form" class="customForm" action="${formAction!}" method="post" onSubmit="return ValidateForm('contact_form');" role="contact form">
|
||||||
<input type="hidden" name="RequiredFields" value="webusername,webuseremail,s34gfd88p9x1" />
|
<input type="hidden" name="RequiredFields" value="webusername,webuseremail,s34gfd88p9x1" />
|
||||||
<input type="hidden" name="RequiredFieldsNames" value="Name,Email address,Comments" />
|
<input type="hidden" name="RequiredFieldsNames" value="Name,Email address,Comments" />
|
||||||
<input type="hidden" name="EmailFields" value="webuseremail" />
|
<input type="hidden" name="EmailFields" value="webuseremail" />
|
||||||
|
@ -17,21 +23,34 @@
|
||||||
<input type="hidden" name="DeliveryType" value="contact" />
|
<input type="hidden" name="DeliveryType" value="contact" />
|
||||||
|
|
||||||
<label for="webusername">Full name <span class="requiredHint"> *</span></label>
|
<label for="webusername">Full name <span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="webusername" />
|
<input type="text" name="webusername" value="${webusername!}"/>
|
||||||
|
|
||||||
<label for="webuseremail">Email address <span class="requiredHint"> *</span></label>
|
<label for="webuseremail">Email address <span class="requiredHint"> *</span></label>
|
||||||
<input type="text" name="webuseremail" />
|
<input type="text" name="webuseremail" value="${webuseremail!}"/>
|
||||||
|
|
||||||
<label>Comments, questions, or suggestions <span class="requiredHint"> *</span></label>
|
<label>Comments, questions, or suggestions <span class="requiredHint"> *</span></label>
|
||||||
<textarea name="s34gfd88p9x1" rows="10" cols="90"></textarea>
|
<textarea name="s34gfd88p9x1" rows="10" cols="90">${comments!}</textarea>
|
||||||
|
|
||||||
|
|
||||||
|
<p><label class="realpersonLabel">Please enter the letters displayed below into the security field:</label>
|
||||||
|
|
||||||
|
<input type="text" id="defaultReal" name="defaultReal"></p>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<input id="submit" type="submit" value="Send Mail" />
|
<br /><input id="submit" type="submit" value="Send Mail" />
|
||||||
</div
|
</div>
|
||||||
|
|
||||||
<p class="requiredHint">* required fields</p>
|
<p class="requiredHint">* required fields</p>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/customForm.css" />')}
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarker/edit/forms/css/customForm.css" />',
|
||||||
${scripts.add('<script type="text/javascript" src="${urls.base}/js/commentForm.js"></script>')}
|
'<link rel="stylesheet" href="${urls.base}/css/jquery_plugins/jquery.realperson.css" />')}
|
||||||
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/commentForm.js"></script>',
|
||||||
|
'<script type="text/javascript" src="${urls.base}/js/jquery_plugins/jquery.realperson.js"></script>',
|
||||||
|
'<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>')}
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
$('#defaultReal').realperson();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
Loading…
Add table
Reference in a new issue