/*
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('")[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('
');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').appendTo("body"),i=t[0].offsetWidth,t.css("overflow","scroll"),r=n('').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;ur.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.monthc.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.pickr.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=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&&nh.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),ay?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.pickh.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=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.pickr.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.pickt.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;r0?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 = 'Add Files'
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 = '';
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)
})
});
}
;
///
///
///
///
///
///
///
///
///
//////// 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('►');
if (supportSlide)
$elem.slideUp(150);
else
$elem.hide();
}
else {
$elemArrow.html('▼');
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');
});
;
///
///
///
///
///
///
// 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 , 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;
};
///
///
///
///
///
// 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 Gary Court
* @see http://github.com/garycourt/murmurhash-js
* @author Austin Appleby
* @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 = '