nm3clol-archived-russellcou.../mirror/www.russellcountyva.us/-1466400618.js

6080 lines
213 KiB
JavaScript

/*
The following errors were found when attempting to minify this file:
- Line 54: Parse error. missing : after property id
- Line 54: Parse error. illegal character
- Line 54: Parse error. missing ; before statement
- Line 54: Parse error. illegal character
- Line 54: Parse error. syntax error
- Line 55: Parse error. syntax error
- Line 56: Parse error. syntax error
- Line 57: Parse error. syntax error
- Line 59: Parse error. syntax error
- Line 60: Parse error. illegal character
- Line 60: Parse error. missing ) after argument list
- Line 60: Parse error. illegal character
- Line 60: Parse error. syntax error
- Line 61: Parse error. syntax error
- Line 62: Parse error. syntax error
- Line 63: Parse error. syntax error
- Line 64: Parse error. syntax error
- Line 66: Parse error. syntax error
- Line 68: Parse error. missing ; before statement
- Line 76: Parse error. syntax error
- Line 78: Parse error. syntax error
- Line 83: Parse error. invalid return
- Line 84: Parse error. syntax error
- Line 86: Parse error. missing ; before statement
- Line 90: Parse error. syntax error
- Line 91: Parse error. syntax error
- Line 92: Parse error. syntax error
- Line 94: Parse error. syntax error
- Line 96: Parse error. missing ; before statement
- Line 102: Parse error. illegal character
- Line 102: Parse error. missing ; before statement
- Line 102: Parse error. illegal character
- Line 103: Parse error. syntax error
- Line 104: Parse error. syntax error
- Line 107: Parse error. syntax error
- Line 110: Parse error. illegal character
- Line 110: Parse error. missing ; before statement
- Line 110: Parse error. illegal character
- Line 114: Parse error. invalid return
- Line 115: Parse error. syntax error
- Line 117: Parse error. missing ; before statement
- Line 118: Parse error. syntax error
- Line 119: Parse error. syntax error
- Line 120: Parse error. syntax error
- Line 125: Parse error. invalid return
- Line 130: Parse error. missing ; after for-loop initializer
- Line 130: Parse error. missing ; before statement
- Line 137: Parse error. syntax error
- Line 144: Parse error. syntax error
- Line 146: Parse error. syntax error
- Line 148: Parse error. syntax error
- Line 149: Parse error. syntax error
- Line 150: Parse error. syntax error
- Line 440: Parse error. missing ; before statement
- Line 4762: Parse error. IE8 (and below) will parse trailing commas in array and object literals incorrectly. If you are targeting newer versions of JS, set the appropriate language_in option.
- Line 5035: Parse error. IE8 (and below) will parse trailing commas in array and object literals incorrectly. If you are targeting newer versions of JS, set the appropriate language_in option.
- Line 5145: Parse error. syntax error
- Line 5150: Parse error. illegal character
- Line 5150: Parse error. missing } in compound statement
- Line 5150: Parse error. missing ; before statement
- Line 5150: Parse error. illegal character
- Line 5151: Parse error. syntax error
- Line 5153: Parse error. missing ) in parenthetical
- Line 5154: Parse error. syntax error
- Line 5159: Parse error. illegal character
- Line 5159: Parse error. missing } in compound statement
- Line 5159: Parse error. missing ; before statement
- Line 5159: Parse error. illegal character
- Line 5161: Parse error. syntax error
- Line 5163: Parse error. invalid return
- Line 5163: Parse error. syntax error
- Line 5168: Parse error. invalid return
- Line 5168: Parse error. illegal character
- Line 5168: Parse error. missing } in compound statement
- Line 5168: Parse error. missing ; before statement
- Line 5168: Parse error. illegal character
- Line 5169: Parse error. syntax error
- Line 5170: Parse error. syntax error
- Line 5172: Parse error. invalid return
- Line 5174: Parse error. syntax error
- Line 5175: Parse error. syntax error
- Line 5176: Parse error. syntax error
*/
/*!
* pickadate.js v3.6.4, 2019/05/25
* By Amsul, http://amsul.ca
* Hosted on http://amsul.github.io/pickadate.js
* Licensed under MIT
*/
(function(n){typeof define=="function"&&define.amd?define("picker",["jquery"],n):typeof exports=="object"?module.exports=n(require("jquery")):typeof window=="object"?window.Picker=n(jQuery):this.Picker=n(jQuery)})(function(n){function t(e,s,h,a){function g(){return t._.node("div",t._.node("div",t._.node("div",t._.node("div",v.component.nodes(y.open),w.box),w.wrap),w.frame),w.holder,'tabindex="-1"')}function rt(){b.data(s,v).addClass(w.input).val(b.data("value")?v.get("select",p.format):e.value).on("focus."+y.id+" click."+y.id,function(n){n.preventDefault();v.open()}).on("mousedown",function(){y.handlingOpen=!0;var t=function(){setTimeout(function(){n(document).off("mouseup",t);y.handlingOpen=!1},0)};n(document).on("mouseup",t)});if(!p.editable)b.on("keydown."+y.id,it);i(e,{haspopup:!0,readonly:!1,owns:e.id+"_root"})}function ut(){i(v.$root[0],"hidden",!0)}function nt(){v.$holder.on({keydown:it,"focus.toOpen":tt,blur:function(){b.removeClass(w.target)},focusin:function(n){v.$root.removeClass(w.focused);n.stopPropagation()},"mousedown click":function(t){var i=r(t,e);i!=v.$holder[0]&&(t.stopPropagation(),t.type!="mousedown"||n(i).is("input, select, textarea, button, option")||(t.preventDefault(),v.$holder.eq(0).focus()))}}).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var r=n(this),i=r.data(),u=r.hasClass(w.navDisabled)||r.hasClass(w.disabled),t=o();t=t&&(t.type||t.href?t:null);(u||t&&!n.contains(v.$root[0],t))&&v.$holder.eq(0).focus();!u&&i.nav?v.set("highlight",v.component.item.highlight,{nav:i.nav}):!u&&"pick"in i?(v.set("select",i.pick),p.closeOnSelect&&v.close(!0)):i.clear?(v.clear(),p.closeOnClear&&v.close(!0)):i.close&&v.close(!0)})}function ft(){var t;p.hiddenName===!0?(t=e.name,e.name=""):(t=[typeof p.hiddenPrefix=="string"?p.hiddenPrefix:"",typeof p.hiddenSuffix=="string"?p.hiddenSuffix:"_submit"],t=t[0]+e.name+t[1]);v._hidden=n('<input type=hidden name="'+t+'"'+(b.data("value")||e.value?' value="'+v.get("select",p.formatSubmit)+'"':"")+">")[0];b.on("change."+y.id,function(){v._hidden.value=e.value?v.get("select",p.formatSubmit):""})}function et(){if(k&&c)v.$holder.find("."+w.frame).one("transitionend",function(){v.$holder.eq(0).focus()});else setTimeout(function(){v.$holder.eq(0).focus()},0)}function tt(n){n.stopPropagation();b.addClass(w.target);v.$root.addClass(w.focused);v.open()}function it(n){var t=n.keyCode,i=/^(8|46)$/.test(t);if(t==27)return v.close(!0),!1;(t==32||i||!y.open&&v.component.key[t])&&(n.preventDefault(),n.stopPropagation(),i?v.clear().close():v.open())}if(!e)return t;var k=!1,y={id:e.id||"P"+Math.abs(~~(Math.random()*new Date)),handlingOpen:!1},p=h?n.extend(!0,{},h.defaults,a):a||{},w=n.extend({},t.klasses(),p.klass),b=n(e),d=function(){return this.start()},v=d.prototype={constructor:d,$node:b,start:function(){if(y&&y.start)return v;y.methods={};y.start=!0;y.open=!1;y.type=e.type;e.autofocus=e==o();e.readOnly=!p.editable;p.id=e.id=e.id||y.id;e.type!="text"&&(e.type="text");v.component=new h(v,p);v.$root=n('<div class="'+w.picker+'" id="'+e.id+'_root" />');ut();v.$holder=n(g()).appendTo(v.$root);nt();p.formatSubmit&&ft();rt();p.containerHidden?n(p.containerHidden).append(v._hidden):b.after(v._hidden);p.container?n(p.container).append(v.$root):b.after(v.$root);v.on({start:v.component.onStart,render:v.component.onRender,stop:v.component.onStop,open:v.component.onOpen,close:v.component.onClose,set:v.component.onSet}).on({start:p.onStart,render:p.onRender,stop:p.onStop,open:p.onOpen,close:p.onClose,set:p.onSet});return k=l(v.$holder[0]),e.autofocus&&v.open(),v.trigger("start").trigger("render")},render:function(t){return t?(v.$holder=n(g()),nt(),v.$root.html(v.$holder)):v.$root.find("."+w.box).html(v.component.nodes(y.open)),v.trigger("render")},stop:function(){return y.start?(v.close(),v._hidden&&v._hidden.parentNode.removeChild(v._hidden),v.$root.remove(),b.removeClass(w.input).removeData(s),setTimeout(function(){b.off("."+y.id)},0),e.type=y.type,e.readOnly=!1,v.trigger("stop"),y.methods={},y.start=!1,v):v},open:function(o){if(y.open)return v;if(b.addClass(w.active),setTimeout(function(){v.$root.addClass(w.opened);i(v.$root[0],"hidden",!1)},0),o!==!1){y.open=!0;k&&n("body").css("overflow","hidden").css("padding-right","+="+f());et();u.on("click."+y.id+" focusin."+y.id,function(n){if(!y.handlingOpen){var t=r(n,e);n.isSimulated||t==e||t==document||n.which==3||v.close(t===v.$holder[0])}}).on("keydown."+y.id,function(i){var u=i.keyCode,f=v.component.key[u],o=r(i,e);u==27?v.close(!0):o==v.$holder[0]&&(f||u==13)?(i.preventDefault(),f?t._.trigger(v.component.key.go,v,[t._.trigger(f)]):v.$root.find("."+w.highlighted).hasClass(w.disabled)||(v.set("select",v.component.item.highlight),p.closeOnSelect&&v.close(!0))):n.contains(v.$root[0],o)&&u==13&&(i.preventDefault(),o.click())})}return v.trigger("open")},close:function(t){return(t&&(p.editable?e.focus():(v.$holder.off("focus.toOpen").focus(),setTimeout(function(){v.$holder.on("focus.toOpen",tt)},0))),b.removeClass(w.active),setTimeout(function(){v.$root.removeClass(w.opened+" "+w.focused);i(v.$root[0],"hidden",!0)},0),!y.open)?v:(y.open=!1,k&&n("body").css("overflow","").css("padding-right","-="+f()),u.off("."+y.id),v.trigger("close"))},clear:function(n){return v.set("clear",null,n)},set:function(t,i,r){var u,f,o=n.isPlainObject(t),e=o?t:{};if(r=o&&n.isPlainObject(i)?i:r||{},t){o||(e[t]=i);for(u in e)f=e[u],u in v.component.item&&(f===undefined&&(f=null),v.component.set(u,f,r)),(u=="select"||u=="clear")&&p.updateInput&&b.val(u=="clear"?"":v.get(u,p.format)).trigger("change");v.render()}return r.muted?v:v.trigger("set",e)},get:function(n,i){if(n=n||"value",y[n]!=null)return y[n];if(n=="valueSubmit"){if(v._hidden)return v._hidden.value;n="value"}if(n=="value")return e.value;if(n in v.component.item){if(typeof i=="string"){var r=v.component.get(n);return r?t._.trigger(v.component.formats.toString,v.component,[i,r]):""}return v.component.get(n)}},on:function(t,i,r){var u,e,o=n.isPlainObject(t),f=o?t:{};if(t){o||(f[t]=i);for(u in f)e=f[u],r&&(u="_"+u),y.methods[u]=y.methods[u]||[],y.methods[u].push(e)}return v},off:function(){var n,t,i=arguments;for(n=0,namesCount=i.length;n<namesCount;n+=1)t=i[n],t in y.methods&&delete y.methods[t];return v},trigger:function(n,i){var r=function(n){var r=y.methods[n];r&&r.map(function(n){t._.trigger(n,v,[i])})};return r("_"+n),r(n),v}};return new d}function l(n){var t,i="position";return n.currentStyle?t=n.currentStyle[i]:window.getComputedStyle&&(t=getComputedStyle(n)[i]),t=="fixed"}function f(){var t,i,r,u;return h.height()<=s.height()?0:(t=n('<div style="visibility:hidden;width:100px" />').appendTo("body"),i=t[0].offsetWidth,t.css("overflow","scroll"),r=n('<div style="width:100%" />').appendTo(t),u=r[0].offsetWidth,t.remove(),i-u)}function r(n,t){var i=[];return(n.path&&(i=n.path),n.originalEvent&&n.originalEvent.path&&(i=n.originalEvent.path),i&&i.length>0)?t&&i.indexOf(t)>=0?t:i[0]:n.target}function i(t,i,r){if(n.isPlainObject(i))for(var u in i)e(t,u,i[u]);else e(t,i,r)}function e(n,t,i){n.setAttribute((t=="role"?"":"aria-")+t,i)}function a(t,i){var r,u,f;n.isPlainObject(t)||(t={attribute:i});i="";for(r in t)u=(r=="role"?"":"aria-")+r,f=t[r],i+=f==null?"":u+'="'+t[r]+'"';return i}function o(){try{return document.activeElement}catch(n){}}var s=n(window),u=n(document),h=n(document.documentElement),c=document.documentElement.style.transition!=null;return t.klasses=function(n){return n=n||"picker",{picker:n,opened:n+"--opened",focused:n+"--focused",input:n+"__input",active:n+"__input--active",target:n+"__input--target",holder:n+"__holder",frame:n+"__frame",wrap:n+"__wrap",box:n+"__box"}},t._={group:function(n){for(var i,u="",r=t._.trigger(n.min,n);r<=t._.trigger(n.max,n,[r]);r+=n.i)i=t._.trigger(n.item,n,[r]),u+=t._.node(n.node,i[0],i[1],i[2]);return u},node:function(t,i,r,u){return i?(i=n.isArray(i)?i.join(""):i,r=r?' class="'+r+'"':"",u=u?" "+u:"","<"+t+r+u+">"+i+"<\/"+t+">"):""},lead:function(n){return(n<10?"0":"")+n},trigger:function(n,t,i){return typeof n=="function"?n.apply(t,i||[]):n},digits:function(n){return/\d/.test(n[1])?2:1},isDate:function(n){return{}.toString.call(n).indexOf("Date")>-1&&this.isInteger(n.getDate())},isInteger:function(n){return{}.toString.call(n).indexOf("Number")>-1&&n%1==0},ariaAttr:a},t.extend=function(i,r){n.fn[i]=function(u,f){var e=this.data(i);return u=="picker"?e:e&&typeof u=="string"?t._.trigger(e[u],e,[f]):this.each(function(){var f=n(this);f.data(i)||new t(this,i,r,u)})};n.fn[i].defaults=r.defaults},t});
/*!
* Date picker for pickadate.js v3.6.4
* http://amsul.github.io/pickadate.js/date.htm
*/
(function(n){typeof define=="function"&&define.amd?define(["./picker","jquery"],n):typeof exports=="object"?module.exports=n(require("./picker.js"),require("jquery")):n(Picker,jQuery)})(function(n,t){function r(n,t){var i=this,r=n.$node[0],o=r.value,u=n.$node.data("value"),f=u||o,s=u?t.formatSubmit:t.format,e=function(){return r.currentStyle?r.currentStyle.direction=="rtl":getComputedStyle(n.$root[0]).direction=="rtl"};i.settings=t;i.$node=n.$node;i.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"};i.item={};i.item.clear=null;i.item.disable=(t.disable||[]).slice(0);i.item.enable=-function(n){return n[0]===!0?n.shift():-1}(i.item.disable);i.set("min",t.min).set("max",t.max).set("now");f?i.set("select",f,{format:s,defaultValue:!0}):i.set("select",null).set("highlight",i.item.now);i.key={40:7,38:-7,39:function(){return e()?-1:1},37:function(){return e()?1:-1},go:function(n){var t=i.item.highlight,r=new Date(t.year,t.month,t.date+n);i.set("highlight",r,{interval:n});this.render()}};n.on("render",function(){n.$root.find("."+t.klass.selectMonth).on("change",function(){var i=this.value;i&&(n.set("highlight",[n.get("view").year,i,n.get("highlight").date]),n.$root.find("."+t.klass.selectMonth).trigger("focus"))});n.$root.find("."+t.klass.selectYear).on("change",function(){var i=this.value;i&&(n.set("highlight",[i,n.get("view").month,n.get("highlight").date]),n.$root.find("."+t.klass.selectYear).trigger("focus"))})},1).on("open",function(){var r="";i.disabled(i.get("now"))&&(r=":not(."+t.klass.buttonToday+")");n.$root.find("button"+r+", select").attr("disabled",!1)},1).on("close",function(){n.$root.find("button, select").attr("disabled",!0)},1)}var u=7,f=6,i=n._;r.prototype.set=function(n,t,i){var r=this,u=r.item;return t===null?(n=="clear"&&(n="select"),u[n]=t,r):(u[n=="enable"?"disable":n=="flip"?"enable":n]=r.queue[n].split(" ").map(function(u){return t=r[u](n,t,i)}).pop(),n=="select"?r.set("highlight",u.select,i):n=="highlight"?r.set("view",u.highlight,i):n.match(/^(flip|min|max|disable|enable)$/)&&(u.select&&r.disabled(u.select)&&r.set("select",u.select,i),u.highlight&&r.disabled(u.highlight)&&r.set("highlight",u.highlight,i)),r)};r.prototype.get=function(n){return this.item[n]};r.prototype.create=function(n,r,u){var f,e=this;return r=r===undefined?n:r,r==-Infinity||r==Infinity?f=r:t.isPlainObject(r)&&i.isInteger(r.pick)?r=r.obj:t.isArray(r)?(r=new Date(r[0],r[1],r[2]),r=i.isDate(r)?r:e.create().obj):r=i.isInteger(r)||i.isDate(r)?e.normalize(new Date(r),u):e.now(n,r,u),{year:f||r.getFullYear(),month:f||r.getMonth(),date:f||r.getDate(),day:f||r.getDay(),obj:f||r,pick:f||r.getTime()}};r.prototype.createRange=function(n,r){var f=this,u=function(n){return n===!0||t.isArray(n)||i.isDate(n)?f.create(n):n};return i.isInteger(n)||(n=u(n)),i.isInteger(r)||(r=u(r)),i.isInteger(n)&&t.isPlainObject(r)?n=[r.year,r.month,r.date+n]:i.isInteger(r)&&t.isPlainObject(n)&&(r=[n.year,n.month,n.date+r]),{from:u(n),to:u(r)}};r.prototype.withinRange=function(n,t){return n=this.createRange(n.from,n.to),t.pick>=n.from.pick&&t.pick<=n.to.pick};r.prototype.overlapRanges=function(n,t){var i=this;return n=i.createRange(n.from,n.to),t=i.createRange(t.from,t.to),i.withinRange(n,t.from)||i.withinRange(n,t.to)||i.withinRange(t,n.from)||i.withinRange(t,n.to)};r.prototype.now=function(n,t,i){return t=new Date,i&&i.rel&&t.setDate(t.getDate()+i.rel),this.normalize(t,i)};r.prototype.navigate=function(n,i,r){var s,f,u,e,c=t.isArray(i),h=t.isPlainObject(i),o=this.item.view;if(c||h){for(h?(f=i.year,u=i.month,e=i.date):(f=+i[0],u=+i[1],e=+i[2]),r&&r.nav&&o&&o.month!==u&&(f=o.year,u=o.month),s=new Date(f,u+(r&&r.nav?r.nav:0),1),f=s.getFullYear(),u=s.getMonth();new Date(f,u,e).getMonth()!==u;)e-=1;i=[f,u,e]}return i};r.prototype.normalize=function(n){return n.setHours(0,0,0,0),n};r.prototype.measure=function(n,t){var r=this;return i.isInteger(t)?t=r.now(n,t,{rel:t}):t?typeof t=="string"&&(t=r.parse(n,t)):t=n=="min"?-Infinity:Infinity,t};r.prototype.viewset=function(n,t){return this.create([t.year,t.month,1])};r.prototype.validate=function(n,r,u){var f=this,c=r,e=u&&u.interval?u.interval:1,h=f.item.enable===-1,l,a,o=f.item.min,s=f.item.max,v,y,p=h&&f.item.disable.filter(function(n){if(t.isArray(n)){var u=f.create(n).pick;u<r.pick?l=!0:u>r.pick&&(a=!0)}return i.isInteger(n)}).length;if((!u||!u.nav&&!u.defaultValue)&&(!h&&f.disabled(r)||h&&f.disabled(r)&&(p||l||a)||!h&&(r.pick<=o.pick||r.pick>=s.pick)))for(h&&!p&&(!a&&e>0||!l&&e<0)&&(e*=-1);f.disabled(r);){if(Math.abs(e)>1&&(r.month<c.month||r.month>c.month)&&(r=c,e=e>0?1:-1),r.pick<=o.pick?(v=!0,e=1,r=f.create([o.year,o.month,o.date+(r.pick===o.pick?0:-1)])):r.pick>=s.pick&&(y=!0,e=-1,r=f.create([s.year,s.month,s.date+(r.pick===s.pick?0:1)])),v&&y)break;r=f.create([r.year,r.month,r.date+e])}return r};r.prototype.disabled=function(n){var r=this,u=r.item.disable.filter(function(u){return i.isInteger(u)?n.day===(r.settings.firstDay?u:u-1)%7:t.isArray(u)||i.isDate(u)?n.pick===r.create(u).pick:t.isPlainObject(u)?r.withinRange(u,n):void 0});return u=u.length&&!u.filter(function(n){return t.isArray(n)&&n[3]=="inverted"||t.isPlainObject(n)&&n.inverted}).length,r.item.enable===-1?!u:u||n.pick<r.item.min.pick||n.pick>r.item.max.pick};r.prototype.parse=function(n,t,r){var f=this,u={};return!t||typeof t!="string"?t:(r&&r.format||(r=r||{},r.format=f.settings.format),f.formats.toArray(r.format).map(function(n){var r=f.formats[n],e=r?i.trigger(r,f,[t,u]):n.replace(/^!/,"").length;r&&(u[n]=t.substr(0,e));t=t.substr(e)}),[u.yyyy||u.yy,+(u.mm||u.m)-1,u.dd||u.d])};r.prototype.formats=function(){function n(n,t,i){var r=n.match(/[^\x00-\x7F]+|[a-zA-Z0-9_\u0080-\u00FF]+/)[0];return i.mm||i.m||(i.m=t.indexOf(r)+1),r.length}function t(n){return n.match(/[a-zA-Z0-9_\u0080-\u00FF]+/)[0].length}return{d:function(n,t){return n?i.digits(n):t.date},dd:function(n,t){return n?2:i.lead(t.date)},ddd:function(n,i){return n?t(n):this.settings.weekdaysShort[i.day]},dddd:function(n,i){return n?t(n):this.settings.weekdaysFull[i.day]},m:function(n,t){return n?i.digits(n):t.month+1},mm:function(n,t){return n?2:i.lead(t.month+1)},mmm:function(t,i){var r=this.settings.monthsShort;return t?n(t,r,i):r[i.month]},mmmm:function(t,i){var r=this.settings.monthsFull;return t?n(t,r,i):r[i.month]},yy:function(n,t){return n?2:(""+t.year).slice(2)},yyyy:function(n,t){return n?4:t.year},toArray:function(n){return n.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(n,t){var r=this;return r.formats.toArray(n).map(function(n){return i.trigger(r.formats[n],r,[0,t])||n.replace(/^!/,"")}).join("")}}}();r.prototype.isDateExact=function(n,r){var u=this;return i.isInteger(n)&&i.isInteger(r)||typeof n=="boolean"&&typeof r=="boolean"?n===r:(i.isDate(n)||t.isArray(n))&&(i.isDate(r)||t.isArray(r))?u.create(n).pick===u.create(r).pick:t.isPlainObject(n)&&t.isPlainObject(r)?u.isDateExact(n.from,r.from)&&u.isDateExact(n.to,r.to):!1};r.prototype.isDateOverlap=function(n,r){var u=this,f=u.settings.firstDay?1:0;return i.isInteger(n)&&(i.isDate(r)||t.isArray(r))?(n=n%7+f,n===u.create(r).day+1):i.isInteger(r)&&(i.isDate(n)||t.isArray(n))?(r=r%7+f,r===u.create(n).day+1):t.isPlainObject(n)&&t.isPlainObject(r)?u.overlapRanges(n,r):!1};r.prototype.flipEnable=function(n){var t=this.item;t.enable=n||(t.enable==-1?1:-1)};r.prototype.deactivate=function(n,r){var f=this,u=f.item.disable.slice(0);return r=="flip"?f.flipEnable():r===!1?(f.flipEnable(1),u=[]):r===!0?(f.flipEnable(-1),u=[]):r.map(function(n){for(var e,r=0;r<u.length;r+=1)if(f.isDateExact(n,u[r])){e=!0;break}e||(i.isInteger(n)||i.isDate(n)||t.isArray(n)||t.isPlainObject(n)&&n.from&&n.to)&&u.push(n)}),u};r.prototype.activate=function(n,r){var f=this,u=f.item.disable,e=u.length;return r=="flip"?f.flipEnable():r===!0?(f.flipEnable(1),u=[]):r===!1?(f.flipEnable(-1),u=[]):r.map(function(n){for(var o,s,h,r=0;r<e;r+=1)if(s=u[r],f.isDateExact(s,n)){o=u[r]=null;h=!0;break}else if(f.isDateOverlap(s,n)){t.isPlainObject(n)?(n.inverted=!0,o=n):t.isArray(n)?(o=n,o[3]||o.push("inverted")):i.isDate(n)&&(o=[n.getFullYear(),n.getMonth(),n.getDate(),"inverted"]);break}if(o)for(r=0;r<e;r+=1)if(f.isDateExact(u[r],n)){u[r]=null;break}if(h)for(r=0;r<e;r+=1)if(f.isDateOverlap(u[r],n)){u[r]=null;break}o&&u.push(o)}),u.filter(function(n){return n!=null})};r.prototype.nodes=function(n){var r=this,t=r.settings,o=r.item,c=o.now,l=o.select,a=o.highlight,e=o.view,w=o.disable,s=o.min,h=o.max,b=function(n,r){return t.firstDay&&(n.push(n.shift()),r.push(r.shift())),i.node("thead",i.node("tr",i.group({min:0,max:u-1,i:1,node:"th",item:function(i){return[n[i],t.klass.weekdays,'scope=col title="'+r[i]+'"']}})))}((t.showWeekdaysFull?t.weekdaysFull:t.weekdaysShort).slice(0),t.weekdaysFull.slice(0)),v=function(n){return i.node("div"," ",t.klass["nav"+(n?"Next":"Prev")]+(n&&e.year>=h.year&&e.month>=h.month||!n&&e.year<=s.year&&e.month<=s.month?" "+t.klass.navDisabled:""),"data-nav="+(n||-1)+' tabindex="0" '+i.ariaAttr({role:"button",controls:r.$node[0].id+"_table"})+' title="'+(n?t.labelMonthNext:t.labelMonthPrev)+'"')},y=function(){var u=t.showMonthsShort?t.monthsShort:t.monthsFull;return t.selectMonths?i.node("select",i.group({min:0,max:11,i:1,node:"option",item:function(n){return[u[n],0,"value="+n+(e.month==n?" selected":"")+(e.year==s.year&&n<s.month||e.year==h.year&&n>h.month?" disabled":"")]}}),t.klass.selectMonth,(n?"":"disabled")+" "+i.ariaAttr({controls:r.$node[0].id+"_table"})+' title="'+t.labelMonthSelect+'"'):i.node("div",u[e.month],t.klass.month)},p=function(){var o=e.year,l=t.selectYears===!0?5:~~(t.selectYears/2),v,y;if(l){var c=s.year,a=h.year,u=o-l,f=o+l;return c>u&&(f+=c-u,u=c),a<f&&(v=u-c,y=f-a,u-=v>y?y:v,f=a),i.node("select",i.group({min:u,max:f,i:1,node:"option",item:function(n){return[n,0,"value="+n+(o==n?" selected":"")]}}),t.klass.selectYear,(n?"":"disabled")+" "+i.ariaAttr({controls:r.$node[0].id+"_table"})+' title="'+t.labelYearSelect+'"')}return i.node("div",o,t.klass.year)};return i.node("div",(t.selectYears?p()+y():y()+p())+v()+v(1),t.klass.header)+i.node("table",b+i.node("tbody",i.group({min:0,max:f-1,i:1,node:"tr",item:function(n){var f=t.firstDay&&r.create([e.year,e.month,1]).day===0?-7:0;return[i.group({min:u*n-e.day+f+1,max:function(){return this.min+u-1},i:1,node:"td",item:function(n){n=r.create([e.year,e.month,n+(t.firstDay?1:0)]);var u=l&&l.pick==n.pick,f=a&&a.pick==n.pick,o=w&&r.disabled(n)||n.pick<s.pick||n.pick>h.pick,v=i.trigger(r.formats.toString,r,[t.format,n]),y=t.id+"_"+n.pick;return[i.node("div",n.date,function(i){return i.push(e.month==n.month?t.klass.infocus:t.klass.outfocus),c.pick==n.pick&&i.push(t.klass.now),u&&i.push(t.klass.selected),f&&i.push(t.klass.highlighted),o&&i.push(t.klass.disabled),i.join(" ")}([t.klass.day]),"data-pick="+n.pick+" id="+y+' tabindex="0" '+i.ariaAttr({role:"gridcell",label:v,selected:u&&r.$node.val()===v?!0:null,activedescendant:f?n.pick:null,disabled:o?!0:null})),""]}})]}})),t.klass.table,'id="'+r.$node[0].id+'_table" '+i.ariaAttr({role:"grid",controls:r.$node[0].id,readonly:!0}))+i.node("div",i.node("button",t.today,t.klass.buttonToday,"type=button data-pick="+c.pick+(n&&!r.disabled(c)?"":" disabled")+" "+i.ariaAttr({controls:r.$node[0].id}))+i.node("button",t.clear,t.klass.buttonClear,"type=button data-clear=1"+(n?"":" disabled")+" "+i.ariaAttr({controls:r.$node[0].id}))+i.node("button",t.close,t.klass.buttonClose,"type=button data-close=true "+(n?"":" disabled")+" "+i.ariaAttr({controls:r.$node[0].id})),t.klass.footer)};r.defaults=function(n){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],today:"Today",clear:"Clear",close:"Close",closeOnSelect:!0,closeOnClear:!0,updateInput:!0,format:"d mmmm, yyyy",klass:{table:n+"table",header:n+"header",navPrev:n+"nav--prev",navNext:n+"nav--next",navDisabled:n+"nav--disabled",month:n+"month",year:n+"year",selectMonth:n+"select--month",selectYear:n+"select--year",weekdays:n+"weekday",day:n+"day",disabled:n+"day--disabled",selected:n+"day--selected",highlighted:n+"day--highlighted",now:n+"day--today",infocus:n+"day--infocus",outfocus:n+"day--outfocus",footer:n+"footer",buttonClear:n+"button--clear",buttonToday:n+"button--today",buttonClose:n+"button--close"}}}(n.klasses().picker+"__");n.extend("pickadate",r)});
/*!
* Time picker for pickadate.js v3.6.4
* http://amsul.github.io/pickadate.js/time.htm
*/
(function(n){typeof define=="function"&&define.amd?define(["./picker","jquery"],n):typeof exports=="object"?module.exports=n(require("./picker.js"),require("jquery")):n(Picker,jQuery)})(function(n,t){function r(n,t){var i=this,f=n.$node[0].value,r=n.$node.data("value"),u=r||f,e=r?t.formatSubmit:t.format;i.settings=t;i.$node=n.$node;i.queue={interval:"i",min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse create validate",view:"parse create validate",disable:"deactivate",enable:"activate"};i.item={};i.item.clear=null;i.item.interval=t.interval||30;i.item.disable=(t.disable||[]).slice(0);i.item.enable=-function(n){return n[0]===!0?n.shift():-1}(i.item.disable);i.set("min",t.min).set("max",t.max).set("now");u?i.set("select",u,{format:e}):i.set("select",null).set("highlight",i.item.now);i.key={40:1,38:-1,39:1,37:-1,go:function(n){i.set("highlight",i.item.highlight.pick+n*i.item.interval,{interval:n*i.item.interval});this.render()}};n.on("render",function(){var i=n.$root.children(),r=i.find("."+t.klass.viewset),u=function(n){return["webkit","moz","ms","o",""].map(function(t){return(t?"-"+t+"-":"")+n})},f=function(n,t){u("transform").map(function(i){n.css(i,t)});u("transition").map(function(i){n.css(i,t)})};r.length&&(f(i,"none"),i[0].scrollTop=~~r.position().top-r[0].clientHeight*2,f(i,""))},1).on("open",function(){n.$root.find("button").attr("disabled",!1)},1).on("close",function(){n.$root.find("button").attr("disabled",!0)},1)}var e=24,u=60,o=12,f=e*u,i=n._;r.prototype.set=function(n,t,i){var r=this,u=r.item;return t===null?(n=="clear"&&(n="select"),u[n]=t,r):(u[n=="enable"?"disable":n=="flip"?"enable":n]=r.queue[n].split(" ").map(function(u){return t=r[u](n,t,i)}).pop(),n=="select"?r.set("highlight",u.select,i):n=="highlight"?r.set("view",u.highlight,i):n=="interval"?r.set("min",u.min,i).set("max",u.max,i):n.match(/^(flip|min|max|disable|enable)$/)&&(u.select&&r.disabled(u.select)&&r.set("select",t,i),u.highlight&&r.disabled(u.highlight)&&r.set("highlight",t,i),n=="min"&&r.set("max",u.max,i)),r)};r.prototype.get=function(n){return this.item[n]};r.prototype.create=function(n,r,o){var s=this;return r=r===undefined?n:r,i.isDate(r)&&(r=[r.getHours(),r.getMinutes()]),t.isPlainObject(r)&&i.isInteger(r.pick)?r=r.pick:t.isArray(r)?r=+r[0]*u+ +r[1]:i.isInteger(r)||(r=s.now(n,r,o)),n=="max"&&r<s.item.min.pick&&(r+=f),n!="min"&&n!="max"&&(r-s.item.min.pick)%s.item.interval!=0&&(r+=s.item.interval),r=s.normalize(n,r,o),{hour:~~(e+r/u)%e,mins:(u+r%u)%u,time:(f+r)%f,pick:r%f}};r.prototype.createRange=function(n,r){var f=this,u=function(n){return n===!0||t.isArray(n)||i.isDate(n)?f.create(n):n};return i.isInteger(n)||(n=u(n)),i.isInteger(r)||(r=u(r)),i.isInteger(n)&&t.isPlainObject(r)?n=[r.hour,r.mins+n*f.settings.interval]:i.isInteger(r)&&t.isPlainObject(n)&&(r=[n.hour,n.mins+r*f.settings.interval]),{from:u(n),to:u(r)}};r.prototype.withinRange=function(n,t){return n=this.createRange(n.from,n.to),t.pick>=n.from.pick&&t.pick<=n.to.pick};r.prototype.overlapRanges=function(n,t){var i=this;return n=i.createRange(n.from,n.to),t=i.createRange(t.from,t.to),i.withinRange(n,t.from)||i.withinRange(n,t.to)||i.withinRange(t,n.from)||i.withinRange(t,n.to)};r.prototype.now=function(n,t){var f=this.item.interval,o=new Date,r=o.getHours()*u+o.getMinutes(),s=i.isInteger(t),e;return r-=r%f,e=t<0&&f*t+r<=-f,r+=n=="min"&&e?0:f,s&&(r+=f*(e&&n!="max"?t+1:t)),r};r.prototype.normalize=function(n,t){var i=this.item.interval,r=this.item.min&&this.item.min.pick||0;return t-(n=="min"?0:(t-r)%i)};r.prototype.measure=function(n,r,f){var o=this;return r||(r=n=="min"?[0,0]:[e-1,u-1]),typeof r=="string"?r=o.parse(n,r):r===!0||i.isInteger(r)?r=o.now(n,r,f):t.isPlainObject(r)&&i.isInteger(r.pick)&&(r=o.normalize(n,r.pick,f)),r};r.prototype.validate=function(n,t,i){var r=this,u=i&&i.interval?i.interval:r.item.interval;return r.disabled(t)&&(t=r.shift(t,u)),t=r.scope(t),r.disabled(t)&&(t=r.shift(t,u*-1)),t};r.prototype.disabled=function(n){var r=this,u=r.item.disable.filter(function(u){return i.isInteger(u)?n.hour==u:t.isArray(u)||i.isDate(u)?n.pick==r.create(u).pick:t.isPlainObject(u)?r.withinRange(u,n):void 0});return u=u.length&&!u.filter(function(n){return t.isArray(n)&&n[2]=="inverted"||t.isPlainObject(n)&&n.inverted}).length,r.item.enable===-1?!u:u||n.pick<r.item.min.pick||n.pick>r.item.max.pick};r.prototype.shift=function(n,t){var i=this,r=i.item.min.pick,u=i.item.max.pick;for(t=t||i.item.interval;i.disabled(n);)if(n=i.create(n.pick+=t),n.pick<=r||n.pick>=u)break;return n};r.prototype.scope=function(n){var t=this.item.min.pick,i=this.item.max.pick;return this.create(n.pick>i?i:n.pick<t?t:n)};r.prototype.parse=function(n,t,r){var s,c,l,f,o,h=this,e={};if(!t||typeof t!="string")return t;r&&r.format||(r=r||{},r.format=h.settings.format);h.formats.toArray(r.format).map(function(n){var r,u=h.formats[n],f=u?i.trigger(u,h,[t,e]):n.replace(/^!/,"").length;u&&(r=t.substr(0,f),e[n]=r.match(/^\d+$/)?+r:r);t=t.substr(f)});for(f in e)o=e[f],i.isInteger(o)?f.match(/^(h|hh)$/i)?(s=o,(f=="h"||f=="hh")&&(s%=12)):f=="i"&&(c=o):f.match(/^a$/i)&&o.match(/^p/i)&&("h"in e||"hh"in e)&&(l=!0);return(l?s+12:s)*u+c};r.prototype.formats={h:function(n,t){return n?i.digits(n):t.hour%o||o},hh:function(n,t){return n?2:i.lead(t.hour%o||o)},H:function(n,t){return n?i.digits(n):""+t.hour%24},HH:function(n,t){return n?i.digits(n):i.lead(t.hour%24)},i:function(n,t){return n?2:i.lead(t.mins)},a:function(n,t){return n?4:f/2>t.time%f?"a.m.":"p.m."},A:function(n,t){return n?2:f/2>t.time%f?"AM":"PM"},toArray:function(n){return n.split(/(h{1,2}|H{1,2}|i|a|A|!.)/g)},toString:function(n,t){var r=this;return r.formats.toArray(n).map(function(n){return i.trigger(r.formats[n],r,[0,t])||n.replace(/^!/,"")}).join("")}};r.prototype.isTimeExact=function(n,r){var u=this;return i.isInteger(n)&&i.isInteger(r)||typeof n=="boolean"&&typeof r=="boolean"?n===r:(i.isDate(n)||t.isArray(n))&&(i.isDate(r)||t.isArray(r))?u.create(n).pick===u.create(r).pick:t.isPlainObject(n)&&t.isPlainObject(r)?u.isTimeExact(n.from,r.from)&&u.isTimeExact(n.to,r.to):!1};r.prototype.isTimeOverlap=function(n,r){var u=this;return i.isInteger(n)&&(i.isDate(r)||t.isArray(r))?n===u.create(r).hour:i.isInteger(r)&&(i.isDate(n)||t.isArray(n))?r===u.create(n).hour:t.isPlainObject(n)&&t.isPlainObject(r)?u.overlapRanges(n,r):!1};r.prototype.flipEnable=function(n){var t=this.item;t.enable=n||(t.enable==-1?1:-1)};r.prototype.deactivate=function(n,r){var f=this,u=f.item.disable.slice(0);return r=="flip"?f.flipEnable():r===!1?(f.flipEnable(1),u=[]):r===!0?(f.flipEnable(-1),u=[]):r.map(function(n){for(var e,r=0;r<u.length;r+=1)if(f.isTimeExact(n,u[r])){e=!0;break}e||(i.isInteger(n)||i.isDate(n)||t.isArray(n)||t.isPlainObject(n)&&n.from&&n.to)&&u.push(n)}),u};r.prototype.activate=function(n,r){var f=this,u=f.item.disable,e=u.length;return r=="flip"?f.flipEnable():r===!0?(f.flipEnable(1),u=[]):r===!1?(f.flipEnable(-1),u=[]):r.map(function(n){for(var o,s,h,r=0;r<e;r+=1)if(s=u[r],f.isTimeExact(s,n)){o=u[r]=null;h=!0;break}else if(f.isTimeOverlap(s,n)){t.isPlainObject(n)?(n.inverted=!0,o=n):t.isArray(n)?(o=n,o[2]||o.push("inverted")):i.isDate(n)&&(o=[n.getFullYear(),n.getMonth(),n.getDate(),"inverted"]);break}if(o)for(r=0;r<e;r+=1)if(f.isTimeExact(u[r],n)){u[r]=null;break}if(h)for(r=0;r<e;r+=1)if(f.isTimeOverlap(u[r],n)){u[r]=null;break}o&&u.push(o)}),u.filter(function(n){return n!=null})};r.prototype.i=function(n,t){return i.isInteger(t)&&t>0?t:this.item.interval};r.prototype.nodes=function(n){var t=this,r=t.settings,u=t.item.select,f=t.item.highlight,e=t.item.view,o=t.item.disable;return i.node("ul",i.group({min:t.item.min.pick,max:t.item.max.pick,i:t.item.interval,node:"li",item:function(n){n=t.create(n);var s=n.pick,h=u&&u.pick==s,c=f&&f.pick==s,l=o&&t.disabled(n),a=i.trigger(t.formats.toString,t,[r.format,n]);return[i.trigger(t.formats.toString,t,[i.trigger(r.formatLabel,t,[n])||r.format,n]),function(n){return h&&n.push(r.klass.selected),c&&n.push(r.klass.highlighted),e&&e.pick==s&&n.push(r.klass.viewset),l&&n.push(r.klass.disabled),n.join(" ")}([r.klass.listItem]),"data-pick="+n.pick+" "+i.ariaAttr({role:"option",label:a,selected:h&&t.$node.val()===a?!0:null,activedescendant:c?!0:null,disabled:l?!0:null})]}})+i.node("li",i.node("button",r.clear,r.klass.buttonClear,"type=button data-clear=1"+(n?"":" disabled")+" "+i.ariaAttr({controls:t.$node[0].id})),"",i.ariaAttr({role:"presentation"})),r.klass.list,i.ariaAttr({role:"listbox",controls:t.$node[0].id}))};r.defaults=function(n){return{clear:"Clear",format:"h:i A",interval:30,closeOnSelect:!0,closeOnClear:!0,updateInput:!0,klass:{picker:n+" "+n+"--time",holder:n+"__holder",list:n+"__list",listItem:n+"__list-item",disabled:n+"__list-item--disabled",selected:n+"__list-item--selected",highlighted:n+"__list-item--highlighted",viewset:n+"__list-item--viewset",now:n+"__list-item--now",buttonClear:n+"__button--clear"}}}(n.klasses().picker);n.extend("pickatime",r)});
// Gets Json object using a given url.
function GetJson(url) {
var result;
$.ajaxSetup({ async: false });
$.post(url, function (data) {
result = data;
});
$.ajaxSetup({ async: true });
return result;
}
function maxLength(field, maxChars) {
if (field.value.length >= maxChars) {
event.returnValue = false;
return false;
}
}
function maxLengthPaste(field, maxChars) {
var copyText = field.value + window.clipboardData.getData("Text");
field.value = copyText.substr(0, maxChars);
if ((copyText.length) > maxChars) {
return false;
}
event.returnValue = true;
}
function appendFilesToInput(appendInput, mainFileInput) {
const valid = validateMultiFileUpload(appendInput, true);
if (!valid) {
alert("The file you are trying to upload is not an allowed file type or has an invalid file name. These are the accepted characters: A-z 0-9 ~ ! ( ) - + = [ ] { } , . _");
appendInput.value = null;
return;
}
const dt = new DataTransfer();
const originalFiles = Array.from(mainFileInput.files);
const existingSet = new Set(originalFiles.map(({ name, size, lastModified }) => `${name}-${size}-${lastModified}`));
originalFiles.forEach(file => {
dt.items.add(file);
})
const addedFiles = Array.from(appendInput.files);
addedFiles.forEach(file => {
if (!existingSet.has(`${file.name}-${file.size}-${file.lastModified}`)) {
dt.items.add(file);
}
})
mainFileInput.files = dt.files;
mainFileInput.dispatchEvent(new Event("change"));
}
function fileAppender(mainFileInput) {
const li = document.createElement("li");
const label = document.createElement("label");
label.innerHTML = '<span class="visuallyhidden">Add Files</span><svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24" aria-hidden="true"><path d="M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z"/></svg>'
const appendInput = document.createElement("input");
appendInput.type = "file";
appendInput.multiple = true;
appendInput.className = "visuallyhidden";
appendInput.addEventListener("change", e => {
appendFilesToInput(appendInput, mainFileInput);
});
label.appendChild(appendInput);
const placeholder = document.createElement("span");
li.appendChild(placeholder);
li.appendChild(label);
return li;
}
function removeFileFromInput(input, idx) {
const dt = new DataTransfer();
const files = Array.from(input.files);
files.splice(idx, 1);
files.forEach(file => {
dt.items.add(file);
});
input.files = dt.files;
}
function listItemFile(input, file, idx) {
const li = document.createElement("li");
const fileNameSpan = document.createElement("span");
fileNameSpan.textContent = file.name;
li.appendChild(fileNameSpan);
const removeButton = document.createElement("button");
removeButton.title = `Remove ${file.name}`;
removeButton.addEventListener("click", e => {
e.preventDefault();
removeFileFromInput(input, idx);
input.dispatchEvent(new Event("change"));
});
removeButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24" fill="darkred" aria-hidden="true"><path d="m336-280 144-144 144 144 56-56-144-144 144-144-56-56-144 144-144-144-56 56 144 144-144 144 56 56ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"></path></svg>';
const removeButtonSpan = document.createElement("span");
removeButtonSpan.textContent = `Remove ${file.name}`;
removeButtonSpan.className = "visuallyhidden";
removeButton.appendChild(removeButtonSpan);
li.appendChild(removeButton);
return li;
}
function listFileInputFiles(fileInput) {
if (fileInput.nextElementSibling?.className === "file-list") {
fileInput.nextElementSibling.remove();
}
const files = fileInput.files || [];
const valid = files.length && validateMultiFileUpload(fileInput, true)
if (!valid) {
fileInput.value = null;
return;
}
if (files.length > 1) {
const ul = document.createElement("ul");
ul.className = "file-list";
for (let i = 0; i < files.length; i++) {
const li = listItemFile(fileInput, files[i], i);
ul.appendChild(li);
}
const fileAppenderLi = fileAppender(fileInput);
ul.appendChild(fileAppenderLi);
fileInput.after(ul);
}
}
function initFileInputs() {
if (!window.FeatureToggles.isActive("CMS.FormCenter.MultipleFileUploadEnhancement")) {
return;
}
document.querySelectorAll(".FileUpload input[type='file']").forEach(fileInput => {
listFileInputFiles(fileInput);
fileInput.addEventListener("change", e => {
listFileInputFiles(fileInput)
})
});
}
;
/// <reference path="../../../../Scripts/jquery-1.3.2-vsdoc.js">
/// <reference path="../../../../Scripts/json2.js">
/// <reference path="../../../../Scripts/HtmlExtensionSupport.js">
/// <reference path="../../../../Scripts/UrlLibrary.js">
/// <reference path="../../../../Common/GlobalJSFunctionsDetail.js" />
/// <reference path="Conditions.js" />
/// <reference path="Validation.js" />
/// <reference path="/Assets/Scripts/DynamicForm/PrintSubmission.js" />
/// <reference path="../../../../Assets/Scripts/DateTimePicker/cp.datetimepicker.js" />
//////// ENUMERATIONS ///////////
var FormCenterHomeJS = (function ($) {
var self = this;
// This value is set on the ItemDetailFE.ascx page, using a value from the
// View Model.
self.submissionURL = '';
return self;
}(jQuery));
var FormCenterHomeScriptResources = GetJson("/FormCenter/Localization");
// Field formats.
var FieldValidation = {
Any: 0,
Letters: 1,
Numeric: 2,
PhoneNumber: 3,
PostalCode: 4,
EmailAddress: 5,
RegEx: 6,
Currency: 7,
Date: 8,
Time: 9,
DateTime: 10,
DateSpan: 11,
TimeSpan: 12,
DateTimeSpan: 13
};
// Supported field types.
var FieldTypes = {
ShortAnswer: 1,
LongAnswer: 2,
Checkboxes: 3,
RadioButtons: 4,
Dropdown: 5,
FileUpload: 6,
ReplyEmail: 10,
Password: 11,
DateTime: 18,
EPayment: 23
};
//////// GLOBALS ////////////////
// Stores instantiated form validator/condition instances for the current form.
var formValidators = null;
var formConditions = null;
// Use with form submissions.
var redirectNewWindow = null;
//////// SUPPORT METHODS ////////f
// Shows extra information for a form detail.
function moreInfo(id) {
changeInfo(id, 'addClass', 'removeClass');
}
// Hides extra information for a form detail.
function lessInfo(id) {
changeInfo(id, 'removeClass', 'addClass');
}
// Internal. Hides or shows extra information.
function changeInfo(id, lessFn, moreFn) {
$([document.getElementById('spnLess' + id), document.getElementById('lnkMore' + id)])[lessFn]('hidden');
$(document.getElementById('spnMore' + id))[moreFn]('hidden');
}
// Used to expand and collapse category sections.
function expandCollaspseCategory(catID) {
var $elem = $('#section' + catID);
var $elemArrow = $('#span' + catID);
var supportSlide = !isie7; // If we can find a better way to detect the incorrect behavior IE7 mode is exhibiting, go for it...
if ($elem.is(':visible')) {
$elemArrow.html('&#9658');
if (supportSlide)
$elem.slideUp(150);
else
$elem.hide();
}
else {
$elemArrow.html('&#9660');
if (supportSlide)
$elem.slideDown(150);
else
$elem.show();
}
}
// Assigns bulk action checkbox group to jQuery expression.
function assignBulkCheckGroup($children, $parent) {
// Isolate children from parent in event of overlap ($children containing the $parent).
// Vastly simplifies the logic in the event handlers by doing this.
var $isolatedChildren = $children.filter(
function (index) {
return $parent.filter(this).length == 0;
}
);
// Cache current number of checked children.
$isolatedChildren.lengthChecked = $isolatedChildren.filter(':checked').length;
// Hook childen change.
$isolatedChildren.change(function (event) {
$isolatedChildren.lengthChecked += (this.checked ? 1 : -1);
var allChildrenChecked = ($isolatedChildren.lengthChecked == $isolatedChildren.length);
$parent.each(function () {
this.checked = allChildrenChecked;
});
});
// Hook parent change.
$parent.change(function (event) {
var parentChecked = this.checked;
$isolatedChildren.lengthChecked = this.checked ? $isolatedChildren.length : 0;
$isolatedChildren.each(function () {
this.checked = parentChecked;
});
});
}
function initCommon() {
// Hack: Internet Explorer 7 mode bizarre display bugs.
$('.sidebar .search.noStyles').css('zoom', '1');
// Hook search category bulk checks.
var $bulkCheck = $('#categoryFilter_0');
var $bulkGroup = $('.categoryList input[type="checkbox"]');
assignBulkCheckGroup($bulkGroup, $bulkCheck);
// Get input jQuery refs.
var $inputFCTerm = $('#inputFCTerm');
var $inputFCSearch = $('#inputFCSearch');
// Hook search button and textbox to capture enter key.
$inputFCTerm.keydown(function (event) {
// If user presses enter, submit for search.
switch (event.which) {
case 10: // LF
case 13: // CR
event.preventDefault();
$inputFCSearch.click();
break;
}
});
$inputFCSearch.click(function (event) {
event.preventDefault();
// Build search querystring.
var qs = {};
var formID = extractFormIDFromURL(location.href);
var categoryID = extractCategoryIDFromURL(location.href);
var searchTerm = $.trim(isNull($inputFCTerm.val(), ''));
if (formID)
qs.formID = formID;
if (categoryID)
qs.categoryID = categoryID;
if (searchTerm != '')
qs.term = searchTerm;
if (!$bulkCheck[0].checked) {
var values = [];
$bulkGroup.filter(':checked').each(function () {
values.push(this.value);
});
if (values.length > 0)
qs.categoryFilter = values.join(',');
}
// Set search URL and go.
window.location = '/FormCenter/Search' + (new QueryStringBuilder(qs)).toString();
});
// Hook search category dropdown.
var $catList = $('#categoryList');
var $catListToggle = $('a.mega');
$catListToggle.click(function (e) {
e.preventDefault();
if ($catList.hasClass('open'))
$catList.slideUp(300);
else
$catList.slideDown(300);
$catListToggle.toggleClass('active');
$catList.toggleClass('open');
});
// Show print dialog if URL contains standard print query string.
if (containsPrint(location.href))
window.print();
}
// Initialization for search (Search.aspx view).
function initSearch() {
if (this.wasInit)
return;
this.wasInit = true;
attachCategoryVisibilityTogglers();
initCommon();
}
// Initialization for category/form list (Index.aspx view).
function initCategoryList() {
if (this.wasInit)
return;
this.wasInit = true;
attachCategoryVisibilityTogglers();
initCommon();
}
// Initialization for confirmation (Confirmation.aspx view).
function initConfirmation() {
if (this.wasInit)
return;
this.wasInit = true;
initCommon();
}
function initPostSubmissionSpam() {
initCommon();
}
// Causes current form to be submitted for printing.
function printForm(saveData) {
if (formValidate()) { //check for valid responses before creating print window
var frm = document.aspnetForm;
var $form = $(document.aspnetForm);
var printPrevType = (getPrintPreviewType() == 1 ? 'Print' : 'Preview');
var formID = extractFormIDFromURL(location.href);
$form.attr('target', 'PrintWindow');
// Change target/action to print data.
frm.action = '/FormCenter/Print?formID=' + formID + '&' + printPrevType + '=YES&Save=' + (saveData ? 'True' : 'False');
var savedProgressID = $('#hdnSavedProgressID').val();
if (savedProgressID != null) {
frm.action = frm.action + '&savedProgressID=' + savedProgressID;
}
submitForm($form, true, saveData, formID);
} else {
enableDisableSubmit(true);
}
}
function submitFormHandler(e) {
try {
let json = JSON.parse(this.response);
if (this.status !== 200 || json.Success !== true) {
$('.submissionConfirmationMessage').html("Something went wrong with the submission. Please try again.");
$('.submissionConfirmation').show();
enableDisableSubmit(true);
return;
}
const responseUrl = this.responseURL && new URL(this.responseURL);
const saveSubmission = responseUrl && responseUrl.searchParams.get('save') && responseUrl.searchParams.get('save').toLowerCase() === 'true';
const doPrint = responseUrl && responseUrl.searchParams.get('print') && responseUrl.searchParams.get('print').toLowerCase() === 'true';
const redirectAfterSubmissionSaved = json.Redirect && json.Redirect === true && saveSubmission === true;
if (redirectAfterSubmissionSaved)
{
if (json.IsHttps === false) {
json.Message = json.Message.replace("https://", "http://");
}
location.href = json.Message;
}
else {
if (saveSubmission === true) {
$('.submissionConfirmationMessage').html(json.Message);
typeof displayStep === "function" && displayStep(1);
$('.submitForm').hide();
$('.submissionConfirmation').show();
}
enableDisableSubmit(true);
}
if (doPrint === true) {
window.open("/FormCenter/Print?formId=" + json.FormId.toString() + '&save=' + (saveSubmission ? 'True' : 'False'));
}
if (json.Success === true) {
document.aspnetForm.reset();
if (typeof (grecaptcha) !== "undefined")
{
grecaptcha.reset();
}
}
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
} catch (ex) {
console.log(ex);
}
}
function submitForm($form, print, saveSubmission, formID) {
var submittedViaWidget = $form.parents(".widgetBody").length > 0;
serializeSpecialFields();
if (submittedViaWidget !== true) {
var printWindow;
if (print === true)
{
printWindow = window.open("", "PrintWindow");
// Deferred object at the window level, this becomes available on the opened window via window.opener
// Whichever view gets rendered will resolve it and pass the appropriate status code.
window.deferredStatus = $.Deferred();
}
if (printWindow) {
window.deferredStatus.done(function (status) {
if (status === CP_DynamicForm_PrintSubmission.StatusCodes.Success) {
if (saveSubmission && saveSubmission === true) {
window.location = '/FormCenter/Confirmation?formID=' + formID;
}
} else {
printWindow.close();
if (saveSubmission) {
window.location = '/FormCenter/ErrorSubmittingForm?formID=' + formID;
}
}
});
}
$form.submit();
}
else {
var submissionUrl = FormCenterHomeJS.submissionURL + (saveSubmission ? '&save=True' : "");
submissionUrl = submissionUrl + (print ? '&print=True' : '');
var formData = new FormData($form[0]);
var xhr = new XMLHttpRequest();
xhr.onload = submitFormHandler;
xhr.onloadend = ajaxPostBackEnd;
xhr.onerror = function() { console.log("A network error occurred with the transaction."); };
xhr.open("POST", submissionUrl);
ajaxPostBackStart('Loading');
xhr.send(formData);
}
}
function serializeSpecialFields()
{
submitCheckboxHandler();
submitRadioHandler();
submitDateTimeHandler();
}
// Initialization for form item printing (Print.aspx view).
function initFormPrint() {
if (this.wasInit)
return;
this.wasInit = true;
initCommon();
initValidationAndConditions();
registerFormPrintEvents();
}
function initValidationAndConditions() {
// Register validation.
if (typeof getFormValidatorData !== 'undefined') {
formValidators = FieldValidator.createMulti(getFormValidatorData());
} else {
formValidators = [];
}
// Register conditions.
if (getFormConditionData) {
formConditions = FieldConditions.createMulti(getFormConditionData(), formValidators);
} else {
formConditions = FieldConditions.createMulti([], formValidators);
}
// Register condition runner and make initial condition check.
formConditionsRunner = new FieldConditionsRunner(formConditions, $.noop, true, false); // TODO: Finish up, put debugCondRunnerLogResults for $.noop.
formConditionsRunner.run();
}
// Initialization for form item (Item.aspx view).
function initForm() {
if (this.wasInit)
return;
this.wasInit = true;
initCommon();
initValidationAndConditions();
initDatePickers();
initTimePickers();
initFileInputs();
registerFormEvents(); // Hook up buttons (submit/cancel/etc).
}
function initDatePickers() {
if ($('.telerikDatePicker').length > 0) {
$('.telerikDatePicker').each(function () {
if (typeof (cp) !== 'undefined')
cp.datetimepicker && cp.datetimepicker.createDatePicker(this);
});
}
}
function initTimePickers() {
if ($('.formCenterTimePicker').length > 0) {
$('.formCenterTimePicker').focusout(function () {
var text = $(this).val().toLowerCase();
if (text != '' && (text.indexOf('am') < 0 && text.indexOf('pm') < 0)) {
text = $(this).val().trim() + ' AM';
$(this).val(text);
}
});
}
else {
$('.telerikTimePicker').each(function () {
if (typeof (cp) !== 'undefined')
cp.datetimepicker && cp.datetimepicker.createTimePicker(this,
{
format: 'h:i A'
});
});
}
}
// Registers event handlers for form.
function registerFormPrintEvents() {
$('#btnFormContinue').click(function (event) {
event.preventDefault();
var frm = document.aspnetForm;
var formID = extractFormIDFromURL(location.href);
var $form = $(document.aspnetForm);
// Change target/action to confirmation page.
frm.action = '/FormCenter/Confirmation?formID=' + formID;
$form.trigger("submit");
});
}
// Registers event handlers for form.
function registerFormEvents() {
// Remove troublemakers (prevent the jQuery submit handler from ever firing, and not needed for this screen anyways).
document.aspnetForm.removeAttribute('onsubmit');
document.aspnetForm.onsubmit = null;
var $form = $(document.aspnetForm);
// TODO: Plug this into other validation.
var wantCopyAddr, $wantCopyAddrLI;
var wantCopy = document.getElementById('wantCopy');
if (wantCopy) {
wantCopyAddr = document.getElementById('wantCopyAddress');
$wantCopyAddrLI = $(wantCopyAddr.parentNode.parentNode);
$(wantCopy).change(function (event) {
if (this.checked)
$wantCopyAddrLI.show();
else
$wantCopyAddrLI.hide();
});
}
/* #2378*/
$(document).keydown(function (event) {
if ((event.keyCode == 13) &&
(event.target.id != 'btnFormSubmit') &&
(event.target.tagName != 'TEXTAREA') &&
(event.target.getAttribute('data-enable-enter-keypress') != 'true')) {
event.preventDefault();
return false;
}
if (event.keyCode === 32 &&
event.target.tagName === 'A' &&
event.target.getAttribute('role') === 'button') {
$(event.target).trigger('click');
event.preventDefault();
return false;
}
});
$form.submit(function () {
// Run validation, stop data submission if necessary.
if (!formValidate()) {
enableDisableSubmit(true);
return false;
}
if (isNull(redirectNewWindow, '').trimEnd() != '')
window.open(redirectNewWindow);
// Field types requiring special serialization code (radio/check/file).
// The deserialization of dictionaries from forms in MVC 2 is somewhat sensitive.
serializeSpecialFields();
return true;
});
$('#btnFormSubmit').click(function (event) {
event.preventDefault();
if (formValidate()) {
processSubmit(handleSubmitClick);
}
});
$('#btnFormPrint').click(function (event) {
event.preventDefault();
printForm(false);
});
$('#btnFormSubmitPrint').click(function (event) {
event.preventDefault();
if (formValidate()) {
processSubmit(handleSubmitPrintClick);
}
});
$('#btnCalculateTotals').click(function (e) {
e.preventDefault();
submitCheckboxHandler();
submitRadioHandler();
if (formValidate()) {
var $form = $(document.aspnetForm);
$.ajax({
url: '/FormCenter/Home/CalculateTotal?formID=' + $('#hdnFormID').val(),
type: 'POST',
data: $(document.aspnetForm).serializeArray(),
success: function (response) {
openCpModal({
title: FormCenterHomeScriptResources.CalculateTotals,
className: 'modalCalculateTotal',
isFrontEnd: window.location.href.indexOf('/Admin/FormCenter') == -1,
htmlContent: response
});
},
error: function (xhr, textStatus, exception) {
alert('Error: ' + xhr.statusText + '\nStatus: ' + xhr.status);
}
});
}
});
$('#btnProceedToCheckOut').click(function (e) {
proceedToCheckOut(e);
});
if ($('.submissionConfirmationOk').length > 0)
{
$('.submissionConfirmationOk').unbind('click').click(function () {
$('.submitForm').show();
$('.submissionConfirmation').hide();
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
})
}
}
function onRecaptchaLoadCallback() {
window.gRecaptchaClientId = grecaptcha.render('inline-recaptcha', {
'sitekey': document.querySelector('#inline-recaptcha').dataset.sitekey,
'badge': 'inline',
'size': 'invisible'
});
}
function processSubmit(callback) {
const recaptcha = document.querySelector('.recaptcha');
if (!recaptcha) {
callback();
return;
}
if (!window.FeatureToggles.isActive("CMS.FormCenter.RecaptchaV3Enabled")) {
window.recaptchaCallback = callback;
grecaptcha.execute();
return;
}
grecaptcha.ready(function() {
grecaptcha.execute(window.gRecaptchaClientId, { action: 'submit' }).then(callback);
});
}
function enableDisableSubmit(enable) {
if (enable) {
if ($('#btnFormSubmitPrint').length > 0) {
$('#btnFormSubmitPrint').removeClass('inactive');
$('#btnFormSubmitPrint').click(function (event) {
handleSubmitPrintClick();
});
}
if ($('#btnFormSubmit').length > 0) {
$('#btnFormSubmit').removeClass('inactive');
$('#btnFormSubmit').click(function (event) {
event.preventDefault();
if (formValidate()) {
closeModalDialog('editItemBehavior');
processSubmit(handleSubmitClick);
}
});
}
} else {
if ($('#btnFormSubmitPrint').length > 0) {
$('#btnFormSubmitPrint').addClass("inactive");
$('#btnFormSubmitPrint').unbind();
}
if ($('#btnFormSubmit').length > 0) {
$('#btnFormSubmit').addClass("inactive");
$('#btnFormSubmit').unbind();
}
}
}
function handleSubmitClick() {
enableDisableSubmit(false);
var frm = document.aspnetForm;
frm.action = FormCenterHomeJS.submissionURL;
var $form = $(frm);
var formID = extractFormIDFromURL(location.href);
submitForm($form, false, true, formID);
}
function handleSubmitPrintClick() {
enableDisableSubmit(false);
printForm(true);
}
function proceedToCheckOut(e) {
e.preventDefault();
serializeSpecialFields();
if (formValidate()) {
var savedProgressID = $('#hdnSavedProgressID').val();
var submitUrl = '/FormCenter/Home/ProceedToCheckOut?formID=' + $('#hdnFormID').val();
if (savedProgressID != null) {
submitUrl = submitUrl + '&savedProgressID=' + savedProgressID;
}
var $form = $(document.aspnetForm);
$form.attr('action', submitUrl);
$form.submit();
}
}
function getModalDialogObjects() {
return {
iframe: document.getElementById('liveEditDialog'),
windowElement: $('.modalContainerCP')[0],
behavior: $find('editItemBehavior'),
titleElement: $('.modalTitle')[0]
};
}
function getBooleanValue(value) {
switch (value.toLowerCase()) {
case "true": case "yes": case "1": return true;
case "false": case "no": case "0": case null: return false;
default: return Boolean(string);
}
}
// Validates current form.
function formValidate() {
var assignFocus = true;
var ERROR_MSG = FormCenterHomeScriptResources.InvalidEmailAddressFormat2;
var wantCopy = document.getElementById('wantCopy');
if (wantCopy) {
wantCopyAddr = document.getElementById('wantCopyAddress');
$wantCopyAddrLI = $(wantCopyAddr.parentNode.parentNode);
if ($wantCopyAddrLI.is(":visible") && wantCopyAddr.value != "") {
if (!emailValidate(wantCopyAddr.value)) {
errorShow(ERROR_MSG);
return false;
}
}
if (wantCopy.checked == false)//if the checkbox is not checked then empty the emailaddress textbox
document.getElementById('wantCopyAddress').value = "";
}
else {
//if the checkbox is not checked then empty the emailaddress textbox
var wantCopyAddress = document.getElementById('wantCopyAddress');
if (wantCopyAddress)
document.getElementById('wantCopyAddress').value = "";
}
if (typeof formValidators.keys !== 'undefined') {
var liCurrent = $('li.current');
var step = "1";
if (liCurrent.length > 0) {
step = liCurrent.attr('id').replace('liStep', '');
}
var wizardStep = $('#wizard' + step);
if (wizardStep.length > 0) {
wizardStep = wizardStep[0];
}
var checkForInappropriateWords = new Array();
for (var i = 0, len = formValidators.keys.length; i < len; i++) {
var key = formValidators.keys[i];
if (wizardStep == null || wizardStep.length == 0 || (wizardStep != null && wizardStep.contains(formValidators[key].elemContainer))) {
if (!formValidators[key].validate(assignFocus, checkForInappropriateWords))
assignFocus = false;
}
}
if (validateInappropriateWords(checkForInappropriateWords)) {
assignFocus = false;
}
}
return assignFocus;
}
function validateInappropriateWords(checkForInappropriateWords) {
var data = {};
var j = 0;
var inappropriateWordsFound = false;
for (j = 0; j < checkForInappropriateWords.length; j++) {
data[checkForInappropriateWords[j].id.toString()] = checkForInappropriateWords[j].elemInput.value.trim();
}
var results = HasInappropriateWordsMultiple(data);
for (j = 0; j < checkForInappropriateWords.length; j++) {
if (results[checkForInappropriateWords[j].id.toString()] == true) {
checkForInappropriateWords[j].handleInappropriateWords(inappropriateWordsFound == false);
inappropriateWordsFound = true;
}
}
return inappropriateWordsFound;
}
// Displays error message if email validation failed
function errorShow(message) {
var elemContainer = $('.anonEmail');
elemContainer.addClass('error');
if (elemContainer.find('.explanation').length == 0) {
var errorElemMsg = document.createElement('p');
errorElemMsg.className = 'explanation';
errorElemMsg.innerHTML = message;
elemContainer.append(errorElemMsg);
}
}
// Determines if URL contains print querystring.
function containsPrint(url) {
return url.search(/(&|\?)print\=yes(&.*|)$/i) > -1;
}
// Extracts CategoryID identifier from URL specified.
function extractCategoryIDFromURL(url) {
url = url.toLowerCase();
var indexOfForm = url.lastIndexOf("/formcenter/");
if (indexOfForm > -1) {
//extract the categoryurl
var formURL = url.substr(indexOfForm + 12);
//check whether u have formid appended
if (formURL.indexOf("/") > -1)
formURL = formURL.substr(0, formURL.indexOf("/"));
//check wheter the url has categoryName
var indexOfHypen = formURL.lastIndexOf("-");
var categoryID = 0;
if (indexOfHypen > -1)
categoryID = formURL.substr(indexOfHypen + 1);
else
categoryID = formURL;
return categoryID;
}
else
return null;
}
// Extracts form identifier from URL specified.
function extractFormIDFromURL(url) {
return $('#hdnFormID').val();
//there is some query string appended if so remove those
if (url.indexOf("/?") > -1) {
url = url.substr(0, url.indexOf("/?"));
}
url = url.toLowerCase();
var indexOfForm = url.lastIndexOf("/formcenter/");
if (indexOfForm > -1) {
//extract the url
var formURL = url.substr(indexOfForm + 12);
if (formURL.indexOf("/") > -1) {
formURL = formURL.substr(formURL.indexOf("/") + 1);
//check wheter the url has categoryName
var indexOfHypen = formURL.lastIndexOf("-");
var formID = 0;
if (indexOfHypen > -1)
formID = formURL.substr(indexOfHypen + 1);
else if (formURL == "")
return null;
else
formID = formURL;
return formID;
}
else
return null;
}
else
return null;
}
// Attaches expand/collapse handlers to section headers.
function attachCategoryVisibilityTogglers() {
$('#FormCenterContent .contentMain').click(function (event) {
var target = event.target;
if (/^lnkLess[0-9]*$/.test(target.id)) {
// Form details should shrink.
lessInfo(parseInt(target.id.substr(7), 10));
event.preventDefault();
}
else if (/^lnkMore[0-9]*$/.test(target.id)) {
// Form details should expand.
moreInfo(parseInt(target.id.substr(7), 10));
event.preventDefault();
}
else {
// If the arrow glyph was clicked, treat it as if the header was clicked.
if (target.nodeName == 'SPAN' && target.className == 'arrow')
target = target.parentNode;
// If the header was clicked.
if (target.nodeName == 'H2') {
var parent = target.parentNode;
// If parent identifier matches expected pattern, get category ID and expand/collapse it.
if (parent && /^cat[0-9]*$/.test(parent.id)) {
var categoryID = parseInt(parent.id.substr(3), 10);
expandCollaspseCategory(categoryID);
// Prevent default code from executing.
event.preventDefault();
}
}
}
});
}
// Called by form submittal to handle radio buttons for serialization.
function submitRadioHandler() {
var names = [];
var values = {};
$checkBoxSelector = null;
$webCheckBox = $('div.formWrap ol.cpForm input[type=radio]');
$mobileCheckBox = $('.mobileGuts input[type=radio]');
if ($webCheckBox.length != 0 && $mobileCheckBox.length == 0)
$checkBoxSelector = $webCheckBox;
if ($webCheckBox.length == 0 && $mobileCheckBox.length != 0)
$checkBoxSelector = $mobileCheckBox;
if ($checkBoxSelector != null) {
// Get list of radio inputs and their values.
$checkBoxSelector.each(function () {
if (!names.contains(this.name)) {
names.push(this.name);
values[this.name] = '';
}
if (this.checked)
values[this.name] = this.value;
})
}
// Map collected data to hidden inputs submitted to server.
for (var i = 0, len = names.length; i < len; i++) {
var inputName = names[i];
var id = (inputName.match(/_/g) || []).length == 2 ? inputName.substring(inputName.indexOf('_') + 1) : inputName;
document.getElementById(id).value = values[inputName];
}
}
// Called by form submittal to handle checkboxes for serialization.
function submitCheckboxHandler() {
var names = [];
var values = {};
$checkBoxSelector = null;
$webCheckBox = $('div.formWrap ol.cpForm input[type=checkbox]');
$mobileCheckBox = $('.mobileGuts input[type=checkbox]');
if ($webCheckBox.length != 0 && $mobileCheckBox.length == 0)
$checkBoxSelector = $webCheckBox;
if ($webCheckBox.length == 0 && $mobileCheckBox.length != 0)
$checkBoxSelector = $mobileCheckBox;
// Get list of checkbox inputs and their values.
if ($checkBoxSelector != null) {
$checkBoxSelector.each(function () {
if (!names.contains(this.name)) {
names.push(this.name);
values[this.name] = [];
}
if (this.checked) {
var val = this.value.replace(/\,/g, '_comma_');
if (val.trim() == '')
val = '_empty_value_';
values[this.name].push(val);
}
});
}
// Map collected data to hidden inputs submitted to server.
for (var i = 0, len = names.length; i < len; i++)
document.getElementById(names[i]).value = values[names[i]].join(',');
}
function submitDateTimeHandler() {
var names = [];
var values = [];
var $datePickers, $timePickers;
if ($('.formCenterDatePicker').length > 0) {
$datePickers = $('.formCenterDatePicker');
$timePickers = $('.formCenterTimePicker');
}
else {
$datePickers = $('.telerikDatePicker');
$timePickers = $('.telerikTimePicker');
}
$datePickers.each(function () {
if (!names.contains(this.name)) {
names.push(this.name);
values[this.name] = [this.value];
}
else {
values[this.name].push(this.value);
}
});
$timePickers.each(function () {
if (!names.contains(this.name)) {
names.push(this.name);
values[this.name] = ['', '', this.value];
}
else {
if (values[this.name].length == 1) {
values[this.name].push('');
}
values[this.name].push(this.value);
}
});
for (var i = 0, len = names.length; i < len; i++)
document.getElementById(names[i]).value = values[names[i]].join();
}
$(function () {
$('#aspnetForm,form[name=aspnetForm]').attr('enctype', "multipart/form-data");
$('#aspnetForm,form[name=aspnetForm]').addClass('submitForm');
});
;
/// <reference path="../../../../Scripts/jquery-1.3.2-vsdoc.js" />
/// <reference path="../../../../Scripts/json2.js" />
/// <reference path="../../../../Scripts/HtmlExtensionSupport.js" />
/// <reference path="../../../../Common/GlobalJSFunctionsDetail.js" />
/// <reference path="../../../../Assets/Scripts/InappropriateWords.js" />
/// <reference path="Home.js" />
// Overridden on a per-form basis. Retrieves validator information for submission validation.
//function getFormValidatorData() {
// return [];
//}
var FormCenterHomeScriptResources = GetJson("/FormCenter/Localization");
var originalTextColorRadio;
var originalTextColorCheckBox;
$.getScript("/Assets/Scripts/InappropriateWords.js");
// Used to properly localize strings.
String.prototype.format = function () {
var args = arguments;
return this.replace(/{(\d+)}/g, function (match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
// Performs validation for a form field.
function FieldValidator(elemInput, id, fieldType, isInternal, isRequired, formatValidation, formatValidationCustom, minAnswer, maxAnswer, maxLength) {
var self = this;
this.elemInputIsArray = $.isArray(elemInput);
if (this.elemInputIsArray) {
for (var i = 0, len = elemInput.length; i < len; i++) {
if (typeof (elemInput[i]) == "string")
elemInput[i] = document.getElementById(elemInput[i]);
}
if (elemInput.length > 0 && elemInput[0]) {
this.elemContainer = elemInput[0].parentNode.parentNode.parentNode.parentNode;
this.elemInput = elemInput;
}
}
else {
if (typeof (elemInput) == "string")
elemInput = document.getElementById(elemInput);
if (elemInput) {
if (fieldType === FieldTypes.DatePicker)
this.elemContainer = elemInput.parentNode.parentNode.parentNode.parentNode;
else
this.elemContainer = elemInput.parentNode.parentNode;
this.elemInput = elemInput;
}
}
this.enabled = true;
this.$elemContainer = $(this.elemContainer);
this.fieldType = fieldType;
if (this.fieldType === FieldTypes.FileUpload) {
//When validating <input type="file" />, we need to update the elemInput reference since it is created a new one when failing inside validateFileUpload method - LC
var validateInputFileUpload = function () {
var $this = $(this);
if (!validateMultiFileUpload($this[0], true)) {
alert("The file you are trying to upload is not an allowed file type or has an invalid file name. These are the accepted characters: A-z 0-9 ~ ! ( ) - + = [ ] { } , . _");
self.elemInput.value = null;
self.elemInput.focus();
}
};
$(this.elemInput).attr("change", "").removeAttr("onChange").unbind("change").change(validateInputFileUpload);
}
this.id = id;
this.isInternal = isInternal;
this.isRequired = isRequired;
this.formatValidation = formatValidation;
this.formatValidationCustom = formatValidationCustom;
this.elemErrorNote = null;
this.minAnswer = minAnswer;
this.maxAnswer = maxAnswer;
this.maxLength = maxLength;
this.focusElementIndex = 0;
this.alreadySetFocus = false;
var isRequiredInfoLableDisplayed = false;
if (this.isRequired && !isRequiredInfoLableDisplayed) {
$('#liRequiredFieldInfo').show();
isRequiredInfoLableDisplayed = true;
}
}
// Static. Creates a single validation object from an options object.
FieldValidator.createSingle = function (options) {
return new FieldValidator(
options.elemInput,
options.id,
options.fieldType,
options.isInternal,
options.isRequired,
options.formatValidation,
options.formatValidationCustom,
options.minAnswer,
options.maxAnswer,
options.maxLength);
};
// Static. Creates array of validation objects from array of option objects.
FieldValidator.createMulti = function (optionsArray) {
var key = null;
var ret = {
keys: [],
add: function (validator) {
var key = validator.id;
this[key] = validator;
this.keys.push(key);
}
};
for (var i = 0, len = optionsArray.length; i < len; i++)
ret.add(FieldValidator.createSingle(optionsArray[i]));
return ret;
};
// Internal. Used by validation() to ensure the input does not exceed the max length.
FieldValidator.prototype.validateMaxLength = function (errorMsg) {
var ERROR_MSG = FormCenterHomeScriptResources.MaxLengthErrorMessage.format(this.maxLength);
if (this.maxLength == null)
return true;
var cleanValue = this.elemInput.value.trim();
if (cleanValue != null && cleanValue.length > this.maxLength) {
errorMsg.push(ERROR_MSG);
return false;
}
return true;
};
// Internal. Used by validate() to ensure user-enterable fields are phone numbers (of NANP format).
FieldValidator.prototype.validatePhone = function (errorMsg) {
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidPhoneNumberFormat);
var origLen = errorMsg.length;
switch (this.fieldType) {
case FieldTypes.ShortAnswer:
case FieldTypes.LongAnswer:
case FieldTypes.Password:
var cleanValue = this.elemInput.value.trim();
if (cleanValue != '' && !phoneValidate(cleanValue, intCountryCode))
errorMsg.push(ERROR_MSG);
break;
}
// Return false if validation check failed (number of errors changed).
return origLen == errorMsg.length;
}
// Internal. Used by validate() to ensure user-enterable fields are postal codes.
FieldValidator.prototype.validatePostal = function (errorMsg) {
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidPostalCode);
var origLen = errorMsg.length;
switch (this.fieldType) {
case FieldTypes.ShortAnswer:
case FieldTypes.LongAnswer:
case FieldTypes.Password:
var cleanValue = this.elemInput.value.trim();
if (cleanValue != '' && !isZipCode(cleanValue, intCountryCode))
errorMsg.push(ERROR_MSG);
break;
}
// Return false if validation check failed (number of errors changed).
return origLen == errorMsg.length;
}
// Internal. Used by validate() to ensure user-enterable fields are email addresses.
FieldValidator.prototype.validateEmail = function (errorMsg) {
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidEmailAddressFormat2);
var origLen = errorMsg.length;
switch (this.fieldType) {
case FieldTypes.ShortAnswer:
case FieldTypes.LongAnswer:
case FieldTypes.Password:
case FieldTypes.ReplyEmail:
var cleanValue = this.elemInput.value.trim();
if (cleanValue != '' && !emailValidate(cleanValue))
errorMsg.push(ERROR_MSG);
break;
}
// Return false if validation check failed (number of errors changed).
return origLen == errorMsg.length;
}
function getNumericThousandsSeparator() {
var dummy = new Number(11111111);
var thousandSep = dummy.toLocaleString().replace(/1/g, '');
return (thousandSep.length > 0 ? thousandSep.charAt(0) : ',');
}
// Internal. Used by validate() to ensure user-enterable fields match custom expression.
FieldValidator.prototype.validateCustom = function (expr, errorMsg) {
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidGenericField);
var origLen = errorMsg.length;
var customRegExp = new RegExp(expr);
switch (this.fieldType) {
case FieldTypes.ShortAnswer:
case FieldTypes.LongAnswer:
case FieldTypes.Password:
var cleanValue = this.elemInput.value.trim();
if (cleanValue != '' && (!customRegExp.test(cleanValue)))
errorMsg.push(ERROR_MSG);
break;
}
// Return false if validation check failed (number of errors changed).
return origLen == errorMsg.length;
}
// Internal. Used by validate() to ensure user-enterable fields are letters only.
FieldValidator.prototype.validateLetters = function (errorMsg) {
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.LettersOnlyField);
var origLen = errorMsg.length;
var letterRegExp = /^[a-zA-Z ]+$/;
switch (this.fieldType) {
case FieldTypes.ShortAnswer:
case FieldTypes.LongAnswer:
case FieldTypes.Password:
var cleanValue = this.elemInput.value.trim();
if (cleanValue != '' && (!letterRegExp.test(cleanValue)))
errorMsg.push(ERROR_MSG);
break;
}
// Return false if validation check failed (number of errors changed).
return origLen == errorMsg.length;
}
// Internal. Used by validate() to ensure user-enterable fields are numeric (numbers, decimal separators, and group separators allowed).
FieldValidator.prototype.validateNumeric = function (errorMsg) {
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.NumericOnlyField);
var origLen = errorMsg.length;
var numericRegExp = new RegExp("^(([0-9]+?[0-9%G]+?[0-9](|%D[0-9]+))|([0-9]*(|%D[0-9]+)))$"
.replace(/%G/g, RegExp.metaEscape(getNumericThousandsSeparator()))
.replace(/%D/g, RegExp.metaEscape(getNumericDecimalSeparator())));
switch (this.fieldType) {
case FieldTypes.ShortAnswer:
case FieldTypes.LongAnswer:
case FieldTypes.Password:
var cleanValue = this.elemInput.value.trim();
if (cleanValue != '' && (!numericRegExp.test(cleanValue)))
errorMsg.push(ERROR_MSG);
break;
}
// Return false if validation check failed (number of errors changed).
return origLen == errorMsg.length;
}
FieldValidator.prototype.validateCurrency = function (errorMsg) {
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.CurrencyOnlyField);
var origLen = errorMsg.length;
var value = this.elemInput.value.trim();
if (!this.isValidMoney(value)) {
errorMsg.push(ERROR_MSG);;
}
// Return false if validation check failed (nubmer of errors changed).
return origLen == errorMsg.length;
}
FieldValidator.prototype.isValidMoney = function (value) {
if (value && value != '')
return /^\$?\s*\d+(,\d{3})*(\.\d{1,2})?$/.test(value);
else
return true;
};
//#region Date Validation
FieldValidator.prototype.validateDate = function (errorMsg) {
var origLen = errorMsg.length;
var date = $(this.elemInput[0]).val();
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidDate);
if (!this.isValidDate(date, this.isRequired)) {
errorMsg.push(ERROR_MSG);
}
// Return false if validation check failed (nubmer of errors changed).
return origLen == errorMsg.length;
}
FieldValidator.prototype.validateTime = function (errorMsg) {
var origLen = errorMsg.length;
var time = $(this.elemInput[0]).val();
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidTime);
if (!this.isValidTime(time, this.isRequired)) {
errorMsg.push(ERROR_MSG);
}
// Return false if validation check failed (nubmer of errors changed).
return origLen == errorMsg.length;
}
FieldValidator.prototype.validateDateTime = function (errorMsg) {
var origLen = errorMsg.length;
var date = $(this.elemInput[0]).val();
var time = $(this.elemInput[1]).val();
var validDate = this.isValidDate(date, this.isRequired);
var validTime = this.isValidTime(time, this.isRequired);
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.InvalidDateTime);
if (!validDate && !validTime) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 0;
this.alreadySetFocus = true;
}
errorMsg.push(ERROR_MSG);
}
else if (!validDate) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 0;
this.alreadySetFocus = true;
}
errorMsg.push(ERROR_MSG);
}
else if (!validTime) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 1;
this.alreadySetFocus = true;
}
errorMsg.push(ERROR_MSG);
}
// Return false if validation check failed (nubmer of errors changed).
return origLen == errorMsg.length;
}
FieldValidator.prototype.validateDateSpan = function (errorMsg) {
var origLen = errorMsg.length;
var date = $(this.elemInput[0]).val();
var dateSpan = $(this.elemInput[1]).val();
if (!this.isValidDate(date, this.isRequired)) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 0;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidStartDate);
}
if (!this.isValidDate(dateSpan, this.isRequired)) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 1;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidEndDate);
}
if (!this.isValidDateRange(date, dateSpan, this.isRequired, this.isRequired)) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 0;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidDateSpan);
}
// Return false if validation check failed (nubmer of errors changed).
return origLen == errorMsg.length;
}
FieldValidator.prototype.validateTimeSpan = function (errorMsg) {
var origLen = errorMsg.length;
var time = $(this.elemInput[0]).val();
var timeSpan = $(this.elemInput[1]).val();
if (!this.isValidTime(time, this.isRequired)) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 0;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidStartTime);
}
if (!this.isValidTime(timeSpan, this.isRequired)) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 1;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidEndTime);
}
if (!this.isValidTimeRange(time, timeSpan, this.isRequired, this.isRequired)) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 0;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidTimeSpan);
}
// Return false if validation check failed (nubmer of errors changed).
return origLen == errorMsg.length;
}
FieldValidator.prototype.validateDateTimeSpan = function (errorMsg) {
var origLen = errorMsg.length;
var date = $(this.elemInput[0]).val();
var dateSpan = $(this.elemInput[1]).val();
var time = $(this.elemInput[2]).val();
var timeSpan = $(this.elemInput[3]).val();
var validDate = this.isValidDate(date, this.isRequired);
var validTime = this.isValidTime(time, this.isRequired);
if (!validDate && !validTime) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 0;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidStartDateTime);
}
else if (!validDate) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 0;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidStartDate);
}
else if (!validTime) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 2;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidStartTime);
}
var validSpanDate = this.isValidDate(dateSpan, this.isRequired);
var validSpanTime = this.isValidTime(timeSpan, this.isRequired);
if (!validSpanDate && !validSpanTime) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 1;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidEndDateTime);
}
else if (!validSpanDate) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 1;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidEndDate);
}
else if (!validSpanTime) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 3;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidEndTime);
}
var isDayBeforeMonth = getDateFormat().toLocaleLowerCase() == "dd/mm/yyyy" ? true : false;
if (!this.isValidDateTimeRange(getDateFromInput(this.elemInput[0], isDayBeforeMonth), getDateFromInput(this.elemInput[1], isDayBeforeMonth), this.isRequired, this.isRequired, time, timeSpan, this.isRequired, this.isRequired)) {
if (!this.alreadySetFocus) {
this.focusElementIndex = 1;
this.alreadySetFocus = true;
}
errorMsg.push(FormCenterHomeScriptResources.InvalidDateTimeSpan);
}
// Return false if validation check failed (nubmer of errors changed).
return origLen == errorMsg.length;
}
FieldValidator.prototype.isValidDate = function (date, dateRequired) {
var objDate = new dateValidator();
return objDate.dateValidateNew(date, dateRequired, '');
}
FieldValidator.prototype.isValidTime = function (time, timeRequired) {
var objDate = new dateValidator();
var amIndex = time.toLowerCase().indexOf('am');
var pmIndex = time.toLowerCase().indexOf('pm');
if (amIndex != -1) {
time = time.substring(0, amIndex).replace(" ", "");
if (time.trim() === "") {
return false;
}
}
else if (pmIndex != -1) {
time = time.substring(0, pmIndex).replace(" ", "");
if (time.trim() === "") {
return false;
}
}
return objDate.timeValidate(time, timeRequired, '');
}
FieldValidator.prototype.isValidTimeRange = function (startTime, endTime, startTimeRequired, endTimeRequired) {
var objDate = new dateValidator();
objDate.ysnAllowTimeOnly = true;
objDate.dtiStartTime = this.stripAMPM(startTime);
objDate.ysnStartTimeRequired = startTimeRequired;
objDate.dtiEndTime = this.stripAMPM(endTime);
objDate.ysnEndTimeRequired = endTimeRequired;
objDate.ysnDatesAreEqual = true;
objDate.strStartAMPM = this.getAMPMString(startTime);
objDate.strEndAMPM = this.getAMPMString(endTime);
objDate.timesAlreadyValidated = true;
return objDate.timeOrderValidate();
}
FieldValidator.prototype.isValidDateRange = function (startDate, endDate, startDateRequired, endDateRequired) {
var objDate = new dateValidator();
objDate.setStartDate(checkDateFormatReturnUSString(startDate, false));
objDate.setEndDate(checkDateFormatReturnUSString(endDate, false));
objDate.setStartDateRequired(startDateRequired);
objDate.setEndDateRequired(endDateRequired);
objDate.datesAlreadyValidated = true;
return objDate.dateOrderValidateNew();
}
FieldValidator.prototype.isValidDateTimeRange = function (startDate, endDate, startDateRequired, endDateRequired, startTime, endTime, startTimeRequired, endTimeRequired) {
var objDate = new dateValidator();
objDate.setStartDate(checkDateFormatReturnUSString(startDate, false));
objDate.setEndDate(checkDateFormatReturnUSString(endDate, false));
objDate.setStartDateRequired(startDateRequired);
objDate.setEndDateRequired(endDateRequired);
objDate.ysnAllowEqualDates = true;
objDate.datesAlreadyValidated = true;
var validDateOrder = objDate.dateOrderValidateNew();
objDate.strStartAMPM = this.getAMPMString(startTime);
objDate.strEndAMPM = this.getAMPMString(endTime);
objDate.ysnAllowTimeOnly = true;
objDate.ysnAllowEqualTimes = !objDate.ysnDatesAreEqual;
objDate.dtiStartTime = this.stripAMPM(startTime);
objDate.ysnStartTimeRequired = startTimeRequired;
objDate.dtiEndTime = this.stripAMPM(endTime);
objDate.ysnEndTimeRequired = endTimeRequired;
objDate.timesAlreadyValidated = true;
var validTimeOrder = objDate.timeOrderValidate();
return validDateOrder && validTimeOrder;
}
FieldValidator.prototype.stripAMPM = function (time) {
var amIndex = time.toLowerCase().indexOf('am');
var pmIndex = time.toLowerCase().indexOf('pm');
if (amIndex != -1) {
time = time.substring(0, amIndex).replace(" ", "");
}
else if (pmIndex != -1) {
time = time.substring(0, pmIndex).replace(" ", "");
}
return time;
}
FieldValidator.prototype.getAMPMString = function (time) {
var amIndex = time.toLowerCase().indexOf('am');
var pmIndex = time.toLowerCase().indexOf('pm');
var AMPM = '';
if (amIndex != -1) {
AMPM = time.substring(amIndex).replace(" ", "");
}
else if (pmIndex != -1) {
AMPM = time.substring(pmIndex).replace(" ", "");
}
return AMPM;
}
//#endregion Date Validation
//checkbox validation done for min and max answer selcted
FieldValidator.prototype.checkBoxValidation = function (errorMsg) {
var origLen = errorMsg.length;
if (this.fieldType == FieldTypes.Checkboxes && ((this.minAnswer != "" && this.minAnswer != undefined) || (this.maxAnswer != "" && this.maxAnswer != undefined))) {
var i = 0, len = this.elemInput.length;
var checkedCount = 0;
for (; i < len; i++) {
if (this.elemInput[i].checked)
checkedCount++;
}
//validation for checkbox min max fields
if (this.minAnswer != "" && this.minAnswer != undefined) {
if (checkedCount < parseInt(this.minAnswer, 10)) // the message is not localized on purpose as this has text and dynamic value
errorMsg.push("This field must have at least " + parseInt(this.minAnswer, 10) + " options selected");
}
if (origLen == errorMsg.length && this.maxAnswer != "" && this.maxAnswer != undefined) {
if (checkedCount > parseInt(this.maxAnswer, 10)) // the message is not localized on purpose as this has text and dynamic value
errorMsg.push("This field can have at most " + parseInt(this.maxAnswer, 10) + " options selected");
}
}
// Return false if validation check failed (number of errors changed).
return origLen == errorMsg.length;
};
// Internal. Used by validate() to ensure required fields are set.
FieldValidator.prototype.validateRequired = function (errorMsg) {
var ERROR_MSG = this.getErrorMessage(FormCenterHomeScriptResources.RequiredField);//FormCenterHomeScriptResources.RequiredField;
var origLen = errorMsg.length;
switch (this.fieldType) {
case FieldTypes.ShortAnswer:
case FieldTypes.LongAnswer:
case FieldTypes.ReplyEmail:
case FieldTypes.Password:
case FieldTypes.FileUpload:
case FieldTypes.CodeSnippet:
case FieldTypes.InputLink:
case FieldTypes.DatePicker:
case FieldTypes.InputImage:
if (this.elemInput != 'undefined' && this.elemInput.value != undefined) {
if (this.elemInput.value.trim() == '')
errorMsg.push(ERROR_MSG);
}
break;
case FieldTypes.Checkboxes:
case FieldTypes.RadioButtons:
var i = 0, len = this.elemInput.length;
for (; i < len; i++) {
if (this.elemInput[i].checked)
break;
}
if (i == len)
errorMsg.push(ERROR_MSG);
break;
case FieldTypes.Dropdown:
case FieldTypes.FormLink:
if (this.elemInput.selectedIndex <= 0)
errorMsg.push(ERROR_MSG);
break;
case FieldTypes.DateTime:
var i = 0, len = this.elemInput.length;
for (; i < len; i++) {
if (this.elemInput[i].value.trim() == '') {
errorMsg.push(ERROR_MSG);
this.focusElementIndex = i;
break;
}
}
}
// Return false if validation check failed (number of errors changed).
return origLen == errorMsg.length;
};
// Performs validation for field and updates format if necessary.
FieldValidator.prototype.validate = function (assignFocusOnFailure, checkForInappropriateWords) {
var errorMsg = [];
// Element not present OR disabled, pass (skipped).
if (this.elemInput == null || !this.enabled)
return true;
if (!this.isRequired || (this.isRequired && this.validateRequired(errorMsg))) {
//checkbox validation done for min and max answer selected
if (this.checkBoxValidation(errorMsg)) {
switch (this.formatValidation) {
case FieldValidation.Letters:
this.validateLetters(errorMsg);
break;
case FieldValidation.Numeric:
this.validateNumeric(errorMsg);
break;
case FieldValidation.Currency:
this.validateCurrency(errorMsg);
break;
case FieldValidation.PhoneNumber:
this.validatePhone(errorMsg);
break;
case FieldValidation.PostalCode:
this.validatePostal(errorMsg);
break;
case FieldValidation.EmailAddress:
this.validateEmail(errorMsg);
break;
case FieldValidation.RegEx:
this.validateCustom(this.formatValidationCustom, errorMsg);
break;
case FieldValidation.Date:
this.validateDate(errorMsg);
break;
case FieldValidation.Time:
this.validateTime(errorMsg);
break;
case FieldValidation.DateTime:
this.validateDateTime(errorMsg);
break;
case FieldValidation.DateSpan:
this.validateDateSpan(errorMsg);
break;
case FieldValidation.TimeSpan:
this.validateTimeSpan(errorMsg);
break;
case FieldValidation.DateTimeSpan:
this.validateDateTimeSpan(errorMsg);
break;
}
}
}
if (this.fieldType === FieldTypes.DatePicker && this.elemInput.value.trim() != '') {
//validate date picker value (based on telerik mvc datePicker)
var datepicker = $(this.elemInput).data("tDatePicker");
if ($(this.elemInput).hasClass('t-state-error') || datepicker.parse(this.elemInput.value.trim()) == null)
errorMsg.push("Invalid date format");
}
if (this.fieldType === FieldTypes.ShortAnswer || this.fieldType === FieldTypes.LongAnswer) {
var validator = this;
if (checkForInappropriateWords != null && typeof (checkForInappropriateWords.push) == 'function') {
checkForInappropriateWords.push(validator);
} else {
if (HasInappropriateWords(this.elemInput.value.trim())) {
$(this.elemInput).addClass('t-state-error');
errorMsg.push(FormCenterHomeScriptResources.InappropriateWords);
}
}
}
if (FeatureToggles.isActive("CMS.FormCenter.EnableServerSideValidationsForSubmissions")
&& this.fieldType === FieldTypes.FileUpload
&& this.elemInput.value.trim() != '') {
if (Math.round((this.elemInput.files[0].size / 1024)) > 20480)
errorMsg.push("Files cannot be larger than 20 MB.");
}
this.validateMaxLength(errorMsg);
if (errorMsg.length > 0 && $(this.elemInput).is(":visible")) {
this.errorShow(errorMsg);
if (assignFocusOnFailure) {
this.focusErrorElement();
}
return false;
} else {
this.errorClear();
return true;
}
};
// Performs validation for admin edit internal only fields and updates format if necessary.
FieldValidator.prototype.validateInternal = function (assignFocusOnFailure, checkForInappropriateWords) {
if (this.isInternal) {
var errorMsg = [];
// Element not present OR disabled, pass (skipped).
if (this.elemInput == null || !this.enabled)
return true;
if (!this.isRequired || (this.isRequired && this.validateRequired(errorMsg))) {
//checkbox validation done for min and max answer selected
if (this.checkBoxValidation(errorMsg)) {
switch (this.formatValidation) {
case FieldValidation.Letters:
this.validateLetters(errorMsg);
break;
case FieldValidation.Numeric:
this.validateNumeric(errorMsg);
break;
case FieldValidation.Currency:
this.validateCurrency(errorMsg);
break;
case FieldValidation.PhoneNumber:
this.validatePhone(errorMsg);
break;
case FieldValidation.PostalCode:
this.validatePostal(errorMsg);
break;
case FieldValidation.EmailAddress:
this.validateEmail(errorMsg);
break;
case FieldValidation.RegEx:
this.validateCustom(this.formatValidationCustom, errorMsg);
break;
case FieldValidation.Date:
this.validateDate(errorMsg);
break;
case FieldValidation.Time:
this.validateTime(errorMsg);
break;
case FieldValidation.DateTime:
this.validateDateTime(errorMsg);
break;
case FieldValidation.DateSpan:
this.validateDateSpan(errorMsg);
break;
case FieldValidation.TimeSpan:
this.validateTimeSpan(errorMsg);
break;
case FieldValidation.DateTimeSpan:
this.validateDateTimeSpan(errorMsg);
break;
}
}
}
if (this.fieldType === FieldTypes.DatePicker && this.elemInput.value.trim() != '') {
//validate date picker value (based on telerik mvc datePicker)
var datepicker = $(this.elemInput).data("tDatePicker");
if ($(this.elemInput).hasClass('t-state-error') || datepicker.parse(this.elemInput.value.trim()) == null)
errorMsg.push("Invalid date format");
}
if (this.fieldType === FieldTypes.ShortAnswer || this.fieldType === FieldTypes.LongAnswer) {
var validator = this;
if (checkForInappropriateWords != null && typeof (checkForInappropriateWords.push) == 'function') {
checkForInappropriateWords.push(validator);
} else {
if (HasInappropriateWords(this.elemInput.value.trim())) {
$(this.elemInput).addClass('t-state-error');
errorMsg.push(FormCenterHomeScriptResources.InappropriateWords);
}
}
}
this.validateMaxLength(errorMsg);
if (errorMsg.length > 0 && $(this.elemInput).is(":visible")) {
this.errorShow(errorMsg);
if (assignFocusOnFailure) {
this.focusErrorElement();
}
return false;
} else {
this.errorClear();
return true;
}
}
else {
return true;
}
};
FieldValidator.prototype.handleInappropriateWords = function (focus) {
var errorMsg = [];
$(this.elemInput).addClass('t-state-error');
errorMsg.push(FormCenterHomeScriptResources.InappropriateWords);
this.errorShow(errorMsg);
if (focus) {
this.focusErrorElement();
}
};
FieldValidator.prototype.focusErrorElement = function () {
var scrollIntoView = function (element) {
var offset = $(element).offset();
var elementTop = offset.top;
// Add a 50px padding to the top of the element, just for aesthetics
$(document).scrollTop(elementTop - 150);
};
if (this.elemInputIsArray) {
if ($(this.elemInput).is(":visible")) {
if (this.elemInput.length > this.focusElementIndex) {
this.elemInput[this.focusElementIndex].focus();
}
else {
this.elemInput[0].focus();
}
scrollIntoView(this.elemInput[0]);
}
this.alreadySetFocus = false;
this.focusElementIndex = 0;
}
else {
if ($(this.elemInput).is(":visible")) {
this.elemInput.focus();
scrollIntoView(this.elemInput);
}
}
}
// Shows error message for field. Called by validate() if field value fails validation.
FieldValidator.prototype.errorShow = function (messages) {
if (this.elemErrorNote)
this.errorClear();
// Element not defined, cannot perform operation.
if (this.elemInput == null)
return;
this.$elemContainer.addClass('error');
this.elemErrorNote = [];
$('ol li.error div').addClass('selfClear');
if (this.elemInput != undefined) {
if (this.elemInput["0"] != undefined) {
//Check current element is radio
if (this.elemInput["0"].type == "radio" & !(this.$elemContainer.closest('li').hasClass('error'))) {
this.$elemContainer.closest('li').addClass('error');
originalTextColorRadio = this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color;
this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color = "#800000";
}
else //Check current element is checkbox
if (this.elemInput["0"].type == "checkbox" & !(this.$elemContainer.closest('li').hasClass('error'))) {
this.$elemContainer.closest('li').addClass('error');
originalTextColorCheckBox = this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color;
this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color = "#800000";
}
}
}
for (var i = 0, len = messages.length; i < len; i++) {
var errorElemMsg = document.createElement('p');
errorElemMsg.className = 'explanation';
var multiSelectable = this.elemInput[0] !== undefined && this.elemInput.tagName !== "SELECT";
if (multiSelectable) {
errorElemMsg.id = 'errorMsg' + this.elemInput[0].id;
}
else {
errorElemMsg.id = 'errorMsg' + this.elemInput.id;
}
errorElemMsg.innerHTML = messages[i];
if (this.elemInput != undefined) {
if (this.elemInput["0"] != undefined) {
if (this.elemInput["0"].type == "radio" || this.elemInput["0"].type == "checkbox") {
errorElemMsg.style.backgroundColor = "#940E0D"
errorElemMsg.style.color = "#FFFFFF";
errorElemMsg.style.fontWeight = "bold"
errorElemMsg.style.lineHeight = "1.2"
errorElemMsg.style.width = "94%"
errorElemMsg.style.margin = ".5em 0 0"
errorElemMsg.style.padding = ".5em"
}
}
}
this.elemContainer.appendChild(errorElemMsg);
this.elemErrorNote.push(errorElemMsg);
}
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
};
// Clears error message for field. Called by validate() if field value passes validation.
FieldValidator.prototype.errorClear = function () {
if (this.elemInput != undefined) {
if (this.elemInput["0"] != undefined) {
var i = 0, len = this.elemInput.length;
for (; i < len; i++) {
if (this.elemInput[i].checked)
break;
}
if (i != len) {
if (this.elemInput["0"].type == "radio") {
this.$elemContainer.closest('li').removeClass('error');
this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color = originalTextColorRadio;
}
else if (this.elemInput["0"].type == "checkbox") {
this.$elemContainer.closest('li').removeClass('error');
this.$elemContainer.closest("fieldset")[0].childNodes[0].style.color = originalTextColorCheckBox;
}
}
}
}
if (this.elemErrorNote == null)
return;
else if (this.elemInput == null)
return;
if (this.elemErrorNote.length > 0) {
var errorParent = this.elemErrorNote[0].parentNode;
for (var i = 0, len = this.elemErrorNote.length; i < len; i++)
errorParent.removeChild(this.elemErrorNote[i]);
this.elemErrorNote = null;
}
this.$elemContainer.removeClass('error');
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
};
FieldValidator.prototype.getErrorMessage = function (errorTemplateMsg) {
var $fieldElemContainer = $(this.elemContainer);
if (!$fieldElemContainer.hasClass('formFieldContainer'))
{
$fieldElemContainer = $fieldElemContainer.parents('.formFieldContainer');
}
var $fieldLabelElem = $fieldElemContainer.find('.labelForFieldElement');
var fieldLabel = '';
if ($fieldLabelElem.length > 0)
{
fieldLabel = $fieldLabelElem.text().replace('*', '');
}
else
{
$fieldLabelElem = $fieldElemContainer.find('legend');
if ($fieldLabelElem.length > 0)
{
fieldLabel = $fieldLabelElem.text().replace('*', '');
}
}
var errorMsg = errorTemplateMsg.format(fieldLabel);
return errorMsg;
};
/// <reference path="../../../../Scripts/jquery-1.3.2-vsdoc.js"/>
/// <reference path="../../../../Scripts/json2.js"/>
/// <reference path="../../../../Scripts/HtmlExtensionSupport.js"/>
/// <reference path="../../../../Common/GlobalJSFunctionsDetail.js" />
/// <reference path="Home.js" />
// Configurable in debug console. Controls behavior of FieldConditionsRunner.log().
var condRunnerHideLogDupes = true;
// Missing methods for IE
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.msMatchesSelector ||
Element.prototype.webkitMatchesSelector;
}
if (!Element.prototype.closest) {
Element.prototype.closest = function (s) {
var el = this;
do {
if (Element.prototype.matches.call(el, s)) return el;
el = el.parentElement || el.parentNode;
} while (el !== null && el.nodeType === 1);
return null;
};
}
////////// Helper Functions ///////////////
$("*").focus(function () {
var inputs = $("input[type=text][cp5ph=true], textarea[cp5ph=true]");
if (inputs != null) {
for (var i = 0; i < inputs.length; i++) {
var elementName = inputs[i].getAttribute('id');
if (elementName != null) {
var top = $('#' + elementName).offset().top;
var left = $('#' + elementName).offset().left;
if (top != -2 && left != -2)
$('#ph_' + elementName).offset({ left: (left + 5), top: (top + 5) });
}
}
}
});
// Helper that handles replacement of special characters.
// * value - variable to handle characters of.
function HandleCharacters(value) {
return value.replace(/,/g, '_d');
}
if (Array.prototype.any == null && !$.isFunction(Array.prototype.any)) {
// Returns true if callback condition returns true for any items in array.
// * callback - Callback function with single argument for current index. The 'this' reference points to the array.
Array.prototype.any = function (callback) {
if (this == null)
return false;
for (var i = 0, len = this.length; i < len; i++) {
if (callback.call(this, i))
return true;
}
return false;
}
}
if (Array.prototype.all == null && !$.isFunction(Array.prototype.all)) {
// Returns true if callback condition returns true for all items in array.
// * callback - Callback function with single argument for current index. The 'this' reference points to the array.
Array.prototype.all = function (callback) {
if (this == null)
return false;
for (var i = 0, len = this.length; i < len; i++) {
if (!callback.call(this, i))
return false;
}
return true;
};
}
if (Error.argNull == null || !$.isFunction(Error.argNull)) {
// Static helper that creates error when null argument that should not be null is encountered.
// * argName - Name of problematic null argument.
Error.argNull = function (argName) {
return new ReferenceError(argName + " cannot be null");
}
}
// Overridden on a per-form basis. Retrieves validator information for submission validation.
// * validators - Validator dictionary.
function getFormConditionData() {
return [];
}
// Prints useful debugging information for FieldConditionsRunner.run() results. Use as done callback.
// Note: When minifiying the JavaScript, this function can/should be removed.
// * logs - Log generated by run().
function debugCondRunnerLogResults(logs) {
if (logs == null)
throw new Error.argNull("logs");
console.log("## run() started at " + (new Date()) + " ##");
for (var i = 0, iLen = logs.length; i < iLen; i++) {
var log = logs[i];
var resultEx = log.isMet ? " (met)" : " (not met)";
console.log(
"field: " + log.id +
", condIndex: " + log.condIndex +
", action: " + ConditionActions.getName(log.actType) +
", result: " + ConditionRunnerActResult.getName(log.result) + resultEx);
if (log.needRestart)
console.log("-- restart --");
}
console.log("## run() ended ##");
console.log("\t");
}
// Helper that repositions line siblings by re-assigning left/middle/right classes.
// * liSiblingList - Array of LI elements for a form line.
function repositionLineSiblings(liSiblingList) {
if (liSiblingList == null)
throw new Error.argNull("liSiblingList");
var sibling, $sibling;
var len = liSiblingList.length;
if (len > 0) {
var operableNodes = [];
for (var i = 0; i < len; i++) {
sibling = liSiblingList[i];
$sibling = $(sibling);
if (!$sibling.hasClass('hidden'))
operableNodes.push($sibling);
}
len = operableNodes.length;
if (len > 0) {
operableNodes[0].removeClass('middle right').addClass('left');
var j = 1;
for (; j < len - 1; j++)
operableNodes[j].removeClass('left right').addClass('middle');
if (j < len)
operableNodes[j].removeClass('left middle').addClass('right');
}
}
}
// Helper that gets sibling field LI elements for a line field LI element.
// * liElem - The LI element for a form field to get line siblings LIs for.
function getLineSiblings(liElem) {
if (liElem == null && (window.location.href).toString().toLowerCase().indexOf("print") != -1)
return "";
if (liElem == null)
throw new Error.argNull("liElem");
var nodeList = [];
var startNode = liElem;
// Get start of line.
while (startNode && !$(startNode).hasClass('lineStart'))
startNode = previousElementSibling(startNode);
// Get end of line.
if (startNode) {
var endNode = startNode;
var $endNode = null;
while (endNode != null) {
$endNode = $(endNode);
if ($endNode.hasClass('lineEnd'))
break;
endNode = nextElementSibling(endNode);
}
}
if (startNode && endNode) {
var nodeEnum = startNode;
while (true) {
nodeList.push(nodeEnum);
if (nodeEnum == endNode)
break;
nodeEnum = nextElementSibling(nodeEnum);
}
}
return nodeList;
}
////////// Enumerations ///////////////////
// Condition actions.
var ConditionActions = {
None: 0,
Show: 1,
Hide: 2,
Require: 3,
RedirectTo: 4,
getName: function (value) {
for (var k in ConditionActions) {
if (ConditionActions[k] == value)
return k;
}
return null;
}
};
// Condition comparison types.
var ConditionComparison = {
None: 0,
GreaterThan: 1,
LessThan: 2,
EqualTo: 3,
NotEqualTo: 4,
Contains: 5,
Available: 6,
Unavailable: 7,
Between: 8,
getName: function (value) {
for (var k in ConditionComparison) {
if (ConditionComparison[k] == value)
return k;
}
return null;
}
};
// Condition runner action results.
var ConditionRunnerActResult = {
None: 0,
SuccessImplicit: 1,
SuccessExplicit: 2,
SkipDuplicate: 3,
SkipContradiction: 4,
getName: function (value) {
for (var k in ConditionRunnerActResult) {
if (ConditionRunnerActResult[k] == value)
return k;
}
return null;
}
};
////////// FieldCondition Class ///////////
// Internal. Creates instance of FieldCondition class.
// * parent - Parent FieldConditions instance.
// * condInfo - Object containing properties {compType, compValue, actElemInput, actID, actType, actFieldType, actURL, actURLNewWindow}.
function FieldCondition(parent, condInfo) {
if (parent == null)
throw new Error.argNull("parent");
else if (condInfo == null)
throw new Error.argNull("condInfo");
$.extend(this, condInfo);
// Set instance parent.
this.parent = parent;
// Process actElemInput argument.
var actElemInput = this.actElemInput;
this.actElemInputIsArray = $.isArray(actElemInput);
if (this.actElemInputIsArray) {
for (var i = 0, len = actElemInput.length; i < len; i++) {
if (typeof (actElemInput[i]) == "string")
actElemInput[i] = document.getElementById(actElemInput[i]);
}
if (actElemInput.length > 0 && actElemInput[0]) {
this.actElemContainer = actElemInput[0].closest('.formFieldContainer');
this.actElemInput = actElemInput;
}
}
else {
if (typeof (actElemInput) == "string")
actElemInput = document.getElementById(actElemInput);
if (actElemInput) {
this.actElemContainer = actElemInput.closest('.formFieldContainer');
this.actElemInput = actElemInput;
}
}
// Get shared container.
this.$actElemContainer = $(this.actElemContainer);
}
// Static. Creates multiple instances from list of condition information.
FieldCondition.createMulti = function (parent, condList) {
if (parent == null)
throw new Error.argNull("parent");
else if (condList == null)
throw new Error.argNull("condList");
var ret = [];
for (var i = 0, len = condList.length; i < len; i++)
ret.push(new FieldCondition(parent, condList[i]));
return ret;
}
// Checks if condition is met and performs any necessary action.
// * updateUI - Determines if UI is updated after check. Treated as true if null/unspecified.
FieldCondition.prototype.check = function (updateUI) {
// TODO: Handle checkboxes/radios/dropdowns when Akila gets that done on back-end.
var thisValue = [];
var compValue = this.compValue;
var isMet = false;
switch (this.actFieldType) {
case FieldTypes.Checkboxes:
for (var i = 0, len = this.actElemInput.length; i < len; i++) {
if (this.actElemInput[i].checked)
thisValue.push(this.actElemInput[i].value.replace(/\,/g, '_comma_'));
}
break;
case FieldTypes.RadioButtons:
for (var i = 0, len = this.actElemInput.length; i < len; i++) {
if (this.actElemInput[i].checked) {
thisValue = [this.actElemInput[i].value];
break;
}
}
break;
case FieldTypes.DateTime:
var tempArray = new Array();
for (var i = 0, len = this.actElemInput.length; i < len; i++) {
tempArray.push([this.actElemInput[i].value])
}
thisValue = [tempArray.join(',')];
break;
default:
thisValue = [this.actElemInput.value];
}
var extractMoneyValue = function (v) {
var stringBeginsWith = function (val, beginString) {
return val.substring(0, beginString.length) === beginString
}
if (v && v != '') {
if (stringBeginsWith(v, '$')) {
return v.substring(1).replace(',', '');
}
}
return v.replace(',', '');
};
var isNum = function (val) {
var extracted = extractMoneyValue(val);
return parseFloat(extracted) === +extracted;
};
var checkAgainst = function (compValue) {
switch (this.compType) {
case ConditionComparison.GreaterThan:
return thisValue.any(function (index) {
if (isNum(this[index]) && isNum(HandleCharacters(compValue))) {
return parseFloat(extractMoneyValue(this[index])) > parseFloat(extractMoneyValue(HandleCharacters(compValue)));
}
return false;
});
case ConditionComparison.LessThan:
return thisValue.any(function (index) {
if (isNum(this[index]) && isNum(HandleCharacters(compValue))) {
return parseFloat(extractMoneyValue(this[index])) < parseFloat(extractMoneyValue(HandleCharacters(compValue)));
}
return false;
});
case ConditionComparison.EqualTo:
if (this.actFieldType == FieldTypes.DateTime) {
if (this.actIsDateTimeSpan) {
return this.checkDateEqualSpan(thisValue[0], compValue);
}
else {
return this.checkDateEqualTo(thisValue[0], compValue);
}
}
else {
return thisValue.any(function (index) {
return (isNull(HandleCharacters(this[index]), '') == isNull(HandleCharacters(compValue), ''));
});
}
case ConditionComparison.NotEqualTo:
return thisValue.any(function (index) { return (isNull(this[index], '').toUpperCase() != isNull(HandleCharacters(compValue), '').toUpperCase()); });
break;
case ConditionComparison.Contains:
var containsExp = new RegExp(RegExp.metaEscape(HandleCharacters(compValue)), 'i');
return thisValue.any(function (index) {
return containsExp.test(this[index]);
});
case ConditionComparison.Unavailable:
return this.$actElemContainer.hasClass('unavailable');
case ConditionComparison.Available:
return !this.$actElemContainer.hasClass('unavailable');
case ConditionComparison.Between:
return this.checkDateBetween(thisValue[0], compValue);
return;
case ConditionComparison.None:
default:
return true;
}
};
switch (this.actFieldType) {
case FieldTypes.Checkboxes:
var compArr = compValue.split(',');
isMet = true;
for (var i = 0, len = compArr.length; i < len; i++) {
if (!checkAgainst.call(this, compArr[i])) {
isMet = false;
break;
}
}
break;
default:
isMet = checkAgainst.call(this, compValue);
}
if (updateUI)
this.doAction(isMet);
return isMet;
};
// Performs changes to applying field based on condition action and comparison result.
FieldCondition.prototype.doAction = function (isMet) {
var validator = (this.parent.validators ? this.parent.validators[this.parent.id] : null);
switch (this.actType) {
case ConditionActions.Show:
this.doActionShow(isMet, validator);
break;
case ConditionActions.Hide:
this.doActionHide(isMet, validator);
break;
case ConditionActions.Require:
this.doActionRequire(isMet, validator);
break;
case ConditionActions.RedirectTo:
this.doActionRedirect(isMet, validator);
break;
}
};
FieldCondition.prototype.doActionShow = function (isMet, validator) {
if (isMet) {
this.parent.$elemContainer.removeClass('hidden');
this.parent.$elemContainer.removeClass('unavailable');
// Update classes assigned to fields (e.g. since what was "left" may now be hidden and a new "left" is needed).
repositionLineSiblings(getLineSiblings(this.parent.elemContainer));
if (this.parent.$elemContainer.find('label > span') != null && this.parent.$elemContainer.find('label > span').length > 0)
$('#liRequiredFieldInfo').show();
if (validator)
validator.enabled = true;
}
else {
this.parent.$elemContainer.addClass('hidden');
this.parent.$elemContainer.addClass('unavailable');
// Update classes assigned to fields (e.g. since what was "left" may now be hidden and a new "left" is needed).
repositionLineSiblings(getLineSiblings(this.parent.elemContainer));
if (validator)
validator.enabled = false;
}
};
FieldCondition.prototype.doActionHide = function (isMet, validator) {
if (isMet) {
this.parent.$elemContainer.addClass('hidden');
this.parent.$elemContainer.addClass('unavailable');
// Update classes assigned to fields (e.g. since what was "left" may now be hidden and a new "left" is needed).
repositionLineSiblings(getLineSiblings(this.parent.elemContainer));
if (validator)
validator.enabled = false;
}
else {
this.parent.$elemContainer.removeClass('hidden');
this.parent.$elemContainer.removeClass('unavailable');
// Update classes assigned to fields (e.g. since what was "left" may now be hidden and a new "left" is needed).
repositionLineSiblings(getLineSiblings(this.parent.elemContainer));
if (validator)
validator.enabled = true;
}
};
FieldCondition.prototype.doActionRequire = function (isMet, validator) {
if (isMet) {
this.parent.$elemReq.removeClass('hidden');
if (validator == null) {
validator = new FieldValidator(this.parent.elemInput, this.parent.id, this.parent.fieldType, this.parent.isInternal, true, FieldValidation.Any);
this.parent.validators.add(validator);
}
this.parent.$elemContainer.find('label.labelForFieldElement > span').show();
$('#liRequiredFieldInfo').show();
if (validator)
validator.isRequired = true;
}
else {
this.parent.$elemReq.addClass('hidden');
this.parent.$elemContainer.find('label.labelForFieldElement > span').hide();
if (validator)
validator.isRequired = false;
}
};
FieldCondition.prototype.doActionRedirect = function (isMet, validator) {
// TODO: Some point alter this to pass in references for submitRedirect/redirectNewWindow. Not ideal at moment to ref. global vars.
var submitRedirect = document.getElementById('submitRedirect');
redirectNewWindow = null;
submitRedirect.value = '';
if (isMet) {
if (this.actURLNewWindow) {
redirectNewWindow = this.actURL;
submitRedirect.value = '';
}
else
submitRedirect.value = this.actURL;
}
};
// Attachs event handler to field to monitor changes.
// * condRunner - FieldConditionsRunner instance to attach.
// Note: Calling more than once will have no effect.
FieldCondition.prototype.attachRunner = function (condRunner) {
if (condRunner == null)
throw new Error.argNull("condRunner");
// Do not try to bind this if it is an internal field condition and we are not running internal field
// conditions.
if (this.parent.isInternal && !condRunner.runInternal)
return;
if ($.data(this.actElemInput, "runner_chghook") == null) {
var changeHook = function (event) {
condRunner.run(true);
!window.isRemoveSetHeights && typeof SetHeights === "function" && SetHeights();
};
$.data(this.actElemInput, "runner_chghook", changeHook);
$(this.actElemInput).change(changeHook);
}
};
// Removes event handler that monitors changes.
// Note: Calling more than once will have no effect.
FieldCondition.prototype.detachRunner = function () {
var changeHook = $.data(this.actElemInput, "runner_chghook");
if (changeHook) {
$(this.actElemInput).unbind('change', changeHook);
$.removeData(this.actElemInput, "runner_chghook");
}
};
FieldCondition.prototype.checkDateCommon = function (thisValue, compValue) {
var defaultDate = '1/1/70';
var defualtDateObj = new Date(defaultDate);
var compArr = compValue.split(',');
var valueArr = thisValue.split(',');
var hasTimeOfDayStart = false;
var hasTimeOfDayEnd = false;
var compareStartDate;
var compareEndDate;
if (compArr[0] == '') {
compareStartDate = new Date(defaultDate + ' ' + compArr[2]);
}
else {
compareStartDate = new Date(compArr[0] + ' ' + compArr[2]);
}
if (compArr[1] == '') {
compareEndDate = new Date(defaultDate + ' ' + compArr[3]);
}
else {
compareEndDate = new Date(compArr[1] + ' ' + compArr[3]);
}
var validStartDate = new Date(defaultDate);
var validEndDate = new Date(defaultDate);
var timeOfDayStart = '';
var timeOfDayEnd = '';
if (valueArr.length == 4) {
if (valueArr[0] == '') {
validStartDate = new Date(defaultDate + ' ' + valueArr[2]);
}
else {
validStartDate = new Date(valueArr[0] + ' ' + valueArr[2]);
}
timeOfDayStart = this.getAMPMString(valueArr[2]);
if (timeOfDayStart != '')
hasTimeOfDayStart = true;
if (valueArr[1] == '') {
validEndDate = new Date(defaultDate + ' ' + valueArr[3]);
}
else {
validEndDate = new Date(valueArr[1] + ' ' + valueArr[3]);
}
timeOfDayEnd = this.getAMPMString(valueArr[3]);
if (timeOfDayEnd != '')
hasTimeOfDayEnd = true;
}
else if (valueArr.length == 2) {
timeOfDayStart = this.getAMPMString(valueArr[0]);
if (timeOfDayStart == '') {
if (valueArr[0] != '') {
validStartDate = new Date(valueArr[0]);
hasTimeOfDayStart = true;
}
}
else {
validStartDate = new Date(defaultDate + ' ' + valueArr[0]);
hasTimeOfDayStart = true;
}
timeOfDayEnd = this.getAMPMString(valueArr[1]);
if (timeOfDayEnd == '') {
if (valueArr[1] != '') {
validEndDate = new Date(valueArr[1]);
hasTimeOfDayEnd = true;
}
}
else {
validEndDate = new Date(defaultDate + ' ' + valueArr[1]);
hasTimeOfDayEnd = true;
}
}
return {
validStartDate: validStartDate,
compareStartDate: compareStartDate,
compareEndDate: compareEndDate,
hasTimeOfDayStart: hasTimeOfDayStart,
validEndDate: validEndDate,
hasTimeOfDayEnd: hasTimeOfDayEnd
};
};
FieldCondition.prototype.checkDateBetween = function (thisValue, compValue) {
var checkDateCommonData = this.checkDateCommon(thisValue, compValue);
return (checkDateCommonData.validStartDate.getTime() >= checkDateCommonData.compareStartDate.getTime() && checkDateCommonData.validStartDate.getTime() <= checkDateCommonData.compareEndDate.getTime() && checkDateCommonData.hasTimeOfDayStart)
&& (checkDateCommonData.validEndDate.getTime() <= checkDateCommonData.compareEndDate.getTime() && checkDateCommonData.validEndDate.getTime() >= checkDateCommonData.compareStartDate.getTime() && checkDateCommonData.hasTimeOfDayEnd);
};
FieldCondition.prototype.checkDateEqualSpan = function (thisValue, compValue) {
var checkDateCommonData = this.checkDateCommon(thisValue, compValue);
return (checkDateCommonData.validStartDate.getTime() == checkDateCommonData.compareStartDate.getTime() && checkDateCommonData.hasTimeOfDayStart)
&& (checkDateCommonData.validEndDate.getTime() == checkDateCommonData.compareEndDate.getTime() && checkDateCommonData.hasTimeOfDayEnd);
};
FieldCondition.prototype.checkDateEqualTo = function (thisValue, compValue) {
var defaultDate = '1/1/70';
var defualtDateObj = new Date(defaultDate);
var compArr = compValue.split(',');
var valueArr = thisValue.split(',');
var compareDate;
var hasTimeOfDay = false;
if (compArr[0] == '') {
compareDate = new Date(defaultDate + ' ' + compArr[2]);
}
else {
compareDate = new Date(compArr[0] + ' ' + compArr[2]);
}
var validDate = new Date(defaultDate);
var timeOfDay = '';
if (valueArr.length == 1) {
timeOfDay = this.getAMPMString(valueArr[0]);
if (timeOfDay == '') {
if (valueArr[0] != '') {
validDate = new Date(valueArr[0]);
hasTimeOfDay = true;
}
}
else {
hasTimeOfDay = true;
validDate = new Date(valueArr[0]);
}
}
else if (valueArr.length == 2) {
timeOfDay = this.getAMPMString(valueArr[1]);
if (timeOfDay != '')
hasTimeOfDay = true;
if (valueArr[0] != '') {
validDate = new Date((valueArr[0] + ' ' + valueArr[1] + ' ').replace(/\-/g, '/'));
}
else {
validDate = new Date((defaultDate + ' ' + valueArr[0] + ' ').replace(/\-/g, '/'));
}
}
return validDate.getTime() == compareDate.getTime() && hasTimeOfDay;
};
FieldCondition.prototype.getAMPMString = function (time) {
var amIndex = time.indexOf('AM');
var pmIndex = time.indexOf('PM');
var timeOfDay = '';
// First see if the time is military time... if so we need to convert it to AM/PM so the rest
// of this function will return the proper value.
if (amIndex === -1 && pmIndex === -1) {
time = militaryTimeToStandard(time);
amIndex = time.indexOf('AM');
pmIndex = time.indexOf('PM');
}
if (amIndex != -1) {
timeOfDay = time.substring(amIndex).replace(" ", "");
}
else if (pmIndex != -1) {
timeOfDay = time.substring(pmIndex).replace(" ", "");
}
return timeOfDay;
};
function militaryTimeToStandard(militaryTime) {
var colonIndex = militaryTime.indexOf(':');
var hours = '';
var min = '';
if (colonIndex === -1) {
hours = militaryTime.substring(0, 2);
min = militaryTime.substring(2, 4);
} else {
var tokens = militaryTime.split(':');
hours = tokens[0];
min = tokens[1];
}
if (hours < 12) {
ampm = 'AM';
} else {
hours = hours - 12;
ampm = 'PM';
}
return parseInt(hours) + ':' + ('00' + min).slice('-2') + ' ' + ampm; ß
}
////////// FieldConditions Class //////////
// Creates instance of FieldConditions class.
// * elemInput - Reference to DOM element of field with condition. May be a DOM element or string containing ID. May also be array of DOM elements or IDs. Multiple elements must share same parent.
// * id - The ID of the field with the condition.
// * fieldType - The field type of the field with the condition.
// * isInternal - Whether or not this condition is for internal-only fields.
// * condList - List (array) of zero or more condition clauses for the field.
// * validators - Validator dictionary.
function FieldConditions(options, validators) {
if (options.elemInput == null)
throw new Error.argNull("options.elemInput");
else if (options.id == null)
throw new Error.argNull("id");
else if (options.fieldType == null)
throw new Error.argNull("options.fieldType");
else if (options.condList == null)
throw new Error.argNull("options.condList");
else if (validators == null)
throw new Error.argNull("validators");
this.elemInputIsArray = $.isArray(options.elemInput);
// Process elemInput argument.
if (this.elemInputIsArray) {
for (var i = 0, len = options.elemInput.length; i < len; i++) {
if (typeof (options.elemInput[i]) == "string")
options.elemInput[i] = document.getElementById(options.elemInput[i]);
}
if (options.elemInput.length > 0 && options.elemInput[0]) {
this.elemContainer = options.elemInput[0].closest('.formFieldContainer');
this.elemInput = options.elemInput;
}
}
else {
if (typeof (options.elemInput) == "string")
options.elemInput = document.getElementById(options.elemInput);
if (options.elemInput) {
this.elemContainer = options.elemInput.closest('.formFieldContainer');
this.elemInput = options.elemInput;
}
}
this.validators = validators;
this.elemReq = document.getElementById('r_' + options.id);
this.$elemContainer = $(this.elemContainer);
this.$elemReq = $(this.elemReq);
this.fieldType = options.fieldType;
this.id = options.id;
this.isInternal = options.isInternal;
this.conditions = FieldCondition.createMulti(this, options.condList);
}
// Static. Creates a single conditions object from an options object.
FieldConditions.createSingle = function (options, validators) {
if (options == null)
throw new Error.argNull("options");
else if (validators == null)
throw new Error.argNull("validators");
return new FieldConditions(
options,
validators);
};
// Static. Creates dictionary of conditions objects from array of option objects.
FieldConditions.createMulti = function (optionsArray, validators) {
if (optionsArray == null)
throw new Error.argNull("optionsArray");
else if (validators == null)
throw new Error.argNull("validators");
var ret = { keys: [] };
var key = null;
for (var i = 0, len = optionsArray.length; i < len; i++) {
if (optionsArray[i].id != null) {
key = optionsArray[i].id;
ret[key] = FieldConditions.createSingle(optionsArray[i], validators);
ret.keys.push(key);
}
}
return ret;
};
// Attachs event handler to field to monitor changes.
// * condRunner - FieldConditionsRunner instance to attach.
// Note: Calling more than once will have no effect.
FieldConditions.prototype.attachRunner = function (condRunner) {
if (condRunner == null)
throw new Error.argNull("condRunner");
for (var i = 0, len = this.conditions.length; i < len; i++)
this.conditions[i].attachRunner(condRunner);
};
// Removes event handler that monitors changes.
// Note: Calling more than once will have no effect.
FieldConditions.prototype.detachRunner = function () {
for (var i = 0, len = this.conditions.length; i < len; i++)
this.conditions[i].detachRunner();
};
////////// FieldConditionsRunner Class ////
// Creates new instance of conditions runners for the field conditions objects provided.
// * allFieldConditions - Array of FieldConditions objects to execute checks for.
// * doneCallback - Method executed when run() completes. Recieves log information as argument.
// * autoAttach - Determines if allFieldConditions are automatically attached to this instance by the constructor. If null/unspecified, treated as true.
// * runInternal - Set to true to execute internal-only fields.
function FieldConditionsRunner(allFieldConditions, doneCallback, autoAttach, runInternal) {
if (allFieldConditions == null)
throw new Error.argNull("allFieldConditions");
else if (doneCallback == null)
throw new Error.argNull("doneCallback");
this.fieldConditions = allFieldConditions;
this.doneCallback = doneCallback;
this.runInternal = runInternal;
if (autoAttach == null || autoAttach)
this.attachConditions();
}
// Static. Internal. Creates static information object for state tracking during execution.
FieldConditionsRunner.createFieldStateInfo = function () {
var ret = {};
ret[ConditionActions.None] = ConditionRunnerActResult.None;
ret[ConditionActions.Show] = ConditionRunnerActResult.None;
ret[ConditionActions.Hide] = ConditionRunnerActResult.None;
ret[ConditionActions.Require] = ConditionRunnerActResult.None;
ret[ConditionActions.RedirectTo] = ConditionRunnerActResult.None;
return ret;
};
// Attaches to FieldConditions/FieldCondition objects that runner will use.
FieldConditionsRunner.prototype.attachConditions = function () {
for (var i = 0, iLen = this.fieldConditions.keys.length; i < iLen; i++)
this.fieldConditions[this.fieldConditions.keys[i]].attachRunner(this);
};
// Detaches to FieldConditions/FieldCondition objects that runner may have used.
FieldConditionsRunner.prototype.detachConditions = function () {
for (var i = 0, iLen = this.fieldConditions.keys.length; i < iLen; i++)
this.fieldConditions[this.fieldConditions.keys[i]].detachRunner(this);
};
// Internal. Cleans up runner for use again.
FieldConditionsRunner.prototype.cleanup = function () {
if (this.fieldConditionResults != null) {
delete this.fieldConditionResults;
delete this.fieldConditionLog;
}
};
// Internal. Called by run() to log result for each condition.
FieldConditionsRunner.prototype.log = function (id, condIndex, actType, result, isMet, needRestart) {
if (condRunnerHideLogDupes && result == ConditionRunnerActResult.SkipDuplicate)
return;
this.fieldConditionLog.push({
id: id,
condIndex: condIndex,
actType: actType,
result: result,
isMet: isMet,
needRestart: needRestart
});
};
// Internal. Sets whether or not the condition engine is executing.
FieldConditionsRunner.prototype.setRunning = function (value) {
if (arguments.length == 0)
this.isRunning = true;
else
this.isRunning = value;
};
// Gets whether or not the condition engine is executing.
FieldConditionsRunner.prototype.getRunning = function () {
return this.isRunning;
};
// Internal. Tells condition execution task to reset cycle (done whenever something changes).
FieldConditionsRunner.prototype.setRestart = function (value) {
if (arguments == null || arguments.length == 0)
this.needRestart = true;
else
this.needRestart = value;
};
// Internal. Gets whether or not the runner needs to restart.
FieldConditionsRunner.prototype.getRestart = function () {
return this.needRestart;
};
// Launches execution of conditions.
// * fromEvent - Should be set to true when triggerd from DOM events.
// NOTE: fromEvent may be a race condition but will be left for now while debugging (to simplify logs).
FieldConditionsRunner.prototype.run = function (fromEvent) {
if (this.getRunning() && !fromEvent)
this.setRestart();
else {
this.setRunning();
this.cleanup();
this.runTask();
this.doneCallback(this.fieldConditionLog);
this.setRunning(false);
}
};
// Internal. Executes conditions. Should not be called while already running, so run() has sync mechanism for this.
// * runInternal - If true, conditions for internal conditions will be ran.
FieldConditionsRunner.prototype.runTask = function (runInternal) {
var needRestart = true;
// Prepare objects for execution.
this.fieldConditionLog = [];
this.fieldConditionResults = [];
this.setRedirectUrl = false;
// Populate state information.
var condCondList = this.fieldConditions;
var condListInfo = null;
var condList = null;
for (var i = 0, iLen = condCondList.keys.length; i < iLen; i++)
this.fieldConditionResults[condCondList[condCondList.keys[i]].id] = FieldConditionsRunner.createFieldStateInfo();
// Number of restart actions (tracked to eventually kill infinite loops that should not happen).
var numRestarts = 0;
// Start/restart actions.
while (needRestart && (++numRestarts < 65535)) {
needRestart = false;
this.setRestart(needRestart);
for (var i = 0, iLen = condCondList.keys.length; i < iLen && !needRestart; i++) {
condListInfo = condCondList[condCondList.keys[i]];
// If we are on the front-end, we don't want to have anything to do with back-end (internal only)
// conditions, they will cause javascript errors.
if (!this.runInternal && condListInfo.isInternal == true)
continue;
if (condListInfo.isInternal == false && document.URL.indexOf("Admin") > -1 && document.URL.indexOf("Submissions") > -1)
continue;
condList = condListInfo.conditions;
for (var j = 0, jLen = condList.length; j < jLen && !needRestart; j++) {
var cond = condList[j];
var results = this.fieldConditionResults[condListInfo.id];
var logState = ConditionRunnerActResult.None;
// Determine whether or not condition is met.
var isMet = cond.check(false);
// This is because the effective action for a failed explicit Show is an implicit Hide (and vice versa).
var effectiveActType = cond.actType;
// Determine if action is contradictory or duplicate and skip UI changes if so.
switch (effectiveActType) {
case ConditionActions.Show:
// Show can collide with hide.
var resultsHide = results[ConditionActions.Hide];
if (resultsHide == ConditionRunnerActResult.SuccessExplicit || (resultsHide == ConditionRunnerActResult.SuccessImplicit && !isMet))
logState = ConditionRunnerActResult.SkipContradiction;
break;
case ConditionActions.Hide:
// Hide can collide with show.
var resultsShow = results[ConditionActions.Show];
if (resultsShow == ConditionRunnerActResult.SuccessExplicit || (resultsShow == ConditionRunnerActResult.SuccessImplicit && !isMet))
logState = ConditionRunnerActResult.SkipContradiction;
break;
case ConditionActions.RedirectTo:
// Redirects work differently since they span all fields. Extra contradiction detection needed.
if (this.setRedirectUrl)
logState = ConditionRunnerActResult.SkipContradiction;
else if (isMet)
this.setRedirectUrl = true;
break;
}
if (isMet && results[effectiveActType] == ConditionRunnerActResult.SuccessExplicit)
logState = ConditionRunnerActResult.SkipDuplicate;
else if (!isMet && results[effectiveActType] == ConditionRunnerActResult.SuccessExplicit)
logState = ConditionRunnerActResult.SkipContradiction;
else if (!isMet && results[effectiveActType] == ConditionRunnerActResult.SuccessImplicit)
logState = ConditionRunnerActResult.SkipDuplicate;
if (logState == ConditionRunnerActResult.None) {
// Determine log result.
logState = isMet ? ConditionRunnerActResult.SuccessExplicit : ConditionRunnerActResult.SuccessImplicit;
// Update running state info.
results[effectiveActType] = logState;
// Update form UI.
cond.doAction(isMet);
// Restart task.
this.setRestart();
needRestart = true;
}
// Log result.
this.log(condListInfo.id, j, cond.actType, logState, isMet, needRestart);
// Some other action could cause this to get set.
if (this.getRestart())
needRestart = true;
}
}
}
if (numRestarts >= 65535)
console[console.warn ? "warn" : "log"]("Infinite Loop (heuristic-detected) in FieldConditionsRunner.runTask()");
};
;
// This file contains javascript functions for the "External Integration" field type.
// REQUIREMENTS:
// FieldSetDesigner.js
// These values must match the values provided in CivicPlus.Entities.Modules.FormCenter.Enums.ExternalIntegrationCommandType
var ExternalIntegrationCommandType = {
XMLCommand: 1,
EchoCommand: 2
};
// Closure containing the client-side functionality for the External Integration field type.
// * externalIntegrationClass - The name of the CSS class that is used to identify external integration buttons.
function ExternalIntegration(externalIntegrationClassname, fieldSetDesigner) {
this.cssClassname = externalIntegrationClassname;
this.fieldSetDesigner = fieldSetDesigner;
this.hookEvents = function () {
var my = this;
if (my.cssClassname == null)
throw 'No external integration button CSS class name has been specified.'
$('.' + this.cssClassname).click(function (event) {
var fieldID = null;
fieldID = event.target.id;
my.sendRequest(fieldID);
});
};
this.sendRequest = function (fieldID) {
var params = this.getFormData();
var formID = $('#Item_FormID').val();
var intFieldID = fieldID.replace('e_', '');
var my = this;
var sendData = {
id: formID,
fieldID: intFieldID,
parameters: JSON.stringify(params)
};
$.ajax({
type: 'post',
url: '/FormCenter/ExecuteExternalIntegrationCommand',
data: sendData,
success: function (data) { my.updateFormData(data, my); },
error: function (xhr, status, error) { alert('An error occurred while sending the request.'); },
beforeSend: function () {
ajaxPostBackStart('Loading');
},
complete: function () {
ajaxPostBackEnd();
}
});
};
// This function takes the values from the JSON result and sets the appropriate
// form field values.
this.updateFormData = function (responseFromController, externalIntegrationObject) {
if (responseFromController.error) {
alert('An error occurred: ' + responseFromController.errorMessage);
return;
}
for (var i = 0, len = responseFromController.length; i < len; i++) {
var param = responseFromController[i];
switch (responseFromController[i].Type) {
case FieldTypes.ShortAnswer:
externalIntegrationObject.updateShortAnswerField(param);
break;
case FieldTypes.LongAnswer:
externalIntegrationObject.updateLongAnswerField(param);
break;
case FieldTypes.Checkboxes:
externalIntegrationObject.updateCheckboxField(param);
break;
case FieldTypes.Dropdown:
externalIntegrationObject.updateDropdownField(param);
break;
case FieldTypes.Password:
externalIntegrationObject.updatePasswordField(param);
break;
case FieldTypes.RadioButtons:
externalIntegrationObject.updateRadioField(param);
break;
case FieldTypes.DateTime:
externalIntegrationObject.updateDateField(param);
break;
}
}
}
this.getFormData = function () {
var params = [];
this.appendShortAnswerFields(params);
this.appendCheckboxFields(params);
this.appendRadioFields(params);
this.appendDropdowns(params);
this.appendTextAreaFields(params);
this.appendPasswordFields(params);
return params;
};
this.createFieldValue = function (fieldID, type, value, externalName) {
return { ID: fieldID, Type: type, Value: value, ExternalName: externalName};
};
this.appendShortAnswerFields = function (params) {
var my = this;
$('input[id^="e_"][type="text"]').each(function (i) {
var element = $(this);
params.push(my.createFieldValue(element.attr('id'), FieldTypes.ShortAnswer, element.val(), my.externalSubmissionName(element)));
});
};
this.externalSubmissionName = function($element) {
return $element.parents('*[data-external-submission-name]').attr('data-external-submission-name');
};
this.updateShortAnswerField = function (param) {
var id = param.ID;
$('#' + param.ID).val(param.Value);
}
this.appendCheckboxFields = function (params) {
var my = this;
$('input[id^="e_"][type="checkbox"]').each(function (index) {
var item = $(this);
var value = item.attr('value');
var checked = false;
if (item.is(':checked')) {
checked = true;
}
var fieldValue = my.createFieldValue(item.attr('id'), FieldTypes.Checkboxes, value, my.externalSubmissionName(item));
fieldValue.Checked = checked;
params.push(fieldValue);
});
};
this.updateCheckboxField = function (param) {
var id = param.ID;
if (param.Checked == true)
$('#' + param.ID).attr('checked', true);
else
$('#' + param.ID).attr('checked', false);
};
this.appendRadioFields = function (params) {
var my = this;
$('input[id^="e_"][type="radio"]').each(function (index) {
var item = $(this);
var value = item.attr('value');
var checked = false;
if (item.is(':checked')) {
checked = true;
}
var fieldValue = my.createFieldValue(item.attr('id'), FieldTypes.RadioButtons, value, my.externalSubmissionName(item));
fieldValue.Checked = checked;
params.push(fieldValue);
});
};
this.updateRadioField = function (param) {
var id = param.ID;
var value = param.Value;
var button = $('input[id^="' + id + '"][value="' + value + '"]');
button.attr('checked', 'checked');
};
this.appendDropdowns = function (params) {
var my = this;
$('select[id^="e_"]').each(function (index) {
var item = $(this);
params.push(my.createFieldValue(item.attr('id'), FieldTypes.Dropdown, item.val(), my.externalSubmissionName(item)));
});
};
this.updateDropdownField = function (param) {
$('#' + param.ID).val(param.Value);
}
this.appendTextAreaFields = function (params) {
var my = this;
$('textarea[id^="e_"]').each(function (index) {
var element = $(this);
if (element.closest('li.LongAnswer').length > 0) {
params.push(my.createFieldValue(element.attr('id'), FieldTypes.LongAnswer, element.text(), my.externalSubmissionName(element)));
}
});
};
this.updateLongAnswerField = function (param) {
$('#' + param.ID).text(param.Value);
}
this.appendPasswordFields = function (params) {
var my = this;
$('input[id^="e_"][type="password"').each(function (i) {
var element = $(this);
params.push(my.createFieldValue(element.attr('id'), FieldTypes.Password, element.val(), my.externalSubmissionName(element)));
});
}
this.updatePasswordField = function (param) {
// We don't want to update password information with values returned from the remote service.
return;
}
this.updateDateField = function (param) {
var my = this;
var isSpan = (param.Value.indexOf(',') >= 0);
var dateID = param.ID + '_date';
var timeID = param.ID + '_time';
var endDateID = param.ID + '_dateSpan';
var endTimeID = param.ID + '_timeSpan';
var updateDate = function (selector, val) {
var datePicker = $('#' + selector);
if (datePicker.length == 0)
return;
datePicker.data('tDatePicker').value(val);
};
var updateTime = function (selector, val) {
var timePicker = $('#' + selector);
if (timePicker.length == 0)
return;
timePicker.data('tTimePicker').value(val);
};
if (isSpan) {
var dateArray = param.Value.split(',');
var startDate = new Date(dateArray[0]);
var endDate = new Date(dateArray[1]);
updateDate(dateID, startDate);
updateTime(timeID, startDate);
updateDate(endDateID, endDate);
updateTime(endTimeID, endDate);
} else {
var startDate = new Date(param.Value);
updateDate(dateID, startDate);
updateTime(timeID, startDate);
}
}
};
// Calls subroutines used to initialize the ExternalIntegration javascript object.
ExternalIntegration.prototype.initialize = function () {
this.hookEvents();
};
var CP_DynamicForm_ExternalSubmissionFE = function($) {
var self = this;
self.getExternalSubmissionData = function() {
var $fieldContainers = $('.formFieldContainer');
var data = {};
$fieldContainers.each(function (index) {
var $container = $(this);
var externalSubmissionName = self.getExternalSubmissionName($container);
var singleFieldData = self.getSingleFieldData($container);
if (singleFieldData != null) {
data[externalSubmissionName] = self.getSingleFieldData($container);
}
});
return data;
};
self.getExternalSubmissionName = function($container) {
return $container.attr('data-external-submission-name');
};
self.getSingleFieldData = function($container) {
var self = this;
var result = null;
if ($container.hasClass('ShortAnswer')) {
result = self.submissionDataShortAnswer($container);
} else if ($container.hasClass('LongAnswer')) {
result = self.submissionDataLongAnswer($container);
} else if ($container.hasClass('Checkboxes')) {
result = self.submissionDataCheckboxes($container);
} else if ($container.hasClass('Dropdown')) {
result = self.submissionDataDropdown($container);
} else if ($container.hasClass('RadioButtons')) {
result = self.submissionDataRadioButtons($container);
} else if ($container.hasClass('ReplyEmail')) {
result = self.submissionDataReplyEmail($container);
} else if ($container.hasClass('DateTime')) {
result = self.submissionDataDateTime($container);
} else if ($container.hasClass('DateTimeSpan')) {
result = self.submissionDataDateTimeSpan($container);
} else if ($container.hasClass('Password')) {
result = self.submissionDataPassword($container);
}
return result;
};
//
// There needs to be one function for each type of field that will be passed to
// an external submission service.
//
self.submissionDataShortAnswer = function($container) {
return $('input[id^=e_]', $container).val();
};
self.submissionDataLongAnswer = function($container) {
return $('textarea', $container).html();
};
self.submissionDataPassword = function($container) {
return $('input[id^=e_]', $container).val();
};
self.submissionDataCheckboxes = function($container) {
var result = [];
var $checkedItems = $('input[type=checkbox]:checked', $container);
$checkedItems.each(function (index) {
result.push($(this).attr('Value'));
});
return result.join();
};
self.submissionDataDropdown = function($container) {
return $('select option:selected').val();
};
self.submissionDataRadioButtons = function($container) {
return $('input:radio:checked', $container).val();
};
self.submissionDataReplyEmail = function($container) {
return $('input[id^=e_]', $container).val();
};
self.isDateTimeValueEmpty = function(val) {
// The telerik controls sometimes have just "0" if the user does not
// enter a value, so this function checks for both an empty value and for "0"
if (val == null || val == '' || val == '0')
return true;
else
return false;
};
self.submissionDataDateTime = function($container) {
var $dateDiv = $('div.date', $container).not('.time')[0];
var $timeDiv = $('div.time', $container)[0];
var date = $('input', $dateDiv).val();
var time = $('input', $timeDiv).val();
return formatDateTime(date, time);
};
self.formatDateTime = function(date, time) {
var dateEmpty = isDateTimeValueEmpty(date);
var timeEmpty = isDateTimeValueEmpty(time);
if (dateEmpty && timeEmpty)
return '';
else if (!dateEmpty && timeEmpty)
return date;
else if (dateEmpty && !timeEmpty)
return time;
else
return date + ' ' + time;
}
self.submissionDataDateTimeSpan = function($container) {
var $startDateDiv = $('div.date', $container).not('.time')[0];
var $startTimeDiv = $('div.date.time', $container)[0];
var startDate = $('input', $startDateDiv).val();
var startTime = $('input', $startTimeDiv).val();
var $endDateDiv = $('div.date', $container).not('.time')[1];
var $endTimeDiv = $('div.date.time', $container)[1];
var endDate = $('input', $endDateDiv).val();
var endTime = $('input', $endTimeDiv).val();
var startDateTime = formatDateTime(startDate, startTime);
var endDateTime = formatDateTime(endDate, endTime);
if (startDateTime == '' && endDateTime == '')
return '';
return startDateTime + ',' + endDateTime;
};
return self;
}(jQuery);
var CP_DynamicForm_PrintSubmission = (function () {
self.StatusCodes = {
Loading: 1,
Success: 2,
Spam: 3,
Timeout: 4
};
return self;
})();
/*
* ----------------------------- JSTORAGE -------------------------------------
* Simple local storage wrapper to save data on the browser side, supporting
* all major browsers - IE6+, Firefox2+, Safari4+, Chrome4+ and Opera 10.5+
*
* Copyright (c) 2010 - 2012 Andris Reinman, andris.reinman@gmail.com
* Project homepage: www.jstorage.info
*
* Licensed under MIT-style license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
(function () {
var
/* jStorage version */
JSTORAGE_VERSION = "0.4.3",
/* detect a dollar object or create one if not found */
$ = window.jQuery || window.$ || (window.$ = {}),
/* check for a JSON handling support */
JSON = {
parse:
window.JSON && (window.JSON.parse || window.JSON.decode) ||
String.prototype.evalJSON && function (str) { return String(str).evalJSON(); } ||
$.parseJSON ||
$.evalJSON,
stringify:
Object.toJSON ||
window.JSON && (window.JSON.stringify || window.JSON.encode) ||
$.toJSON
};
// Break if no JSON support was found
if (!JSON.parse || !JSON.stringify) {
throw new Error("No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page");
}
var
/* This is the object, that holds the cached values */
_storage = { __jstorage_meta: { CRC32: {} } },
/* Actual browser storage (localStorage or globalStorage['domain']) */
_storage_service = { jStorage: "{}" },
/* DOM element for older IE versions, holds userData behavior */
_storage_elm = null,
/* How much space does the storage take */
_storage_size = 0,
/* which backend is currently used */
_backend = false,
/* onchange observers */
_observers = {},
/* timeout to wait after onchange event */
_observer_timeout = false,
/* last update time */
_observer_update = 0,
/* pubsub observers */
_pubsub_observers = {},
/* skip published items older than current timestamp */
_pubsub_last = +new Date(),
/* Next check for TTL */
_ttl_timeout,
/**
* XML encoding and decoding as XML nodes can't be JSON'ized
* XML nodes are encoded and decoded if the node is the value to be saved
* but not if it's as a property of another object
* Eg. -
* $.jStorage.set("key", xmlNode); // IS OK
* $.jStorage.set("key", {xml: xmlNode}); // NOT OK
*/
_XMLService = {
/**
* Validates a XML node to be XML
* based on jQuery.isXML function
*/
isXML: function (elm) {
var documentElement = (elm ? elm.ownerDocument || elm : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
},
/**
* Encodes a XML node to string
* based on http://www.mercurytide.co.uk/news/article/issues-when-working-ajax/
*/
encode: function (xmlNode) {
if (!this.isXML(xmlNode)) {
return false;
}
try { // Mozilla, Webkit, Opera
return new XMLSerializer().serializeToString(xmlNode);
} catch (E1) {
try { // IE
return xmlNode.xml;
} catch (E2) { }
}
return false;
},
/**
* Decodes a XML node from string
* loosely based on http://outwestmedia.com/jquery-plugins/xmldom/
*/
decode: function (xmlString) {
var dom_parser = ("DOMParser" in window && (new DOMParser()).parseFromString) ||
(window.ActiveXObject && function (_xmlString) {
var xml_doc = new ActiveXObject('Microsoft.XMLDOM');
xml_doc.async = 'false';
xml_doc.loadXML(_xmlString);
return xml_doc;
}),
resultXML;
if (!dom_parser) {
return false;
}
resultXML = dom_parser.call("DOMParser" in window && (new DOMParser()) || window, xmlString, 'text/xml');
return this.isXML(resultXML) ? resultXML : false;
}
};
////////////////////////// PRIVATE METHODS ////////////////////////
/**
* Initialization function. Detects if the browser supports DOM Storage
* or userData behavior and behaves accordingly.
*/
function _init() {
/* Check if browser supports localStorage */
var localStorageReallyWorks = false;
if ("localStorage" in window) {
try {
window.localStorage.setItem('_tmptest', 'tmpval');
localStorageReallyWorks = true;
window.localStorage.removeItem('_tmptest');
} catch (BogusQuotaExceededErrorOnIos5) {
// Thanks be to iOS5 Private Browsing mode which throws
// QUOTA_EXCEEDED_ERRROR DOM Exception 22.
}
}
if (localStorageReallyWorks) {
try {
if (window.localStorage) {
_storage_service = window.localStorage;
_backend = "localStorage";
_observer_update = _storage_service.jStorage_update;
}
} catch (E3) {/* Firefox fails when touching localStorage and cookies are disabled */ }
}
/* Check if browser supports globalStorage */
else if ("globalStorage" in window) {
try {
if (window.globalStorage) {
_storage_service = window.globalStorage[window.location.hostname];
_backend = "globalStorage";
_observer_update = _storage_service.jStorage_update;
}
} catch (E4) {/* Firefox fails when touching localStorage and cookies are disabled */ }
}
/* Check if browser supports userData behavior */
else {
_storage_elm = document.createElement('link');
if (_storage_elm.addBehavior) {
/* Use a DOM element to act as userData storage */
_storage_elm.style.behavior = 'url(#default#userData)';
/* userData element needs to be inserted into the DOM! */
document.getElementsByTagName('head')[0].appendChild(_storage_elm);
try {
_storage_elm.load("jStorage");
} catch (E) {
// try to reset cache
_storage_elm.setAttribute("jStorage", "{}");
_storage_elm.save("jStorage");
_storage_elm.load("jStorage");
}
var data = "{}";
try {
data = _storage_elm.getAttribute("jStorage");
} catch (E5) { }
try {
_observer_update = _storage_elm.getAttribute("jStorage_update");
} catch (E6) { }
_storage_service.jStorage = data;
_backend = "userDataBehavior";
} else {
_storage_elm = null;
return;
}
}
// Load data from storage
_load_storage();
// remove dead keys
_handleTTL();
// start listening for changes
_setupObserver();
// initialize publish-subscribe service
_handlePubSub();
// handle cached navigation
if ("addEventListener" in window) {
window.addEventListener("pageshow", function (event) {
if (event.persisted) {
_storageObserver();
}
}, false);
}
}
/**
* Reload data from storage when needed
*/
function _reloadData() {
var data = "{}";
if (_backend == "userDataBehavior") {
_storage_elm.load("jStorage");
try {
data = _storage_elm.getAttribute("jStorage");
} catch (E5) { }
try {
_observer_update = _storage_elm.getAttribute("jStorage_update");
} catch (E6) { }
_storage_service.jStorage = data;
}
_load_storage();
// remove dead keys
_handleTTL();
_handlePubSub();
}
/**
* Sets up a storage change observer
*/
function _setupObserver() {
if (_backend == "localStorage" || _backend == "globalStorage") {
if ("addEventListener" in window) {
window.addEventListener("storage", _storageObserver, false);
} else {
document.attachEvent("onstorage", _storageObserver);
}
} else if (_backend == "userDataBehavior") {
setInterval(_storageObserver, 1000);
}
}
/**
* Fired on any kind of data change, needs to check if anything has
* really been changed
*/
function _storageObserver() {
var updateTime;
// cumulate change notifications with timeout
clearTimeout(_observer_timeout);
_observer_timeout = setTimeout(function () {
if (_backend == "localStorage" || _backend == "globalStorage") {
updateTime = _storage_service.jStorage_update;
} else if (_backend == "userDataBehavior") {
_storage_elm.load("jStorage");
try {
updateTime = _storage_elm.getAttribute("jStorage_update");
} catch (E5) { }
}
if (updateTime && updateTime != _observer_update) {
_observer_update = updateTime;
_checkUpdatedKeys();
}
}, 25);
}
/**
* Reloads the data and checks if any keys are changed
*/
function _checkUpdatedKeys() {
var oldCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32)),
newCrc32List;
_reloadData();
newCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32));
var key,
updated = [],
removed = [];
for (key in oldCrc32List) {
if (oldCrc32List.hasOwnProperty(key)) {
if (!newCrc32List[key]) {
removed.push(key);
continue;
}
if (oldCrc32List[key] != newCrc32List[key] && String(oldCrc32List[key]).substr(0, 2) == "2.") {
updated.push(key);
}
}
}
for (key in newCrc32List) {
if (newCrc32List.hasOwnProperty(key)) {
if (!oldCrc32List[key]) {
updated.push(key);
}
}
}
_fireObservers(updated, "updated");
_fireObservers(removed, "deleted");
}
/**
* Fires observers for updated keys
*
* @param {Array|String} keys Array of key names or a key
* @param {String} action What happened with the value (updated, deleted, flushed)
*/
function _fireObservers(keys, action) {
keys = [].concat(keys || []);
if (action == "flushed") {
keys = [];
for (var key in _observers) {
if (_observers.hasOwnProperty(key)) {
keys.push(key);
}
}
action = "deleted";
}
for (var i = 0, len = keys.length; i < len; i++) {
if (_observers[keys[i]]) {
for (var j = 0, jlen = _observers[keys[i]].length; j < jlen; j++) {
_observers[keys[i]][j](keys[i], action);
}
}
if (_observers["*"]) {
for (var j = 0, jlen = _observers["*"].length; j < jlen; j++) {
_observers["*"][j](keys[i], action);
}
}
}
}
/**
* Publishes key change to listeners
*/
function _publishChange() {
var updateTime = (+new Date()).toString();
if (_backend == "localStorage" || _backend == "globalStorage") {
_storage_service.jStorage_update = updateTime;
} else if (_backend == "userDataBehavior") {
_storage_elm.setAttribute("jStorage_update", updateTime);
_storage_elm.save("jStorage");
}
_storageObserver();
}
/**
* Loads the data from the storage based on the supported mechanism
*/
function _load_storage() {
/* if jStorage string is retrieved, then decode it */
if (_storage_service.jStorage) {
try {
_storage = JSON.parse(String(_storage_service.jStorage));
} catch (E6) { _storage_service.jStorage = "{}"; }
} else {
_storage_service.jStorage = "{}";
}
_storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
if (!_storage.__jstorage_meta) {
_storage.__jstorage_meta = {};
}
if (!_storage.__jstorage_meta.CRC32) {
_storage.__jstorage_meta.CRC32 = {};
}
}
/**
* This functions provides the "save" mechanism to store the jStorage object
*/
function _save() {
_dropOldEvents(); // remove expired events
try {
_storage_service.jStorage = JSON.stringify(_storage);
// If userData is used as the storage engine, additional
if (_storage_elm) {
_storage_elm.setAttribute("jStorage", _storage_service.jStorage);
_storage_elm.save("jStorage");
}
_storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
} catch (E7) {/* probably cache is full, nothing is saved this way*/ }
}
/**
* Function checks if a key is set and is string or numberic
*
* @param {String} key Key name
*/
function _checkKey(key) {
if (!key || (typeof key != "string" && typeof key != "number")) {
throw new TypeError('Key name must be string or numeric');
}
if (key == "__jstorage_meta") {
throw new TypeError('Reserved key name');
}
return true;
}
/**
* Removes expired keys
*/
function _handleTTL() {
var curtime, i, TTL, CRC32, nextExpire = Infinity, changed = false, deleted = [];
clearTimeout(_ttl_timeout);
if (!_storage.__jstorage_meta || typeof _storage.__jstorage_meta.TTL != "object") {
// nothing to do here
return;
}
curtime = +new Date();
TTL = _storage.__jstorage_meta.TTL;
CRC32 = _storage.__jstorage_meta.CRC32;
for (i in TTL) {
if (TTL.hasOwnProperty(i)) {
if (TTL[i] <= curtime) {
delete TTL[i];
delete CRC32[i];
delete _storage[i];
changed = true;
deleted.push(i);
} else if (TTL[i] < nextExpire) {
nextExpire = TTL[i];
}
}
}
// set next check
if (nextExpire != Infinity) {
_ttl_timeout = setTimeout(_handleTTL, nextExpire - curtime);
}
// save changes
if (changed) {
_save();
_publishChange();
_fireObservers(deleted, "deleted");
}
}
/**
* Checks if there's any events on hold to be fired to listeners
*/
function _handlePubSub() {
var i, len;
if (!_storage.__jstorage_meta.PubSub) {
return;
}
var pubelm,
_pubsubCurrent = _pubsub_last;
for (i = len = _storage.__jstorage_meta.PubSub.length - 1; i >= 0; i--) {
pubelm = _storage.__jstorage_meta.PubSub[i];
if (pubelm[0] > _pubsub_last) {
_pubsubCurrent = pubelm[0];
_fireSubscribers(pubelm[1], pubelm[2]);
}
}
_pubsub_last = _pubsubCurrent;
}
/**
* Fires all subscriber listeners for a pubsub channel
*
* @param {String} channel Channel name
* @param {Mixed} payload Payload data to deliver
*/
function _fireSubscribers(channel, payload) {
if (_pubsub_observers[channel]) {
for (var i = 0, len = _pubsub_observers[channel].length; i < len; i++) {
// send immutable data that can't be modified by listeners
_pubsub_observers[channel][i](channel, JSON.parse(JSON.stringify(payload)));
}
}
}
/**
* Remove old events from the publish stream (at least 2sec old)
*/
function _dropOldEvents() {
if (!_storage.__jstorage_meta.PubSub) {
return;
}
var retire = +new Date() - 2000;
for (var i = 0, len = _storage.__jstorage_meta.PubSub.length; i < len; i++) {
if (_storage.__jstorage_meta.PubSub[i][0] <= retire) {
// deleteCount is needed for IE6
_storage.__jstorage_meta.PubSub.splice(i, _storage.__jstorage_meta.PubSub.length - i);
break;
}
}
if (!_storage.__jstorage_meta.PubSub.length) {
delete _storage.__jstorage_meta.PubSub;
}
}
/**
* Publish payload to a channel
*
* @param {String} channel Channel name
* @param {Mixed} payload Payload to send to the subscribers
*/
function _publish(channel, payload) {
if (!_storage.__jstorage_meta) {
_storage.__jstorage_meta = {};
}
if (!_storage.__jstorage_meta.PubSub) {
_storage.__jstorage_meta.PubSub = [];
}
_storage.__jstorage_meta.PubSub.unshift([+new Date, channel, payload]);
_save();
_publishChange();
}
/**
* JS Implementation of MurmurHash2
*
* SOURCE: https://github.com/garycourt/murmurhash-js (MIT licensed)
*
* @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
* @see http://github.com/garycourt/murmurhash-js
* @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
* @see http://sites.google.com/site/murmurhash/
*
* @param {string} str ASCII only
* @param {number} seed Positive integer only
* @return {number} 32-bit positive integer hash
*/
function murmurhash2_32_gc(str, seed) {
var
l = str.length,
h = seed ^ l,
i = 0,
k;
while (l >= 4) {
k =
((str.charCodeAt(i) & 0xff)) |
((str.charCodeAt(++i) & 0xff) << 8) |
((str.charCodeAt(++i) & 0xff) << 16) |
((str.charCodeAt(++i) & 0xff) << 24);
k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
k ^= k >>> 24;
k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;
l -= 4;
++i;
}
switch (l) {
case 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
case 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
case 1: h ^= (str.charCodeAt(i) & 0xff);
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
}
h ^= h >>> 13;
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
h ^= h >>> 15;
return h >>> 0;
}
////////////////////////// PUBLIC INTERFACE /////////////////////////
$.jStorage = {
/* Version number */
version: JSTORAGE_VERSION,
/**
* Sets a key's value.
*
* @param {String} key Key to set. If this value is not set or not
* a string an exception is raised.
* @param {Mixed} value Value to set. This can be any value that is JSON
* compatible (Numbers, Strings, Objects etc.).
* @param {Object} [options] - possible options to use
* @param {Number} [options.TTL] - optional TTL value
* @return {Mixed} the used value
*/
set: function (key, value, options) {
_checkKey(key);
options = options || {};
// undefined values are deleted automatically
if (typeof value == "undefined") {
this.deleteKey(key);
return value;
}
if (_XMLService.isXML(value)) {
value = { _is_xml: true, xml: _XMLService.encode(value) };
} else if (typeof value == "function") {
return undefined; // functions can't be saved!
} else if (value && typeof value == "object") {
// clone the object before saving to _storage tree
value = JSON.parse(JSON.stringify(value));
}
_storage[key] = value;
_storage.__jstorage_meta.CRC32[key] = "2." + murmurhash2_32_gc(JSON.stringify(value), 0x9747b28c);
this.setTTL(key, options.TTL || 0); // also handles saving and _publishChange
_fireObservers(key, "updated");
return value;
},
/**
* Looks up a key in cache
*
* @param {String} key - Key to look up.
* @param {mixed} def - Default value to return, if key didn't exist.
* @return {Mixed} the key value, default value or null
*/
get: function (key, def) {
_checkKey(key);
if (key in _storage) {
if (_storage[key] && typeof _storage[key] == "object" && _storage[key]._is_xml) {
return _XMLService.decode(_storage[key].xml);
} else {
return _storage[key];
}
}
return typeof (def) == 'undefined' ? null : def;
},
/**
* Deletes a key from cache.
*
* @param {String} key - Key to delete.
* @return {Boolean} true if key existed or false if it didn't
*/
deleteKey: function (key) {
_checkKey(key);
if (key in _storage) {
delete _storage[key];
// remove from TTL list
if (typeof _storage.__jstorage_meta.TTL == "object" &&
key in _storage.__jstorage_meta.TTL) {
delete _storage.__jstorage_meta.TTL[key];
}
delete _storage.__jstorage_meta.CRC32[key];
_save();
_publishChange();
_fireObservers(key, "deleted");
return true;
}
return false;
},
/**
* Sets a TTL for a key, or remove it if ttl value is 0 or below
*
* @param {String} key - key to set the TTL for
* @param {Number} ttl - TTL timeout in milliseconds
* @return {Boolean} true if key existed or false if it didn't
*/
setTTL: function (key, ttl) {
var curtime = +new Date();
_checkKey(key);
ttl = Number(ttl) || 0;
if (key in _storage) {
if (!_storage.__jstorage_meta.TTL) {
_storage.__jstorage_meta.TTL = {};
}
// Set TTL value for the key
if (ttl > 0) {
_storage.__jstorage_meta.TTL[key] = curtime + ttl;
} else {
delete _storage.__jstorage_meta.TTL[key];
}
_save();
_handleTTL();
_publishChange();
return true;
}
return false;
},
/**
* Gets remaining TTL (in milliseconds) for a key or 0 when no TTL has been set
*
* @param {String} key Key to check
* @return {Number} Remaining TTL in milliseconds
*/
getTTL: function (key) {
var curtime = +new Date(), ttl;
_checkKey(key);
if (key in _storage && _storage.__jstorage_meta.TTL && _storage.__jstorage_meta.TTL[key]) {
ttl = _storage.__jstorage_meta.TTL[key] - curtime;
return ttl || 0;
}
return 0;
},
/**
* Deletes everything in cache.
*
* @return {Boolean} Always true
*/
flush: function () {
_storage = { __jstorage_meta: { CRC32: {} } };
_save();
_publishChange();
_fireObservers(null, "flushed");
return true;
},
/**
* Returns a read-only copy of _storage
*
* @return {Object} Read-only copy of _storage
*/
storageObj: function () {
function F() { }
F.prototype = _storage;
return new F();
},
/**
* Returns an index of all used keys as an array
* ['key1', 'key2',..'keyN']
*
* @return {Array} Used keys
*/
index: function () {
var index = [], i;
for (i in _storage) {
if (_storage.hasOwnProperty(i) && i != "__jstorage_meta") {
index.push(i);
}
}
return index;
},
/**
* How much space in bytes does the storage take?
*
* @return {Number} Storage size in chars (not the same as in bytes,
* since some chars may take several bytes)
*/
storageSize: function () {
return _storage_size;
},
/**
* Which backend is currently in use?
*
* @return {String} Backend name
*/
currentBackend: function () {
return _backend;
},
/**
* Test if storage is available
*
* @return {Boolean} True if storage can be used
*/
storageAvailable: function () {
return !!_backend;
},
/**
* Register change listeners
*
* @param {String} key Key name
* @param {Function} callback Function to run when the key changes
*/
listenKeyChange: function (key, callback) {
_checkKey(key);
if (!_observers[key]) {
_observers[key] = [];
}
_observers[key].push(callback);
},
/**
* Remove change listeners
*
* @param {String} key Key name to unregister listeners against
* @param {Function} [callback] If set, unregister the callback, if not - unregister all
*/
stopListening: function (key, callback) {
_checkKey(key);
if (!_observers[key]) {
return;
}
if (!callback) {
delete _observers[key];
return;
}
for (var i = _observers[key].length - 1; i >= 0; i--) {
if (_observers[key][i] == callback) {
_observers[key].splice(i, 1);
}
}
},
/**
* Subscribe to a Publish/Subscribe event stream
*
* @param {String} channel Channel name
* @param {Function} callback Function to run when the something is published to the channel
*/
subscribe: function (channel, callback) {
channel = (channel || "").toString();
if (!channel) {
throw new TypeError('Channel not defined');
}
if (!_pubsub_observers[channel]) {
_pubsub_observers[channel] = [];
}
_pubsub_observers[channel].push(callback);
},
/**
* Publish data to an event stream
*
* @param {String} channel Channel name
* @param {Mixed} payload Payload to deliver
*/
publish: function (channel, payload) {
channel = (channel || "").toString();
if (!channel) {
throw new TypeError('Channel not defined');
}
_publish(channel, payload);
},
/**
* Reloads the data from browser storage
*/
reInit: function () {
_reloadData();
}
};
// Initialize jStorage
_init();
})();
window.pageHandleResponsive = true;
$.when(window.Pages.rwdReady).done(function () {
toggleClassMedia("maxWidth600px", ".cpForm:media(this-max-width: 600px)");
toggleClassMedia("maxWidth515px", "#FormCenterContent:media(this-max-width: 515px)");
toggleClassMedia("maxWidth485px", "#FormCenterContent:media(this-max-width: 485px)");
toggleClassMedia("maxWidth440px", ".cpForm:media(this-max-width: 440px)");
toggleClassMedia("maxWidth395px", "#FormCenterContent:media(this-max-width: 395px)");
toggleClassMedia("maxWidth380px", ".cpForm:media(this-max-width: 380px)");
});
/**
cp.datepicker.js provides an JavaScript Date picker control.
*/
var cp = cp || {};
$(document).ready(function() {
cp.datetimepicker = (function($) {
// These are the publicly-accessible methods
if (!$) { return; }
return {
createTimePicker: createTimePicker,
createDatePicker: createDatePicker,
};
// getOptionsFromHtmlAttributes parses through any attribute in the user-specific HTML date or time picker and
// overwrites the values in "options" with values corresponding to "data-cp-datetimepicker-{optionName}". The
// "optionName" portion of the attribute should correspond to a property of the pickadate or pickatime
// options element.
function getOptionsFromHtmlAttributes($inputElement, originalOptions) {
$($inputElement[0].attributes).each(function() {
if (this.name.match('^data-cp-datetimepicker-')) {
var optionName = this.name.replace('data-cp-datetimepicker-', '');
var originalValue = originalOptions[optionName];
if (!originalValue) {
// We only want to set the option value if it was not already set in the JavaScript options.
// That is, the JavaScript options should always win over the HTML5 options.
var optionVal = this.value;
if (parseInt(optionVal)) {
optionVal = parseInt(optionVal);
}
originalOptions[optionName] = optionVal;
}
}
});
return originalOptions;
}
// createTimePicker creates a new time picker object out of the DOM object specified by timeTextboxSelector.
// The timeTextboxSelector object must be an HTML INPUT element.
function createTimePicker(timeTextboxSelector, options) {
// The actualy Input Time component will be a hidden field. The DOM object in the source HTML
// will be the editable text field for the user.
options = options || {};
var $inputTextBox = $(timeTextboxSelector);
if (!($inputTextBox) || $inputTextBox.length === 0) {
// We got passed a bad selector
console.log('ERR: cp.datetimepicker :: Could not find element: ' + timeTextboxSelector);
return;
}
// Set any options that were specified directly from within the HTML tag.
options = getOptionsFromHtmlAttributes($inputTextBox, options);
//Wrap fieldSetSelector inside div if wrapInsideDiv is true
var fieldSetSelector = '<fieldset class="fieldset__datetimepicker__wrapper">';
if (options.wrapInsideDiv) {
fieldSetSelector = '<div class="t-widget t-timepicker">' + fieldSetSelector + '</div>';
}
$fieldset = $(fieldSetSelector);
$inputTextBox.wrap($fieldset);
var $hiddenTimeInput = $('<input type="text" class="cp_input_datetime" tabindex="-1"/>');
$hiddenTimeInput.attr('data-cp-time-textbox-selector', timeTextboxSelector);
$hiddenTimeInput.attr('aria-hidden', true);
$hiddenTimeInput.insertAfter($inputTextBox);
// We need to force "editable" in the options, otherwise things start to break.
options.editable = true;
$hiddenTimeInput.pickatime(options);
var pickerObject = $hiddenTimeInput.pickatime('picker'); // reference to the pickatime object
$inputTextBox.on({
change: function() {
var inputTime = this.value;
pickerObject.set('customSelect', insertColonIfOverFourChars(inputTime), options);
},
focus: function() {
pickerObject.open(false);
// We have to set the tab-index of the "clear" button, so tabbing through fields works properly.
$('.picker__button--clear').attr('tabindex', -1);
},
blur: function() {
pickerObject.close(true);
}
});
pickerObject.on('set', function(e) {
var inputVal = $inputTextBox.val();
var selectedVal = autoTimeFormat(inputVal);
if (typeof e.clear === "object" || (typeof e.select !== "undefined" && !isNaN(e.select)) || (e.customSelect && !selectedVal.match(/^([1-9]|1[012])(:[0-5]\d) [APap][mM]$/))) {
selectedVal = this.get('value') === '' ? '12:00 AM' : this.get('value');
}
$inputTextBox.val(selectedVal);
$inputTextBox.attr('value', selectedVal);
});
// Priming initialization if there was a value specified for the input
if ($inputTextBox.val() !== '') {
pickerObject.set('select', $inputTextBox.val(), options);
}
$(pickerObject.$root).find('.picker__list').attr('aria-label', 'Time List');
return pickerObject;
}
// createDatePicker creates a new date picker object using the element specified by "dateTextboxSelector".
// The dateTextboxSelector object must be an HTML INPUT element.
function createDatePicker(dateTextboxSelector, options) {
// The actualy Input Date component will be a hidden field. The DOM object in the source HTML
// will be the editable text field for the user.
options = options || {};
var $inputTextBox = $(dateTextboxSelector);
if (!($inputTextBox) || $inputTextBox.length === 0) {
// We got passed a bad selector
console.log('ERR: cp.datetimepicker :: Could not find element: ' + dateTextboxSelector);
return;
}
// Set any options that were specified directly from within the HTML tag.
options = getOptionsFromHtmlAttributes($inputTextBox, options);
var dateAsString = $inputTextBox.val();
if (options.format == 'dd/mm/yyyy' && dateAsString.length > 0) {
var splitDate = autoCompleteDate(dateAsString, options.format).split('/');
$inputTextBox.val(splitDate[1] + '/' + splitDate[0] + '/' + splitDate[2]);
}
if (options.useNativeControls) {
$inputTextBox.prop('type', 'date');
return;
}
var $hiddenDateInput = $('<input type="text" class="cp_input_datetime" tabindex="-1"/>');
$hiddenDateInput.attr('data-cp-date-textbox-selector', dateTextboxSelector);
$hiddenDateInput.attr('aria-hidden', true);
var fieldsetSelector = '<fieldset class="fieldset__datetimepicker__wrapper"></fieldset>';
if (options.wrapInsideDiv)
fieldsetSelector = '<div class="t-widget t-datepicker">' + fieldsetSelector + '</div>';
$fieldset = $(fieldsetSelector);
$fieldset.attr("data-cp-datetimepicker-selector", dateTextboxSelector);
$inputTextBox.wrap($fieldset);
$hiddenDateInput.insertAfter($inputTextBox);
// We have to force the editable option, otherwise things start to break.
options.editable = true;
$hiddenDateInput.pickadate(options);
var pickerObject = $hiddenDateInput.pickadate('picker'); // reference to the pickadate object
$inputTextBox.attr("role", "combobox");
$inputTextBox.attr("aria-haspopup", "dialog");
$inputTextBox.attr("aria-expanded", "false");
$inputTextBox.attr("aria-controls", pickerObject.$root.attr("id"));
// Add handler to make sure datepicker is visible when shown
pickerObject && pickerObject.on('open', function() {
$inputTextBox.attr("aria-expanded", "true");
// Add a slight delay to ensure that the flyout has been added to the dom and the flyoutHeight is nonzero
setTimeout(function() {
// Get the position of the datepicker flyout relative to the top of the document
var flyoutTop = pickerObject.$holder[0].getBoundingClientRect().top;
// Get the height of the datepicker flyout
var flyoutHeight = pickerObject.$holder[0].offsetHeight;
// Get the height of the viewport
var viewportHeight = window.innerHeight;
// Calculate the amount of scrolling needed to make the entire datepicker flyout visible
var scrollAmount = flyoutTop + flyoutHeight - viewportHeight;
// If the datepicker flyout is not fully visible, scroll the viewport down to make it visible
if (scrollAmount > 0) {
window.scrollTo(0, scrollAmount + window.scrollY);
}
}, 50);
});
function focusInput() {
$inputTextBox.off("focus", openPicker);
$inputTextBox.focus();
$inputTextBox.on("focus", openPicker);
}
pickerObject.on('close', function() {
//Trigger the change event on the picker object's element.
window.parent.$(dateTextboxSelector).change();
$inputTextBox.attr("aria-expanded", "false");
focusInput();
});
// setDate is a helper function that should only be called from within this module.
function setDate(dateAsString, placeholder) {
if (dateAsString === '') {
pickerObject.set('clear', null, null);
} else {
if (pickerObject.component.settings.format == 'dd/mm/yyyy') {
var splitDate = autoCompleteDate(dateAsString, pickerObject.component.settings.format).split('/');
var date = splitDate[1] + '/' + splitDate[0] + '/' + splitDate[2];
var epochDate = Date.parse(date);
} else {
var epochDate = Date.parse(autoCompleteDate(dateAsString, pickerObject.component.settings.format));
}
if (!epochDate) {
return;
} else {
var parsedDate = new Date(epochDate);
pickerObject.set('select',
[parsedDate.getFullYear(), parsedDate.getMonth(), parsedDate.getDate()]);
}
}
}
var intervalID;
//Moves the date picker further up the DOM so it isn't overlapped https://civicplus.tpondemand.com/entity/22312
function adjustDTPicker() {
if (intervalID === 0) {
return;
}
var elemPicker = $('.picker--opened')[0];
if (elemPicker) {
$(elemPicker).appendTo('#cpDatePickerWrapper');
elemPicker.style.fontSize = 'inherit';
}
clearInterval(intervalID);
$('.cpDatePickerElevate').each(function() {
var $dateInput = $(this);
if ($dateInput.is(':focus')) {
adjustFlyoutPosition($dateInput, $('#cpDatePickerWrapper'));
}
});
intervalID = 0;
}
if ($('#cpDatePickerWrapper').length > 0) {
$(window).resize(function() {
$('.cpDatePickerElevate').each(function() {
var $dateInput = $(this);
if ($dateInput.is(':focus')) {
adjustFlyoutPosition($dateInput, $('#cpDatePickerWrapper'));
}
});
});
}
function openPicker() {
// We have to set the tab-index of the "today", "close", and "clear" buttons, so tabbing through fields works properly.
$('.picker__button--close').attr('tabindex', -1);
$('.picker__button--today').attr('tabindex', -1);
$('.picker__button--clear').attr('tabindex', -1);
pickerObject.$holder.find('[tabindex="-1"]').attr('tabindex', 0)
pickerObject.open(false);
if ($('#cpDatePickerWrapper').length > 0)
intervalID = setInterval(adjustDTPicker, 50);
}
$inputTextBox.on({
change: function() {
setDate(this.value);
},
focus: openPicker,
click: openPicker,
keydown: function(e) {
if (e.keyCode === 9) {
pickerObject.$holder.find('[tabindex="0"]').attr('tabindex', -1);
}
if (e.keyCode === 40) {
e.preventDefault();
pickerObject.open();
}
},
blur: function(e) {
pickerObject.close(true);
$inputTextBox.attr("aria-expanded", "false");
},
});
pickerObject.on('set', function() {
$inputTextBox.val(this.get('value'));
$inputTextBox.attr('value', this.get('value'));
});
// Priming initialization if there was a value specified for the input
if ($inputTextBox.val() !== '') {
setDate($inputTextBox.val());
}
return pickerObject;
}
function insertColonIfOverFourChars(inputString) {
if (inputString != null && inputString.length > 3 && inputString.indexOf(":") < 0) {
inputString = inputString.slice(0, 2) + ":" + inputString.slice(2, inputString.length);
}
return inputString;
}
function autoCompleteDate(dateAsString, formatString) {
try {
var fdts = null;
var currentDate = new Date();
//guard clauses
if (formatString == null || formatString.length === 0) {
formatString === "mm/dd/yyyy";
}
if ((dateAsString == null || dateAsString.length == 0 || dateAsString.indexOf(".") != -1) && formatString.toLowerCase == "dd/mm/yyyy") {
return ('0' + currentDate.getDate()).slice(-2) + '/' + ('0' + (currentDate.getMonth() + 1)).slice(-2) + '/' + currentDate.getFullYear();
} else if (dateAsString == null || dateAsString.length == 0 || dateAsString.indexOf(".") != -1) {
return ('0' + (currentDate.getMonth() + 1)).slice(-2) + '/' + ('0' + currentDate.getDate()).slice(-2) + '/' + currentDate.getFullYear();
}
fdts = dateAsString.split("/");
if (fdts != null) {
//switch mm/dd/yyyy to be dd/mm/yyyy for logic further down
if (formatString.toLowerCase() !== "dd/mm/yyyy") {
var day = fdts[1];
var month = fdts[0];
fdts[0] = day;
fdts[1] = month;
}
if (fdts[0] == null || fdts[0] === '0' || fdts[0].length < 1 || fdts[0].length > 2) {
fdts[0] = currentDate.getDate();
}
if (fdts[1] == null || fdts[1] === '0' || fdts[1].length < 1 || fdts[1].length > 2) {
fdts[1] = currentDate.getMonth() + 1;
}
if (fdts[2] == null || (fdts[2].length !== 2 && fdts[2].length !== 4)) {
//For last year's date it also adds time at the end of date so extracting year
fdts[2] = !isNaN(fdts[2].substr(0, 4)) ? fdts[2].substr(0, 4) : currentDate.getFullYear();
} else if (fdts[2].length === 2) {
var yr = fdts[2];
var crDate = new Date();
var crCtry = crDate.getFullYear();
var pstCnry = crCtry - 100;
crCtry = crCtry + ' ';
pstCnry = pstCnry + ' ';
crCtry = crCtry.substr(0, 2);
pstCnry = pstCnry.substr(0, 2);
if (yr >= 32)
yr = pstCnry + yr;
else
yr = crCtry + yr;
fdts[2] = yr;
}
}
if (formatString.toLowerCase() === "dd/mm/yyyy") {
dateAsString = ('0' + fdts[0]).slice(-2) + '/' + ('0' + fdts[1]).slice(-2) + '/' + fdts[2];
} else {
dateAsString = ('0' + fdts[1]).slice(-2) + '/' + ('0' + fdts[0]).slice(-2) + '/' + fdts[2];
}
return dateAsString;
} catch (e) {
return "";
}
}
function autoTimeFormat(inputString) {
const regex1 = /^(0?[1-9]|1[0-2]) ?([ap]m)$/i; //eg: 5AM -> 5:00 AM
const regex2 = /^(\d{1,2})(\d{2}) ?([ap]m)$/i; //eg: 500AM -> 5:00 AM
const regex3 = /^(\d{1,2})(?::(\d{2}))?\s*([ap]m)?$/i; //eg: 05:00 am or 5:00 am -> 5:00 AM
if (regex1.test(inputString)) {
return inputString.replace(regex1, (match, hour, period) => {
const hourNum = parseInt(hour);
const formattedHour = hourNum === 12 ? 12 : hourNum % 12; // Convert to 12-hour format
const formattedMinute = "00"; // Add 00 as minutes
const formattedPeriod = period.toUpperCase(); // Convert period to uppercase
return `${formattedHour}:${formattedMinute} ${formattedPeriod}`;
});
}
else if (regex2.test(inputString)) {
return inputString.replace(regex2, (match, hour, minute, period) => {
const hourNum = parseInt(hour);
const formattedHour = hourNum === 12 ? 12 : hourNum % 12; // Convert to 12-hour format
const formattedMinute = minute.padStart(2, "0"); // Pad minute with zero if necessary
const formattedPeriod = period.toUpperCase(); // Convert period to uppercase
return `${formattedHour}:${formattedMinute} ${formattedPeriod}`;
});
}
else if (regex3.test(inputString)) {
return inputString.replace(regex3, (match, hour, minute, period) => {
const hourNum = parseInt(hour);
const formattedHour = hourNum === 12 ? 12 : hourNum % 12; // Convert to 12-hour format
const formattedMinute = minute ? minute : "00"; // Set minute to "00" if not provided
const formattedPeriod = period ? period.toUpperCase() : ""; // Convert period to uppercase if provided
return `${formattedHour}:${formattedMinute} ${formattedPeriod}`;
});
}
else {
return inputString;
}
}
})(window.FeatureToggles.isActive("CMS.JqueryUpgrade.UpgradeTo224") && $('#hdnModuleEligibleForJquery224Upgrade').val() == "true" ? jQuery : typeof jQuery182 === "function" ? jQuery182 : null );
});
;
/*!
* jQuery Form Plugin
* version: 2.69 (06-APR-2011)
* @requires jQuery v1.3.2 or later
*
* Examples and documentation at: http://malsup.com/jquery/form/
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
; (function ($) {
/*
Usage Note:
-----------
Do not use both ajaxSubmit and ajaxForm on the same form. These
functions are intended to be exclusive. Use ajaxSubmit if you want
to bind your own submit handler to the form. For example,
$(document).ready(function() {
$('#myForm').bind('submit', function(e) {
e.preventDefault(); // <-- important
$(this).ajaxSubmit({
target: '#output'
});
});
});
Use ajaxForm when you want the plugin to manage all the event binding
for you. For example,
$(document).ready(function() {
$('#myForm').ajaxForm({
target: '#output'
});
});
When using ajaxForm, the ajaxSubmit function will be invoked for you
at the appropriate time.
*/
/**
* ajaxSubmit() provides a mechanism for immediately submitting
* an HTML form using AJAX.
*/
$.fn.ajaxSubmit = function (options) {
// fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
if (!this.length) {
log('ajaxSubmit: skipping submit process - no element selected');
return this;
}
if (typeof options == 'function') {
options = { success: options };
}
var action = this.attr('action');
var url = (typeof action === 'string') ? $.trim(action) : '';
if (url) {
// clean url (don't include hash vaue)
url = (url.match(/^([^#]+)/) || [])[1];
}
url = url || window.location.href || '';
options = $.extend(true, {
url: url,
success: $.ajaxSettings.success,
type: this[0].getAttribute('method') || 'GET', // IE7 massage (see issue 57)
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
}, options);
// hook for manipulating the form data before it is extracted;
// convenient for use with rich editors like tinyMCE or FCKEditor
var veto = {};
this.trigger('form-pre-serialize', [this, options, veto]);
if (veto.veto) {
log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
return this;
}
// provide opportunity to alter form data before it is serialized
if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
log('ajaxSubmit: submit aborted via beforeSerialize callback');
return this;
}
var n, v, a = this.formToArray(options.semantic);
if (options.data) {
options.extraData = options.data;
for (n in options.data) {
if (options.data[n] instanceof Array) {
for (var k in options.data[n]) {
a.push({ name: n, value: options.data[n][k] });
}
}
else {
v = options.data[n];
v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
a.push({ name: n, value: v });
}
}
}
// give pre-submit callback an opportunity to abort the submit
if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
log('ajaxSubmit: submit aborted via beforeSubmit callback');
return this;
}
// fire vetoable 'validate' event
this.trigger('form-submit-validate', [a, this, options, veto]);
if (veto.veto) {
log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
return this;
}
var q = $.param(a);
if (options.type.toUpperCase() == 'GET') {
options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
options.data = null; // data is null for 'get'
}
else {
options.data = q; // data is the query string for 'post'
}
var $form = this, callbacks = [];
if (options.resetForm) {
callbacks.push(function () { $form.resetForm(); });
}
if (options.clearForm) {
callbacks.push(function () { $form.clearForm(); });
}
// perform a load on the target only if dataType is not provided
if (!options.dataType && options.target) {
var oldSuccess = options.success || function () { };
callbacks.push(function (data) {
var fn = options.replaceTarget ? 'replaceWith' : 'html';
$(options.target)[fn](data).each(oldSuccess, arguments);
});
}
else if (options.success) {
callbacks.push(options.success);
}
options.success = function (data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
var context = options.context || options; // jQuery 1.4+ supports scope context
for (var i = 0, max = callbacks.length; i < max; i++) {
callbacks[i].apply(context, [data, status, xhr || $form, $form]);
}
};
// are there files to upload?
var fileInputs = $('input:file', this).length > 0;
var mp = 'multipart/form-data';
var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
// options.iframe allows user to force iframe mode
// 06-NOV-09: now defaulting to iframe mode if file input is detected
if (options.iframe !== false && (fileInputs || options.iframe || multipart)) {
// hack to fix Safari hang (thanks to Tim Molendijk for this)
// see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
if (options.closeKeepAlive) {
$.get(options.closeKeepAlive, fileUpload);
}
else {
fileUpload();
}
}
else {
$.ajax(options);
}
// fire 'notify' event
this.trigger('form-submit-notify', [this, options]);
return this;
// private function for handling file uploads (hat tip to YAHOO!)
function fileUpload() {
var form = $form[0];
if ($(':input[name=submit],:input[id=submit]', form).length) {
// if there is an input with a name or id of 'submit' then we won't be
// able to invoke the submit fn on the form (at least not x-browser)
alert('Error: Form elements must not have name or id of "submit".');
return;
}
var s = $.extend(true, {}, $.ajaxSettings, options);
s.context = s.context || s;
var id = 'jqFormIO' + (new Date().getTime()), fn = '_' + id;
var $io = $('<iframe id="' + id + '" name="' + id + '" src="' + s.iframeSrc + '" />');
var io = $io[0];
$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
var xhr = { // mock object
aborted: 0,
responseText: null,
responseXML: null,
status: 0,
statusText: 'n/a',
getAllResponseHeaders: function () { },
getResponseHeader: function () { },
setRequestHeader: function () { },
abort: function () {
log('aborting upload...');
var e = 'aborted';
this.aborted = 1;
$io.attr('src', s.iframeSrc); // abort op in progress
xhr.error = e;
s.error && s.error.call(s.context, xhr, 'error', e);
g && $.event.trigger("ajaxError", [xhr, s, e]);
s.complete && s.complete.call(s.context, xhr, 'error');
}
};
var g = s.global;
// trigger ajax global events so that activity/block indicators work like normal
if (g && !$.active++) {
$.event.trigger("ajaxStart");
}
if (g) {
$.event.trigger("ajaxSend", [xhr, s]);
}
if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
if (s.global) {
$.active--;
}
return;
}
if (xhr.aborted) {
return;
}
var timedOut = 0;
// add submitting element to data if we know it
var sub = form.clk;
if (sub) {
var n = sub.name;
if (n && !sub.disabled) {
s.extraData = s.extraData || {};
s.extraData[n] = sub.value;
if (sub.type == "image") {
s.extraData[n + '.x'] = form.clk_x;
s.extraData[n + '.y'] = form.clk_y;
}
}
}
// take a breath so that pending repaints get some cpu time before the upload starts
function doSubmit() {
// make sure form attrs are set
var t = $form.attr('target'), a = $form.attr('action');
// update form attrs in IE friendly way
form.setAttribute('target', id);
if (form.getAttribute('method') != 'POST') {
form.setAttribute('method', 'POST');
}
if (form.getAttribute('action') != s.url) {
form.setAttribute('action', s.url);
}
// ie borks in some cases when setting encoding
if (!s.skipEncodingOverride) {
$form.attr({
encoding: 'multipart/form-data',
enctype: 'multipart/form-data'
});
}
// support timout
if (s.timeout) {
setTimeout(function () { timedOut = true; cb(); }, s.timeout);
}
// add "extra" data to form if provided in options
var extraInputs = [];
try {
if (s.extraData) {
for (var n in s.extraData) {
extraInputs.push(
$('<input type="hidden" name="' + n + '" value="' + s.extraData[n] + '" />')
.appendTo(form)[0]);
}
}
// add iframe to doc and submit the form
$io.appendTo('body');
io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
form.submit();
}
finally {
// reset attrs and remove "extra" input elements
form.setAttribute('action', a);
if (t) {
form.setAttribute('target', t);
} else {
$form.removeAttr('target');
}
$(extraInputs).remove();
}
}
if (s.forceSync) {
doSubmit();
}
else {
setTimeout(doSubmit, 10); // this lets dom updates render
}
var data, doc, domCheckCount = 50;
function cb() {
if (xhr.aborted) {
return;
}
var doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
if (!doc || doc.location.href == s.iframeSrc) {
// response not received yet
if (!timedOut)
return;
}
io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
var ok = true;
try {
if (timedOut) {
throw 'timeout';
}
var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
log('isXml=' + isXml);
if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
if (--domCheckCount) {
// in some browsers (Opera) the iframe DOM is not always traversable when
// the onload callback fires, so we loop a bit to accommodate
log('requeing onLoad callback, DOM not available');
setTimeout(cb, 250);
return;
}
// let this fall through because server response could be an empty document
//log('Could not access iframe DOM after mutiple tries.');
//throw 'DOMException: not available';
}
//log('response detected');
xhr.responseText = doc.body ? doc.body.innerHTML : doc.documentElement ? doc.documentElement.innerHTML : null;
xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
xhr.getResponseHeader = function (header) {
var headers = { 'content-type': s.dataType };
return headers[header];
};
var scr = /(json|script)/.test(s.dataType);
if (scr || s.textarea) {
// see if user embedded response in textarea
var ta = doc.getElementsByTagName('textarea')[0];
if (ta) {
xhr.responseText = ta.value;
}
else if (scr) {
// account for browsers injecting pre around json response
var pre = doc.getElementsByTagName('pre')[0];
var b = doc.getElementsByTagName('body')[0];
if (pre) {
xhr.responseText = pre.textContent;
}
else if (b) {
xhr.responseText = b.innerHTML;
}
}
}
else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
xhr.responseXML = toXml(xhr.responseText);
}
data = httpData(xhr, s.dataType, s);
}
catch (e) {
log('error caught:', e);
ok = false;
xhr.error = e;
s.error && s.error.call(s.context, xhr, 'error', e);
g && $.event.trigger("ajaxError", [xhr, s, e]);
}
if (xhr.aborted) {
log('upload aborted');
ok = false;
}
// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
if (ok) {
s.success && s.success.call(s.context, data, 'success', xhr);
g && $.event.trigger("ajaxSuccess", [xhr, s]);
}
g && $.event.trigger("ajaxComplete", [xhr, s]);
if (g && ! --$.active) {
$.event.trigger("ajaxStop");
}
s.complete && s.complete.call(s.context, xhr, ok ? 'success' : 'error');
// clean up
setTimeout(function () {
$io.removeData('form-plugin-onload');
$io.remove();
xhr.responseXML = null;
}, 100);
}
var toXml = $.parseXML || function (s, doc) { // use parseXML if available (jQuery 1.5+)
if (window.ActiveXObject) {
doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = 'false';
doc.loadXML(s);
}
else {
doc = (new DOMParser()).parseFromString(s, 'text/xml');
}
return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
};
var parseJSON = $.parseJSON || function (s) {
return window['eval']('(' + s + ')');
};
var httpData = function (xhr, type, s) { // mostly lifted from jq1.4.4
var ct = xhr.getResponseHeader('content-type') || '',
xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
data = xml ? xhr.responseXML : xhr.responseText;
if (xml && data.documentElement.nodeName === 'parsererror') {
$.error && $.error('parsererror');
}
if (s && s.dataFilter) {
data = s.dataFilter(data, type);
}
if (typeof data === 'string') {
if (type === 'json' || !type && ct.indexOf('json') >= 0) {
data = parseJSON(data);
} else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
$.globalEval(data);
}
}
return data;
};
}
};
/**
* ajaxForm() provides a mechanism for fully automating form submission.
*
* The advantages of using this method instead of ajaxSubmit() are:
*
* 1: This method will include coordinates for <input type="image" /> elements (if the element
* is used to submit the form).
* 2. This method will include the submit element's name/value data (for the element that was
* used to submit the form).
* 3. This method binds the submit() method to the form for you.
*
* The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
* passes the options argument along after properly binding events for submit elements and
* the form itself.
*/
$.fn.ajaxForm = function (options) {
// in jQuery 1.3+ we can fix mistakes with the ready state
if (this.length === 0) {
var o = { s: this.selector, c: this.context };
if (!$.isReady && o.s) {
log('DOM not ready, queuing ajaxForm');
$(function () {
$(o.s, o.c).ajaxForm(options);
});
return this;
}
// is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
return this;
}
return this.ajaxFormUnbind().bind('submit.form-plugin', function (e) {
if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
e.preventDefault();
$(this).ajaxSubmit(options);
}
}).bind('click.form-plugin', function (e) {
var target = e.target;
var $el = $(target);
if (!($el.is(":submit,input:image"))) {
// is this a child element of the submit el? (ex: a span within a button)
var t = $el.closest(':submit');
if (t.length == 0) {
return;
}
target = t[0];
}
var form = this;
form.clk = target;
if (target.type == 'image') {
if (e.offsetX != undefined) {
form.clk_x = e.offsetX;
form.clk_y = e.offsetY;
} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
var offset = $el.offset();
form.clk_x = e.pageX - offset.left;
form.clk_y = e.pageY - offset.top;
} else {
form.clk_x = e.pageX - target.offsetLeft;
form.clk_y = e.pageY - target.offsetTop;
}
}
// clear form vars
setTimeout(function () { form.clk = form.clk_x = form.clk_y = null; }, 100);
});
};
// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function () {
return this.unbind('submit.form-plugin click.form-plugin');
};
/**
* formToArray() gathers form element data into an array of objects that can
* be passed to any of the following ajax functions: $.get, $.post, or load.
* Each object in the array has both a 'name' and 'value' property. An example of
* an array for a simple login form might be:
*
* [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
*
* It is this array that is passed to pre-submit callback functions provided to the
* ajaxSubmit() and ajaxForm() methods.
*/
$.fn.formToArray = function (semantic) {
var a = [];
if (this.length === 0) {
return a;
}
var form = this[0];
var els = semantic ? form.getElementsByTagName('*') : form.elements;
if (!els) {
return a;
}
var i, j, n, v, el, max, jmax;
for (i = 0, max = els.length; i < max; i++) {
el = els[i];
n = el.name;
if (!n) {
continue;
}
if (semantic && form.clk && el.type == "image") {
// handle image inputs on the fly when semantic == true
if (!el.disabled && form.clk == el) {
a.push({ name: n, value: $(el).val() });
a.push({ name: n + '.x', value: form.clk_x }, { name: n + '.y', value: form.clk_y });
}
continue;
}
v = $.fieldValue(el, true);
if (v && v.constructor == Array) {
for (j = 0, jmax = v.length; j < jmax; j++) {
a.push({ name: n, value: v[j] });
}
}
else if (v !== null && typeof v != 'undefined') {
a.push({ name: n, value: v });
}
}
if (!semantic && form.clk) {
// input type=='image' are not found in elements array! handle it here
var $input = $(form.clk), input = $input[0];
n = input.name;
if (n && !input.disabled && input.type == 'image') {
a.push({ name: n, value: $input.val() });
a.push({ name: n + '.x', value: form.clk_x }, { name: n + '.y', value: form.clk_y });
}
}
return a;
};
/**
* Serializes form data into a 'submittable' string. This method will return a string
* in the format: name1=value1&amp;name2=value2
*/
$.fn.formSerialize = function (semantic) {
//hand off to jQuery.param for proper encoding
return $.param(this.formToArray(semantic));
};
/**
* Serializes all field elements in the jQuery object into a query string.
* This method will return a string in the format: name1=value1&amp;name2=value2
*/
$.fn.fieldSerialize = function (successful) {
var a = [];
this.each(function () {
var n = this.name;
if (!n) {
return;
}
var v = $.fieldValue(this, successful);
if (v && v.constructor == Array) {
for (var i = 0, max = v.length; i < max; i++) {
a.push({ name: n, value: v[i] });
}
}
else if (v !== null && typeof v != 'undefined') {
a.push({ name: this.name, value: v });
}
});
//hand off to jQuery.param for proper encoding
return $.param(a);
};
/**
* Returns the value(s) of the element in the matched set. For example, consider the following form:
*
* <form><fieldset>
* <input name="A" type="text" />
* <input name="A" type="text" />
* <input name="B" type="checkbox" value="B1" />
* <input name="B" type="checkbox" value="B2"/>
* <input name="C" type="radio" value="C1" />
* <input name="C" type="radio" value="C2" />
* </fieldset></form>
*
* var v = $(':text').fieldValue();
* // if no values are entered into the text inputs
* v == ['','']
* // if values entered into the text inputs are 'foo' and 'bar'
* v == ['foo','bar']
*
* var v = $(':checkbox').fieldValue();
* // if neither checkbox is checked
* v === undefined
* // if both checkboxes are checked
* v == ['B1', 'B2']
*
* var v = $(':radio').fieldValue();
* // if neither radio is checked
* v === undefined
* // if first radio is checked
* v == ['C1']
*
* The successful argument controls whether or not the field element must be 'successful'
* (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
* The default value of the successful argument is true. If this value is false the value(s)
* for each element is returned.
*
* Note: This method *always* returns an array. If no valid value can be determined the
* array will be empty, otherwise it will contain one or more values.
*/
$.fn.fieldValue = function (successful) {
for (var val = [], i = 0, max = this.length; i < max; i++) {
var el = this[i];
var v = $.fieldValue(el, successful);
if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
continue;
}
v.constructor == Array ? $.merge(val, v) : val.push(v);
}
return val;
};
/**
* Returns the value of the field element.
*/
$.fieldValue = function (el, successful) {
var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
if (successful === undefined) {
successful = true;
}
if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
(t == 'checkbox' || t == 'radio') && !el.checked ||
(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
tag == 'select' && el.selectedIndex == -1)) {
return null;
}
if (tag == 'select') {
var index = el.selectedIndex;
if (index < 0) {
return null;
}
var a = [], ops = el.options;
var one = (t == 'select-one');
var max = (one ? index + 1 : ops.length);
for (var i = (one ? index : 0); i < max; i++) {
var op = ops[i];
if (op.selected) {
var v = op.value;
if (!v) { // extra pain for IE...
v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
}
if (one) {
return v;
}
a.push(v);
}
}
return a;
}
return $(el).val();
};
/**
* Clears the form data. Takes the following actions on the form's input fields:
* - input text fields will have their 'value' property set to the empty string
* - select elements will have their 'selectedIndex' property set to -1
* - checkbox and radio inputs will have their 'checked' property set to false
* - inputs of type submit, button, reset, and hidden will *not* be effected
* - button elements will *not* be effected
*/
$.fn.clearForm = function () {
return this.each(function () {
$('input,select,textarea', this).clearFields();
});
};
/**
* Clears the selected form elements.
*/
$.fn.clearFields = $.fn.clearInputs = function () {
return this.each(function () {
var t = this.type, tag = this.tagName.toLowerCase();
if (t == 'text' || t == 'password' || tag == 'textarea') {
this.value = '';
}
else if (t == 'checkbox' || t == 'radio') {
this.checked = false;
}
else if (tag == 'select') {
this.selectedIndex = -1;
}
});
};
/**
* Resets the form data. Causes all form elements to be reset to their original value.
*/
$.fn.resetForm = function () {
return this.each(function () {
// guard against an input with the name of 'reset'
// note that IE reports the reset function as an 'object'
if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
this.reset();
}
});
};
/**
* Enables or disables any matching elements.
*/
$.fn.enable = function (b) {
if (b === undefined) {
b = true;
}
return this.each(function () {
this.disabled = !b;
});
};
/**
* Checks/unchecks any matching checkboxes or radio buttons and
* selects/deselects and matching option elements.
*/
$.fn.selected = function (select) {
if (select === undefined) {
select = true;
}
return this.each(function () {
var t = this.type;
if (t == 'checkbox' || t == 'radio') {
this.checked = select;
}
else if (this.tagName.toLowerCase() == 'option') {
var $sel = $(this).parent('select');
if (select && $sel[0] && $sel[0].type == 'select-one') {
// deselect all other options
$sel.find('option').selected(false);
}
this.selected = select;
}
});
};
// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
if ($.fn.ajaxSubmit.debug) {
var msg = '[jquery.form] ' + Array.prototype.join.call(arguments, '');
if (window.console && window.console.log) {
window.console.log(msg);
}
else if (window.opera && window.opera.postError) {
window.opera.postError(msg);
}
}
};
})(jQuery);
;