scripts.js 135 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816
  1. /*!
  2. * iCheck v1.0.2, http://git.io/arlzeA
  3. * ===================================
  4. * Powerful jQuery and Zepto plugin for checkboxes and radio buttons customization
  5. *
  6. * (c) 2013 Damir Sultanov, http://fronteed.com
  7. * MIT Licensed
  8. */
  9. (function($) {
  10. // Cached vars
  11. var _iCheck = 'iCheck',
  12. _iCheckHelper = _iCheck + '-helper',
  13. _checkbox = 'checkbox',
  14. _radio = 'radio',
  15. _checked = 'checked',
  16. _unchecked = 'un' + _checked,
  17. _disabled = 'disabled',
  18. _determinate = 'determinate',
  19. _indeterminate = 'in' + _determinate,
  20. _update = 'update',
  21. _type = 'type',
  22. _click = 'click',
  23. _touch = 'touchbegin.i touchend.i',
  24. _add = 'addClass',
  25. _remove = 'removeClass',
  26. _callback = 'trigger',
  27. _label = 'label',
  28. _cursor = 'cursor',
  29. _mobile = /ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent);
  30. // Plugin init
  31. $.fn[_iCheck] = function(options, fire) {
  32. // Walker
  33. var handle = 'input[type="' + _checkbox + '"], input[type="' + _radio + '"]',
  34. stack = $(),
  35. walker = function(object) {
  36. object.each(function() {
  37. var self = $(this);
  38. if (self.is(handle)) {
  39. stack = stack.add(self);
  40. } else {
  41. stack = stack.add(self.find(handle));
  42. }
  43. });
  44. };
  45. // Check if we should operate with some method
  46. if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(options)) {
  47. // Normalize method's name
  48. options = options.toLowerCase();
  49. // Find checkboxes and radio buttons
  50. walker(this);
  51. return stack.each(function() {
  52. var self = $(this);
  53. if (options == 'destroy') {
  54. tidy(self, 'ifDestroyed');
  55. } else {
  56. operate(self, true, options);
  57. }
  58. // Fire method's callback
  59. if ($.isFunction(fire)) {
  60. fire();
  61. }
  62. });
  63. // Customization
  64. } else if (typeof options == 'object' || !options) {
  65. // Check if any options were passed
  66. var settings = $.extend({
  67. checkedClass: _checked,
  68. disabledClass: _disabled,
  69. indeterminateClass: _indeterminate,
  70. labelHover: true
  71. }, options),
  72. selector = settings.handle,
  73. hoverClass = settings.hoverClass || 'hover',
  74. focusClass = settings.focusClass || 'focus',
  75. activeClass = settings.activeClass || 'active',
  76. labelHover = !!settings.labelHover,
  77. labelHoverClass = settings.labelHoverClass || 'hover',
  78. // Setup clickable area
  79. area = ('' + settings.increaseArea).replace('%', '') | 0;
  80. // Selector limit
  81. if (selector == _checkbox || selector == _radio) {
  82. handle = 'input[type="' + selector + '"]';
  83. }
  84. // Clickable area limit
  85. if (area < -50) {
  86. area = -50;
  87. }
  88. // Walk around the selector
  89. walker(this);
  90. return stack.each(function() {
  91. var self = $(this);
  92. // If already customized
  93. tidy(self);
  94. var node = this,
  95. id = node.id,
  96. // Layer styles
  97. offset = -area + '%',
  98. size = 100 + (area * 2) + '%',
  99. layer = {
  100. position: 'absolute',
  101. top: offset,
  102. left: offset,
  103. display: 'block',
  104. width: size,
  105. height: size,
  106. margin: 0,
  107. padding: 0,
  108. background: '#fff',
  109. border: 0,
  110. opacity: 0
  111. },
  112. // Choose how to hide input
  113. hide = _mobile ? {
  114. position: 'absolute',
  115. visibility: 'hidden'
  116. } : area ? layer : {
  117. position: 'absolute',
  118. opacity: 0
  119. },
  120. // Get proper class
  121. className = node[_type] == _checkbox ? settings.checkboxClass || 'i' + _checkbox : settings.radioClass || 'i' + _radio,
  122. // Find assigned labels
  123. label = $(_label + '[for="' + id + '"]').add(self.closest(_label)),
  124. // Check ARIA option
  125. aria = !!settings.aria,
  126. // Set ARIA placeholder
  127. ariaID = _iCheck + '-' + Math.random().toString(36).substr(2,6),
  128. // Parent & helper
  129. parent = '<div class="' + className + '" ' + (aria ? 'role="' + node[_type] + '" ' : ''),
  130. helper;
  131. // Set ARIA "labelledby"
  132. if (aria) {
  133. label.each(function() {
  134. parent += 'aria-labelledby="';
  135. if (this.id) {
  136. parent += this.id;
  137. } else {
  138. this.id = ariaID;
  139. parent += ariaID;
  140. }
  141. parent += '"';
  142. });
  143. }
  144. // Wrap input
  145. parent = self.wrap(parent + '/>')[_callback]('ifCreated').parent().append(settings.insert);
  146. // Layer addition
  147. helper = $('<ins class="' + _iCheckHelper + '"/>').css(layer).appendTo(parent);
  148. // Finalize customization
  149. self.data(_iCheck, {o: settings, s: self.attr('style')}).css(hide);
  150. !!settings.inheritClass && parent[_add](node.className || '');
  151. !!settings.inheritID && id && parent.attr('id', _iCheck + '-' + id);
  152. parent.css('position') == 'static' && parent.css('position', 'relative');
  153. operate(self, true, _update);
  154. // Label events
  155. if (label.length) {
  156. label.on(_click + '.i mouseover.i mouseout.i ' + _touch, function(event) {
  157. var type = event[_type],
  158. item = $(this);
  159. // Do nothing if input is disabled
  160. if (!node[_disabled]) {
  161. // Click
  162. if (type == _click) {
  163. if ($(event.target).is('a')) {
  164. return;
  165. }
  166. operate(self, false, true);
  167. // Hover state
  168. } else if (labelHover) {
  169. // mouseout|touchend
  170. if (/ut|nd/.test(type)) {
  171. parent[_remove](hoverClass);
  172. item[_remove](labelHoverClass);
  173. } else {
  174. parent[_add](hoverClass);
  175. item[_add](labelHoverClass);
  176. }
  177. }
  178. if (_mobile) {
  179. event.stopPropagation();
  180. } else {
  181. return false;
  182. }
  183. }
  184. });
  185. }
  186. // Input events
  187. self.on(_click + '.i focus.i blur.i keyup.i keydown.i keypress.i', function(event) {
  188. var type = event[_type],
  189. key = event.keyCode;
  190. // Click
  191. if (type == _click) {
  192. return false;
  193. // Keydown
  194. } else if (type == 'keydown' && key == 32) {
  195. if (!(node[_type] == _radio && node[_checked])) {
  196. if (node[_checked]) {
  197. off(self, _checked);
  198. } else {
  199. on(self, _checked);
  200. }
  201. }
  202. return false;
  203. // Keyup
  204. } else if (type == 'keyup' && node[_type] == _radio) {
  205. !node[_checked] && on(self, _checked);
  206. // Focus/blur
  207. } else if (/us|ur/.test(type)) {
  208. parent[type == 'blur' ? _remove : _add](focusClass);
  209. }
  210. });
  211. // Helper events
  212. helper.on(_click + ' mousedown mouseup mouseover mouseout ' + _touch, function(event) {
  213. var type = event[_type],
  214. // mousedown|mouseup
  215. toggle = /wn|up/.test(type) ? activeClass : hoverClass;
  216. // Do nothing if input is disabled
  217. if (!node[_disabled]) {
  218. // Click
  219. if (type == _click) {
  220. operate(self, false, true);
  221. // Active and hover states
  222. } else {
  223. // State is on
  224. if (/wn|er|in/.test(type)) {
  225. // mousedown|mouseover|touchbegin
  226. parent[_add](toggle);
  227. // State is off
  228. } else {
  229. parent[_remove](toggle + ' ' + activeClass);
  230. }
  231. // Label hover
  232. if (label.length && labelHover && toggle == hoverClass) {
  233. // mouseout|touchend
  234. label[/ut|nd/.test(type) ? _remove : _add](labelHoverClass);
  235. }
  236. }
  237. if (_mobile) {
  238. event.stopPropagation();
  239. } else {
  240. return false;
  241. }
  242. }
  243. });
  244. });
  245. } else {
  246. return this;
  247. }
  248. };
  249. // Do something with inputs
  250. function operate(input, direct, method) {
  251. var node = input[0],
  252. state = /er/.test(method) ? _indeterminate : /bl/.test(method) ? _disabled : _checked,
  253. active = method == _update ? {
  254. checked: node[_checked],
  255. disabled: node[_disabled],
  256. indeterminate: input.attr(_indeterminate) == 'true' || input.attr(_determinate) == 'false'
  257. } : node[state];
  258. // Check, disable or indeterminate
  259. if (/^(ch|di|in)/.test(method) && !active) {
  260. on(input, state);
  261. // Uncheck, enable or determinate
  262. } else if (/^(un|en|de)/.test(method) && active) {
  263. off(input, state);
  264. // Update
  265. } else if (method == _update) {
  266. // Handle states
  267. for (var each in active) {
  268. if (active[each]) {
  269. on(input, each, true);
  270. } else {
  271. off(input, each, true);
  272. }
  273. }
  274. } else if (!direct || method == 'toggle') {
  275. // Helper or label was clicked
  276. if (!direct) {
  277. input[_callback]('ifClicked');
  278. }
  279. // Toggle checked state
  280. if (active) {
  281. if (node[_type] !== _radio) {
  282. off(input, state);
  283. }
  284. } else {
  285. on(input, state);
  286. }
  287. }
  288. }
  289. // Add checked, disabled or indeterminate state
  290. function on(input, state, keep) {
  291. var node = input[0],
  292. parent = input.parent(),
  293. checked = state == _checked,
  294. indeterminate = state == _indeterminate,
  295. disabled = state == _disabled,
  296. callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
  297. regular = option(input, callback + capitalize(node[_type])),
  298. specific = option(input, state + capitalize(node[_type]));
  299. // Prevent unnecessary actions
  300. if (node[state] !== true) {
  301. // Toggle assigned radio buttons
  302. if (!keep && state == _checked && node[_type] == _radio && node.name) {
  303. var form = input.closest('form'),
  304. inputs = 'input[name="' + node.name + '"]';
  305. inputs = form.length ? form.find(inputs) : $(inputs);
  306. inputs.each(function() {
  307. if (this !== node && $(this).data(_iCheck)) {
  308. off($(this), state);
  309. }
  310. });
  311. }
  312. // Indeterminate state
  313. if (indeterminate) {
  314. // Add indeterminate state
  315. node[state] = true;
  316. // Remove checked state
  317. if (node[_checked]) {
  318. off(input, _checked, 'force');
  319. }
  320. // Checked or disabled state
  321. } else {
  322. // Add checked or disabled state
  323. if (!keep) {
  324. node[state] = true;
  325. }
  326. // Remove indeterminate state
  327. if (checked && node[_indeterminate]) {
  328. off(input, _indeterminate, false);
  329. }
  330. }
  331. // Trigger callbacks
  332. callbacks(input, checked, state, keep);
  333. }
  334. // Add proper cursor
  335. if (node[_disabled] && !!option(input, _cursor, true)) {
  336. parent.find('.' + _iCheckHelper).css(_cursor, 'default');
  337. }
  338. // Add state class
  339. parent[_add](specific || option(input, state) || '');
  340. // Set ARIA attribute
  341. if (!!parent.attr('role') && !indeterminate) {
  342. parent.attr('aria-' + (disabled ? _disabled : _checked), 'true');
  343. }
  344. // Remove regular state class
  345. parent[_remove](regular || option(input, callback) || '');
  346. }
  347. // Remove checked, disabled or indeterminate state
  348. function off(input, state, keep) {
  349. var node = input[0],
  350. parent = input.parent(),
  351. checked = state == _checked,
  352. indeterminate = state == _indeterminate,
  353. disabled = state == _disabled,
  354. callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
  355. regular = option(input, callback + capitalize(node[_type])),
  356. specific = option(input, state + capitalize(node[_type]));
  357. // Prevent unnecessary actions
  358. if (node[state] !== false) {
  359. // Toggle state
  360. if (indeterminate || !keep || keep == 'force') {
  361. node[state] = false;
  362. }
  363. // Trigger callbacks
  364. callbacks(input, checked, callback, keep);
  365. }
  366. // Add proper cursor
  367. if (!node[_disabled] && !!option(input, _cursor, true)) {
  368. parent.find('.' + _iCheckHelper).css(_cursor, 'pointer');
  369. }
  370. // Remove state class
  371. parent[_remove](specific || option(input, state) || '');
  372. // Set ARIA attribute
  373. if (!!parent.attr('role') && !indeterminate) {
  374. parent.attr('aria-' + (disabled ? _disabled : _checked), 'false');
  375. }
  376. // Add regular state class
  377. parent[_add](regular || option(input, callback) || '');
  378. }
  379. // Remove all traces
  380. function tidy(input, callback) {
  381. if (input.data(_iCheck)) {
  382. // Remove everything except input
  383. input.parent().html(input.attr('style', input.data(_iCheck).s || ''));
  384. // Callback
  385. if (callback) {
  386. input[_callback](callback);
  387. }
  388. // Unbind events
  389. input.off('.i').unwrap();
  390. $(_label + '[for="' + input[0].id + '"]').add(input.closest(_label)).off('.i');
  391. }
  392. }
  393. // Get some option
  394. function option(input, state, regular) {
  395. if (input.data(_iCheck)) {
  396. return input.data(_iCheck).o[state + (regular ? '' : 'Class')];
  397. }
  398. }
  399. // Capitalize some string
  400. function capitalize(string) {
  401. return string.charAt(0).toUpperCase() + string.slice(1);
  402. }
  403. // Executable handlers
  404. function callbacks(input, checked, callback, keep) {
  405. if (!keep) {
  406. if (checked) {
  407. input[_callback]('ifToggled');
  408. }
  409. input[_callback]('ifChanged')[_callback]('if' + capitalize(callback));
  410. }
  411. }
  412. })(window.jQuery || window.Zepto);
  413. /**
  414. * WHMCS core JS library reference
  415. *
  416. * @copyright Copyright (c) WHMCS Limited 2005-2017
  417. * @license http://www.whmcs.com/license/ WHMCS Eula
  418. */
  419. (function (window, factory) {
  420. if (typeof window.WHMCS !== 'object') {
  421. window.WHMCS = factory;
  422. }
  423. }(
  424. window,
  425. {
  426. hasModule: function (name) {
  427. return (typeof WHMCS[name] !== 'undefined'
  428. && Object.getOwnPropertyNames(WHMCS[name]).length > 0);
  429. },
  430. loadModule: function (name, module) {
  431. if (this.hasModule(name)) {
  432. return;
  433. }
  434. WHMCS[name] = {};
  435. if (typeof module === 'function') {
  436. (module).apply(WHMCS[name]);
  437. } else {
  438. for (var key in module) {
  439. if (module.hasOwnProperty(key)) {
  440. WHMCS[name][key] = {};
  441. (module[key]).apply(WHMCS[name][key]);
  442. }
  443. }
  444. }
  445. }
  446. }
  447. ));
  448. jQuery(document).ready(function() {
  449. jQuery(document).on('click', '.disable-on-click', function () {
  450. jQuery(this).addClass('disabled');
  451. if (jQuery(this).hasClass('spinner-on-click')) {
  452. var icon = $(this).find('i.fas,i.far,i.fal,i.fab');
  453. jQuery(icon)
  454. .removeAttr('class')
  455. .addClass('fas fa-spinner fa-spin');
  456. }
  457. });
  458. });
  459. function scrollToGatewayInputError() {
  460. var displayError = jQuery('.gateway-errors,.assisted-cc-input-feedback').first(),
  461. frm = displayError.closest('form');
  462. if (!frm) {
  463. frm = jQuery('form').first();
  464. }
  465. frm.find('button[type="submit"],input[type="submit"]')
  466. .prop('disabled', false)
  467. .removeClass('disabled')
  468. .find('i.fas,i.far,i.fal,i.fab')
  469. .removeAttr('class')
  470. .addClass('fas fa-arrow-circle-right')
  471. .find('span').toggle();
  472. if (displayError.length) {
  473. if (elementOutOfViewPort(displayError[0])) {
  474. jQuery('html, body').animate(
  475. {
  476. scrollTop: displayError.offset().top - 50
  477. },
  478. 500
  479. );
  480. }
  481. }
  482. }
  483. function elementOutOfViewPort(element) {
  484. // Get element's bounding
  485. var bounding = element.getBoundingClientRect();
  486. // Check if it's out of the viewport on each side
  487. var out = {};
  488. out.top = bounding.top < 0;
  489. out.left = bounding.left < 0;
  490. out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);
  491. out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);
  492. out.any = out.top || out.left || out.bottom || out.right;
  493. return out.any;
  494. };
  495. /**
  496. * WHMCS authentication module
  497. *
  498. * @copyright Copyright (c) WHMCS Limited 2005-2017
  499. * @license http://www.whmcs.com/license/ WHMCS Eula
  500. */
  501. (function(module) {
  502. if (!WHMCS.hasModule('authn')) {
  503. WHMCS.loadModule('authn', module);
  504. }
  505. })({
  506. provider: function () {
  507. var callbackFired = false;
  508. /**
  509. * @return {jQuery}
  510. */
  511. this.feedbackContainer = function () {
  512. return jQuery(".providerLinkingFeedback");
  513. };
  514. /**
  515. * @returns {jQuery}
  516. */
  517. this.btnContainer = function () {
  518. return jQuery(".providerPreLinking");
  519. };
  520. this.feedbackMessage = function (context) {
  521. if (typeof context === 'undefined') {
  522. context = 'complete_sign_in';
  523. }
  524. var msgContainer = jQuery('p.providerLinkingMsg-preLink-' + context);
  525. if (msgContainer.length) {
  526. return msgContainer.first().html();
  527. }
  528. return '';
  529. };
  530. this.showProgressMessage = function(callback) {
  531. this.feedbackContainer().fadeIn('fast', function () {
  532. if (typeof callback === 'function' && !callbackFired) {
  533. callbackFired = true;
  534. callback();
  535. }
  536. });
  537. };
  538. this.preLinkInit = function (callback) {
  539. var icon = '<i class="fas fa-fw fa-spinner fa-spin"></i> ';
  540. this.feedbackContainer()
  541. .removeClass('alert-danger alert-success')
  542. .addClass('alert alert-info')
  543. .html(icon + this.feedbackMessage())
  544. .hide();
  545. var btnContainer = this.btnContainer();
  546. if (btnContainer.length) {
  547. if (btnContainer.data('hideOnPrelink')) {
  548. var self = this;
  549. btnContainer.fadeOut('false', function ()
  550. {
  551. self.showProgressMessage(callback)
  552. });
  553. } else if (btnContainer.data('disableOnPrelink')) {
  554. btnContainer.find('.btn').addClass('disabled');
  555. this.showProgressMessage(callback);
  556. } else {
  557. this.showProgressMessage(callback);
  558. }
  559. } else {
  560. this.showProgressMessage(callback);
  561. }
  562. };
  563. this.displayError = function (provider, errorCondition, providerErrorText){
  564. jQuery('#providerLinkingMessages .provider-name').html(provider);
  565. var feedbackMsg = this.feedbackMessage('connect_error');
  566. if (errorCondition) {
  567. var errorMsg = this.feedbackMessage(errorCondition);
  568. if (errorMsg) {
  569. feedbackMsg = errorMsg
  570. }
  571. }
  572. if (providerErrorText && $('.btn-logged-in-admin').length > 0) {
  573. feedbackMsg += ' Error: ' + providerErrorText;
  574. }
  575. this.feedbackContainer().removeClass('alert-info alert-success')
  576. .addClass('alert alert-danger')
  577. .html(feedbackMsg).slideDown();
  578. };
  579. this.displaySuccess = function (data, context, provider) {
  580. var icon = provider.icon;
  581. var htmlTarget = context.htmlTarget;
  582. var targetLogin = context.targetLogin;
  583. var targetRegister = context.targetRegister;
  584. var displayName = provider.name;
  585. var feedbackMsg = '';
  586. switch (data.result) {
  587. case "logged_in":
  588. case "2fa_needed":
  589. feedbackMsg = this.feedbackMessage('2fa_needed');
  590. this.feedbackContainer().removeClass('alert-danger alert-warning alert-success')
  591. .addClass('alert alert-info')
  592. .html(feedbackMsg);
  593. window.location = data.redirect_url
  594. ? decodeURIComponent(data.redirect_url)
  595. : decodeURIComponent(context.redirectUrl);
  596. break;
  597. case "linking_complete":
  598. var accountInfo = '';
  599. if (data.remote_account.email) {
  600. accountInfo = data.remote_account.email;
  601. } else {
  602. accountInfo = data.remote_account.firstname + " " + data.remote_account.lastname;
  603. }
  604. accountInfo = accountInfo.trim();
  605. feedbackMsg = this.feedbackMessage('linking_complete').trim().replace(':displayName', displayName);
  606. if (accountInfo) {
  607. feedbackMsg = feedbackMsg.replace(/\.$/, ' (' + accountInfo + ').');
  608. }
  609. this.feedbackContainer().removeClass('alert-danger alert-warning alert-info')
  610. .addClass('alert alert-success')
  611. .html(icon + feedbackMsg);
  612. break;
  613. case "login_to_link":
  614. if (htmlTarget === targetLogin) {
  615. feedbackMsg = this.feedbackMessage('login_to_link-signin-required');
  616. this.feedbackContainer().removeClass('alert-danger alert-success alert-info')
  617. .addClass('alert alert-warning')
  618. .html(icon + feedbackMsg);
  619. } else {
  620. var emailField = jQuery("input[name=email]");
  621. var firstNameField = jQuery("input[name=firstname]");
  622. var lastNameField = jQuery("input[name=lastname]");
  623. if (emailField.val() === "") {
  624. emailField.val(data.remote_account.email);
  625. }
  626. if (firstNameField.val() === "") {
  627. firstNameField.val(data.remote_account.firstname);
  628. }
  629. if (lastNameField.val() === "") {
  630. lastNameField.val(data.remote_account.lastname);
  631. }
  632. if (htmlTarget === targetRegister) {
  633. if (typeof WHMCS.client.registration === 'object') {
  634. WHMCS.client.registration.prefillPassword();
  635. }
  636. feedbackMsg = this.feedbackMessage('login_to_link-registration-required');
  637. this.feedbackContainer().fadeOut('slow', function () {
  638. $(this).removeClass('alert-danger alert-success alert-info')
  639. .addClass('alert alert-warning')
  640. .html(icon + feedbackMsg).fadeIn('fast');
  641. });
  642. } else {
  643. // this is checkout
  644. if (typeof WHMCS.client.registration === 'object') {
  645. WHMCS.client.registration.prefillPassword();
  646. }
  647. var self = this;
  648. this.feedbackContainer().each(function (i, el) {
  649. var container = $(el);
  650. var linkContext = container.siblings('div .providerPreLinking').data('linkContext');
  651. container.fadeOut('slow', function () {
  652. if (linkContext === 'checkout-new') {
  653. feedbackMsg = self.feedbackMessage('checkout-new');
  654. } else {
  655. feedbackMsg = self.feedbackMessage('login_to_link-signin-required');
  656. }
  657. container.removeClass('alert-danger alert-success alert-info')
  658. .addClass('alert alert-warning')
  659. .html(icon + feedbackMsg).fadeIn('fast');
  660. });
  661. });
  662. }
  663. }
  664. break;
  665. case "other_user_exists":
  666. feedbackMsg = this.feedbackMessage('other_user_exists');
  667. this.feedbackContainer().removeClass('alert-info alert-success')
  668. .addClass('alert alert-danger')
  669. .html(icon + feedbackMsg).slideDown();
  670. break;
  671. case "already_linked":
  672. feedbackMsg = this.feedbackMessage('already_linked');
  673. this.feedbackContainer().removeClass('alert-info alert-success')
  674. .addClass('alert alert-danger')
  675. .html(icon + feedbackMsg).slideDown();
  676. break;
  677. default:
  678. feedbackMsg = this.feedbackMessage('default');
  679. this.feedbackContainer().removeClass('alert-info alert-success')
  680. .addClass('alert alert-danger')
  681. .html(icon + feedbackMsg).slideDown();
  682. break;
  683. }
  684. };
  685. this.signIn = function (config, context, provider, providerDone, providerError) {
  686. jQuery.ajax(config).done(function(data) {
  687. providerDone();
  688. WHMCS.authn.provider.displaySuccess(data, context, provider);
  689. var table = jQuery('#tableLinkedAccounts');
  690. if (table.length) {
  691. WHMCS.ui.dataTable.getTableById('tableLinkedAccounts').ajax.reload();
  692. }
  693. }).error(function() {
  694. providerError();
  695. WHMCS.authn.provider.displayError();
  696. });
  697. };
  698. return this;
  699. }});
  700. /**
  701. * WHMCS client module
  702. *
  703. * @copyright Copyright (c) WHMCS Limited 2005-2017
  704. * @license http://www.whmcs.com/license/ WHMCS Eula
  705. */
  706. (function(module) {
  707. if (!WHMCS.hasModule('client')) {
  708. WHMCS.loadModule('client', module);
  709. }
  710. })({
  711. registration: function () {
  712. this.prefillPassword = function (params) {
  713. params = params || {};
  714. if (typeof params.hideContainer === 'undefined') {
  715. var id = (jQuery('#inputSecurityQId').attr('id')) ? '#containerPassword' : '#containerNewUserSecurity';
  716. params.hideContainer = jQuery(id);
  717. params.hideInputs = true;
  718. } else if (typeof params.hideContainer === 'string' && params.hideContainer.length) {
  719. params.hideContainer = jQuery(params.hideContainer);
  720. }
  721. if (typeof params.form === 'undefined') {
  722. params.form = {
  723. password: [
  724. {id: 'inputNewPassword1'},
  725. {id: 'inputNewPassword2'}
  726. ]
  727. };
  728. }
  729. var prefillFunc = function () {
  730. var $randomPasswd = WHMCS.utils.simpleRNG();
  731. for (var i = 0, len = params.form.password.length; i < len; i++) {
  732. jQuery('#' + params.form.password[i].id)
  733. .val($randomPasswd).trigger('keyup');
  734. }
  735. };
  736. if (params.hideInputs) {
  737. params.hideContainer.slideUp('fast', prefillFunc);
  738. } else {
  739. prefillFunc();
  740. }
  741. };
  742. return this;
  743. }});
  744. /**
  745. * WHMCS HTTP module
  746. *
  747. * @copyright Copyright (c) WHMCS Limited 2005-2018
  748. * @license http://www.whmcs.com/license/ WHMCS Eula
  749. */
  750. (function(module) {
  751. if (!WHMCS.hasModule('http')) {
  752. WHMCS.loadModule('http', module);
  753. }
  754. })({
  755. jqClient: function () {
  756. _getSettings = function (url, data, success, dataType)
  757. {
  758. if (typeof url === 'object') {
  759. /*
  760. Settings may be the only argument
  761. */
  762. return url;
  763. }
  764. if (typeof data === 'function') {
  765. /*
  766. If 'data' is omitted, 'success' will come in its place
  767. */
  768. success = data;
  769. data = null;
  770. }
  771. return {
  772. url: url,
  773. data: data,
  774. success: success,
  775. dataType: dataType
  776. };
  777. };
  778. /**
  779. * @param url
  780. * @param data
  781. * @param success
  782. * @param dataType
  783. * @returns {*}
  784. */
  785. this.get = function (url, data, success, dataType)
  786. {
  787. return WHMCS.http.client.request(
  788. jQuery.extend(
  789. _getSettings(url, data, success, dataType),
  790. {
  791. type: 'GET'
  792. }
  793. )
  794. );
  795. };
  796. /**
  797. * @param url
  798. * @param data
  799. * @param success
  800. * @param dataType
  801. * @returns {*}
  802. */
  803. this.post = function (url, data, success, dataType)
  804. {
  805. return WHMCS.http.client.request(
  806. jQuery.extend(
  807. _getSettings(url, data, success, dataType),
  808. {
  809. type: 'POST'
  810. }
  811. )
  812. );
  813. };
  814. /**
  815. * @param options
  816. * @returns {*}
  817. */
  818. this.jsonGet = function (options) {
  819. options = options || {};
  820. this.get(options.url, options.data, function(response) {
  821. if (response.warning) {
  822. console.log('[WHMCS] Warning: ' + response.warning);
  823. if (typeof options.warning === 'function') {
  824. options.warning(response.warning);
  825. }
  826. } else if (response.error) {
  827. console.log('[WHMCS] Error: ' + response.error);
  828. if (typeof options.error === 'function') {
  829. options.error(response.error);
  830. }
  831. } else {
  832. if (typeof options.success === 'function') {
  833. options.success(response);
  834. }
  835. }
  836. }, 'json').error(function(xhr, errorMsg){
  837. console.log('[WHMCS] Error: ' + errorMsg);
  838. if (typeof options.fail === 'function') {
  839. options.fail(errorMsg);
  840. }
  841. }).always(function() {
  842. if (typeof options.always === 'function') {
  843. options.always();
  844. }
  845. });
  846. };
  847. /**
  848. * @param options
  849. * @returns {*}
  850. */
  851. this.jsonPost = function (options) {
  852. options = options || {};
  853. this.post(options.url, options.data, function(response) {
  854. if (response.warning) {
  855. console.log('[WHMCS] Warning: ' + response.warning);
  856. if (typeof options.warning === 'function') {
  857. options.warning(response.warning);
  858. }
  859. } else if (response.error) {
  860. console.log('[WHMCS] Error: ' + response.error);
  861. if (typeof options.error === 'function') {
  862. options.error(response.error);
  863. }
  864. } else {
  865. if (typeof options.success === 'function') {
  866. options.success(response);
  867. }
  868. }
  869. }, 'json').fail(function(xhr, errorMsg){
  870. console.log('[WHMCS] Fail: ' + errorMsg);
  871. if (typeof options.fail === 'function') {
  872. options.fail(errorMsg, xhr);
  873. }
  874. }).always(function() {
  875. if (typeof options.always === 'function') {
  876. options.always();
  877. }
  878. });
  879. };
  880. return this;
  881. },
  882. client: function () {
  883. var methods = ['get', 'post', 'put', 'delete'];
  884. var client = this;
  885. _beforeRequest = function (settings)
  886. {
  887. /*
  888. Enforcing dataType was found to break many invocations expecting HTML back.
  889. If/when those are refactored, this may be uncommented to enforce a safer
  890. data transit.
  891. */
  892. /*if (typeof settings.dataType === 'undefined') {
  893. settings.dataType = 'json';
  894. }*/
  895. if (typeof settings.type === 'undefined') {
  896. // default request type is GET
  897. settings.type = 'GET';
  898. }
  899. /*
  900. Add other preprocessing here if required
  901. */
  902. return settings;
  903. };
  904. this.request = function (settings)
  905. {
  906. settings = _beforeRequest(settings || {});
  907. return jQuery.ajax(settings);
  908. };
  909. /*
  910. Create shortcut methods for methods[] array above
  911. */
  912. jQuery.each(methods, function(index, method) {
  913. client[method] = (function(method, client) {
  914. return function (settings)
  915. {
  916. settings = settings || {};
  917. settings.type = method.toUpperCase();
  918. return client.request(settings);
  919. }
  920. })(method, client);
  921. });
  922. return this;
  923. }
  924. });
  925. /**
  926. * WHMCS UI module
  927. *
  928. * @copyright Copyright (c) WHMCS Limited 2005-2017
  929. * @license http://www.whmcs.com/license/ WHMCS Eula
  930. */
  931. (function(module) {
  932. if (!WHMCS.hasModule('ui')) {
  933. WHMCS.loadModule('ui', module);
  934. }
  935. })({
  936. /**
  937. * Confirmation PopUp
  938. */
  939. confirmation: function () {
  940. /**
  941. * @type {Array} Registered confirmation root selectors
  942. */
  943. var toggles = [];
  944. /**
  945. * Register/Re-Register all confirmation elements with jQuery
  946. * By default all elements of data toggle "confirmation" will be registered
  947. *
  948. * @param {(string|undefined)} rootSelector
  949. * @return {Array} array of registered toggles
  950. */
  951. this.register = function (rootSelector) {
  952. if (typeof rootSelector === 'undefined') {
  953. rootSelector = '[data-toggle=confirmation]';
  954. }
  955. if (toggles.indexOf(rootSelector) < 0) {
  956. toggles.push(rootSelector);
  957. }
  958. jQuery(rootSelector).confirmation({
  959. rootSelector: rootSelector
  960. });
  961. return toggles;
  962. };
  963. return this;
  964. },
  965. /**
  966. * Data Driven Table
  967. */
  968. dataTable: function () {
  969. /**
  970. * @type {{}}
  971. */
  972. this.tables = {};
  973. /**
  974. * Register all tables on page with the class "data-driven"
  975. */
  976. this.register = function () {
  977. var self = this;
  978. jQuery('table.data-driven').each(function (i, table) {
  979. self.getTableById(table.id, undefined);
  980. });
  981. };
  982. /**
  983. * Get a table by id; create table object on fly as necessary
  984. *
  985. * @param {string} id
  986. * @param {({}|undefined)} options
  987. * @returns {DataTable}
  988. */
  989. this.getTableById = function (id, options) {
  990. var self = this;
  991. var el = jQuery('#' + id);
  992. if (typeof self.tables[id] === 'undefined') {
  993. if (typeof options === 'undefined') {
  994. options = {
  995. dom: '<"listtable"ift>pl',
  996. paging: false,
  997. lengthChange: false,
  998. searching: false,
  999. ordering: true,
  1000. info: false,
  1001. autoWidth: true,
  1002. language: {
  1003. emptyTable: (el.data('lang-empty-table')) ? el.data('lang-empty-table') : "No records found"
  1004. }
  1005. };
  1006. }
  1007. var ajaxUrl = el.data('ajax-url');
  1008. if (typeof ajaxUrl !== 'undefined') {
  1009. options.ajax = {
  1010. url: ajaxUrl
  1011. };
  1012. }
  1013. var dom = el.data('dom');
  1014. if (typeof dom !== 'undefined') {
  1015. options.dom = dom;
  1016. }
  1017. var searching = el.data('searching');
  1018. if (typeof searching !== 'undefined') {
  1019. options.searching = searching;
  1020. }
  1021. var responsive = el.data('responsive');
  1022. if (typeof responsive !== 'undefined') {
  1023. options.responsive = responsive;
  1024. }
  1025. var ordering = el.data('ordering');
  1026. if (typeof ordering !== 'undefined') {
  1027. options["ordering"] = ordering;
  1028. }
  1029. var order = el.data('order');
  1030. if (typeof order !== 'undefined' && order) {
  1031. options["order"] = order;
  1032. }
  1033. var colCss = el.data('columns');
  1034. if (typeof colCss !== 'undefined' && colCss) {
  1035. options["columns"] = colCss;
  1036. }
  1037. var autoWidth = el.data('auto-width');
  1038. if (typeof autoWidth !== 'undefined') {
  1039. options["autoWidth"] = autoWidth;
  1040. }
  1041. var paging = el.data('paging');
  1042. if (typeof paging !== 'undefined') {
  1043. options["paging"] = paging;
  1044. }
  1045. var lengthChange = el.data('length-change');
  1046. if (typeof lengthChange !== 'undefined') {
  1047. options["lengthChange"] = lengthChange;
  1048. }
  1049. var pageLength = el.data('page-length');
  1050. if (typeof pageLength !== 'undefined') {
  1051. options["pageLength"] = pageLength;
  1052. }
  1053. self.tables[id] = self.initTable(el, options);
  1054. } else if (typeof options !== 'undefined') {
  1055. var oldTable = self.tables[id];
  1056. var initOpts = oldTable.init();
  1057. var newOpts = jQuery.extend( initOpts, options);
  1058. oldTable.destroy();
  1059. self.tables[id] = self.initTable(el, newOpts);
  1060. }
  1061. return self.tables[id];
  1062. };
  1063. this.initTable = function (el, options) {
  1064. var table = el.DataTable(options);
  1065. var self = this;
  1066. if (el.data('on-draw')) {
  1067. table.on('draw.dt', function (e, settings) {
  1068. var namedCallback = el.data('on-draw');
  1069. if (typeof window[namedCallback] === 'function') {
  1070. window[namedCallback](e, settings);
  1071. }
  1072. });
  1073. } else if (el.data('on-draw-rebind-confirmation')) {
  1074. table.on('draw.dt', function (e) {
  1075. self.rebindConfirmation(e);
  1076. });
  1077. }
  1078. return table;
  1079. };
  1080. this.rebindConfirmation = function (e) {
  1081. var self = this;
  1082. var tableId = e.target.id;
  1083. var toggles = WHMCS.ui.confirmation.register();
  1084. for(var i = 0, len = toggles.length; i < len; i++ ) {
  1085. jQuery(toggles[i]).on(
  1086. 'confirmed.bs.confirmation',
  1087. function (e)
  1088. {
  1089. e.preventDefault();
  1090. WHMCS.http.jqClient.post(
  1091. jQuery(e.target).data('target-url'),
  1092. {
  1093. 'token': csrfToken
  1094. }
  1095. ).done(function (data)
  1096. {
  1097. if (data.status === 'success' || data.status === 'okay') {
  1098. self.getTableById(tableId, undefined).ajax.reload();
  1099. }
  1100. });
  1101. }
  1102. );
  1103. }
  1104. };
  1105. return this;
  1106. },
  1107. clipboard: function() {
  1108. this.copy = function(e) {
  1109. e.preventDefault();
  1110. var trigger = $(e.currentTarget);
  1111. var contentElement = $(trigger).data('clipboard-target');
  1112. var container = $(contentElement).parent();
  1113. try {
  1114. var tempElement = $('<textarea>')
  1115. .css('position', 'fixed')
  1116. .css('opacity', '0')
  1117. .css('width', '1px')
  1118. .css('height', '1px')
  1119. .val($(contentElement).val());
  1120. container.append(tempElement);
  1121. tempElement.focus().select();
  1122. document.execCommand('copy');
  1123. } finally {
  1124. tempElement.remove();
  1125. }
  1126. trigger.tooltip({
  1127. trigger: 'click',
  1128. placement: 'bottom'
  1129. });
  1130. WHMCS.ui.toolTip.setTip(trigger, 'Copied!');
  1131. WHMCS.ui.toolTip.hideTip(trigger);
  1132. };
  1133. return this;
  1134. },
  1135. /**
  1136. * ToolTip and Clipboard behaviors
  1137. */
  1138. toolTip: function () {
  1139. this.setTip = function (btn, message) {
  1140. var tip = btn.data('bs.tooltip');
  1141. if (tip.hoverState !== 'in') {
  1142. tip.hoverState = 'in';
  1143. }
  1144. btn.attr('data-original-title', message);
  1145. tip.show();
  1146. return tip;
  1147. };
  1148. this.hideTip = function (btn) {
  1149. return setTimeout(function() {
  1150. btn.data('bs.tooltip').hide()
  1151. }, 2000);
  1152. }
  1153. },
  1154. jsonForm: function() {
  1155. this.managedElements = 'input,textarea,select';
  1156. this.initFields = function (form) {
  1157. var self = this;
  1158. $(form).find(self.managedElements).each(function () {
  1159. var field = this;
  1160. $(field).on('keypress change', function () {
  1161. if (self.fieldHasError(field)) {
  1162. self.clearFieldError(field);
  1163. }
  1164. });
  1165. });
  1166. };
  1167. this.init = function (form) {
  1168. var self = this;
  1169. self.initFields(form);
  1170. $(form).on('submit', function(e) {
  1171. e.preventDefault();
  1172. e.stopPropagation();
  1173. self.clearErrors(form);
  1174. var formModal = $(form).parents('.modal[role="dialog"]').first();
  1175. if ($(formModal).length) {
  1176. $(formModal).on('show.bs.modal hidden.bs.modal', function() {
  1177. self.clearErrors(form);
  1178. });
  1179. /*
  1180. * Make this optional if the form is used for editing
  1181. */
  1182. $(formModal).on('show.bs.modal', function() {
  1183. $(form)[0].reset();
  1184. });
  1185. }
  1186. WHMCS.http.client.post({
  1187. url: $(form).attr('action'),
  1188. data: $(form).serializeArray(),
  1189. })
  1190. .done(function (response) {
  1191. self.onSuccess(form, response);
  1192. })
  1193. .fail(function (jqXHR) {
  1194. self.onError(form, jqXHR);
  1195. })
  1196. .always(function (data) {
  1197. self.onRequestComplete(form, data);
  1198. });
  1199. });
  1200. };
  1201. this.initAll = function () {
  1202. var self = this;
  1203. $('form[data-role="json-form"]').each(function() {
  1204. var formElement = this;
  1205. self.init(formElement);
  1206. });
  1207. };
  1208. this.markFieldErrors = function (form, fields)
  1209. {
  1210. var self = this;
  1211. var errorMessage = null;
  1212. var field, fieldLookup;
  1213. for (var fieldName in fields) {
  1214. if (fields.hasOwnProperty(fieldName)) {
  1215. errorMessage = fields[fieldName];
  1216. }
  1217. fieldLookup = self.managedElements.split(',').map(function(element) {
  1218. return element + '[name="' + fieldName + '"]';
  1219. }).join(',');
  1220. field = $(form).find(fieldLookup);
  1221. if (errorMessage) {
  1222. $(field).parents('.form-group').addClass('has-error');
  1223. $(field).attr('title', errorMessage);
  1224. $(field).tooltip();
  1225. }
  1226. }
  1227. $(form).find('.form-group.has-error input[title]').first().tooltip('show');
  1228. };
  1229. this.fieldHasError = function (field) {
  1230. return $(field).parents('.form-group').hasClass('has-error');
  1231. };
  1232. this.clearFieldError = function (field) {
  1233. /**
  1234. * Try dispose first for BS 4, which will raise error
  1235. * on BS 3 or older, then we use destroy instead
  1236. */
  1237. try {
  1238. $(field).tooltip('dispose');
  1239. } catch (err) {
  1240. $(field).tooltip('destroy');
  1241. }
  1242. $(field).parents('.form-group').removeClass('has-error');
  1243. };
  1244. this.onSuccess = function (form, response) {
  1245. var formOnSuccess = $(form).data('on-success');
  1246. if (typeof formOnSuccess === 'function') {
  1247. formOnSuccess(response.data);
  1248. }
  1249. };
  1250. this.onError = function (form, jqXHR) {
  1251. if (jqXHR.responseJSON && jqXHR.responseJSON.fields && typeof jqXHR.responseJSON.fields === 'object') {
  1252. this.markFieldErrors(form, jqXHR.responseJSON.fields);
  1253. } else {
  1254. // TODO: replace with client-accessible generic error messaging
  1255. console.log('Unknown error - please try again later.');
  1256. }
  1257. var formOnError = $(form).data('on-error');
  1258. if (typeof formOnError === 'function') {
  1259. formOnError(jqXHR);
  1260. }
  1261. };
  1262. this.clearErrors = function (form) {
  1263. var self = this;
  1264. $(form).find(self.managedElements).each(function () {
  1265. self.clearFieldError(this);
  1266. })
  1267. };
  1268. this.onRequestComplete = function (form, data) {
  1269. // implement as needed
  1270. };
  1271. return this;
  1272. },
  1273. effects: function () {
  1274. this.errorShake = function (element) {
  1275. /**
  1276. * Shake effect without jQuery UI inspired by Hiren Patel | ninty9notout:
  1277. * @see https://github.com/ninty9notout/jquery-shake/blob/51f3dcf625970c78505bcac831fd9e28fc85d374/jquery.ui.shake.js
  1278. */
  1279. options = options || {};
  1280. var options = $.extend({
  1281. direction: "left",
  1282. distance: 8,
  1283. times: 3,
  1284. speed: 90
  1285. }, options);
  1286. return element.each(function () {
  1287. var el = $(this), props = {
  1288. position: el.css("position"),
  1289. top: el.css("top"),
  1290. bottom: el.css("bottom"),
  1291. left: el.css("left"),
  1292. right: el.css("right")
  1293. };
  1294. el.css("position", "relative");
  1295. var ref = (options.direction === "up" || options.direction === "down") ? "top" : "left";
  1296. var motion = (options.direction === "up" || options.direction === "left") ? "pos" : "neg";
  1297. var animation = {}, animation1 = {}, animation2 = {};
  1298. animation[ref] = (motion === "pos" ? "-=" : "+=") + options.distance;
  1299. animation1[ref] = (motion === "pos" ? "+=" : "-=") + options.distance * 2;
  1300. animation2[ref] = (motion === "pos" ? "-=" : "+=") + options.distance * 2;
  1301. el.animate(animation, options.speed);
  1302. for (var i = 1; i < options.times; i++) {
  1303. el.animate(animation1, options.speed).animate(animation2, options.speed);
  1304. }
  1305. el.animate(animation1, options.speed).animate(animation, options.speed / 2, function () {
  1306. el.css(props);
  1307. });
  1308. });
  1309. };
  1310. }
  1311. });
  1312. /**
  1313. * Form module
  1314. *
  1315. * @copyright Copyright (c) WHMCS Limited 2005-2017
  1316. * @license http://www.whmcs.com/license/ WHMCS Eula
  1317. */
  1318. (function(module) {
  1319. if (!WHMCS.hasModule('form')) {
  1320. WHMCS.loadModule('form', module);
  1321. }
  1322. })(
  1323. function () {
  1324. this.checkAllBound = false;
  1325. this.register = function () {
  1326. if (!this.checkAllBound) {
  1327. this.bindCheckAll();
  1328. this.checkAllBound = true;
  1329. }
  1330. };
  1331. this.bindCheckAll = function ()
  1332. {
  1333. var huntSelector = '.btn-check-all';
  1334. jQuery('body').on('click', huntSelector, function (e) {
  1335. var btn = jQuery(e.target);
  1336. var targetInputs = jQuery(
  1337. '#' + btn.data('checkbox-container') + ' input[type="checkbox"]'
  1338. );
  1339. if (btn.data('btn-check-toggle')) {
  1340. // one control that changes
  1341. var textDeselect = 'Deselect All';
  1342. var textSelect = 'Select All';
  1343. if (btn.data('label-text-deselect')) {
  1344. textDeselect = btn.data('label-text-deselect');
  1345. }
  1346. if (btn.data('label-text-select')) {
  1347. textSelect = btn.data('label-text-select');
  1348. }
  1349. if (btn.hasClass('toggle-active')) {
  1350. targetInputs.prop('checked',false);
  1351. btn.text(textSelect);
  1352. btn.removeClass('toggle-active');
  1353. } else {
  1354. targetInputs.prop('checked',true);
  1355. btn.text(textDeselect);
  1356. btn.addClass('toggle-active');
  1357. }
  1358. } else {
  1359. // two controls that are static
  1360. if (btn.data('btn-toggle-on')) {
  1361. targetInputs.prop('checked',true);
  1362. } else {
  1363. targetInputs.prop('checked',false);
  1364. }
  1365. }
  1366. });
  1367. };
  1368. this.reloadCaptcha = function (element)
  1369. {
  1370. if (typeof grecaptcha !== 'undefined') {
  1371. grecaptcha.reset();
  1372. } else {
  1373. if (!element) {
  1374. element = jQuery('#inputCaptchaImage');
  1375. }
  1376. var src = jQuery(element).data('src');
  1377. jQuery(element).attr('src', src + '?nocache=' + (new Date()).getTime());
  1378. var userInput = jQuery('#inputCaptcha');
  1379. if (userInput.length) {
  1380. userInput.val('');
  1381. }
  1382. }
  1383. };
  1384. return this;
  1385. });
  1386. /**
  1387. * reCaptcha module
  1388. *
  1389. * @copyright Copyright (c) WHMCS Limited 2005-2020
  1390. * @license http://www.whmcs.com/license/ WHMCS Eula
  1391. */
  1392. var recaptchaLoadComplete = false,
  1393. recaptchaCount = 0,
  1394. recaptchaType = 'recaptcha',
  1395. recaptchaValidationComplete = false;
  1396. (function(module) {
  1397. if (!WHMCS.hasModule('recaptcha')) {
  1398. WHMCS.loadModule('recaptcha', module);
  1399. }
  1400. })(
  1401. function () {
  1402. this.register = function () {
  1403. if (recaptchaLoadComplete) {
  1404. return;
  1405. }
  1406. var postLoad = [],
  1407. recaptchaForms = jQuery(".btn-recaptcha").parents('form'),
  1408. isInvisible = false;
  1409. recaptchaForms.each(function (i, el){
  1410. if (typeof recaptchaSiteKey === 'undefined') {
  1411. console.log('Recaptcha site key not defined');
  1412. return;
  1413. }
  1414. recaptchaCount += 1;
  1415. var frm = jQuery(el),
  1416. btnRecaptcha = frm.find(".btn-recaptcha"),
  1417. required = (typeof requiredText !== 'undefined') ? requiredText : 'Required',
  1418. recaptchaId = 'divDynamicRecaptcha' + recaptchaCount;
  1419. isInvisible = btnRecaptcha.hasClass('btn-recaptcha-invisible')
  1420. // if no recaptcha element, make one
  1421. var recaptchaContent = frm.find('#' + recaptchaId + ' .g-recaptcha'),
  1422. recaptchaElement = frm.find('.recaptcha-container'),
  1423. appendElement = frm;
  1424. if (recaptchaElement.length) {
  1425. recaptchaElement.attr('id', recaptchaElement.attr('id') + recaptchaCount);
  1426. appendElement = recaptchaElement;
  1427. }
  1428. if (!recaptchaContent.length) {
  1429. appendElement.append('<div id="#' + recaptchaId + '" class="g-recaptcha"></div>');
  1430. recaptchaContent = appendElement.find('#' + recaptchaId);
  1431. }
  1432. // propagate invisible recaptcha if necessary
  1433. if (!isInvisible) {
  1434. recaptchaContent.data('toggle', 'tooltip')
  1435. .data('placement', 'bottom')
  1436. .data('trigger', 'manual')
  1437. .attr('title', required)
  1438. .hide();
  1439. }
  1440. // alter form to work around JS behavior on .submit() when there
  1441. // there is an input with the name 'submit'
  1442. var btnSubmit = frm.find("input[name='submit']");
  1443. if (btnSubmit.length) {
  1444. var action = frm.prop('action');
  1445. frm.prop('action', action + '&submit=1');
  1446. btnSubmit.remove();
  1447. }
  1448. // make callback for grecaptcha to invoke after
  1449. // injecting token & make it known via data-callback
  1450. var funcName = recaptchaId + 'Callback';
  1451. window[funcName] = function () {
  1452. if (isInvisible) {
  1453. frm.submit();
  1454. }
  1455. };
  1456. // setup an on form submit event to ensure that we
  1457. // are allowing required field validation to occur before
  1458. // we do the invisible recaptcha checking
  1459. if (isInvisible) {
  1460. recaptchaType = 'invisible';
  1461. frm.on('submit.recaptcha', function (event) {
  1462. var recaptchaId = frm.find('.g-recaptcha').data('recaptcha-id');
  1463. if (!grecaptcha.getResponse(recaptchaId).trim()) {
  1464. event.preventDefault();
  1465. grecaptcha.execute(recaptchaId);
  1466. recaptchaValidationComplete = false;
  1467. } else {
  1468. recaptchaValidationComplete = true;
  1469. }
  1470. });
  1471. } else {
  1472. postLoad.push(function () {
  1473. recaptchaContent.slideDown('fast', function() {
  1474. // just in case there's a delay in DOM; rare
  1475. recaptchaContent.find(':first').addClass('center-block');
  1476. });
  1477. });
  1478. postLoad.push(function() {
  1479. recaptchaContent.find(':first').addClass('center-block');
  1480. });
  1481. }
  1482. });
  1483. window.recaptchaLoadCallback = function() {
  1484. jQuery('.g-recaptcha').each(function(i, el) {
  1485. var element = jQuery(el),
  1486. frm = element.closest('form'),
  1487. btn = frm.find('.btn-recaptcha'),
  1488. idToUse = element.attr('id').substring(1);
  1489. var recaptchaId = grecaptcha.render(
  1490. el,
  1491. {
  1492. sitekey: recaptchaSiteKey,
  1493. size: (btn.hasClass('btn-recaptcha-invisible')) ? 'invisible' : 'normal',
  1494. callback: idToUse + 'Callback'
  1495. }
  1496. );
  1497. element.data('recaptcha-id', recaptchaId);
  1498. });
  1499. }
  1500. // fetch/invoke the grecaptcha lib
  1501. if (recaptchaForms.length) {
  1502. var gUrl = "https://www.google.com/recaptcha/api.js?onload=recaptchaLoadCallback&render=explicit";
  1503. jQuery.getScript(gUrl, function () {
  1504. for(var i = postLoad.length - 1; i >= 0 ; i--){
  1505. postLoad[i]();
  1506. }
  1507. });
  1508. }
  1509. recaptchaLoadComplete = true;
  1510. };
  1511. return this;
  1512. });
  1513. /**
  1514. * General utilities module
  1515. *
  1516. * @copyright Copyright (c) WHMCS Limited 2005-2017
  1517. * @license http://www.whmcs.com/license/ WHMCS Eula
  1518. */
  1519. (function(module) {
  1520. if (!WHMCS.hasModule('utils')) {
  1521. WHMCS.loadModule('utils', module);
  1522. }
  1523. })(
  1524. function () {
  1525. /**
  1526. * Not crypto strong; server-side must discard for
  1527. * something with more entropy; the value is sufficient
  1528. * for strong client-side validation check
  1529. */
  1530. this.simpleRNG = function () {
  1531. var chars = './$_-#!,^*()|';
  1532. var r = 0;
  1533. for (var i = 0; r < 3; i++) {
  1534. r += Math.floor((Math.random() * 10) / 2);
  1535. }
  1536. r = Math.floor(r);
  1537. var s = '';
  1538. for (var x = 0; x < r; x++) {
  1539. v = (Math.random() + 1).toString(24).split('.')[1];
  1540. if ((Math.random()) > 0.5) {
  1541. s += btoa(v).substr(0,4)
  1542. } else {
  1543. s += v
  1544. }
  1545. if ((Math.random()) > 0.5) {
  1546. s += chars.substr(
  1547. Math.floor(Math.random() * 13),
  1548. 1
  1549. );
  1550. }
  1551. }
  1552. return s;
  1553. };
  1554. this.getRouteUrl = function (path) {
  1555. return whmcsBaseUrl + "/index.php?rp=" + path;
  1556. };
  1557. this.validateBaseUrl = function() {
  1558. if (typeof window.whmcsBaseUrl === 'undefined') {
  1559. console.log('Warning: The WHMCS Base URL definition is missing '
  1560. + 'from your active template. Please refer to '
  1561. + 'https://docs.whmcs.com/WHMCS_Base_URL_Template_Variable '
  1562. + 'for more information and details of how to resolve this '
  1563. + 'warning.');
  1564. window.whmcsBaseUrl = this.autoDetermineBaseUrl();
  1565. window.whmcsBaseUrlAutoSet = true;
  1566. } else if (window.whmcsBaseUrl === ''
  1567. && typeof window.whmcsBaseUrlAutoSet !== 'undefined'
  1568. && window.whmcsBaseUrlAutoSet === true
  1569. ) {
  1570. window.whmcsBaseUrl = this.autoDetermineBaseUrl();
  1571. }
  1572. };
  1573. this.autoDetermineBaseUrl = function() {
  1574. var windowLocation = window.location.href;
  1575. var phpExtensionLocation = -1;
  1576. if (typeof windowLocation !== 'undefined') {
  1577. phpExtensionLocation = windowLocation.indexOf('.php');
  1578. }
  1579. if (phpExtensionLocation === -1) {
  1580. windowLocation = jQuery('#Primary_Navbar-Home a').attr('href');
  1581. if (typeof windowLocation !== 'undefined') {
  1582. phpExtensionLocation = windowLocation.indexOf('.php');
  1583. }
  1584. }
  1585. if (phpExtensionLocation !== -1) {
  1586. windowLocation = windowLocation.substring(0, phpExtensionLocation);
  1587. var lastTrailingSlash = windowLocation.lastIndexOf('/');
  1588. if (lastTrailingSlash !== false) {
  1589. return windowLocation.substring(0, lastTrailingSlash);
  1590. }
  1591. }
  1592. return '';
  1593. };
  1594. this.normaliseStringValue = function(status) {
  1595. return status ? status.toLowerCase().replace(/\s/g, '-') : '';
  1596. };
  1597. this.generatePassword = function(len) {
  1598. var charset = this.getPasswordCharacterSet();
  1599. var result = "";
  1600. for (var i = 0; len > i; i++)
  1601. result += charset[this.randomInt(charset.length)];
  1602. return result;
  1603. };
  1604. this.getPasswordCharacterSet = function() {
  1605. var rawCharset = '0123456789'
  1606. + 'abcdefghijklmnopqrstuvwxyz'
  1607. + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  1608. + '!#$%()*+,-.:;=@_|{ldelim}{rdelim}~';
  1609. // Parse UTF-16, remove duplicates, convert to array of strings
  1610. var charset = [];
  1611. for (var i = 0; rawCharset.length > i; i++) {
  1612. var c = rawCharset.charCodeAt(i);
  1613. if (0xD800 > c || c >= 0xE000) { // Regular UTF-16 character
  1614. var s = rawCharset.charAt(i);
  1615. if (charset.indexOf(s) == -1)
  1616. charset.push(s);
  1617. continue;
  1618. }
  1619. if (0xDC00 > c ? rawCharset.length > i + 1 : false) { // High surrogate
  1620. var d = rawCharset.charCodeAt(i + 1);
  1621. if (d >= 0xDC00 ? 0xE000 > d : false) { // Low surrogate
  1622. var s = rawCharset.substring(i, i + 2);
  1623. i++;
  1624. if (charset.indexOf(s) == -1)
  1625. charset.push(s);
  1626. continue;
  1627. }
  1628. }
  1629. throw "Invalid UTF-16";
  1630. }
  1631. return charset;
  1632. };
  1633. this.randomInt = function(n) {
  1634. var x = this.randomIntMathRandom(n);
  1635. x = (x + this.randomIntBrowserCrypto(n)) % n;
  1636. return x;
  1637. };
  1638. this.randomIntMathRandom = function(n) {
  1639. var x = Math.floor(Math.random() * n);
  1640. if (0 > x || x >= n)
  1641. throw "Arithmetic exception";
  1642. return x;
  1643. };
  1644. this.randomIntBrowserCrypto = function(n) {
  1645. var cryptoObject = null;
  1646. if ("crypto" in window)
  1647. cryptoObject = crypto;
  1648. else if ("msCrypto" in window)
  1649. cryptoObject = msCrypto;
  1650. else
  1651. return 0;
  1652. if (!("getRandomValues" in cryptoObject) || !("Uint32Array" in window) || typeof Uint32Array != "function")
  1653. cryptoObject = null;
  1654. if (cryptoObject == null)
  1655. return 0;
  1656. // Generate an unbiased sample
  1657. var x = new Uint32Array(1);
  1658. do cryptoObject.getRandomValues(x);
  1659. while (x[0] - x[0] % n > 4294967296 - n);
  1660. return x[0] % n;
  1661. };
  1662. return this;
  1663. });
  1664. WHMCS.utils.validateBaseUrl();
  1665. if (typeof localTrans === 'undefined') {
  1666. localTrans = function (phraseId, fallback)
  1667. {
  1668. if (typeof _localLang !== 'undefined') {
  1669. if (typeof _localLang[phraseId] !== 'undefined') {
  1670. if (_localLang[phraseId].length > 0) {
  1671. return _localLang[phraseId];
  1672. }
  1673. }
  1674. }
  1675. return fallback;
  1676. }
  1677. }
  1678. var domainLookupCallCount,
  1679. checkoutForm,
  1680. furtherSuggestions;
  1681. jQuery(document).ready(function(){
  1682. jQuery('#order-standard_cart').find('input').not('.no-icheck').iCheck({
  1683. inheritID: true,
  1684. checkboxClass: 'icheckbox_square-blue',
  1685. radioClass: 'iradio_square-blue',
  1686. increaseArea: '20%'
  1687. });
  1688. jQuery('.mc-promo .header').click(function(e) {
  1689. e.preventDefault();
  1690. if (jQuery(e.target).is('.btn, .btn span,.btn .fa')) {
  1691. return;
  1692. }
  1693. jQuery(this).parent().find('.rotate').toggleClass('down');
  1694. jQuery(this).parent().find('.body').slideToggle('fast');
  1695. });
  1696. jQuery('.mc-promos.viewcart .mc-promo:first-child .header').click();
  1697. var cardNumber = jQuery('#inputCardNumber'),
  1698. existingCvv = jQuery('#inputCardCVV2');
  1699. if (cardNumber.length) {
  1700. cardNumber.payment('formatCardNumber');
  1701. jQuery('#inputCardCVV').payment('formatCardCVC');
  1702. jQuery('#inputCardStart').payment('formatCardExpiry');
  1703. jQuery('#inputCardExpiry').payment('formatCardExpiry');
  1704. }
  1705. if (existingCvv.length) {
  1706. existingCvv.payment('formatCardCVC');
  1707. }
  1708. var $orderSummaryEl = jQuery("#orderSummary");
  1709. if ($orderSummaryEl.length) {
  1710. var offset = jQuery("#scrollingPanelContainer").parent('.row').offset();
  1711. var maxTopOffset = jQuery("#scrollingPanelContainer").parent('.row').outerHeight() - 35;
  1712. var topPadding = 15;
  1713. jQuery(window).resize(function() {
  1714. offset = jQuery("#scrollingPanelContainer").parent('.row').offset();
  1715. maxTopOffset = jQuery("#scrollingPanelContainer").parent('.row').outerHeight() - 35;
  1716. repositionScrollingSidebar();
  1717. });
  1718. jQuery(window).scroll(function() {
  1719. repositionScrollingSidebar();
  1720. });
  1721. repositionScrollingSidebar();
  1722. }
  1723. function repositionScrollingSidebar() {
  1724. if (jQuery('#scrollingPanelContainer').css('float') === 'none') {
  1725. $orderSummaryEl.stop().css('margin-top', '0');
  1726. return false;
  1727. }
  1728. var heightOfOrderSummary = $orderSummaryEl.outerHeight();
  1729. var offsetTop = 0;
  1730. if (typeof offset !== "undefined") {
  1731. offsetTop = offset.top;
  1732. }
  1733. var newTopOffset = jQuery(window).scrollTop() - offsetTop + topPadding;
  1734. if (newTopOffset > maxTopOffset - heightOfOrderSummary) {
  1735. newTopOffset = maxTopOffset - heightOfOrderSummary;
  1736. }
  1737. if (jQuery(window).scrollTop() > offsetTop) {
  1738. $orderSummaryEl.stop().animate({
  1739. marginTop: newTopOffset
  1740. });
  1741. } else {
  1742. $orderSummaryEl.stop().animate({
  1743. marginTop: 0
  1744. });
  1745. }
  1746. }
  1747. jQuery("#frmConfigureProduct").submit(function(e) {
  1748. e.preventDefault();
  1749. var button = jQuery('#btnCompleteProductConfig');
  1750. var btnOriginalText = jQuery(button).html();
  1751. jQuery(button).find('i').removeClass('fa-arrow-circle-right').addClass('fa-spinner fa-spin');
  1752. WHMCS.http.jqClient.post("cart.php", 'ajax=1&a=confproduct&' + jQuery("#frmConfigureProduct").serialize(),
  1753. function(data) {
  1754. if (data) {
  1755. jQuery("#btnCompleteProductConfig").html(btnOriginalText);
  1756. jQuery("#containerProductValidationErrorsList").html(data);
  1757. jQuery("#containerProductValidationErrors").show();
  1758. // scroll to error container if below it
  1759. if (jQuery(window).scrollTop() > jQuery("#containerProductValidationErrors").offset().top) {
  1760. jQuery('html, body').scrollTop(jQuery("#containerProductValidationErrors").offset().top - 15);
  1761. }
  1762. } else {
  1763. window.location = 'cart.php?a=confdomains';
  1764. }
  1765. }
  1766. );
  1767. });
  1768. jQuery("#productConfigurableOptions").on('ifChecked', 'input', function() {
  1769. recalctotals();
  1770. });
  1771. jQuery("#productConfigurableOptions").on('ifUnchecked', 'input', function() {
  1772. recalctotals();
  1773. });
  1774. jQuery("#productConfigurableOptions").on('change', 'select', function() {
  1775. recalctotals();
  1776. });
  1777. jQuery(".addon-products").on('click', '.panel-addon', function(e) {
  1778. e.preventDefault();
  1779. var $activeAddon = jQuery(this);
  1780. if ($activeAddon.hasClass('panel-addon-selected')) {
  1781. $activeAddon.find('input[type="checkbox"]').iCheck('uncheck');
  1782. } else {
  1783. $activeAddon.find('input[type="checkbox"]').iCheck('check');
  1784. }
  1785. });
  1786. jQuery(".addon-products").on('ifChecked', '.panel-addon input', function(event) {
  1787. var $activeAddon = jQuery(this).parents('.panel-addon');
  1788. $activeAddon.addClass('panel-addon-selected');
  1789. $activeAddon.find('input[type="checkbox"]').iCheck('check');
  1790. $activeAddon.find('.panel-add').html('<i class="fas fa-shopping-cart"></i> '+localTrans('addedToCartRemove', 'Added to Cart (Remove)'));
  1791. recalctotals();
  1792. });
  1793. jQuery(".addon-products").on('ifUnchecked', '.panel-addon input', function(event) {
  1794. var $activeAddon = jQuery(this).parents('.panel-addon');
  1795. $activeAddon.removeClass('panel-addon-selected');
  1796. $activeAddon.find('input[type="checkbox"]').iCheck('uncheck');
  1797. $activeAddon.find('.panel-add').html('<i class="fas fa-plus"></i> '+localTrans('addToCart', 'Add to Cart'));
  1798. recalctotals();
  1799. });
  1800. jQuery("#frmConfigureProduct").on('ifChecked', '.addon-selector', function(event) {
  1801. recalctotals();
  1802. });
  1803. if (jQuery(".domain-selection-options input:checked").length == 0) {
  1804. var firstInput = jQuery(".domain-selection-options input:first");
  1805. jQuery(firstInput).iCheck('check');
  1806. jQuery(firstInput).parents('.option').addClass('option-selected');
  1807. }
  1808. jQuery("#domain" + jQuery(".domain-selection-options input:checked").val()).show();
  1809. jQuery(".domain-selection-options input").on('ifChecked', function(event){
  1810. jQuery(".domain-selection-options .option").removeClass('option-selected');
  1811. jQuery(this).parents('.option').addClass('option-selected');
  1812. jQuery(".domain-input-group").hide();
  1813. jQuery("#domain" + jQuery(this).val()).show();
  1814. });
  1815. jQuery('#frmProductDomain').submit(function (e) {
  1816. e.preventDefault();
  1817. var btnSearchObj = jQuery(this).find('button[type="submit"]'),
  1818. domainSearchResults = jQuery("#DomainSearchResults"),
  1819. spotlightTlds = jQuery('#spotlightTlds'),
  1820. suggestions = jQuery('#domainSuggestions'),
  1821. btnDomainContinue = jQuery('#btnDomainContinue'),
  1822. domainoption = jQuery(".domain-selection-options input:checked").val(),
  1823. sldInput = jQuery("#" + domainoption + "sld"),
  1824. sld = sldInput.val(),
  1825. tld = '',
  1826. pid = jQuery('#frmProductDomainPid').val(),
  1827. tldInput = '',
  1828. idnLanguage = jQuery('#idnLanguageSelector');
  1829. jQuery('.field-error-msg').hide();
  1830. if (idnLanguage.is(':visible')) {
  1831. idnLanguage.slideUp();
  1832. idnLanguage.find('select').val('');
  1833. }
  1834. if (domainoption == 'incart') {
  1835. sldInput = jQuery("#" + domainoption + "sld option:selected");
  1836. sld = sldInput.text();
  1837. } else if (domainoption == 'subdomain') {
  1838. tldInput = jQuery("#" + domainoption + "tld option:selected");
  1839. tld = tldInput.text();
  1840. } else {
  1841. tldInput = jQuery("#" + domainoption + "tld");
  1842. tld = tldInput.val();
  1843. if (sld && !tld) {
  1844. tldInput.tooltip('show');
  1845. tldInput.focus();
  1846. return false;
  1847. }
  1848. if (tld.substr(0, 1) != '.') {
  1849. tld = '.' + tld;
  1850. }
  1851. }
  1852. if (!sld) {
  1853. sldInput.tooltip('show');
  1854. sldInput.focus();
  1855. return false;
  1856. }
  1857. sldInput.tooltip('hide');
  1858. if (tldInput.length) {
  1859. tldInput.tooltip('hide');
  1860. }
  1861. jQuery('input[name="domainoption"]').iCheck('disable');
  1862. domainLookupCallCount = 0;
  1863. btnSearchObj.attr('disabled', 'disabled').addClass('disabled');
  1864. jQuery('.domain-lookup-result').hide();
  1865. jQuery('#primaryLookupResult div').filter(function() {
  1866. return $(this).closest('#idnLanguageSelector').length === 0;
  1867. }).hide();
  1868. jQuery('#primaryLookupResult').find('.register-price-label').show().end()
  1869. .find('.transfer-price-label').hide();
  1870. jQuery('.domain-lookup-register-loader').hide();
  1871. jQuery('.domain-lookup-transfer-loader').hide();
  1872. jQuery('.domain-lookup-other-loader').hide();
  1873. if (domainoption == 'register') {
  1874. jQuery('.domain-lookup-register-loader').show();
  1875. } else if (domainoption == 'transfer') {
  1876. jQuery('.domain-lookup-transfer-loader').show();
  1877. } else {
  1878. jQuery('.domain-lookup-other-loader').show();
  1879. }
  1880. jQuery('.domain-lookup-loader').show();
  1881. suggestions.find('div:not(.actions)').hide().end()
  1882. .find('.clone').remove();
  1883. jQuery('div.panel-footer.more-suggestions').hide()
  1884. .find('a').show().end()
  1885. .find('span.no-more').hide();
  1886. jQuery('.btn-add-to-cart').removeAttr('disabled')
  1887. .find('span').hide().end()
  1888. .find('span.to-add').show();
  1889. btnDomainContinue.hide().attr('disabled', 'disabled');
  1890. if (domainoption != 'register') {
  1891. spotlightTlds.hide();
  1892. jQuery('.suggested-domains').hide();
  1893. }
  1894. if (!domainSearchResults.is(":visible")) {
  1895. domainSearchResults.fadeIn();
  1896. }
  1897. if (domainoption == 'register') {
  1898. spotlightTlds.fadeIn('fast');
  1899. jQuery('#resultDomainOption').val(domainoption);
  1900. var lookup = WHMCS.http.jqClient.post(
  1901. WHMCS.utils.getRouteUrl('/domain/check'),
  1902. {
  1903. token: csrfToken,
  1904. type: 'domain',
  1905. domain: sld + tld,
  1906. sld: sld,
  1907. tld: tld,
  1908. source: 'cartAddDomain'
  1909. },
  1910. 'json'
  1911. ),
  1912. spotlight = WHMCS.http.jqClient.post(
  1913. WHMCS.utils.getRouteUrl('/domain/check'),
  1914. {
  1915. token: csrfToken,
  1916. type: 'spotlight',
  1917. domain: sld + tld,
  1918. sld: sld,
  1919. tld: tld,
  1920. source: 'cartAddDomain'
  1921. },
  1922. 'json'
  1923. ),
  1924. suggestion = WHMCS.http.jqClient.post(
  1925. WHMCS.utils.getRouteUrl('/domain/check'),
  1926. {
  1927. token: csrfToken,
  1928. type: 'suggestions',
  1929. domain: sld + tld,
  1930. sld: sld,
  1931. tld: tld,
  1932. source: 'cartAddDomain'
  1933. },
  1934. 'json'
  1935. );
  1936. // primary lookup handler
  1937. lookup.done(function (data) {
  1938. jQuery.each(data.result, function(index, domain) {
  1939. var pricing = null,
  1940. result = jQuery('#primaryLookupResult'),
  1941. available = result.find('.domain-available'),
  1942. availablePrice = result.find('.domain-price'),
  1943. unavailable = result.find('.domain-unavailable'),
  1944. invalid= result.find('.domain-invalid'),
  1945. contactSupport = result.find('.domain-contact-support'),
  1946. resultDomain = jQuery('#resultDomain'),
  1947. resultDomainPricing = jQuery('#resultDomainPricingTerm'),
  1948. error = result.find('.domain-error');
  1949. result.show();
  1950. jQuery('.domain-lookup-primary-loader').hide();
  1951. if (typeof domain !== 'string' && !domain.error && domain.isValidDomain) {
  1952. error.hide();
  1953. pricing = domain.pricing;
  1954. if (domain.isAvailable && typeof pricing !== 'string') {
  1955. if (domain.domainName !== domain.idnDomainName && idnLanguage.not(':visible')) {
  1956. idnLanguage.slideDown();
  1957. }
  1958. if (domain.preferredTLDNotAvailable) {
  1959. unavailable.show().find('strong').html(domain.originalUnavailableDomain);
  1960. }
  1961. contactSupport.hide();
  1962. available.show().find('strong').html(domain.domainName);
  1963. availablePrice.show().find('span.price').html(pricing[Object.keys(pricing)[0]].register).end()
  1964. .find('button').attr('data-domain', domain.domainName);
  1965. resultDomain.val(domain.domainName);
  1966. resultDomainPricing.val(Object.keys(pricing)[0]).attr('name', 'domainsregperiod[' + domain.domainName +']');
  1967. btnDomainContinue.removeAttr('disabled');
  1968. } else {
  1969. unavailable.show().find('strong').html(domain.domainName);
  1970. contactSupport.hide();
  1971. if (typeof pricing === 'string' && pricing == 'ContactUs') {
  1972. contactSupport.show();
  1973. }
  1974. }
  1975. } else {
  1976. var done = false,
  1977. reg = /<br\s*\/>/,
  1978. errors = [];
  1979. if (!domain.isValidDomain && domain.domainErrorMessage) {
  1980. invalid.text(domain.domainErrorMessage);
  1981. } else if (domain.error || index === 'error') {
  1982. if (typeof domain === 'string') {
  1983. error.text(domain);
  1984. } else if (!domain.error.match(reg)) {
  1985. error.text(domain.error);
  1986. } else {
  1987. error.text('');
  1988. errors = domain.error.split(reg);
  1989. for(var i=0; i < errors.length; i++) {
  1990. var errorMsg = errors[i];
  1991. if (errorMsg.length) {
  1992. if (error.text()) {
  1993. // only add line break if there is
  1994. // multiple lines of text
  1995. error.append('<br />');
  1996. }
  1997. error.append(jQuery('<span></span>').text(errorMsg));
  1998. }
  1999. }
  2000. }
  2001. error.show();
  2002. done = true;
  2003. }
  2004. if (!done) {
  2005. invalid.show();
  2006. }
  2007. }
  2008. });
  2009. }).always(function() {
  2010. hasProductDomainLookupEnded(3, btnSearchObj);
  2011. });
  2012. // spotlight lookup handler
  2013. spotlight.done(function(data) {
  2014. if (typeof data != 'object' || data.result.length == 0 || data.result.error) {
  2015. jQuery('.domain-lookup-spotlight-loader').hide();
  2016. return;
  2017. }
  2018. jQuery.each(data.result, function(index, domain) {
  2019. var tld = domain.tldNoDots,
  2020. pricing = domain.pricing,
  2021. result = jQuery('#spotlight' + tld + ' .domain-lookup-result');
  2022. jQuery('.domain-lookup-spotlight-loader').hide();
  2023. result.find('button').hide();
  2024. if (domain.isValidDomain) {
  2025. if (domain.isAvailable && typeof pricing !== 'string') {
  2026. if (domain.domainName !== domain.idnDomainName && idnLanguage.not(':visible')) {
  2027. idnLanguage.slideDown();
  2028. }
  2029. result
  2030. .find('span.available').html(pricing[Object.keys(pricing)[0]].register).show().end()
  2031. .find('button.btn-add-to-cart')
  2032. .attr('data-domain', domain.domainName)
  2033. .show();
  2034. result.find('button.domain-contact-support').hide();
  2035. } else {
  2036. if (typeof pricing === 'string') {
  2037. if (pricing == '') {
  2038. result.find('button.unavailable').show();
  2039. } else {
  2040. result.find('button.domain-contact-support').show();
  2041. }
  2042. result.find('span.available').hide();
  2043. } else {
  2044. result.find('button.unavailable').show();
  2045. result.find('span.available').hide();
  2046. }
  2047. }
  2048. } else {
  2049. result.find('button.invalid:hidden').show().end()
  2050. .find('span.available').hide().end()
  2051. .find('button').not('button.invalid').hide();
  2052. }
  2053. result.show();
  2054. });
  2055. }).always(function() {
  2056. hasProductDomainLookupEnded(3, btnSearchObj);
  2057. });
  2058. // suggestions lookup handler
  2059. suggestion.done(function (data) {
  2060. if (typeof data != 'object' || data.result.length == 0 || data.result.error) {
  2061. jQuery('.suggested-domains').fadeOut('fast', function() {
  2062. jQuery(this).hide();
  2063. });
  2064. return;
  2065. } else {
  2066. jQuery('.suggested-domains').show();
  2067. }
  2068. var suggestionCount = 1;
  2069. jQuery.each(data.result, function(index, domain) {
  2070. var tld = domain.tld,
  2071. pricing = domain.pricing;
  2072. suggestions.find('div:first').clone(true, true).appendTo(suggestions);
  2073. var newSuggestion = suggestions.find('div.domain-suggestion').last();
  2074. newSuggestion.addClass('clone')
  2075. .find('span.domain').html(domain.sld).end()
  2076. .find('span.extension').html('.' + tld);
  2077. if (domain.domainName !== domain.idnDomainName && idnLanguage.not(':visible')) {
  2078. idnLanguage.slideDown();
  2079. }
  2080. if (typeof pricing === 'string') {
  2081. newSuggestion.find('button.btn-add-to-cart').remove();
  2082. if (pricing != '') {
  2083. newSuggestion.find('button.domain-contact-support').show().end()
  2084. .find('span.price').hide();
  2085. } else {
  2086. newSuggestion.remove();
  2087. }
  2088. } else {
  2089. newSuggestion.find('button.btn-add-to-cart').attr('data-domain', domain.domainName).end()
  2090. .find('span.price').html(pricing[Object.keys(pricing)[0]].register);
  2091. }
  2092. if (suggestionCount <= 10) {
  2093. newSuggestion.show();
  2094. }
  2095. suggestionCount++;
  2096. if (domain.group) {
  2097. newSuggestion.find('span.promo')
  2098. .addClass(domain.group)
  2099. .html(domain.group.toUpperCase())
  2100. .show();
  2101. }
  2102. furtherSuggestions = suggestions.find('div.domain-suggestion.clone').not(':visible').length;
  2103. if (furtherSuggestions > 0) {
  2104. jQuery('div.more-suggestions').show();
  2105. }
  2106. });
  2107. jQuery('.domain-lookup-suggestions-loader').hide();
  2108. jQuery('#domainSuggestions').show();
  2109. }).always(function() {
  2110. hasProductDomainLookupEnded(3, btnSearchObj);
  2111. });
  2112. } else if (domainoption == 'transfer') {
  2113. jQuery('#resultDomainOption').val(domainoption);
  2114. var transfer = WHMCS.http.jqClient.post(
  2115. WHMCS.utils.getRouteUrl('/domain/check'),
  2116. {
  2117. token: csrfToken,
  2118. type: 'transfer',
  2119. domain: sld + tld,
  2120. sld: sld,
  2121. tld: tld,
  2122. source: 'cartAddDomain'
  2123. },
  2124. 'json'
  2125. );
  2126. transfer.done(function (data) {
  2127. if (typeof data != 'object' || data.result.length == 0) {
  2128. jQuery('.domain-lookup-primary-loader').hide();
  2129. return;
  2130. }
  2131. var result = jQuery('#primaryLookupResult'),
  2132. transfereligible = result.find('.transfer-eligible'),
  2133. transferPrice = result.find('.domain-price'),
  2134. transfernoteligible = result.find('.transfer-not-eligible'),
  2135. resultDomain = jQuery('#resultDomain'),
  2136. resultDomainPricing = jQuery('#resultDomainPricingTerm');
  2137. if (Object.keys(data.result).length === 0) {
  2138. jQuery('.domain-lookup-primary-loader').hide();
  2139. result.show();
  2140. transfernoteligible.show();
  2141. }
  2142. jQuery.each(data.result, function(index, domain) {
  2143. var pricing = domain.pricing;
  2144. jQuery('.domain-lookup-primary-loader').hide();
  2145. result.show();
  2146. if (domain.isRegistered) {
  2147. transfereligible.show();
  2148. transferPrice.show().find('.register-price-label').hide().end()
  2149. .find('.transfer-price-label').show().end()
  2150. .find('span.price').html(pricing[Object.keys(pricing)[0]].transfer).end()
  2151. .find('button').attr('data-domain', domain.domainName);
  2152. resultDomain.val(domain.domainName);
  2153. resultDomainPricing.val(Object.keys(pricing)[0]).attr('name', 'domainsregperiod[' + domain.domainName +']');
  2154. btnDomainContinue.removeAttr('disabled');
  2155. } else {
  2156. transfernoteligible.show();
  2157. }
  2158. });
  2159. }).always(function() {
  2160. hasProductDomainLookupEnded(1, btnSearchObj);
  2161. });
  2162. } else if (domainoption == 'owndomain' || domainoption == 'subdomain' || domainoption == 'incart') {
  2163. var otherDomain = WHMCS.http.jqClient.post(
  2164. WHMCS.utils.getRouteUrl('/domain/check'),
  2165. {
  2166. token: csrfToken,
  2167. type: domainoption,
  2168. pid: pid,
  2169. domain: sld + tld,
  2170. sld: sld,
  2171. tld: tld,
  2172. source: 'cartAddDomain'
  2173. },
  2174. 'json'
  2175. );
  2176. otherDomain.done(function(data) {
  2177. if (typeof data != 'object' || data.result.length == 0) {
  2178. jQuery('.domain-lookup-subdomain-loader').hide();
  2179. return;
  2180. }
  2181. jQuery.each(data.result, function(index, result) {
  2182. if (result.status === true) {
  2183. window.location = 'cart.php?a=confproduct&i=' + result.num;
  2184. } else {
  2185. jQuery('.domain-lookup-primary-loader').hide();
  2186. if (typeof result === 'string') {
  2187. jQuery('#primaryLookupResult').show().find('.domain-error')
  2188. .text(result)
  2189. .show();
  2190. } else {
  2191. jQuery('#primaryLookupResult').show().find('.domain-invalid').show();
  2192. }
  2193. }
  2194. });
  2195. }).always(function(){
  2196. hasProductDomainLookupEnded(1, btnSearchObj);
  2197. });
  2198. }
  2199. btnDomainContinue.show();
  2200. });
  2201. jQuery('#frmProductDomainSelections').on('submit', function(e) {
  2202. var idnLanguage = jQuery('#idnLanguageSelector'),
  2203. idnLanguageInput = idnLanguage.find('select');
  2204. if (!idnLanguage.not(':visible') && !idnLanguageInput.val()) {
  2205. e.preventDefault();
  2206. idnLanguageInput.showInputError();
  2207. return false;
  2208. }
  2209. return true;
  2210. });
  2211. jQuery("#btnAlreadyRegistered").click(function() {
  2212. jQuery("#containerNewUserSignup").slideUp('', function() {
  2213. jQuery("#containerExistingUserSignin").slideDown('', function() {
  2214. jQuery("#inputCustType").val('existing');
  2215. jQuery("#btnAlreadyRegistered").fadeOut('', function() {
  2216. jQuery("#btnNewUserSignup").fadeIn();
  2217. });
  2218. });
  2219. });
  2220. jQuery("#containerNewUserSecurity").hide();
  2221. if (jQuery("#stateselect").attr('required')) {
  2222. jQuery("#stateselect").removeAttr('required').addClass('requiredAttributeRemoved');
  2223. }
  2224. jQuery('.marketing-email-optin').slideUp();
  2225. });
  2226. jQuery("#btnNewUserSignup").click(function() {
  2227. jQuery("#containerExistingUserSignin").slideUp('', function() {
  2228. jQuery("#containerNewUserSignup").slideDown('', function() {
  2229. jQuery("#inputCustType").val('new');
  2230. if (jQuery("#passwdFeedback").html().length == 0) {
  2231. jQuery("#containerNewUserSecurity").show();
  2232. }
  2233. jQuery("#btnNewUserSignup").fadeOut('', function() {
  2234. jQuery("#btnAlreadyRegistered").fadeIn();
  2235. });
  2236. });
  2237. jQuery('.marketing-email-optin').slideDown();
  2238. });
  2239. if (jQuery("#stateselect").hasClass('requiredAttributeRemoved')) {
  2240. jQuery("#stateselect").attr('required', 'required').removeClass('requiredAttributeRemoved');
  2241. }
  2242. });
  2243. jQuery("#btnExistingLogin").click(function() {
  2244. var inputLoginEmail = jQuery('#inputLoginEmail').val(),
  2245. inputLoginPassword = jQuery('#inputLoginPassword').val(),
  2246. existingLoginMessage = jQuery('#existingLoginMessage'),
  2247. btnExistingLogin = jQuery('#btnExistingLogin');
  2248. btnExistingLogin.prop('disabled', true)
  2249. .addClass('disabled')
  2250. .find('span').toggle();
  2251. WHMCS.http.jqClient.jsonPost({
  2252. url: WHMCS.utils.getRouteUrl('/login/cart'),
  2253. data: {
  2254. username: inputLoginEmail,
  2255. password: inputLoginPassword,
  2256. token: csrfToken
  2257. },
  2258. success: function (data) {
  2259. if (!data.redirectUrl) {
  2260. location.reload(true);
  2261. } else {
  2262. window.location.href = data.redirectUrl;
  2263. }
  2264. },
  2265. error: function (error) {
  2266. if (error) {
  2267. existingLoginMessage.slideUp('fast')
  2268. .toggle()
  2269. .html(error)
  2270. .slideDown('fast');
  2271. btnExistingLogin.prop('disabled', false)
  2272. .removeClass('disabled')
  2273. .find('span').toggle();
  2274. }
  2275. }
  2276. });
  2277. });
  2278. jQuery('.account-select').on('ifChecked', function(event) {
  2279. var userSignupContainer = jQuery('#containerNewUserSignup'),
  2280. stateSelect = jQuery("#stateselect"),
  2281. thisValue = jQuery(this).val(),
  2282. btnCompleteOrder = jQuery('#btnCompleteOrder'),
  2283. existingPayMethods = jQuery('#existingCardsContainer'),
  2284. existingUserEmail = jQuery('#inputEmail');
  2285. if (existingPayMethods.length) {
  2286. existingPayMethods.html('');
  2287. }
  2288. if (existingUserEmail.length) {
  2289. existingUserEmail.attr('value', '');
  2290. }
  2291. jQuery('#containerExistingAccountSelect')
  2292. .find('div.account.active')
  2293. .removeClass('active');
  2294. jQuery(this).closest('div.account').addClass('active');
  2295. if (thisValue === 'new') {
  2296. if (userSignupContainer.not(':visible')) {
  2297. userSignupContainer.slideDown('', function () {
  2298. jQuery("#inputCustType").val('add');
  2299. jQuery('.marketing-email-optin').slideDown();
  2300. });
  2301. if (stateSelect.hasClass('requiredAttributeRemoved')) {
  2302. stateSelect.attr('required', 'required')
  2303. .removeClass('requiredAttributeRemoved');
  2304. }
  2305. }
  2306. } else {
  2307. btnCompleteOrder.addClass('disabled');
  2308. if (btnCompleteOrder.hasClass('spinner-on-click')) {
  2309. var icon = btnCompleteOrder.find('i.fas,i.far,i.fal,i.fab');
  2310. jQuery(icon)
  2311. .data('original-class', icon.attr('class'))
  2312. .removeAttr('class')
  2313. .addClass('fas fa-spinner fa-spin');
  2314. }
  2315. jQuery("#inputCustType").val('account');
  2316. if (userSignupContainer.is(':visible')) {
  2317. userSignupContainer.slideUp();
  2318. if (stateSelect.attr('required')) {
  2319. stateSelect.removeAttr('required')
  2320. .addClass('requiredAttributeRemoved');
  2321. }
  2322. jQuery('.marketing-email-optin').slideUp();
  2323. }
  2324. }
  2325. WHMCS.http.jqClient.jsonPost({
  2326. url: WHMCS.utils.getRouteUrl('/cart/account/select'),
  2327. data: {
  2328. account_id: thisValue,
  2329. token: csrfToken
  2330. },
  2331. success: function(data) {
  2332. var creditDiv = jQuery('#applyCreditContainer');
  2333. jQuery('#totalCartPrice').text(data.total);
  2334. creditDiv.find('p').first().text(data.availableCreditBalance);
  2335. if (!data.canUseCreditOnCheckout && creditDiv.is(':visible')) {
  2336. var skipCreditOnCheckout = jQuery('#skipCreditOnCheckout');
  2337. creditDiv.hide();
  2338. skipCreditOnCheckout.prop('checked', true);
  2339. } else if (data.canUseCreditOnCheckout) {
  2340. var useCreditOnCheckout = jQuery('#useCreditOnCheckout'),
  2341. spanFullCredit = jQuery('#spanFullCredit'),
  2342. spanUseCredit = jQuery('#spanUseCredit');
  2343. if (data.full) {
  2344. spanFullCredit.show().find('span').text(data.creditBalance);
  2345. if (spanUseCredit.is(':visible')) {
  2346. spanUseCredit.slideDown();
  2347. }
  2348. } else {
  2349. spanUseCredit.show().find('span').text(data.creditBalance);
  2350. if (spanFullCredit.is(':visible')) {
  2351. spanFullCredit.slideUp();
  2352. }
  2353. }
  2354. useCreditOnCheckout.iCheck('check');
  2355. if (creditDiv.not(':visible')) {
  2356. creditDiv.slideDown();
  2357. }
  2358. }
  2359. if (existingPayMethods.length) {
  2360. existingPayMethods.html(data.existingCards);
  2361. existingPayMethods.find('input[type="radio"]').iCheck({
  2362. inheritID: true,
  2363. checkboxClass: 'icheckbox_square-blue',
  2364. radioClass: 'iradio_square-blue',
  2365. increaseArea: '20%'
  2366. });
  2367. var firstVisible = jQuery('input[name="ccinfo"]:visible').first();
  2368. if (firstVisible.length) {
  2369. firstVisible.iCheck('check');
  2370. }
  2371. }
  2372. },
  2373. always: function() {
  2374. btnCompleteOrder.removeClass('disabled');
  2375. if (btnCompleteOrder.hasClass('spinner-on-click')) {
  2376. var icon = btnCompleteOrder.find('i.fas,i.far,i.fal,i.fab');
  2377. if (jQuery(icon).hasClass('fa-spinner')) {
  2378. jQuery(icon)
  2379. .removeAttr('class')
  2380. .addClass(icon.data('original-class'));
  2381. }
  2382. }
  2383. }
  2384. });
  2385. });
  2386. var existingCards = jQuery(document).find('.existing-card'),
  2387. cvvFieldContainer = jQuery('#cvv-field-container'),
  2388. existingCardContainer = jQuery('#existingCardsContainer'),
  2389. newCardInfo = jQuery('#newCardInfo'),
  2390. newCardSaveSettings = jQuery('#newCardSaveSettings'),
  2391. inputNoStoreContainer = jQuery('#inputNoStoreContainer'),
  2392. existingCardInfo = jQuery('#existingCardInfo'),
  2393. newCardOption = jQuery('#new'),
  2394. creditCardInputFields = jQuery('#creditCardInputFields');
  2395. jQuery(document).on('ifChecked', '.existing-card', function(event) {
  2396. newCardSaveSettings.slideUp().find('input').attr('disabled', 'disabled');
  2397. if (jQuery('.payment-methods:checked').data('remote-inputs') === 1) {
  2398. return;
  2399. }
  2400. newCardInfo.slideUp().find('input').attr('disabled', 'disabled');
  2401. existingCardInfo.slideDown().find('input').removeAttr('disabled');
  2402. });
  2403. newCardOption.on('ifChecked', function(event) {
  2404. newCardSaveSettings.slideDown().find('input').removeAttr('disabled');
  2405. if (jQuery('.payment-methods:checked').data('remote-inputs') === 1) {
  2406. return;
  2407. }
  2408. newCardInfo.slideDown().find('input').removeAttr('disabled');
  2409. existingCardInfo.slideUp().find('input').attr('disabled', 'disabled');
  2410. });
  2411. if (!existingCards.length) {
  2412. existingCardInfo.slideUp().find('input').attr('disabled', 'disabled');
  2413. }
  2414. jQuery(".payment-methods").on('ifChecked', function(event) {
  2415. if (jQuery(this).hasClass('is-credit-card')) {
  2416. var gatewayPaymentType = jQuery(this).data('payment-type'),
  2417. gatewayModule = jQuery(this).val(),
  2418. showLocal = jQuery(this).data('show-local'),
  2419. relevantMethods = [];
  2420. if (gatewayPaymentType === 'RemoteCreditCard') {
  2421. inputNoStoreContainer.hide().find('input').prop('disabled', 'disabled');
  2422. } else {
  2423. if (inputNoStoreContainer.not(':visible')) {
  2424. inputNoStoreContainer.slideDown().find('input').removeProp('disabled');
  2425. }
  2426. }
  2427. existingCards.each(function(index) {
  2428. var paymentType = jQuery(this).data('payment-type'),
  2429. paymentModule = jQuery(this).data('payment-gateway'),
  2430. payMethodId = jQuery(this).val();
  2431. var paymentTypeMatch = (paymentType === gatewayPaymentType);
  2432. var paymentModuleMatch = false;
  2433. if (gatewayPaymentType === 'RemoteCreditCard') {
  2434. // only show remote credit cards that belong to the selected gateway
  2435. paymentModuleMatch = (paymentModule === gatewayModule);
  2436. } else if (gatewayPaymentType === 'CreditCard') {
  2437. // any local credit card can be used with any credit card gateway
  2438. paymentModuleMatch = true;
  2439. }
  2440. if (showLocal && paymentType === 'CreditCard') {
  2441. paymentTypeMatch = true;
  2442. paymentModuleMatch = true;
  2443. }
  2444. var payMethodElements = jQuery('[data-paymethod-id="' + payMethodId + '"]');
  2445. if (paymentTypeMatch && paymentModuleMatch) {
  2446. jQuery(payMethodElements).show();
  2447. relevantMethods.push(this);
  2448. } else {
  2449. jQuery(payMethodElements).hide();
  2450. }
  2451. });
  2452. var enabledRelevantMethods = relevantMethods.filter(function (item) {
  2453. return ! jQuery(item).attr('disabled');
  2454. });
  2455. if (enabledRelevantMethods.length > 0) {
  2456. var defaultId = null;
  2457. jQuery.each(enabledRelevantMethods, function(index, value) {
  2458. var jQueryElement = jQuery(value),
  2459. order = parseInt(jQueryElement.data('order-preference'), 10);
  2460. if ((defaultId === null) || (order < defaultId)) {
  2461. defaultId = jQueryElement.val();
  2462. if (order === 0) {
  2463. return false;
  2464. }
  2465. }
  2466. });
  2467. if (defaultId === null) {
  2468. defaultId = 'new';
  2469. }
  2470. jQuery.each(enabledRelevantMethods, function(index, value) {
  2471. var jQueryElement = jQuery(value);
  2472. if (jQueryElement.val() === defaultId) {
  2473. jQueryElement.iCheck('check');
  2474. return false;
  2475. }
  2476. });
  2477. existingCardContainer.show();
  2478. existingCardInfo.show().find('input').removeAttr('disabled');
  2479. } else {
  2480. jQuery(newCardOption).iCheck('check');
  2481. existingCardContainer.hide();
  2482. existingCardInfo.hide().find('input').attr('disabled', 'disabled');
  2483. }
  2484. if (!creditCardInputFields.is(":visible")) {
  2485. creditCardInputFields.slideDown();
  2486. }
  2487. } else {
  2488. creditCardInputFields.slideUp();
  2489. }
  2490. });
  2491. // make sure relevant payment methods are displayed for the pre-selected gateway
  2492. jQuery(".payment-methods:checked").trigger('ifChecked');
  2493. jQuery('.cc-input-container .paymethod-info').click(function() {
  2494. var payMethodId = $(this).data('paymethod-id');
  2495. var input = jQuery('input[name="ccinfo"][value=' + payMethodId + ']:not(:disabled)');
  2496. if (input.length > 0) {
  2497. input.iCheck('check');
  2498. }
  2499. });
  2500. jQuery("#inputDomainContact").on('change', function() {
  2501. var thisInput = jQuery(this);
  2502. if (this.value === "addingnew") {
  2503. thisInput.closest('div').addClass('pb-2');
  2504. jQuery("#domainRegistrantInputFields").parent('div').slideDown();
  2505. } else {
  2506. jQuery("#domainRegistrantInputFields").parent('div').slideUp(function () {
  2507. thisInput.closest('div').removeClass('pb-2');
  2508. });
  2509. }
  2510. });
  2511. if (typeof registerFormPasswordStrengthFeedback == 'function') {
  2512. jQuery("#inputNewPassword1").keyup(registerFormPasswordStrengthFeedback);
  2513. } else {
  2514. jQuery("#inputNewPassword1").keyup(function ()
  2515. {
  2516. passwordStrength = getPasswordStrength(jQuery(this).val());
  2517. if (passwordStrength >= 75) {
  2518. textLabel = langPasswordStrong;
  2519. cssClass = 'success';
  2520. } else
  2521. if (passwordStrength >= 30) {
  2522. textLabel = langPasswordModerate;
  2523. cssClass = 'warning';
  2524. } else {
  2525. textLabel = langPasswordWeak;
  2526. cssClass = 'danger';
  2527. }
  2528. jQuery("#passwordStrengthTextLabel").html(langPasswordStrength + ': ' + passwordStrength + '% ' + textLabel);
  2529. jQuery("#passwordStrengthMeterBar").css(
  2530. 'width',
  2531. passwordStrength + '%'
  2532. ).attr('aria-valuenow', passwordStrength);
  2533. jQuery("#passwordStrengthMeterBar").removeClass(
  2534. 'progress-bar-success progress-bar-warning progress-bar-danger').addClass(
  2535. 'progress-bar-' + cssClass);
  2536. });
  2537. }
  2538. jQuery('#inputDomain').on('shown.bs.tooltip', function () {
  2539. setTimeout(function(input) {
  2540. input.tooltip('hide');
  2541. },
  2542. 5000,
  2543. jQuery(this)
  2544. );
  2545. });
  2546. jQuery('#frmDomainChecker').submit(function (e) {
  2547. e.preventDefault();
  2548. var frmDomain = jQuery('#frmDomainChecker'),
  2549. inputDomain = jQuery('#inputDomain'),
  2550. suggestions = jQuery('#domainSuggestions'),
  2551. reCaptchaContainer = jQuery('#divDynamicRecaptcha'),
  2552. captcha = jQuery('#inputCaptcha'),
  2553. idnLanguage = jQuery('#idnLanguageSelector');
  2554. jQuery('.field-error-msg').hide();
  2555. if (idnLanguage.is(':visible')) {
  2556. idnLanguage.slideUp();
  2557. idnLanguage.find('select').val('');
  2558. }
  2559. domainLookupCallCount = 0;
  2560. // check a domain has been entered
  2561. if (!inputDomain.val()) {
  2562. inputDomain.tooltip('show');
  2563. inputDomain.focus();
  2564. return;
  2565. }
  2566. inputDomain.tooltip('hide');
  2567. if (jQuery('#captchaContainer').length) {
  2568. validate_captcha(frmDomain);
  2569. return;
  2570. }
  2571. reCaptchaContainer.tooltip('hide');
  2572. captcha.tooltip('hide');
  2573. // disable repeat submit and show loader
  2574. jQuery('#btnCheckAvailability').attr('disabled', 'disabled').addClass('disabled');
  2575. jQuery('.domain-lookup-result').hide();
  2576. jQuery('.domain-lookup-loader').show();
  2577. // reset elements
  2578. suggestions.find('div:not(.actions)').hide();
  2579. suggestions.find('.clone').remove();
  2580. jQuery('div.panel-footer.more-suggestions').hide()
  2581. .find('a').show().end()
  2582. .find('span.no-more').hide();
  2583. jQuery('.btn-add-to-cart').removeAttr('disabled')
  2584. .find('span').hide().end()
  2585. .find('span.to-add').show();
  2586. // fade in results
  2587. if (jQuery('#DomainSearchResults').not(":visible")) {
  2588. jQuery('.domain-pricing').fadeOut('fast', function() {
  2589. jQuery('#DomainSearchResults').fadeIn();
  2590. });
  2591. }
  2592. var lookup = WHMCS.http.jqClient.post(
  2593. WHMCS.utils.getRouteUrl('/domain/check'),
  2594. frmDomain.serialize() + '&type=domain',
  2595. 'json'
  2596. ),
  2597. spotlight = WHMCS.http.jqClient.post(
  2598. WHMCS.utils.getRouteUrl('/domain/check'),
  2599. frmDomain.serialize() + '&type=spotlight',
  2600. 'json'
  2601. ),
  2602. suggestion = WHMCS.http.jqClient.post(
  2603. WHMCS.utils.getRouteUrl('/domain/check'),
  2604. frmDomain.serialize() + '&type=suggestions',
  2605. 'json'
  2606. );
  2607. // primary lookup handler
  2608. lookup.done(function (data) {
  2609. if (typeof data != 'object' || data.result.length == 0) {
  2610. jQuery('.domain-lookup-primary-loader').hide();
  2611. return;
  2612. }
  2613. jQuery.each(data.result, function(index, domain) {
  2614. var pricing = null,
  2615. result = jQuery('#primaryLookupResult'),
  2616. available = result.find('.domain-available'),
  2617. availablePrice = result.find('.domain-price'),
  2618. contactSupport = result.find('.domain-contact-support'),
  2619. unavailable = result.find('.domain-unavailable'),
  2620. invalid = result.find('.domain-invalid'),
  2621. error = result.find('.domain-error');
  2622. jQuery('.domain-lookup-primary-loader').hide();
  2623. result.find('.btn-add-to-cart').removeClass('checkout');
  2624. result.show();
  2625. if (typeof domain !== 'string' && !domain.error && domain.isValidDomain) {
  2626. pricing = domain.pricing;
  2627. unavailable.hide();
  2628. contactSupport.hide();
  2629. invalid.hide();
  2630. error.hide();
  2631. if (domain.isAvailable && typeof pricing !== 'string') {
  2632. if (domain.domainName !== domain.idnDomainName && idnLanguage.not(':visible')) {
  2633. idnLanguage.slideDown();
  2634. }
  2635. if (domain.preferredTLDNotAvailable) {
  2636. unavailable.show().find('strong').html(domain.originalUnavailableDomain);
  2637. }
  2638. available.show().find('strong').html(domain.domainName);
  2639. availablePrice.show().find('span.price').html(pricing[Object.keys(pricing)[0]].register).end()
  2640. .find('button').attr('data-domain', domain.domainName);
  2641. } else {
  2642. available.hide();
  2643. availablePrice.hide();
  2644. contactSupport.hide();
  2645. unavailable.show().find('strong').html(domain.domainName);
  2646. if (typeof pricing === 'string' && pricing == 'ContactUs') {
  2647. contactSupport.show();
  2648. }
  2649. }
  2650. } else {
  2651. available.hide();
  2652. availablePrice.hide();
  2653. unavailable.hide();
  2654. contactSupport.hide();
  2655. invalid.hide();
  2656. error.hide();
  2657. var done = false,
  2658. reg = /<br\s*\/>/,
  2659. errors = [];
  2660. if (!domain.isValidDomain && domain.domainErrorMessage) {
  2661. invalid.text(domain.domainErrorMessage);
  2662. } else if (domain.error || index === 'error') {
  2663. if (typeof domain === 'string') {
  2664. error.text(domain);
  2665. } else if (!domain.error.match(reg)) {
  2666. error.text(domain.error);
  2667. } else {
  2668. error.text('');
  2669. errors = domain.error.split(reg);
  2670. for(var i=0; i < errors.length; i++) {
  2671. var errorMsg = errors[i];
  2672. if (errorMsg.length) {
  2673. if (error.text()) {
  2674. // only add line break if there is
  2675. // multiple lines of text
  2676. error.append('<br />');
  2677. }
  2678. error.append(jQuery('<span></span>').text(errorMsg));
  2679. }
  2680. }
  2681. }
  2682. error.show();
  2683. done = true;
  2684. }
  2685. if (!done) {
  2686. invalid.show();
  2687. }
  2688. }
  2689. });
  2690. }).always(function() {
  2691. hasDomainLookupEnded();
  2692. });
  2693. // spotlight lookup handler
  2694. spotlight.done(function(data) {
  2695. if (typeof data != 'object' || data.result.length == 0 || data.result.error) {
  2696. jQuery('.domain-lookup-spotlight-loader').hide();
  2697. return;
  2698. }
  2699. jQuery.each(data.result, function(index, domain) {
  2700. var tld = domain.tldNoDots,
  2701. pricing = domain.pricing,
  2702. result = jQuery('#spotlight' + tld + ' .domain-lookup-result');
  2703. jQuery('.domain-lookup-spotlight-loader').hide();
  2704. result.find('button').hide();
  2705. if (domain.isValidDomain) {
  2706. if (domain.isAvailable && typeof pricing !== 'string') {
  2707. if (domain.domainName !== domain.idnDomainName && idnLanguage.not(':visible')) {
  2708. idnLanguage.slideDown();
  2709. }
  2710. result.find('button.unavailable').hide().end()
  2711. .find('button.invalid').hide().end()
  2712. .find('span.available').html(pricing[Object.keys(pricing)[0]].register).show().end()
  2713. .find('button').not('button.unavailable').not('button.invalid')
  2714. .attr('data-domain', domain.domainName)
  2715. .show();
  2716. result.find('button.domain-contact-support').hide();
  2717. } else {
  2718. if (typeof pricing === 'string') {
  2719. if (pricing == '') {
  2720. result.find('button.unavailable').show();
  2721. } else {
  2722. result.find('button.domain-contact-support').show();
  2723. }
  2724. result.find('button.invalid').hide();
  2725. result.find('span.available').hide();
  2726. } else {
  2727. result.find('button.invalid').hide().end()
  2728. .find('button.unavailable').show().end()
  2729. .find('span.available').hide();
  2730. }
  2731. }
  2732. } else {
  2733. result.find('button.invalid:hidden').show().end()
  2734. .find('span.available').hide().end()
  2735. .find('button').not('button.invalid').hide();
  2736. }
  2737. result.show();
  2738. });
  2739. }).always(function() {
  2740. hasDomainLookupEnded();
  2741. });
  2742. // suggestions lookup handler
  2743. suggestion.done(function (data) {
  2744. if (typeof data != 'object' || data.result.length == 0 || data.result.error) {
  2745. jQuery('.suggested-domains').fadeOut('fast', function() {
  2746. jQuery(this).hide();
  2747. });
  2748. return;
  2749. } else {
  2750. jQuery('.suggested-domains').show();
  2751. }
  2752. var suggestionCount = 1;
  2753. jQuery.each(data.result, function(index, domain) {
  2754. var tld = domain.tld,
  2755. pricing = domain.pricing;
  2756. suggestions.find('div:first').clone(true, true).appendTo(suggestions);
  2757. var newSuggestion = suggestions.find('div.domain-suggestion').last();
  2758. newSuggestion.addClass('clone')
  2759. .find('span.domain').html(domain.sld).end()
  2760. .find('span.extension').html('.' + tld);
  2761. if (typeof pricing === 'string') {
  2762. newSuggestion.find('button.btn-add-to-cart').remove();
  2763. if (pricing != '') {
  2764. newSuggestion.find('button.domain-contact-support').show().end()
  2765. .find('span.price').hide();
  2766. } else {
  2767. newSuggestion.remove();
  2768. }
  2769. } else {
  2770. if (domain.domainName !== domain.idnDomainName && idnLanguage.not(':visible')) {
  2771. idnLanguage.slideDown();
  2772. }
  2773. newSuggestion.find('button.btn-add-to-cart').attr('data-domain', domain.domainName).end()
  2774. .find('span.price').html(pricing[Object.keys(pricing)[0]].register);
  2775. }
  2776. if (suggestionCount <= 10) {
  2777. newSuggestion.show();
  2778. }
  2779. suggestionCount++;
  2780. if (domain.group) {
  2781. newSuggestion.find('span.promo')
  2782. .addClass(domain.group)
  2783. .show();
  2784. newSuggestion.find('span.sales-group-' + domain.group)
  2785. .show();
  2786. }
  2787. furtherSuggestions = suggestions.find('div.domain-suggestion.clone:hidden').length;
  2788. if (furtherSuggestions > 0) {
  2789. jQuery('div.more-suggestions').show();
  2790. }
  2791. });
  2792. jQuery('.domain-lookup-suggestions-loader').hide();
  2793. jQuery('#domainSuggestions').show();
  2794. }).always(function() {
  2795. hasDomainLookupEnded();
  2796. });
  2797. });
  2798. jQuery('.btn-add-to-cart').on('click', function() {
  2799. if (jQuery(this).hasClass('checkout')) {
  2800. window.location = 'cart.php?a=confdomains';
  2801. return;
  2802. }
  2803. var domain = jQuery(this).attr('data-domain'),
  2804. buttons = jQuery('button[data-domain="' + domain + '"]'),
  2805. whois = jQuery(this).attr('data-whois'),
  2806. isProductDomain = jQuery(this).hasClass('product-domain'),
  2807. btnDomainContinue = jQuery('#btnDomainContinue'),
  2808. resultDomain = jQuery('#resultDomain'),
  2809. resultDomainPricing = jQuery('#resultDomainPricingTerm'),
  2810. idnLanguage = jQuery('#idnLanguageSelector'),
  2811. idnLanguageInput = idnLanguage.find('select');
  2812. if (idnLanguage.is(':visible') && !idnLanguageInput.val()) {
  2813. idnLanguageInput.showInputError();
  2814. return;
  2815. }
  2816. buttons.find('span.to-add').hide();
  2817. buttons.find('span.loading').show();
  2818. var sideOrder =
  2819. ((jQuery(this).parents('.spotlight-tlds').length > 0)
  2820. ||
  2821. (jQuery(this).parents('.suggested-domains').length > 0)) ? 1 : 0;
  2822. var addToCart = WHMCS.http.jqClient.post(
  2823. window.location.pathname,
  2824. {
  2825. a: 'addToCart',
  2826. domain: domain,
  2827. token: csrfToken,
  2828. whois: whois,
  2829. sideorder: sideOrder,
  2830. idnlanguage: idnLanguageInput.val()
  2831. },
  2832. 'json'
  2833. ).done(function (data) {
  2834. buttons.find('span.loading').hide();
  2835. if (data.result === 'added') {
  2836. buttons.find('span.added').show();
  2837. if (!isProductDomain) {
  2838. buttons.removeAttr('disabled').addClass('checkout');
  2839. }
  2840. if (resultDomain.length && !resultDomain.val()) {
  2841. resultDomain.val(domain);
  2842. resultDomainPricing.val(data.period).attr('name', 'domainsregperiod[' + domain +']');
  2843. if (btnDomainContinue.length > 0 && btnDomainContinue.is(':disabled')) {
  2844. btnDomainContinue.removeAttr('disabled');
  2845. }
  2846. }
  2847. jQuery('#cartItemCount').html(data.cartCount);
  2848. } else {
  2849. buttons.find('span.available.price').hide();
  2850. buttons.find('span.unavailable').show();
  2851. buttons.attr('disabled', 'disabled');
  2852. }
  2853. });
  2854. });
  2855. jQuery('#frmDomainTransfer').submit(function (e) {
  2856. e.preventDefault();
  2857. var frmDomain = jQuery('#frmDomainTransfer'),
  2858. transferButton = jQuery('#btnTransferDomain'),
  2859. inputDomain = jQuery('#inputTransferDomain'),
  2860. authField = jQuery('#inputAuthCode'),
  2861. domain = inputDomain.val(),
  2862. authCode = authField.val(),
  2863. redirect = false,
  2864. reCaptchaContainer = jQuery('#divDynamicRecaptcha'),
  2865. captcha = jQuery('#inputCaptcha');
  2866. if (!domain) {
  2867. inputDomain.tooltip('show');
  2868. inputDomain.focus();
  2869. return false;
  2870. }
  2871. inputDomain.tooltip('hide');
  2872. if (jQuery('#captchaContainer').length) {
  2873. validate_captcha(frmDomain);
  2874. return;
  2875. }
  2876. reCaptchaContainer.tooltip('hide');
  2877. captcha.tooltip('hide');
  2878. transferButton.attr('disabled', 'disabled').addClass('disabled')
  2879. .find('span').show().end()
  2880. .find('.loader').show();
  2881. WHMCS.http.jqClient.post(
  2882. frmDomain.attr('action'),
  2883. frmDomain.serialize(),
  2884. null,
  2885. 'json'
  2886. ).done(function (data) {
  2887. if (typeof data != 'object') {
  2888. transferButton.find('span').hide().end()
  2889. .find('#addToCart').show().end()
  2890. .removeAttr('disabled').removeClass('disabled');
  2891. return false;
  2892. }
  2893. var result = data.result;
  2894. if (result == 'added') {
  2895. window.location = 'cart.php?a=confdomains';
  2896. redirect = true;
  2897. } else {
  2898. if (result.isRegistered == true) {
  2899. if (result.epp == true && !authCode) {
  2900. authField.tooltip('show');
  2901. authField.focus();
  2902. }
  2903. } else {
  2904. jQuery('#transferUnavailable').html(result.unavailable)
  2905. .fadeIn('fast', function() {
  2906. setTimeout(function(input) {
  2907. input.fadeOut('fast');
  2908. },
  2909. 3000,
  2910. jQuery(this)
  2911. );
  2912. }
  2913. );
  2914. }
  2915. }
  2916. }).always(function () {
  2917. if (redirect == false) {
  2918. transferButton.find('span').hide().end()
  2919. .find('#addToCart').show().end()
  2920. .removeAttr('disabled').removeClass('disabled');
  2921. }
  2922. });
  2923. });
  2924. jQuery("#btnEmptyCart").click(function() {
  2925. jQuery('#modalEmptyCart').modal('show');
  2926. });
  2927. jQuery("#cardType li a").click(function (e) {
  2928. e.preventDefault();
  2929. jQuery("#selectedCardType").html(jQuery(this).html());
  2930. jQuery("#cctype").val(jQuery('span.type', this).html().trim());
  2931. });
  2932. jQuery(document).on('click', '.domain-contact-support', function(e) {
  2933. e.preventDefault();
  2934. var child = window.open();
  2935. child.opener = null;
  2936. child.location = 'submitticket.php';
  2937. });
  2938. jQuery('#frmConfigureProduct input:visible, #frmConfigureProduct select:visible').first().focus();
  2939. jQuery('#frmProductDomain input[type=text]:visible').first().focus();
  2940. jQuery('#frmDomainChecker input[type=text]:visible').first().focus();
  2941. jQuery('#frmDomainTransfer input[type=text]:visible').first().focus();
  2942. jQuery('.checkout .mc-promo .btn-add').click(function(e) {
  2943. var self = jQuery(this),
  2944. productKey = self.data('product-key'),
  2945. upSellBox = jQuery('#promo_' + productKey);
  2946. self.attr('disabled', 'disabled')
  2947. .find('span.arrow i').removeClass('fa-chevron-right').addClass('fa-spinner fa-spin');
  2948. WHMCS.http.jqClient.post(
  2949. window.location.pathname,
  2950. {
  2951. 'a': 'addUpSell',
  2952. 'product_key': productKey,
  2953. 'checkoutModal': true,
  2954. 'token': csrfToken
  2955. },
  2956. function (data) {
  2957. if (typeof data.modal !== 'undefined') {
  2958. openModal(
  2959. data.modal,
  2960. '',
  2961. data.modalTitle,
  2962. '',
  2963. '',
  2964. data.modalSubmit,
  2965. data.modelSubmitId
  2966. );
  2967. return;
  2968. }
  2969. if (data.done) {
  2970. jQuery('#totalCartPrice').text(data.newTotal);
  2971. upSellBox.fadeOut();
  2972. }
  2973. },
  2974. 'json'
  2975. );
  2976. });
  2977. jQuery('.viewcart .mc-promo .btn-add').click(function(e) {
  2978. var self = jQuery(this);
  2979. self.attr('disabled', 'disabled')
  2980. .find('span.arrow i').removeClass('fa-chevron-right').addClass('fa-spinner fa-spin');
  2981. WHMCS.http.jqClient.post(
  2982. window.location.pathname,
  2983. {
  2984. 'a': 'addUpSell',
  2985. 'product_key': self.data('product-key'),
  2986. 'token': csrfToken
  2987. },
  2988. function (data) {
  2989. if (typeof data.modal !== 'undefined') {
  2990. openModal(
  2991. data.modal,
  2992. '',
  2993. data.modalTitle,
  2994. '',
  2995. '',
  2996. data.modalSubmit,
  2997. data.modelSubmitId
  2998. );
  2999. return;
  3000. }
  3001. window.location.reload(true);
  3002. },
  3003. 'json'
  3004. );
  3005. });
  3006. jQuery(document).on('click', '#btnAddUpSellCheckout', function(e) {
  3007. var upsellModalForm = jQuery('#upsellModalForm');
  3008. WHMCS.http.jqClient.post(
  3009. 'cart.php',
  3010. upsellModalForm.serialize(),
  3011. function (data) {
  3012. if (data.done){
  3013. jQuery('#totalCartPrice').text(data.newTotal);
  3014. }
  3015. },
  3016. 'json'
  3017. );
  3018. return false;
  3019. });
  3020. jQuery(document).on('click', '#btnAddUpSell', function(e) {
  3021. needRefresh = true;
  3022. });
  3023. var useFullCreditOnCheckout = jQuery('#iCheck-useFullCreditOnCheckout'),
  3024. skipCreditOnCheckout = jQuery('#iCheck-skipCreditOnCheckout');
  3025. useFullCreditOnCheckout.on('ifChecked', function() {
  3026. var radio = jQuery('#useFullCreditOnCheckout'),
  3027. selectedPaymentMethod = jQuery('input[name="paymentmethod"]:checked'),
  3028. isCcSelected = selectedPaymentMethod.hasClass('is-credit-card'),
  3029. firstNonCcGateway = jQuery('input[name="paymentmethod"]')
  3030. .not(jQuery('input.is-credit-card[name="paymentmethod"]'))
  3031. .first(),
  3032. container = jQuery('#paymentGatewaysContainer'),
  3033. ccInputFields = jQuery('#creditCardInputFields');
  3034. if (radio.prop('checked')) {
  3035. if (isCcSelected && firstNonCcGateway.length !== 0) {
  3036. firstNonCcGateway.iCheck('check');
  3037. ccInputFields.slideUp();
  3038. container.slideUp();
  3039. } else if (isCcSelected && !container.is(":visible")) {
  3040. ccInputFields.slideDown();
  3041. container.slideDown();
  3042. }
  3043. }
  3044. });
  3045. skipCreditOnCheckout.on('ifChecked', function() {
  3046. var selectedPaymentMethod = jQuery('input[name="paymentmethod"]:checked'),
  3047. isCcSelected = selectedPaymentMethod.hasClass('is-credit-card'),
  3048. container = jQuery('#paymentGatewaysContainer');
  3049. if (!container.is(":visible")) {
  3050. container.slideDown();
  3051. if (isCcSelected) {
  3052. jQuery('#creditCardInputFields').slideDown();
  3053. }
  3054. }
  3055. });
  3056. if (jQuery('#applyCreditContainer').data('apply-credit') === 1 && useFullCreditOnCheckout.length) {
  3057. skipCreditOnCheckout.iCheck('check');
  3058. useFullCreditOnCheckout.iCheck('check');
  3059. }
  3060. jQuery('#domainRenewals').find('span.added').hide().end().find('span.to-add').find('i').hide();
  3061. jQuery('.btn-add-renewal-to-cart').on('click', function() {
  3062. var self = jQuery(this),
  3063. domainId = self.data('domain-id'),
  3064. period = jQuery('#renewalPricing' + domainId).val();
  3065. if (self.hasClass('checkout')) {
  3066. window.location = 'cart.php?a=view';
  3067. return;
  3068. }
  3069. self.attr('disabled', 'disabled').each(function() {
  3070. jQuery(this).find('i').fadeIn('fast').end().css('width', jQuery(this).outerWidth());
  3071. });
  3072. WHMCS.http.jqClient.post(
  3073. WHMCS.utils.getRouteUrl('/cart/domain/renew/add'),
  3074. {
  3075. domainId: domainId,
  3076. period: period,
  3077. token: csrfToken
  3078. },
  3079. null,
  3080. 'json'
  3081. ).done(function (data) {
  3082. self.find('span.to-add').hide();
  3083. if (data.result === 'added') {
  3084. self.find('span.added').show().end().find('i').fadeOut('fast').css('width', self.outerWidth());
  3085. }
  3086. recalculateRenewalTotals();
  3087. });
  3088. });
  3089. jQuery(document).on('submit', '#removeRenewalForm', function(e) {
  3090. e.preventDefault();
  3091. WHMCS.http.jqClient.post(
  3092. whmcsBaseUrl + '/cart.php',
  3093. jQuery(this).serialize() + '&ajax=1'
  3094. ).done(function(data) {
  3095. var domainId = data.i,
  3096. button = jQuery('#renewDomain' + domainId);
  3097. button.attr('disabled', 'disabled').each(function() {
  3098. jQuery(this).find('span.added').hide().end()
  3099. .removeClass('checkout').find('span.to-add').show().end().removeAttr('disabled');
  3100. jQuery(this).css('width', jQuery(this).outerWidth());
  3101. });
  3102. }).always(function () {
  3103. jQuery('#modalRemoveItem').modal('hide');
  3104. recalculateRenewalTotals();
  3105. });
  3106. });
  3107. jQuery('.select-renewal-pricing').on('change', function() {
  3108. var self = jQuery(this),
  3109. domainId = self.data('domain-id'),
  3110. button = jQuery('#renewDomain' + domainId);
  3111. button.attr('disabled', 'disabled').each(function() {
  3112. jQuery(this).css('width', jQuery(this).outerWidth());
  3113. jQuery(this).find('span.added').hide().end()
  3114. .removeClass('checkout').find('span.to-add').show().end().removeAttr('disabled');
  3115. });
  3116. });
  3117. jQuery('#domainRenewalFilter').on('keyup', function() {
  3118. var inputText = jQuery(this).val().toLowerCase();
  3119. jQuery('#domainRenewals').find('div.domain-renewal').filter(function() {
  3120. jQuery(this).toggle(jQuery(this).data('domain').toLowerCase().indexOf(inputText) > -1);
  3121. });
  3122. });
  3123. checkoutForm = jQuery('#frmCheckout');
  3124. if (checkoutForm.length) {
  3125. checkoutForm.on('submit', validateCheckoutCreditCardInput);
  3126. }
  3127. if (existingCardContainer.is(':visible')) {
  3128. newCardInfo.slideUp();
  3129. }
  3130. });
  3131. //checkoutForm
  3132. function validateCheckoutCreditCardInput(e)
  3133. {
  3134. var newOrExisting = jQuery('input[name="ccinfo"]:checked').val(),
  3135. submitButton = checkoutForm.find('*[type="submit"]'),
  3136. cardType = null,
  3137. submit = true,
  3138. selectedPaymentMethod = checkoutForm.find('input[name="paymentmethod"]:checked'),
  3139. isCreditCardGateway = selectedPaymentMethod.hasClass('is-credit-card'),
  3140. isRemoteCard = selectedPaymentMethod.data('payment-type') === 'RemoteCreditCard',
  3141. cardNumber = jQuery('#inputCardNumber');
  3142. checkoutForm.find('.form-group').removeClass('has-error');
  3143. checkoutForm.find('.field-error-msg').hide();
  3144. if (isCreditCardGateway && !isRemoteCard) {
  3145. var cvvField = checkoutForm.find('#inputCardCVV2');
  3146. if (newOrExisting === 'new') {
  3147. cvvField = checkoutForm.find('#inputCardCVV');
  3148. cardType = jQuery.payment.cardType(checkoutForm.find('#inputCardNumber').val());
  3149. if (!jQuery.payment.validateCardNumber(checkoutForm.find('#inputCardNumber').val()) || cardNumber.hasClass('unsupported')) {
  3150. var error = cardNumber.data('message-invalid');
  3151. if (cardNumber.hasClass('unsupported')) {
  3152. error = cardNumber.data('message-unsupported');
  3153. }
  3154. checkoutForm.find('#inputCardNumber').setInputError(error).showInputError();
  3155. submit = false;
  3156. }
  3157. if (
  3158. !jQuery.payment.validateCardExpiry(
  3159. checkoutForm.find('#inputCardExpiry').payment('cardExpiryVal')
  3160. )
  3161. ) {
  3162. checkoutForm.find('#inputCardExpiry').showInputError();
  3163. submit = false;
  3164. }
  3165. }
  3166. if (!jQuery.payment.validateCardCVC(cvvField.val(), cardType)) {
  3167. cvvField.showInputError();
  3168. submit = false;
  3169. }
  3170. if (!submit) {
  3171. submitButton.prop('disabled', false)
  3172. .removeClass('disabled')
  3173. .find('i')
  3174. .removeAttr('class')
  3175. .addClass('fas fa-arrow-circle-right');
  3176. e.preventDefault();
  3177. }
  3178. }
  3179. }
  3180. function hasDomainLookupEnded() {
  3181. domainLookupCallCount++;
  3182. if (domainLookupCallCount == 3) {
  3183. jQuery('#btnCheckAvailability').removeAttr('disabled').removeClass('disabled');
  3184. }
  3185. }
  3186. function hasProductDomainLookupEnded(total, button) {
  3187. domainLookupCallCount++;
  3188. if (domainLookupCallCount == total) {
  3189. button.removeAttr('disabled').removeClass('disabled');
  3190. jQuery('input[name="domainoption"]').iCheck('enable');
  3191. }
  3192. }
  3193. function domainGotoNextStep() {
  3194. jQuery("#domainLoadingSpinner").show();
  3195. jQuery("#frmProductDomainSelections").submit();
  3196. }
  3197. function removeItem(type, num) {
  3198. jQuery('#inputRemoveItemType').val(type);
  3199. jQuery('#inputRemoveItemRef').val(num);
  3200. jQuery('#modalRemoveItem').modal('show');
  3201. }
  3202. function updateConfigurableOptions(i, billingCycle) {
  3203. WHMCS.http.jqClient.post("cart.php", 'a=cyclechange&ajax=1&i='+i+'&billingcycle='+billingCycle,
  3204. function(data) {
  3205. jQuery("#productConfigurableOptions").html(jQuery(data).find('#productConfigurableOptions').html());
  3206. jQuery('input').iCheck({
  3207. inheritID: true,
  3208. checkboxClass: 'icheckbox_square-blue',
  3209. radioClass: 'iradio_square-blue',
  3210. increaseArea: '20%'
  3211. });
  3212. }
  3213. );
  3214. recalctotals();
  3215. }
  3216. function recalctotals() {
  3217. if (!jQuery("#orderSummaryLoader").is(":visible")) {
  3218. jQuery("#orderSummaryLoader").fadeIn('fast');
  3219. }
  3220. var thisRequestId = Math.floor((Math.random() * 1000000) + 1);
  3221. window.lastSliderUpdateRequestId = thisRequestId;
  3222. var post = WHMCS.http.jqClient.post("cart.php", 'ajax=1&a=confproduct&calctotal=true&'+jQuery("#frmConfigureProduct").serialize());
  3223. post.done(
  3224. function(data) {
  3225. if (thisRequestId == window.lastSliderUpdateRequestId) {
  3226. jQuery("#producttotal").html(data);
  3227. }
  3228. }
  3229. );
  3230. post.always(
  3231. function() {
  3232. jQuery("#orderSummaryLoader").delay(500).fadeOut('slow');
  3233. }
  3234. );
  3235. }
  3236. function recalculateRenewalTotals() {
  3237. if (!jQuery("#orderSummaryLoader").is(":visible")) {
  3238. jQuery("#orderSummaryLoader").fadeIn('fast');
  3239. }
  3240. var thisRequestId = Math.floor((Math.random() * 1000000) + 1);
  3241. window.lastSliderUpdateRequestId = thisRequestId;
  3242. WHMCS.http.jqClient.get(
  3243. WHMCS.utils.getRouteUrl('/cart/domain/renew/calculate')
  3244. ).done(function(data) {
  3245. if (thisRequestId === window.lastSliderUpdateRequestId) {
  3246. jQuery("#producttotal").html(data.body);
  3247. }
  3248. }).always(
  3249. function() {
  3250. jQuery("#orderSummaryLoader").delay(500).fadeOut('slow');
  3251. }
  3252. );
  3253. }
  3254. function selectDomainPricing(domainName, price, period, yearsString, suggestionNumber) {
  3255. jQuery("#domainSuggestion" + suggestionNumber).iCheck('check');
  3256. jQuery("[name='domainsregperiod[" + domainName + "]']").val(period);
  3257. jQuery("[name='" + domainName + "-selected-price']").html('<b class="glyphicon glyphicon-shopping-cart"></b>'
  3258. + ' ' + period + ' ' + yearsString + ' @ ' + price);
  3259. }
  3260. function selectDomainPeriodInCart(domainName, price, period, yearsString) {
  3261. var loader = jQuery("#orderSummaryLoader");
  3262. if (loader.not(':visible')) {
  3263. loader.fadeIn('fast');
  3264. }
  3265. jQuery("[name='" + domainName + "Pricing']").html(period + ' ' + yearsString + ' <span class="caret"></span>');
  3266. jQuery("[name='" + domainName + "Price']").html(price);
  3267. var update = WHMCS.http.jqClient.post(
  3268. window.location.pathname,
  3269. {
  3270. domain: domainName,
  3271. period: period,
  3272. a: 'updateDomainPeriod',
  3273. token: csrfToken
  3274. }
  3275. );
  3276. update.done(
  3277. function(data) {
  3278. if (data.forceReload) {
  3279. window.location.reload();
  3280. return;
  3281. }
  3282. data.domains.forEach(function(domain) {
  3283. jQuery("[name='" + domain.domain + "Price']").parent('div').find('.renewal-price').html(
  3284. domain.prefixedRenewPrice + domain.shortRenewalYearsLanguage
  3285. );
  3286. });
  3287. jQuery('#subtotal').html(data.subtotal);
  3288. if (data.promotype) {
  3289. jQuery('#discount').html(data.discount);
  3290. }
  3291. if (data.taxrate) {
  3292. jQuery('#taxTotal1').html(data.taxtotal);
  3293. }
  3294. if (data.taxrate2) {
  3295. jQuery('#taxTotal2').html(data.taxtotal2);
  3296. }
  3297. var recurringSpan = jQuery('#recurring');
  3298. recurringSpan.find('span:visible').not('span.cost').fadeOut('fast');
  3299. if (data.totalrecurringannually) {
  3300. jQuery('#recurringAnnually').fadeIn('fast').find('.cost').html(data.totalrecurringannually);
  3301. }
  3302. if (data.totalrecurringbiennially) {
  3303. jQuery('#recurringBiennially').fadeIn('fast').find('.cost').html(data.totalrecurringbiennially);
  3304. }
  3305. if (data.totalrecurringmonthly) {
  3306. jQuery('#recurringMonthly').fadeIn('fast').find('.cost').html(data.totalrecurringmonthly);
  3307. }
  3308. if (data.totalrecurringquarterly) {
  3309. jQuery('#recurringQuarterly').fadeIn('fast').find('.cost').html(data.totalrecurringquarterly);
  3310. }
  3311. if (data.totalrecurringsemiannually) {
  3312. jQuery('#recurringSemiAnnually').fadeIn('fast').find('.cost').html(data.totalrecurringsemiannually);
  3313. }
  3314. if (data.totalrecurringtriennially) {
  3315. jQuery('#recurringTriennially').fadeIn('fast').find('.cost').html(data.totalrecurringtriennially);
  3316. }
  3317. jQuery('#totalDueToday').html(data.total);
  3318. }
  3319. );
  3320. update.always(
  3321. function() {
  3322. loader.delay(500).fadeOut('slow');
  3323. }
  3324. );
  3325. }
  3326. function loadMoreSuggestions()
  3327. {
  3328. var suggestions = jQuery('#domainSuggestions'),
  3329. suggestionCount;
  3330. for (suggestionCount = 1; suggestionCount <= 10; suggestionCount++) {
  3331. if (furtherSuggestions > 0) {
  3332. suggestions.find('div.domain-suggestion.clone:hidden:first').slideDown();
  3333. furtherSuggestions = suggestions.find('div.domain-suggestion.clone:hidden').length;
  3334. } else {
  3335. jQuery('div.more-suggestions').find('a').addClass('hidden').end().find('span.no-more').removeClass('hidden');
  3336. return;
  3337. }
  3338. }
  3339. }
  3340. function validate_captcha(form)
  3341. {
  3342. var reCaptcha = jQuery('#g-recaptcha-response'),
  3343. reCaptchaContainer = jQuery('#divDynamicRecaptcha'),
  3344. captcha = jQuery('#inputCaptcha');
  3345. if (reCaptcha.length && !reCaptcha.val()) {
  3346. reCaptchaContainer.tooltip('show');
  3347. return false;
  3348. }
  3349. if (captcha.length && !captcha.val()) {
  3350. captcha.tooltip('show');
  3351. return false;
  3352. }
  3353. var validate = WHMCS.http.jqClient.post(
  3354. form.attr('action'),
  3355. form.serialize() + '&a=validateCaptcha',
  3356. null,
  3357. 'json'
  3358. );
  3359. validate.done(function(data) {
  3360. if (data.error) {
  3361. jQuery('#inputCaptcha').attr('data-original-title', data.error).tooltip('show');
  3362. if (captcha.length) {
  3363. jQuery('#inputCaptchaImage').replaceWith(
  3364. '<img id="inputCaptchaImage" src="' + whmcsBaseUrl + '/includes/verifyimage.php?nocache=' + new Date().getTime() + '" align="middle" />'
  3365. );
  3366. }
  3367. } else {
  3368. jQuery('#captchaContainer').remove();
  3369. form.trigger('submit');
  3370. }
  3371. });
  3372. }