Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit 5555748482df134c776e8b36c965af525181bb73 1 parent b6091d4
Robert DeSimone authored
12 README.md
Source Rendered
... ... @@ -1,4 +1,14 @@
1 1 jquery.contactForm
2 2 ==================
3 3
4   -A self-contained jQuery contact form plug-in, written in CoffeeScript.
  4 +A self-contained jQuery contact form plug-in, written in CoffeeScript.
  5 +
  6 +Features:
  7 + * Optionally uses [Tipsy](http://onehackoranother.com/projects/jquery/tipsy/) for validation messages (if already loaded)
  8 + * Fully self-contained - just .contactForm() an element and all child elements will be created.
  9 + * .destroy() method allows hooking for use by other plug-ins (like [fancyBox](http://fancyapps.com/fancybox/))
  10 + * Produces nice JSON output, has many overrides for customizing text and classes
  11 +
  12 +TODO:
  13 +------------------
  14 + * Fix rendering bug with Android browser (have not tested other mobile browsers)
190 jquery.contactForm.coffee
... ... @@ -0,0 +1,190 @@
  1 +(($) ->
  2 + settings =
  3 + validate: true
  4 + debug: false
  5 + responseHeader: "Thank You!"
  6 + responseMsg: "Your contact information and message has been sent. We will get back to you soon!"
  7 + contactFormHeader: "Contact Us"
  8 + contactFormMsg: "Please use this form to contact us at your convenience."
  9 + preferredContactMethods: [ "Choose a contact method", "Phone", "E-mail" ]
  10 + postUrl: "/Home/PostContactUs"
  11 + maxNameLength: 100
  12 + dontSend: false
  13 +
  14 + createInput = (parent, labelText, namePrefix, inputType = "text") ->
  15 + labelDiv = $("<div />",
  16 + class: "label"
  17 + )
  18 + label = $("<label />",
  19 + text: labelText
  20 + ).appendTo labelDiv
  21 +
  22 + parent.append labelDiv
  23 +
  24 + inputDiv = $("<div />",
  25 + class: "input"
  26 + )
  27 +
  28 + input = ""
  29 +
  30 + switch inputType
  31 + when "select"
  32 + input = $("<select />",
  33 + type: inputType
  34 + val: ""
  35 + name: namePrefix + "Input"
  36 + )
  37 + populateOptions($(input), settings.preferredContactMethods)
  38 + when "textarea"
  39 + input = $("<textarea />",
  40 + type: inputType
  41 + rows: 10
  42 + val: ""
  43 + name: namePrefix + "Input"
  44 + 'data-val-text': labelText + " is not valid"
  45 + )
  46 + when "button"
  47 + input = $("<input />",
  48 + type: "button"
  49 + val: "Submit"
  50 + name: namePrefix + "Input"
  51 + )
  52 + else
  53 + input = $("<input />",
  54 + type: inputType
  55 + val: ""
  56 + class: 'required'
  57 + 'data-val-text': labelText + " is not valid"
  58 + name: namePrefix + "Input"
  59 + )
  60 +
  61 +
  62 + input.appendTo inputDiv
  63 + parent.append inputDiv
  64 + return input
  65 +
  66 +
  67 + populateOptions = (parent, options) ->
  68 + parent.append $("<option>" + option + "</option>", value: option) for option in options
  69 +
  70 + createHeading = (parent, headerText, message) ->
  71 + responseDiv = $("<div class='message-body-response-header' />")
  72 +
  73 + header = $("<h1>" + headerText + "</h1>")
  74 + responseText = $("<p>" + message + "</p>")
  75 +
  76 + header.appendTo responseDiv
  77 + responseText.appendTo responseDiv
  78 +
  79 + responseDiv.appendTo parent
  80 +
  81 + return responseDiv
  82 +
  83 + methods =
  84 + init: (options) ->
  85 + console?.log "Preparing contactForm"
  86 + @each ->
  87 + thisRef = $(@)
  88 +
  89 + form = $("<form>",
  90 + class: "contactForm"
  91 + method: "get"
  92 + action: ""
  93 + )
  94 + settings = $.extend settings, options
  95 +
  96 + contactFormHead = createHeading(thisRef, settings.contactFormHeader, settings.contactFormMsg)
  97 + responseHead = createHeading(thisRef, settings.responseHeader, settings.responseMsg)
  98 + responseHead.hide()
  99 + nameInput = createInput(form, "Name", "name")
  100 + emailInput = createInput(form, "Email", "email")
  101 + phoneInput = createInput(form, "Phone", "phone")
  102 + preferredContactMethodInput = createInput(form, "Contact me via", "preferredContact", "select")
  103 + subjectInput = createInput(form, "Subject", "subject")
  104 + messageInput = createInput(form, "Message", "message", "textarea")
  105 + submitInput = createInput(form, "", "submit", "button")
  106 + form.appendTo $(@)
  107 +
  108 + submitInput.click ->
  109 + # Validation method would go here
  110 + return unless settings.validate and formIsValid form
  111 + postData =
  112 + ContactName: nameInput.val()
  113 + ContactEmail: emailInput.val()
  114 + ContactPhone: phoneInput.val()
  115 + ContactVia: preferredContactMethodInput.val()
  116 + ContactSubject: subjectInput.val()
  117 + ContactMessage: messageInput.val()
  118 +
  119 + console?.log JSON.stringify(postData) if options.debug
  120 + form.hide()
  121 + contactFormHead.hide()
  122 + responseHead.show()
  123 +
  124 + if !settings.dontSend
  125 + $.ajax settings.postUrl,
  126 + type: 'POST'
  127 + dataType: 'json'
  128 + data: postData
  129 +
  130 + destroy: () ->
  131 + console?.log "Removing"
  132 + @find('a').each (index, element) =>
  133 + $(element).tipsy "hide"
  134 + @empty()
  135 +
  136 + formIsValid = (form) ->
  137 + invalid = 0
  138 + form.find('input, textarea').each (index, element) =>
  139 +
  140 + thisInput = $(element)
  141 + thisInputInvalid = false
  142 +
  143 + if $.fn.tipsy
  144 + tipsyDiv = $('body').find('div.tipsy-inner:contains("' + thisInput.attr('data-val-text') + '")')
  145 + if tipsyDiv
  146 + tipsyDiv.parent().remove()
  147 +
  148 + switch thisInput.attr('name')
  149 + when "nameInput", "subjectInput", "messageInput"
  150 + if thisInput.val().length < 2 or !/[A-Za-z0-9'].*/.test(thisInput.val())
  151 + invalid++
  152 + thisInputInvalid = true
  153 + when "phoneInput"
  154 + phoneVal = thisInput.val().replace(/[\+\(\)\-x\s]/g, '')
  155 + if phoneVal and isNaN phoneVal
  156 + invalid++
  157 + thisInputInvalid = true
  158 + when "emailInput"
  159 + emailRe = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
  160 + if thisInput.val().length < 6 or !emailRe.test(thisInput.val())
  161 + invalid++
  162 + thisInputInvalid = true
  163 +
  164 + if thisInputInvalid
  165 + valElem = $("<a />",
  166 + title: thisInput.attr('data-val-text')
  167 + href: "#"
  168 + )
  169 + thisInput.after(valElem)
  170 + if $.fn.tipsy
  171 + valElem.tipsy
  172 + trigger: 'manual'
  173 + gravity: 'w'
  174 + fade: true
  175 + valElem.tipsy "show"
  176 +
  177 +
  178 +
  179 + if invalid > 0 then return false else return true
  180 +
  181 + $.fn.contactForm = (method) ->
  182 + if methods[method]
  183 + methods[method].apply this, Array.prototype.slice.call arguments, 1
  184 + else if typeof method is 'object' or !method
  185 + methods.init.apply this, arguments
  186 + else
  187 + $.error "jQuery.pluginName: Method #{ method } does not exist on jQuery.pluginName"
  188 + return
  189 +)(jQuery)
  190 +
230 jquery.contactForm.js
... ... @@ -0,0 +1,230 @@
  1 +// Generated by CoffeeScript 1.4.0
  2 +(function() {
  3 +
  4 + (function($) {
  5 + var createHeading, createInput, formIsValid, methods, populateOptions, settings;
  6 + settings = {
  7 + validate: true,
  8 + debug: false,
  9 + responseHeader: "Thank You!",
  10 + responseMsg: "Your contact information and message has been sent. We will get back to you soon!",
  11 + contactFormHeader: "Contact Us",
  12 + contactFormMsg: "Please use this form to contact us at your convenience.",
  13 + preferredContactMethods: ["Choose a contact method", "Phone", "E-mail"],
  14 + postUrl: "/Home/PostContactUs",
  15 + maxNameLength: 100,
  16 + dontSend: false
  17 + };
  18 + createInput = function(parent, labelText, namePrefix, inputType) {
  19 + var input, inputDiv, label, labelDiv;
  20 + if (inputType == null) {
  21 + inputType = "text";
  22 + }
  23 + labelDiv = $("<div />", {
  24 + "class": "label"
  25 + });
  26 + label = $("<label />", {
  27 + text: labelText
  28 + }).appendTo(labelDiv);
  29 + parent.append(labelDiv);
  30 + inputDiv = $("<div />", {
  31 + "class": "input"
  32 + });
  33 + input = "";
  34 + switch (inputType) {
  35 + case "select":
  36 + input = $("<select />", {
  37 + type: inputType,
  38 + val: "",
  39 + name: namePrefix + "Input"
  40 + });
  41 + populateOptions($(input), settings.preferredContactMethods);
  42 + break;
  43 + case "textarea":
  44 + input = $("<textarea />", {
  45 + type: inputType,
  46 + rows: 10,
  47 + val: "",
  48 + name: namePrefix + "Input",
  49 + 'data-val-text': labelText + " is not valid"
  50 + });
  51 + break;
  52 + case "button":
  53 + input = $("<input />", {
  54 + type: "button",
  55 + val: "Submit",
  56 + name: namePrefix + "Input"
  57 + });
  58 + break;
  59 + default:
  60 + input = $("<input />", {
  61 + type: inputType,
  62 + val: "",
  63 + "class": 'required',
  64 + 'data-val-text': labelText + " is not valid",
  65 + name: namePrefix + "Input"
  66 + });
  67 + }
  68 + input.appendTo(inputDiv);
  69 + parent.append(inputDiv);
  70 + return input;
  71 + };
  72 + populateOptions = function(parent, options) {
  73 + var option, _i, _len, _results;
  74 + _results = [];
  75 + for (_i = 0, _len = options.length; _i < _len; _i++) {
  76 + option = options[_i];
  77 + _results.push(parent.append($("<option>" + option + "</option>", {
  78 + value: option
  79 + })));
  80 + }
  81 + return _results;
  82 + };
  83 + createHeading = function(parent, headerText, message) {
  84 + var header, responseDiv, responseText;
  85 + responseDiv = $("<div class='message-body-response-header' />");
  86 + header = $("<h1>" + headerText + "</h1>");
  87 + responseText = $("<p>" + message + "</p>");
  88 + header.appendTo(responseDiv);
  89 + responseText.appendTo(responseDiv);
  90 + responseDiv.appendTo(parent);
  91 + return responseDiv;
  92 + };
  93 + methods = {
  94 + init: function(options) {
  95 + if (typeof console !== "undefined" && console !== null) {
  96 + console.log("Preparing contactForm");
  97 + }
  98 + return this.each(function() {
  99 + var contactFormHead, emailInput, form, messageInput, nameInput, phoneInput, preferredContactMethodInput, responseHead, subjectInput, submitInput, thisRef;
  100 + thisRef = $(this);
  101 + form = $("<form>", {
  102 + "class": "contactForm",
  103 + method: "get",
  104 + action: ""
  105 + });
  106 + settings = $.extend(settings, options);
  107 + contactFormHead = createHeading(thisRef, settings.contactFormHeader, settings.contactFormMsg);
  108 + responseHead = createHeading(thisRef, settings.responseHeader, settings.responseMsg);
  109 + responseHead.hide();
  110 + nameInput = createInput(form, "Name", "name");
  111 + emailInput = createInput(form, "Email", "email");
  112 + phoneInput = createInput(form, "Phone", "phone");
  113 + preferredContactMethodInput = createInput(form, "Contact me via", "preferredContact", "select");
  114 + subjectInput = createInput(form, "Subject", "subject");
  115 + messageInput = createInput(form, "Message", "message", "textarea");
  116 + submitInput = createInput(form, "", "submit", "button");
  117 + form.appendTo($(this));
  118 + return submitInput.click(function() {
  119 + var postData;
  120 + if (!(settings.validate && formIsValid(form))) {
  121 + return;
  122 + }
  123 + postData = {
  124 + ContactName: nameInput.val(),
  125 + ContactEmail: emailInput.val(),
  126 + ContactPhone: phoneInput.val(),
  127 + ContactVia: preferredContactMethodInput.val(),
  128 + ContactSubject: subjectInput.val(),
  129 + ContactMessage: messageInput.val()
  130 + };
  131 + if (options.debug) {
  132 + if (typeof console !== "undefined" && console !== null) {
  133 + console.log(JSON.stringify(postData));
  134 + }
  135 + }
  136 + form.hide();
  137 + contactFormHead.hide();
  138 + responseHead.show();
  139 + if (!settings.dontSend) {
  140 + return $.ajax(settings.postUrl, {
  141 + type: 'POST',
  142 + dataType: 'json',
  143 + data: postData
  144 + });
  145 + }
  146 + });
  147 + });
  148 + },
  149 + destroy: function() {
  150 + var _this = this;
  151 + if (typeof console !== "undefined" && console !== null) {
  152 + console.log("Removing");
  153 + }
  154 + this.find('a').each(function(index, element) {
  155 + return $(element).tipsy("hide");
  156 + });
  157 + return this.empty();
  158 + }
  159 + };
  160 + formIsValid = function(form) {
  161 + var invalid,
  162 + _this = this;
  163 + invalid = 0;
  164 + form.find('input, textarea').each(function(index, element) {
  165 + var emailRe, phoneVal, thisInput, thisInputInvalid, tipsyDiv, valElem;
  166 + thisInput = $(element);
  167 + thisInputInvalid = false;
  168 + if ($.fn.tipsy) {
  169 + tipsyDiv = $('body').find('div.tipsy-inner:contains("' + thisInput.attr('data-val-text') + '")');
  170 + if (tipsyDiv) {
  171 + tipsyDiv.parent().remove();
  172 + }
  173 + }
  174 + switch (thisInput.attr('name')) {
  175 + case "nameInput":
  176 + case "subjectInput":
  177 + case "messageInput":
  178 + if (thisInput.val().length < 2 || !/[A-Za-z0-9'].*/.test(thisInput.val())) {
  179 + invalid++;
  180 + thisInputInvalid = true;
  181 + }
  182 + break;
  183 + case "phoneInput":
  184 + phoneVal = thisInput.val().replace(/[\+\(\)\-x\s]/g, '');
  185 + if (phoneVal && isNaN(phoneVal)) {
  186 + invalid++;
  187 + thisInputInvalid = true;
  188 + }
  189 + break;
  190 + case "emailInput":
  191 + emailRe = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  192 + if (thisInput.val().length < 6 || !emailRe.test(thisInput.val())) {
  193 + invalid++;
  194 + thisInputInvalid = true;
  195 + }
  196 + }
  197 + if (thisInputInvalid) {
  198 + valElem = $("<a />", {
  199 + title: thisInput.attr('data-val-text'),
  200 + href: "#"
  201 + });
  202 + thisInput.after(valElem);
  203 + if ($.fn.tipsy) {
  204 + valElem.tipsy({
  205 + trigger: 'manual',
  206 + gravity: 'w',
  207 + fade: true
  208 + });
  209 + return valElem.tipsy("show");
  210 + }
  211 + }
  212 + });
  213 + if (invalid > 0) {
  214 + return false;
  215 + } else {
  216 + return true;
  217 + }
  218 + };
  219 + $.fn.contactForm = function(method) {
  220 + if (methods[method]) {
  221 + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
  222 + } else if (typeof method === 'object' || !method) {
  223 + return methods.init.apply(this, arguments);
  224 + } else {
  225 + return $.error("jQuery.pluginName: Method " + method + " does not exist on jQuery.pluginName");
  226 + }
  227 + };
  228 + })(jQuery);
  229 +
  230 +}).call(this);
1  jquery.contactForm.min.js
... ... @@ -0,0 +1 @@
  1 +(function(){(function($){var createHeading,createInput,formIsValid,methods,populateOptions,settings;settings={validate:true,debug:false,responseHeader:"Thank You!",responseMsg:"Your contact information and message has been sent. We will get back to you soon!",contactFormHeader:"Contact Us",contactFormMsg:"Please use this form to contact us at your convenience.",preferredContactMethods:["Choose a contact method","Phone","E-mail"],postUrl:"/Home/PostContactUs",maxNameLength:100,dontSend:false};createInput=function(parent,labelText,namePrefix,inputType){var input,inputDiv,label,labelDiv;if(inputType==null){inputType="text"}labelDiv=$("<div />",{"class":"label"});label=$("<label />",{text:labelText}).appendTo(labelDiv);parent.append(labelDiv);inputDiv=$("<div />",{"class":"input"});input="";switch(inputType){case"select":input=$("<select />",{type:inputType,val:"",name:namePrefix+"Input"});populateOptions($(input),settings.preferredContactMethods);break;case"textarea":input=$("<textarea />",{type:inputType,rows:10,val:"",name:namePrefix+"Input","data-val-text":labelText+" is not valid"});break;case"button":input=$("<input />",{type:"button",val:"Submit",name:namePrefix+"Input"});break;default:input=$("<input />",{type:inputType,val:"","class":"required","data-val-text":labelText+" is not valid",name:namePrefix+"Input"})}input.appendTo(inputDiv);parent.append(inputDiv);return input};populateOptions=function(parent,options){var option,_i,_len,_results;_results=[];for(_i=0,_len=options.length;_i<_len;_i++){option=options[_i];_results.push(parent.append($("<option>"+option+"</option>",{value:option})))}return _results};createHeading=function(parent,headerText,message){var header,responseDiv,responseText;responseDiv=$("<div class='message-body-response-header' />");header=$("<h1>"+headerText+"</h1>");responseText=$("<p>"+message+"</p>");header.appendTo(responseDiv);responseText.appendTo(responseDiv);responseDiv.appendTo(parent);return responseDiv};methods={init:function(options){if(typeof console!=="undefined"&&console!==null){console.log("Preparing contactForm")}return this.each(function(){var contactFormHead,emailInput,form,messageInput,nameInput,phoneInput,preferredContactMethodInput,responseHead,subjectInput,submitInput,thisRef;thisRef=$(this);form=$("<form>",{"class":"contactForm",method:"get",action:""});settings=$.extend(settings,options);contactFormHead=createHeading(thisRef,settings.contactFormHeader,settings.contactFormMsg);responseHead=createHeading(thisRef,settings.responseHeader,settings.responseMsg);responseHead.hide();nameInput=createInput(form,"Name","name");emailInput=createInput(form,"Email","email");phoneInput=createInput(form,"Phone","phone");preferredContactMethodInput=createInput(form,"Contact me via","preferredContact","select");subjectInput=createInput(form,"Subject","subject");messageInput=createInput(form,"Message","message","textarea");submitInput=createInput(form,"","submit","button");form.appendTo($(this));return submitInput.click(function(){var postData;if(!(settings.validate&&formIsValid(form))){return}postData={ContactName:nameInput.val(),ContactEmail:emailInput.val(),ContactPhone:phoneInput.val(),ContactVia:preferredContactMethodInput.val(),ContactSubject:subjectInput.val(),ContactMessage:messageInput.val()};if(options.debug){if(typeof console!=="undefined"&&console!==null){console.log(JSON.stringify(postData))}}form.hide();contactFormHead.hide();responseHead.show();if(!settings.dontSend){return $.ajax(settings.postUrl,{type:"POST",dataType:"json",data:postData})}})})},destroy:function(){var _this=this;if(typeof console!=="undefined"&&console!==null){console.log("Removing")}this.find("a").each(function(index,element){return $(element).tipsy("hide")});return this.empty()}};formIsValid=function(form){var invalid,_this=this;invalid=0;form.find("input, textarea").each(function(index,element){var emailRe,phoneVal,thisInput,thisInputInvalid,tipsyDiv,valElem;thisInput=$(element);thisInputInvalid=false;if($.fn.tipsy){tipsyDiv=$("body").find('div.tipsy-inner:contains("'+thisInput.attr("data-val-text")+'")');if(tipsyDiv){tipsyDiv.parent().remove()}}switch(thisInput.attr("name")){case"nameInput":case"subjectInput":case"messageInput":if(thisInput.val().length<2||!/[A-Za-z0-9'].*/.test(thisInput.val())){invalid++;thisInputInvalid=true}break;case"phoneInput":phoneVal=thisInput.val().replace(/[\+\(\)\-x\s]/g,"");if(phoneVal&&isNaN(phoneVal)){invalid++;thisInputInvalid=true}break;case"emailInput":emailRe=/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;if(thisInput.val().length<6||!emailRe.test(thisInput.val())){invalid++;thisInputInvalid=true}}if(thisInputInvalid){valElem=$("<a />",{title:thisInput.attr("data-val-text"),href:"#"});thisInput.after(valElem);if($.fn.tipsy){valElem.tipsy({trigger:"manual",gravity:"w",fade:true});return valElem.tipsy("show")}}});if(invalid>0){return false}else{return true}};$.fn.contactForm=function(method){if(methods[method]){return methods[method].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof method==="object"||!method){return methods.init.apply(this,arguments)}else{return $.error("jQuery.pluginName: Method "+method+" does not exist on jQuery.pluginName")}}}})(jQuery)}).call(this);

0 comments on commit 5555748

Please sign in to comment.
Something went wrong with that request. Please try again.