admin-functions.js 84 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541
  1. // make it a global variable so other scripts can access it
  2. var booked_load_calendar_date_booking_options;
  3. ;(function($, window, document, undefined) {
  4. var $win = $(window);
  5. $.fn.spin.presets.booked = {
  6. lines: 10, // The number of lines to draw
  7. length: 7, // The length of each line
  8. width: 5, // The line thickness
  9. radius: 11, // The radius of the inner circle
  10. corners: 1, // Corner roundness (0..1)
  11. rotate: 0, // The rotation offset
  12. direction: 1, // 1: clockwise, -1: counterclockwise
  13. color: '#555', // #rgb or #rrggbb or array of colors
  14. speed: 1, // Rounds per second
  15. trail: 60, // Afterglow percentage
  16. shadow: false, // Whether to render a shadow
  17. hwaccel: false, // Whether to use hardware acceleration
  18. className: 'booked-spinner', // The CSS class to assign to the spinner
  19. zIndex: 2e9, // The z-index (defaults to 2000000000)
  20. top: '50%', // Top position relative to parent
  21. left: '50%' // Left position relative to parent
  22. }
  23. $.fn.spin.presets.booked_white = {
  24. lines: 13, // The number of lines to draw
  25. length: 11, // The length of each line
  26. width: 5, // The line thickness
  27. radius: 18, // The radius of the inner circle
  28. scale: 1,
  29. corners: 1, // Corner roundness (0..1)
  30. rotate: 0, // The rotation offset
  31. direction: 1, // 1: clockwise, -1: counterclockwise
  32. color: '#fff', // #rgb or #rrggbb or array of colors
  33. speed: 1, // Rounds per second
  34. trail: 60, // Afterglow percentage
  35. shadow: false, // Whether to render a shadow
  36. hwaccel: false, // Whether to use hardware acceleration
  37. className: 'booked-spinner', // The CSS class to assign to the spinner
  38. zIndex: 2e9, // The z-index (defaults to 2000000000)
  39. top: '50%', // Top position relative to parent
  40. left: '50%' // Left position relative to parent
  41. }
  42. $win.on('load', function() {
  43. var currentlySaving = false;
  44. if ($('#booked-welcome-screen').length){
  45. $('#booked-welcome-screen').fitVids();
  46. }
  47. // Custom Time Slots
  48. var timeslotsContainter = $('#customTimeslotsContainer');
  49. timeslotsContainter.find('.booked-customTimeslot').each(function(){
  50. var thisTimeslot = $(this);
  51. var rand = Math.floor((Math.random() * 100000000) + 1);
  52. init_custom_timeslot_block(thisTimeslot,rand)
  53. });
  54. $('body').on('click','.addCustomTimeslot',function(e){
  55. e.preventDefault();
  56. var thisTimeslot = $('.booked-customTimeslotTemplate').clone().appendTo(timeslotsContainter).removeClass().addClass('booked-customTimeslot').show();
  57. var rand = Math.floor((Math.random() * 100000000) + 1);
  58. init_custom_timeslot_block(thisTimeslot,rand);
  59. });
  60. var preventApptsBefore = $('body').find('.booked_prevent_appointments_before');
  61. var preventApptsAfter = $('body').find('.booked_prevent_appointments_after');
  62. preventApptsBefore.datepicker({
  63. dateFormat: "yy-mm-dd",
  64. beforeShow: function(input, inst) {
  65. $('#ui-datepicker-div').removeClass();
  66. $('#ui-datepicker-div').addClass('booked_custom_date_picker');
  67. },
  68. onSelect: function(selected) {
  69. $('.booked_prevent_appointments_after').datepicker("option","minDate", selected);
  70. booked_datepicker_show_formatted_date( 'booked_prevent_appointments_before', selected );
  71. }
  72. });
  73. preventApptsAfter.datepicker({
  74. dateFormat: "yy-mm-dd",
  75. beforeShow: function(input, inst) {
  76. $('#ui-datepicker-div').removeClass();
  77. $('#ui-datepicker-div').addClass('booked_custom_date_picker');
  78. },
  79. onSelect: function(selected) {
  80. $('.booked_prevent_appointments_before').datepicker("option","maxDate", selected);
  81. booked_datepicker_show_formatted_date( 'booked_prevent_appointments_after', selected );
  82. }
  83. });
  84. $('body').on('change','select[name="booked_booking_type"]',function(){
  85. var thisSelectVal = $(this).find('option:selected').val();
  86. if (thisSelectVal == "guest"){
  87. var selectedRadio = $('input[name="booked_appointment_redirect_type"]:checked').val();
  88. if (selectedRadio == 'booked-profile'){
  89. $('input[name="booked_appointment_redirect_type"][value=""]').prop("checked",true);
  90. }
  91. }
  92. });
  93. $('body').on('change','#booked_hide_unavailable_timeslots,#booked_public_appointments',function(){
  94. var thisCheckbox = $(this);
  95. var thisID = thisCheckbox.attr('id');
  96. if (thisCheckbox.is(':checked') && thisID == 'booked_hide_unavailable_timeslots'){
  97. $('#booked_public_appointments').prop('checked', false);
  98. } else if (thisCheckbox.is(':checked') && thisID == 'booked_public_appointments') {
  99. $('#booked_hide_unavailable_timeslots').prop('checked', false);
  100. }
  101. });
  102. $('body').on('click','form#newAppointmentForm input[type=submit]',function(e){
  103. e.preventDefault();
  104. var thisForm = $('#newAppointmentForm'),
  105. customerType = thisForm.find('input[name=customer_type]:checked').val(),
  106. customerID = thisForm.find('select[name=user_id]').val(),
  107. name = thisForm.find('input[name=name]').val(),
  108. surname = thisForm.find('input[name=surname]').val(),
  109. guest_name = thisForm.find('input[name=guest_name]').val(),
  110. guest_email = thisForm.find('input[name=guest_email]').val(),
  111. guest_surname = thisForm.find('input[name=guest_surname]').val(),
  112. email = thisForm.find('input[name=email]').val(),
  113. password = thisForm.find('input[name=password]').val(),
  114. date = thisForm.find('input[name=date]').val(),
  115. calendar_id = thisForm.data('calendar-id'),
  116. $activeTD = $('table.booked-calendar').find('td.active'),
  117. surnameActive = thisForm.find('input[name=surname]').length,
  118. guest_surnameActive = thisForm.find('input[name=guest_surname]').length,
  119. guest_emailActive = thisForm.find('input[name=guest_email]').length,
  120. showRequiredError = false;
  121. $(this).parents('form.booked-form').find('input,textarea,select').each(function(i,field){
  122. var required = $(this).attr('required');
  123. if (required && $(field).attr('type') == 'hidden'){
  124. var fieldParts = $(field).attr('name');
  125. fieldParts = fieldParts.split('---');
  126. fieldName = fieldParts[0];
  127. fieldNumber = fieldParts[1].split('___');
  128. fieldNumber = fieldNumber[0];
  129. if (fieldName == 'radio-buttons-label'){
  130. var radioValue = false;
  131. $('input:radio[name="single-radio-button---'+fieldNumber+'[]"]:checked').each(function(){
  132. if ($(this).val()){
  133. radioValue = $(this).val();
  134. }
  135. });
  136. if (!radioValue){
  137. showRequiredError = true;
  138. }
  139. } else if (fieldName == 'checkboxes-label'){
  140. var checkboxValue = false;
  141. $('input:checkbox[name="single-checkbox---'+fieldNumber+'[]"]:checked').each(function(){
  142. if ($(this).val()){
  143. checkboxValue = $(this).val();
  144. }
  145. });
  146. if (!checkboxValue){
  147. showRequiredError = true;
  148. }
  149. }
  150. } else if (required && $(field).attr('type') != 'hidden' && $(field).val() == ''){
  151. showRequiredError = true;
  152. }
  153. });
  154. if (showRequiredError){
  155. alert(booked_js_vars.i18n_fill_out_required_fields);
  156. return false;
  157. }
  158. if (customerType == 'guest' && guest_name && !guest_surnameActive && !guest_emailActive ||
  159. customerType == 'guest' && guest_name && guest_surnameActive && guest_surname && !guest_emailActive ||
  160. customerType == 'guest' && guest_name && guest_emailActive && guest_email && !guest_surnameActive ||
  161. customerType == 'guest' && guest_name && guest_emailActive && guest_email && guest_surnameActive && guest_surname ){
  162. $thisButton = $(this);
  163. $('form.booked-form input').each(function(){
  164. thisDefault = $(this).attr('title');
  165. thisVal = $(this).val();
  166. if (thisDefault == thisVal){ $(this).val(''); }
  167. });
  168. $thisButton.val(booked_js_vars.i18n_please_wait).attr('disabled',true);
  169. $thisButton.parents('form').find('button.cancel').attr('disabled',true);
  170. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  171. type : 'post',
  172. url : booked_js_vars.ajax_url,
  173. data : $('form.booked-form').serializeArray(),
  174. success: function(date) {
  175. data = date.split('###');
  176. if (data[0] == 'error'){
  177. $thisButton.val( booked_js_vars.i18n_create_appointment ).attr('disabled',false);
  178. $thisButton.parents('form').find('button.cancel').attr('disabled',false);
  179. $('form.booked-form input').each(function(){
  180. thisDefault = $(this).attr('title');
  181. thisVal = $(this).val();
  182. if (!thisVal){ $(this).val(thisDefault); }
  183. });
  184. alert(data[1]);
  185. } else {
  186. $.ajax({
  187. url : booked_js_vars.ajax_url,
  188. type : 'post',
  189. data : {'action':'booked_admin_calendar_date','date':data[1],'calendar_id':calendar_id},
  190. success : function(html){
  191. $('tr.entryBlock').find('td').html( html );
  192. $('tr.entryBlock').find('.booked-appt-list').show();
  193. $('tr.entryBlock').find('.booked-appt-list').addClass('shown');
  194. $('.bookedAppointmentTab.active').fadeIn(300);
  195. }
  196. });
  197. $.ajax({
  198. url : booked_js_vars.ajax_url,
  199. type : 'post',
  200. data : {'action':'booked_admin_refresh_date_square','date':data[1],'calendar_id':calendar_id},
  201. success : function(html){
  202. $activeTD.replaceWith(html);
  203. adjust_calendar_boxes();
  204. }
  205. });
  206. close_booked_modal();
  207. }
  208. }
  209. });
  210. return false;
  211. } else if ( customerType == 'guest' && guest_emailActive && !guest_email && guest_surnameActive && !guest_surname ||
  212. customerType == 'guest' && guest_emailActive && !guest_email && guest_surnameActive && guest_surname ){
  213. alert(booked_js_vars.i18n_appt_required_guest_fields_all);
  214. } else if ( customerType == 'guest' && guest_emailActive && !guest_email && !guest_surnameActive ){
  215. alert(booked_js_vars.i18n_appt_required_guest_fields_name_email);
  216. } else if ( customerType == 'guest' && guest_surnameActive && !guest_surname ){
  217. alert(booked_js_vars.i18n_appt_required_guest_fields_surname);
  218. } else if ( customerType == 'guest' && !guest_name ){
  219. alert(booked_js_vars.i18n_appt_required_guest_fields);
  220. }
  221. if (customerType == 'current' && customerID){
  222. $('form.booked-form input').each(function(){
  223. thisDefault = $(this).attr('title');
  224. thisVal = $(this).val();
  225. if (thisDefault == thisVal){ $(this).val(''); }
  226. });
  227. $(this).val(booked_js_vars.i18n_please_wait).attr('disabled',true);
  228. $(this).parents('form').find('button.cancel').attr('disabled',true);
  229. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  230. type : 'post',
  231. url : booked_js_vars.ajax_url,
  232. data : $('form.booked-form').serializeArray(),
  233. success: function(date) {
  234. data = date.split('###');
  235. if (data[0] == 'error'){
  236. $thisButton.val( booked_js_vars.i18n_create_appointment ).attr('disabled',false);
  237. $thisButton.parents('form').find('button.cancel').attr('disabled',false);
  238. $('form.booked-form input').each(function(){
  239. thisDefault = $(this).attr('title');
  240. thisVal = $(this).val();
  241. if (!thisVal){ $(this).val(thisDefault); }
  242. });
  243. alert(data[1]);
  244. } else {
  245. $.ajax({
  246. url : booked_js_vars.ajax_url,
  247. type : 'post',
  248. data : {'action':'booked_admin_calendar_date','date':data[1],'calendar_id':calendar_id},
  249. success : function(html){
  250. $('tr.entryBlock').find('td').html( html );
  251. $('tr.entryBlock').find('.booked-appt-list').show();
  252. $('tr.entryBlock').find('.booked-appt-list').addClass('shown');
  253. $('.bookedAppointmentTab.active').fadeIn(300);
  254. }
  255. });
  256. $.ajax({
  257. url : booked_js_vars.ajax_url,
  258. type : 'post',
  259. data : {'action':'booked_admin_refresh_date_square','date':data[1],'calendar_id':calendar_id},
  260. success : function(html){
  261. $activeTD.replaceWith(html);
  262. adjust_calendar_boxes();
  263. }
  264. });
  265. }
  266. close_booked_modal();
  267. }
  268. });
  269. return false;
  270. } else if (customerType == 'current' && !customerID){
  271. alert(booked_js_vars.i18n_choose_customer);
  272. }
  273. if ( customerType == 'new' && name && email && !surnameActive || customerType == 'new' && name && email && surnameActive && surname ){
  274. $('form.booked-form input').each(function(){
  275. thisDefault = $(this).attr('title');
  276. thisVal = $(this).val();
  277. if (thisDefault == thisVal){ $(this).val(''); }
  278. });
  279. $thisButton = $(this);
  280. $thisButton.val(booked_js_vars.i18n_please_wait).attr('disabled',true);
  281. $thisButton.parents('form').find('button.cancel').attr('disabled',true);
  282. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  283. type : 'post',
  284. url : booked_js_vars.ajax_url,
  285. data : $('form.booked-form').serialize(),
  286. success: function(data) {
  287. data = date.split('###');
  288. if (data[0] == 'error'){
  289. $thisButton.val( booked_js_vars.i18n_create_appointment ).attr('disabled',false);
  290. $thisButton.parents('form').find('button.cancel').attr('disabled',false);
  291. $('form.booked-form input').each(function(){
  292. thisDefault = $(this).attr('title');
  293. thisVal = $(this).val();
  294. if (!thisVal){ $(this).val(thisDefault); }
  295. });
  296. alert(data[1]);
  297. } else {
  298. $.ajax({
  299. url : booked_js_vars.ajax_url,
  300. type : 'post',
  301. data : {'action':'booked_admin_calendar_date','date':data[1],'calendar_id':calendar_id},
  302. success : function(html){
  303. $('tr.entryBlock').find('td').html( html );
  304. $('tr.entryBlock').find('.booked-appt-list').show();
  305. $('tr.entryBlock').find('.booked-appt-list').addClass('shown');
  306. $('.bookedAppointmentTab.active').fadeIn(300);
  307. }
  308. });
  309. $.ajax({
  310. url : booked_js_vars.ajax_url,
  311. type : 'post',
  312. data : {'action':'booked_admin_refresh_date_square','date':data[1],'calendar_id':calendar_id},
  313. success : function(html){
  314. $activeTD.replaceWith(html);
  315. adjust_calendar_boxes();
  316. }
  317. });
  318. close_booked_modal();
  319. }
  320. }
  321. });
  322. return false;
  323. } else if ( customerType == 'new' && !name || customerType == 'new' && !email || customerType == 'new' && surnameActive && !surname ){
  324. alert(booked_js_vars.i18n_appt_required_fields);
  325. }
  326. });
  327. $('body').on('click','form#editAppointmentForm input[type=submit]',function(e){
  328. e.preventDefault();
  329. var thisForm = $('#editAppointmentForm'),
  330. name = thisForm.find('input[name=name]').val(),
  331. surname = thisForm.find('input[name=surname]').val(),
  332. email = thisForm.find('input[name=email]').val(),
  333. date = thisForm.find('input[name=appt_date]').val(),
  334. calendar_id = thisForm.find('input[name=calendar_id]').val(),
  335. $thisButton = $(this),
  336. $activeTD = $('table.booked-calendar').find('td.active'),
  337. showRequiredError = false;
  338. thisForm.find('input,select').each(function(i,field){
  339. var required = $(this).attr('required');
  340. if ( required && $(field).val() == '' ){
  341. showRequiredError = true;
  342. }
  343. });
  344. if (showRequiredError){
  345. alert(booked_js_vars.i18n_fill_out_required_fields);
  346. return false;
  347. }
  348. $thisButton.val(booked_js_vars.i18n_please_wait).attr('disabled',true);
  349. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  350. type : 'post',
  351. url : booked_js_vars.ajax_url,
  352. data : thisForm.serializeArray(),
  353. success: function(result) {
  354. data = result.split('###');
  355. if (data[0] == 'error'){
  356. $thisButton.val( booked_js_vars.i18n_update_appointment ).attr('disabled',false);
  357. alert(data[1]);
  358. } else if ( !$('table.booked-calendar').length ) {
  359. location.reload();
  360. } else {
  361. var active_date = $activeTD.data('date');
  362. $.ajax({
  363. url : booked_js_vars.ajax_url,
  364. type : 'post',
  365. data : {'action':'booked_admin_calendar_date','date':active_date,'calendar_id':calendar_id},
  366. success : function(html){
  367. $('tr.entryBlock').find('td').html( html );
  368. $('tr.entryBlock').find('.booked-appt-list').show();
  369. $('tr.entryBlock').find('.booked-appt-list').addClass('shown');
  370. $('.bookedAppointmentTab.active').fadeIn(300);
  371. }
  372. });
  373. $.ajax({
  374. url : booked_js_vars.ajax_url,
  375. type : 'post',
  376. data : {'action':'booked_admin_refresh_date_square','date':active_date,'calendar_id':calendar_id},
  377. success : function(html){
  378. $activeTD.replaceWith(html);
  379. adjust_calendar_boxes();
  380. }
  381. });
  382. if ( active_date != date ){
  383. $.ajax({
  384. url : booked_js_vars.ajax_url,
  385. type : 'post',
  386. data : {'action':'booked_admin_refresh_date_square','inactive':false,'date':date,'calendar_id':calendar_id},
  387. success : function(html){
  388. $( 'table.booked-calendar' ).find( 'td[data-date="' + date + '"]' ).replaceWith(html);
  389. adjust_calendar_boxes();
  390. }
  391. });
  392. }
  393. close_booked_modal();
  394. }
  395. }
  396. });
  397. });
  398. function init_custom_timeslot_block(thisTimeslot,rand){
  399. hideAddCustomTimeslotsForm();
  400. thisTimeslot.find('#vacationDayCheckbox').attr('id','vacationDayCheckbox-'+rand);
  401. thisTimeslot.find('label[for="vacationDayCheckbox"]').attr('for','vacationDayCheckbox-'+rand);
  402. var disableApptsValue = thisTimeslot.find('#vacationDayCheckbox-'+rand).is(':checked');
  403. if (disableApptsValue){
  404. hideAddCustomTimeslotsForm();
  405. thisTimeslot.find('button.addSingleTimeslot,button.addBulkTimeslots,.customTimeslotsList').hide();
  406. } else {
  407. $('button.addBulkTimeslots').attr('disabled',false);
  408. $('button.addSingleTimeslot').attr('disabled',false);
  409. $('#booked-customTimePickerTemplates').find('.customBulk,customSingle').show();
  410. }
  411. thisTimeslot.on('change','#vacationDayCheckbox-'+rand,function(){
  412. thisCheckbox = $(this);
  413. if (thisCheckbox.is(':checked')){
  414. hideAddCustomTimeslotsForm();
  415. thisTimeslot.find('button.addSingleTimeslot,button.addBulkTimeslots,.customTimeslotsList').hide();
  416. } else {
  417. $('#booked-customTimePickerTemplates').find('.customBulk,customSingle').show();
  418. thisTimeslot.find('button.addSingleTimeslot,button.addBulkTimeslots,.customTimeslotsList').show();
  419. }
  420. });
  421. thisTimeslot.find('.booked_custom_start_date').datepicker({
  422. dateFormat: "yy-mm-dd",
  423. beforeShow: function(input, inst) {
  424. $('#ui-datepicker-div').removeClass();
  425. $('#ui-datepicker-div').addClass('booked_custom_date_picker');
  426. },
  427. onSelect: function(selected) {
  428. thisTimeslot.find('.booked_custom_end_date').datepicker("option","minDate", selected);
  429. updateCustomTimeslotEncodedField();
  430. $('#booked-saveCustomTimeslots').prop('disabled',false).addClass('button-primary');
  431. },
  432. onClose: function(selected) {
  433. thisTimeslot.find('.booked_custom_start_date').datepicker("option","maxDate", selected);
  434. updateCustomTimeslotEncodedField();
  435. $('#booked-saveCustomTimeslots').prop('disabled',false).addClass('button-primary');
  436. }
  437. });
  438. thisTimeslot.find('.booked_custom_end_date').datepicker({
  439. dateFormat: "yy-mm-dd",
  440. beforeShow: function(input, inst) {
  441. $('#ui-datepicker-div').removeClass();
  442. $('#ui-datepicker-div').addClass('booked_custom_date_picker');
  443. },
  444. onSelect: function(selected) {
  445. thisTimeslot.find('.booked_custom_start_date').datepicker("option","maxDate", selected);
  446. updateCustomTimeslotEncodedField();
  447. $('#booked-saveCustomTimeslots').prop('disabled',false).addClass('button-primary');
  448. },
  449. onClose: function(selected) {
  450. thisTimeslot.find('.booked_custom_start_date').datepicker("option","maxDate", selected);
  451. updateCustomTimeslotEncodedField();
  452. $('#booked-saveCustomTimeslots').prop('disabled',false).addClass('button-primary');
  453. }
  454. });
  455. thisTimeslot.on('click','button.addSingleTimeslot',function(e){
  456. e.preventDefault();
  457. $(this).attr('disabled',true);
  458. $('button.addBulkTimeslots').prop('disabled',false);
  459. $('#booked-saveCustomTimeslots').prop('disabled',true);
  460. $('#booked-customTimePickerTemplates').find('input').val('').attr('checked',false);
  461. $('#booked-customTimePickerTemplates').find('select').prop('selectedIndex',0);
  462. $('#booked-customTimePickerTemplates').appendTo(thisTimeslot).show();
  463. $('#booked-customTimePickerTemplates').find('.customBulk').hide();
  464. $('#booked-customTimePickerTemplates').find('.customSingle').hide().fadeIn(200);
  465. });
  466. thisTimeslot.on('click','button.addBulkTimeslots',function(e){
  467. e.preventDefault();
  468. $(this).attr('disabled',true);
  469. $('button.addSingleTimeslot').prop('disabled',false);
  470. $('#booked-saveCustomTimeslots').prop('disabled',true);
  471. $('#booked-customTimePickerTemplates').find('input').val('').attr('checked',false);
  472. $('#booked-customTimePickerTemplates').find('select').prop('selectedIndex',0);
  473. $('#booked-customTimePickerTemplates').appendTo(thisTimeslot).show();
  474. $('#booked-customTimePickerTemplates').find('.customBulk').hide().fadeIn(200);
  475. $('#booked-customTimePickerTemplates').find('.customSingle').hide();
  476. });
  477. $('#booked-customTimePickerTemplates').on('click','button.cancel',function(e){
  478. e.preventDefault();
  479. hideAddCustomTimeslotsForm();
  480. });
  481. thisTimeslot.on('click','.deleteCustomTimeslot',function(e){
  482. e.preventDefault();
  483. var confirmDelete = confirm(booked_js_vars.i18n_confirm_cts_delete);
  484. if (confirmDelete){
  485. $('#booked-customTimePickerTemplates').find('.customBulk,customSingle').hide();
  486. $('#booked-customTimePickerTemplates').hide().appendTo('#booked-custom-timeslots');
  487. $('button.addBulkTimeslots').prop('disabled',false);
  488. $('button.addSingleTimeslot').prop('disabled',false);
  489. $('#booked-saveCustomTimeslots').prop('disabled',false);
  490. $(this).parents('.booked-customTimeslot').remove();
  491. var lastItem = false;
  492. var lastItemType = false;
  493. $('#customTimeslotsContainer > *').each(function(){
  494. var thisItem = $(this);
  495. var isH3 = thisItem.is('h3');
  496. var isDIV = thisItem.is('div');
  497. if (lastItemType == 'h3' && isH3){
  498. lastItem.remove();
  499. }
  500. if (isH3){ lastItemType = 'h3'; }
  501. if (isDIV){ lastItemType = 'div'; }
  502. lastItem = $(this);
  503. });
  504. if (lastItemType == 'h3'){
  505. lastItem.remove();
  506. }
  507. updateCustomTimeslotEncodedField();
  508. $('#booked-saveCustomTimeslots').prop('disabled',false).addClass('button-primary').trigger('click');
  509. }
  510. });
  511. thisTimeslot.on('change','> input, > select',function(){
  512. updateCustomTimeslotEncodedField();
  513. $('#booked-saveCustomTimeslots').prop('disabled',false).addClass('button-primary');
  514. });
  515. thisTimeslot.on('change','input#all_day_custom',function(){
  516. var thisCheckbox = $(this);
  517. if (thisCheckbox.is(':checked')){
  518. thisCheckbox.parents('.customSingle').find('select[name="startTime"]').val('0000').hide();
  519. thisCheckbox.parents('.customSingle').find('select[name="endTime"]').val('2400').hide();
  520. } else {
  521. thisCheckbox.parents('.customSingle').find('select[name="startTime"]').prop('selectedIndex',0).show();
  522. thisCheckbox.parents('.customSingle').find('select[name="endTime"]').prop('selectedIndex',0).show();
  523. }
  524. });
  525. thisTimeslot.on('click','.customTimeslotsList .delete',function(e){
  526. e.preventDefault();
  527. var confirmDelete = confirm(booked_js_vars.i18n_confirm_cts_delete);
  528. if (confirmDelete){
  529. var thisButton = $(this),
  530. thisTimeslot = thisButton.parent();
  531. deleteTimeslot = thisButton.parent().attr('data-timeslot'),
  532. calendar_id = thisButton.parents('.booked-customTimeslot').find('[name="booked_custom_calendar_id"]').val(),
  533. start_date = thisButton.parents('.booked-customTimeslot').find('[name="booked_custom_start_date"]').val(),
  534. end_date = thisButton.parents('.booked-customTimeslot').find('[name="booked_custom_end_date"]').val(),
  535. currentTimesBox = thisButton.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots]'),
  536. currentArray = thisButton.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots]').val(),
  537. currentTimesBoxDetails = thisButton.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots_details]'),
  538. currentArrayDetails = thisButton.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots_details]').val(),
  539. timeslotList = thisButton.parents('.booked-customTimeslot').find('.customTimeslotsList');
  540. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  541. type : 'post',
  542. url : booked_js_vars.ajax_url,
  543. data : {
  544. 'action' : 'booked_admin_delete_custom_timeslot',
  545. 'calendar_id' : calendar_id,
  546. 'start_date' : start_date,
  547. 'end_date' : end_date,
  548. 'timeslot' : deleteTimeslot,
  549. 'currentArray' : currentArray,
  550. 'currentArrayDetails' : currentArrayDetails,
  551. },
  552. beforeSend: function(){
  553. savingState(true);
  554. },
  555. success: function(data) {
  556. response = JSON.parse(data);
  557. currentTimesBox.val( JSON.stringify(response.timeslot) );
  558. currentTimesBoxDetails.val( JSON.stringify(response.timeslot_details) );
  559. $('#booked-customTimePickerTemplates').find('input').val('').attr('checked',false);
  560. $('#booked-customTimePickerTemplates').find('select').prop('selectedIndex',0);
  561. $('#booked-customTimePickerTemplates').find('.customBulk,customSingle').hide();
  562. $('#booked-customTimePickerTemplates').hide().appendTo('#booked-custom-timeslots');
  563. $('button.addBulkTimeslots').prop('disabled',false);
  564. $('button.addSingleTimeslot').prop('disabled',false);
  565. $('#booked-saveCustomTimeslots').prop('disabled',false);
  566. $('.customSingle').find('select[name="startTime"]').prop('selectedIndex',0).show();
  567. $('.customSingle').find('select[name="endTime"]').prop('selectedIndex',0).show();
  568. updateCustomTimeslotEncodedField();
  569. loadCustomTimeSlots(timeslotList,data);
  570. thisTimeslot.slideUp(200);
  571. $('#booked-saveCustomTimeslots').trigger('click');
  572. }
  573. });
  574. }
  575. });
  576. var preventMultiClicks;
  577. thisTimeslot.on('click','.changeCount',function(e){
  578. e.preventDefault();
  579. if (!currentlySaving){
  580. var $button = $(this),
  581. $timeslot = $button.parents('.timeslot');
  582. $countText = $button.parent().find('.count'),
  583. countAdjust = $button.attr('data-count'),
  584. currentTimesBox = $button.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots]'),
  585. currentArray = $button.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots]').val(),
  586. timeslot = $button.parents('.timeslot').attr('data-timeslot'),
  587. currentCount = $countText.find('em').text();
  588. clearTimeout(preventMultiClicks);
  589. newCount = parseInt(currentCount) + parseInt(countAdjust);
  590. if (newCount < 1) {
  591. newCount = 1;
  592. } else {
  593. if (newCount != 1) { slot_text = booked_js_vars.i18n_slots; } else { slot_text = booked_js_vars.i18n_slot; }
  594. $countText.html('<em>' + newCount + '</em> ' + slot_text);
  595. preventMultiClicks = setTimeout(function(){
  596. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  597. type : 'post',
  598. url : booked_js_vars.ajax_url,
  599. data : {
  600. 'action' : 'booked_admin_adjust_custom_timeslot_count',
  601. 'newCount' : newCount,
  602. 'timeslot' : timeslot,
  603. 'currentArray' : currentArray,
  604. },
  605. success: function(data) {
  606. currentTimesBox.val(data);
  607. updateCustomTimeslotEncodedField();
  608. $('#booked-saveCustomTimeslots').prop('disabled',false).trigger('click');
  609. currentlySaving = false;
  610. }
  611. });
  612. },350);
  613. }
  614. }
  615. });
  616. // Single add
  617. thisTimeslot.on('click','.addSingleTimeslot_button',function(e){
  618. e.preventDefault();
  619. var $button = $(this);
  620. $button.attr('disabled',true);
  621. var addTimeslotsFormWrapper = $('#booked-customTimePickerTemplates .customSingle');
  622. var startTime = addTimeslotsFormWrapper.find('select[name=startTime]').val(),
  623. startTimeText = addTimeslotsFormWrapper.find('select[name=startTime] :selected').text(),
  624. endTime = addTimeslotsFormWrapper.find('select[name=endTime]').val(),
  625. endTimeText = addTimeslotsFormWrapper.find('select[name=endTime] :selected').text(),
  626. count = addTimeslotsFormWrapper.find('select[name=count]').val(),
  627. countText = addTimeslotsFormWrapper.find('select[name=count] :selected').text(),
  628. title = addTimeslotsFormWrapper.find('input[name=title]').val(),
  629. calendar_id = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('[name="booked_custom_calendar_id"]').val(),
  630. start_date = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('[name="booked_custom_start_date"]').val(),
  631. end_date = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('[name="booked_custom_end_date"]').val(),
  632. currentTimesBox = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots]'),
  633. currentTimes = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots]').val(),
  634. currentTimesDetailsBox = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots_details]'),
  635. currentTimesDetails = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots_details]').val(),
  636. timeslotList = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('.customTimeslotsList');
  637. var formData = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('#single-timeslot-form').serializeObject();
  638. formData['action'] = 'booked_admin_add_custom_timeslot';
  639. formData['calendar_id'] = calendar_id;
  640. formData['currentTimes'] = currentTimes;
  641. formData['currentTimesDetails'] = currentTimesDetails;
  642. formData['start_date'] = start_date;
  643. formData['end_date'] = end_date;
  644. formData['title'] = title;
  645. if (startTime && endTime && count){
  646. if (endTime <= startTime && startTime != 'allday'){
  647. $button.attr('disabled',false);
  648. alert(booked_js_vars.i18n_time_error);
  649. return false;
  650. }
  651. if (startTime == '0000' && endTime == '2400' || startTime == 'allday' && endTime == '2400'){
  652. appt_add_confirm = confirm(booked_js_vars.i18n_single_add_confirm + ':\n'+booked_js_vars.i18n_all_day+' x'+count);
  653. } else {
  654. appt_add_confirm = confirm(booked_js_vars.i18n_single_add_confirm + ':\n'+startTimeText+' '+booked_js_vars.i18n_to+' '+endTimeText+' x'+count);
  655. }
  656. if (appt_add_confirm == true){
  657. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  658. type : 'post',
  659. url : booked_js_vars.ajax_url,
  660. data : formData,
  661. beforeSend: function(){
  662. savingState(true);
  663. },
  664. success: function(data) {
  665. response = JSON.parse(data);
  666. currentTimesBox.val( JSON.stringify( response.timeslot ) );
  667. currentTimesDetailsBox.val( JSON.stringify( response.timeslot_details ) );
  668. $button.attr('disabled',false);
  669. $('#booked-customTimePickerTemplates').find('input').val('').attr('checked',false);
  670. $('#booked-customTimePickerTemplates').find('select').prop('selectedIndex',0);
  671. $('#booked-customTimePickerTemplates').find('.customBulk,customSingle').hide();
  672. $('#booked-customTimePickerTemplates').hide().appendTo('#booked-custom-timeslots');
  673. $('button.addBulkTimeslots').prop('disabled',false);
  674. $('button.addSingleTimeslot').prop('disabled',false);
  675. $('#booked-saveCustomTimeslots').prop('disabled',false);
  676. $('.customSingle').find('select[name="startTime"]').prop('selectedIndex',0).show();
  677. $('.customSingle').find('select[name="endTime"]').prop('selectedIndex',0).show();
  678. updateCustomTimeslotEncodedField();
  679. loadCustomTimeSlots(timeslotList,data);
  680. $('#booked-saveCustomTimeslots').trigger('click');
  681. }
  682. });
  683. }
  684. } else {
  685. $button.attr('disabled',false);
  686. alert(booked_js_vars.i18n_all_fields_required);
  687. return false;
  688. }
  689. });
  690. // Bulk add
  691. thisTimeslot.on('click','.addBulkTimeslots_button',function(e){
  692. e.preventDefault();
  693. var $button = $(this);
  694. $button.attr('disabled',true);
  695. var addTimeslotsFormWrapper = $('#booked-customTimePickerTemplates .customBulk');
  696. var startTime = addTimeslotsFormWrapper.find('select[name=startTime]').val(),
  697. startTimeText = addTimeslotsFormWrapper.find('select[name=startTime] :selected').text(),
  698. endTime = addTimeslotsFormWrapper.find('select[name=endTime]').val(),
  699. endTimeText = addTimeslotsFormWrapper.find('select[name=endTime] :selected').text(),
  700. interval = addTimeslotsFormWrapper.find('select[name=interval]').val(),
  701. time_between = addTimeslotsFormWrapper.find('select[name=time_between]').val(),
  702. intervalText = addTimeslotsFormWrapper.find('select[name=interval] :selected').text(),
  703. count = addTimeslotsFormWrapper.find('select[name=count]').val(),
  704. countText = addTimeslotsFormWrapper.find('select[name=count] :selected').text(),
  705. title = addTimeslotsFormWrapper.find('input[name=title]').val(),
  706. calendar_id = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('[name="booked_custom_calendar_id"]').val(),
  707. start_date = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('[name="booked_custom_start_date"]').val(),
  708. end_date = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('[name="booked_custom_end_date"]').val(),
  709. currentTimesBox = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots]'),
  710. currentTimes = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots]').val(),
  711. currentTimesDetailsBox = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots_details]'),
  712. currentTimesDetails = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('input[name=booked_this_custom_timelots_details]').val(),
  713. timeslotList = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('.customTimeslotsList');
  714. var formData = addTimeslotsFormWrapper.parents('.booked-customTimeslot').find('#bulk-timeslot-form').serializeObject();
  715. formData['action'] = 'booked_admin_add_custom_timeslots';
  716. formData['calendar_id'] = calendar_id;
  717. formData['currentTimes'] = currentTimes;
  718. formData['currentTimesDetails'] = currentTimesDetails;
  719. formData['start_date'] = start_date;
  720. formData['end_date'] = end_date;
  721. formData['title'] = title;
  722. if (startTime && endTime && interval && count){
  723. if (endTime <= startTime){
  724. $button.attr('disabled',false);
  725. alert(booked_js_vars.i18n_time_error);
  726. return false;
  727. }
  728. appt_add_confirm = confirm(booked_js_vars.i18n_bulk_add_confirm);
  729. if (appt_add_confirm == true){
  730. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  731. type : 'post',
  732. url : booked_js_vars.ajax_url,
  733. data : formData,
  734. beforeSend: function(){
  735. savingState(true);
  736. },
  737. success: function(data) {
  738. response = JSON.parse(data);
  739. currentTimesBox.val( JSON.stringify( response.timeslot ) );
  740. currentTimesDetailsBox.val( JSON.stringify( response.timeslot_details ) );
  741. $button.attr('disabled',false);
  742. $('#booked-customTimePickerTemplates').find('input').val('').attr('checked',false);
  743. $('#booked-customTimePickerTemplates').find('select').prop('selectedIndex',0);
  744. $('#booked-customTimePickerTemplates').find('.customBulk,customSingle').hide();
  745. $('#booked-customTimePickerTemplates').hide().appendTo('#booked-custom-timeslots');
  746. $('button.addBulkTimeslots').prop('disabled',false);
  747. $('button.addSingleTimeslot').prop('disabled',false);
  748. $('#booked-saveCustomTimeslots').prop('disabled',false);
  749. updateCustomTimeslotEncodedField();
  750. loadCustomTimeSlots(timeslotList,data);
  751. $('#booked-saveCustomTimeslots').trigger('click');
  752. }
  753. });
  754. }
  755. } else {
  756. $button.attr('disabled',false);
  757. alert(booked_js_vars.i18n_all_fields_required);
  758. return false;
  759. }
  760. });
  761. }
  762. function hideAddCustomTimeslotsForm(){
  763. $('#booked-customTimePickerTemplates').find('.customBulk,customSingle').hide();
  764. $('#booked-customTimePickerTemplates').hide().appendTo('#booked-custom-timeslots');
  765. $('button.addBulkTimeslots').attr('disabled',false);
  766. $('button.addSingleTimeslot').attr('disabled',false);
  767. updateCustomTimeslotEncodedField();
  768. }
  769. function loadCustomTimeSlots(timeslotsBlock,json_array){
  770. var parentTimeslotBlock = timeslotsBlock.parents('.booked-customTimeslot'),
  771. start_date = parentTimeslotBlock.find('[name="booked_custom_start_date"]').val(),
  772. end_date = parentTimeslotBlock.find('[name="booked_custom_end_date"]').val(),
  773. calendar_id = parentTimeslotBlock.find('[name="booked_custom_calendar_id"]').val(),
  774. json_array_jsoned = JSON.parse(json_array);
  775. $.ajax({
  776. url : booked_js_vars.ajax_url,
  777. type : 'post',
  778. data : {'action':'booked_admin_custom_timeslots_list','json_array':JSON.stringify(json_array_jsoned.timeslot),'json_array_detailed':JSON.stringify(json_array_jsoned.timeslot_details),'start_date':start_date,'end_date':end_date,'calendar_id':calendar_id},
  779. success : function(html){
  780. timeslotsBlock.html( html );
  781. }
  782. });
  783. }
  784. $('#booked-custom-timeslots').on('click','#booked-saveCustomTimeslots',function(e){
  785. e.preventDefault();
  786. var custom_timeslots_encoded = $('#custom_timeslots_encoded').val();
  787. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  788. type : 'post',
  789. url : booked_js_vars.ajax_url,
  790. data : {
  791. 'action' : 'booked_admin_save_custom_time_slots',
  792. 'custom_timeslots_encoded' : custom_timeslots_encoded
  793. },
  794. beforeSend: function(){
  795. $('#booked-saveCustomTimeslots').attr('disabled',true);
  796. savingState(true);
  797. },
  798. success: function(data) {
  799. $('#customTimeslotsContainer .booked-customTimeslot').css('border-color','#ddd');
  800. $('#booked-saveCustomTimeslots').prop('disabled',true).removeClass('button-primary');
  801. }
  802. });
  803. });
  804. /* END Custom Time Slots */
  805. if ($('.booked-color-field').length){
  806. $('.booked-color-field').wpColorPicker();
  807. }
  808. // Upload Image Button
  809. var _custom_media = true,
  810. _orig_send_attachment = wp.media.editor.send.attachment;
  811. $('#booked_email_logo_button').click(function(e) {
  812. var send_attachment_bkp = wp.media.editor.send.attachment;
  813. var button = $(this);
  814. var id = button.attr('id').replace('_button', '');
  815. _custom_media = true;
  816. wp.media.editor.send.attachment = function(props, attachment){
  817. if ( _custom_media ) {
  818. $("#"+id).val(attachment.url);
  819. $("#"+id+"-img").attr('src',attachment.url).show();
  820. $('#booked_email_logo_button_remove').show();
  821. } else {
  822. return _orig_send_attachment.apply( this, [props, attachment] );
  823. };
  824. }
  825. wp.media.editor.open(button);
  826. return false;
  827. });
  828. $('#booked_email_logo_button_remove').click(function(e) {
  829. e.preventDefault();
  830. $("#booked_email_logo").val('');
  831. $("#booked_email_logo-img").attr('src','').hide();
  832. $(this).hide();
  833. });
  834. // END Upload Image Button
  835. // Custom Fields
  836. var CF_SortablesForm = $('#booked-cf-sortables-form'),
  837. CF_SortablesContainer = $('#booked-cf-sortables'),
  838. CF_SortablesTemplatesContainer = $('#booked-cf-sortable-templates'),
  839. CF_SingleLineTextTemplate = $('#bookedCFTemplate-single-line-text'),
  840. CF_ParagraphTextTemplate = $('#bookedCFTemplate-paragraph-text'),
  841. CF_CheckboxesTemplate = $('#bookedCFTemplate-checkboxes'),
  842. CF_RadioButtonsTemplate = $('#bookedCFTemplate-radio-buttons'),
  843. CF_DropDownTemplate = $('#bookedCFTemplate-drop-down');
  844. init_booked_custom_fields();
  845. $('body').on('keyup','#booked-cf-sortables input',function() {
  846. update_CF_Data(CF_SortablesForm);
  847. });
  848. $('body').on('keyup','#booked-cf-sortables textarea',function() {
  849. update_CF_Data(CF_SortablesForm);
  850. });
  851. $('body').on('click','.booked-cf-block .cfButton',function(e){
  852. e.preventDefault();
  853. var CF_ButtonType = $(this).attr('data-type');
  854. appendLocation = $(this).parent().find('ul:first');
  855. var newSortable = CF_SortablesTemplatesContainer.find('#bookedCFTemplate-'+CF_ButtonType).clone().appendTo(appendLocation);
  856. // Assign this field a random number
  857. if (CF_ButtonType == 'plain-text-content'){
  858. var thisInput = newSortable.find('textarea[name="'+CF_ButtonType+'"]');
  859. var thisRequiredCheckbox = false;
  860. } else {
  861. var thisInput = newSortable.find('input[name="'+CF_ButtonType+'"]');
  862. var thisRequiredCheckbox = newSortable.find('input[name="required"]');
  863. }
  864. if (CF_ButtonType == 'single-radio-button'){
  865. var thisTextField = $(this).parents('li').find('input[type=text]:first').attr('name');
  866. thisTextField = thisTextField.split('---');
  867. var randomNumber = thisTextField[1];
  868. randomNumber = randomNumber.split('___');
  869. randomNumber = randomNumber[0];
  870. } else if (CF_ButtonType == 'single-checkbox'){
  871. var thisTextField = $(this).parents('li').find('input[type=text]:first').attr('name');
  872. thisTextField = thisTextField.split('---');
  873. var randomNumber = thisTextField[1];
  874. randomNumber = randomNumber.split('___');
  875. randomNumber = randomNumber[0];
  876. } else {
  877. var randomNumber = Math.floor((Math.random() * 9999999) + 1000000);
  878. }
  879. if (CF_ButtonType != 'plain-text-content'){
  880. thisRequiredCheckbox.attr('name','required---'+randomNumber).attr('id','required---'+randomNumber).parent().find('label').attr('for','required---'+randomNumber);
  881. }
  882. thisInput.attr('name',CF_ButtonType+'---'+randomNumber);
  883. thisInput.css('border-color','#FFBA00');
  884. /*
  885. * allow other script to apply their modification before initializing the sortables
  886. * $(document).on("booked-on-cbutton-click", function(event, params) { code goes here });
  887. */
  888. $(document).trigger("booked-on-cbutton-click", {
  889. button_object: $(this),
  890. this_input: thisInput,
  891. button_type: CF_ButtonType,
  892. random_number: randomNumber
  893. });
  894. CF_SortablesContainer.show();
  895. init_booked_cf_sortables();
  896. });
  897. $('body').on('change','.booked-cf-block .cf-required-checkbox',function(e){
  898. var thisCheckboxVal = $(this).attr('checked');
  899. var thisTextField = $(this).parents('li').find('input[type=text]:first');
  900. var currentValue = thisTextField.attr('name');
  901. if (thisCheckboxVal == 'checked'){
  902. thisTextField.attr('name',currentValue+'___required');
  903. } else {
  904. currentValue = currentValue.split('___');
  905. currentValue = currentValue[0];
  906. thisTextField.attr('name',currentValue);
  907. }
  908. update_CF_Data(CF_SortablesForm);
  909. });
  910. $('body').on('click','.booked-cf-block .cf-delete',function(e){
  911. var confirm_delete = confirm("Are you sure you want to delete this field?");
  912. if (confirm_delete){
  913. $(this).parent().remove();
  914. if ($('#booked-cf-sortables').is(':empty')){
  915. $('#booked-cf-sortables').hide();
  916. }
  917. update_CF_Data(CF_SortablesForm);
  918. }
  919. });
  920. function update_CF_Data(CF_SortablesForm){
  921. var sortableContent = JSON.stringify(CF_SortablesForm.serializeArray());
  922. $('#booked_custom_fields').val(sortableContent);
  923. }
  924. function init_booked_custom_fields(){
  925. CF_SortablesForm = $('#booked-cf-sortables-form');
  926. CF_SortablesContainer = $('#booked-cf-sortables');
  927. if (CF_SortablesContainer.length){
  928. if (!CF_SortablesContainer.is(':empty')){
  929. CF_SortablesContainer.show();
  930. }
  931. var CF_SortingObject = CF_SortablesContainer.sortable({
  932. handle: ".main-handle",
  933. stop: function(){
  934. update_CF_Data(CF_SortablesForm);
  935. }
  936. });
  937. init_booked_cf_sortables();
  938. }
  939. }
  940. function init_booked_cf_sortables(){
  941. CF_SortablesForm = $('#booked-cf-sortables-form');
  942. $('#booked-cf-checkboxes').sortable({
  943. handle: ".sub-handle",
  944. stop: function(){
  945. update_CF_Data(CF_SortablesForm);
  946. }
  947. });
  948. $('#booked-cf-radio-buttons').sortable({
  949. handle: ".sub-handle",
  950. stop: function(){
  951. update_CF_Data(CF_SortablesForm);
  952. }
  953. });
  954. $('#booked-cf-drop-down').sortable({
  955. handle: ".sub-handle",
  956. stop: function(){
  957. update_CF_Data(CF_SortablesForm);
  958. }
  959. });
  960. update_CF_Data(CF_SortablesForm);
  961. }
  962. $('#booked-custom-fields').on('click','#booked-cf-saveButton',function(e){
  963. e.preventDefault();
  964. var booked_custom_fields = $('#booked_custom_fields').val(),
  965. booked_cf_calendar_id = $('#booked-cfSwitcher select').val();
  966. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  967. type : 'post',
  968. url : booked_js_vars.ajax_url,
  969. data : {
  970. 'action' : 'booked_admin_save_custom_fields',
  971. 'booked_custom_fields' : booked_custom_fields,
  972. 'booked_cf_calendar_id' : booked_cf_calendar_id
  973. },
  974. beforeSend: function(){
  975. $('#booked-cf-saveButton').attr('disabled',true);
  976. savingState(true);
  977. },
  978. success: function(data) {
  979. $('#booked-cf-saveButton').attr('disabled',false);
  980. $('#booked-cf-sortables input[type=text]').css('border-color','#ccc');
  981. $('#booked-cf-sortables textarea').css('border-color','#ccc');
  982. }
  983. });
  984. });
  985. // END Custom Fields
  986. var checkedClass = 'custom-input-checked';
  987. var disabledClass = 'custom-input-disabled';
  988. /* Main Admin Tabs */
  989. if ($('.booked-admin-tabs').length){
  990. // Tabs
  991. $('.tab-content').hide();
  992. var adminTabs = $('.booked-admin-tabs');
  993. var tabHash = window.location.hash;
  994. if (tabHash){
  995. var activeTab = tabHash;
  996. activeTab = activeTab.split('#');
  997. activeTab = activeTab[1];
  998. adminTabs.find('li').removeClass('active');
  999. adminTabs.find('a[href="'+tabHash+'"]').parent().addClass('active');
  1000. $('#booked-'+activeTab).show();
  1001. } else {
  1002. var activeTab = adminTabs.find('.active > a').attr('href');
  1003. activeTab = activeTab.split('#');
  1004. activeTab = activeTab[1];
  1005. $('#booked-'+activeTab).show();
  1006. }
  1007. adminTabs.find('li > a').on('click', function(e) {
  1008. //e.preventDefault();
  1009. $('.tab-content').hide();
  1010. adminTabs.find('li').removeClass('active');
  1011. $(this).parent().addClass('active');
  1012. var activeTab = $(this).attr('href');
  1013. activeTab = activeTab.split('#');
  1014. activeTab = activeTab[1];
  1015. if (activeTab == 'import_export_uninstall'){
  1016. $('.submit-section').hide();
  1017. } else {
  1018. $('.submit-section').show();
  1019. }
  1020. $('#booked-'+activeTab).show();
  1021. });
  1022. }
  1023. /* Admin Sub-Tabs */
  1024. if ($('.booked-admin-subtabs').length){
  1025. // Tabs
  1026. $('.subtab-content').hide();
  1027. var adminSubTabs = $('.booked-admin-subtabs');
  1028. adminSubTabs.each(function(){
  1029. theseSubTabs = $(this);
  1030. var thisWrapper = theseSubTabs.parents('.tab-content');
  1031. var activeSubTab = theseSubTabs.find('.active > a').attr('href');
  1032. activeSubTab = activeSubTab.split('#');
  1033. activeSubTab = activeSubTab[1];
  1034. $('#booked-subtab-'+activeSubTab).show();
  1035. theseSubTabs.find('li > a').on('click', function(e) {
  1036. e.preventDefault();
  1037. thisWrapper.find('.subtab-content').hide();
  1038. theseSubTabs.find('li').removeClass('active');
  1039. $(this).parent().addClass('active');
  1040. var activeSubTab = $(this).attr('href');
  1041. activeSubTab = activeSubTab.split('#');
  1042. activeSubTab = activeSubTab[1];
  1043. $('#booked-subtab-'+activeSubTab).show();
  1044. });
  1045. });
  1046. }
  1047. /* Click the Cancel button */
  1048. $('#bookedTimeslotsWrap').on('click','td.addTimeslot .cancel',function(e){
  1049. e.preventDefault();
  1050. reset_add_timeslot_button();
  1051. });
  1052. function reset_add_timeslot_button(){
  1053. var addButton = $('#bookedTimeslotsWrap').find('.addTimeslot.active').find('a.booked-add-timeslot');
  1054. var dayName = addButton.parent().attr('data-day');
  1055. var clearButton = $('table.booked-timeslots th[data-day="'+dayName+'"]').find('.booked-clear-timeslots');
  1056. $('td.addTimeslot').find('select').show();
  1057. $('td.addTimeslot').removeClass('active');
  1058. $('td.addTimeslot a.button').html( booked_js_vars.i18n_add ).removeClass('button-primary').appendTo('table.booked-timeslots th[data-day="'+dayName+'"]');
  1059. $('#timepickerTemplate').appendTo( '#booked-defaults' ).hide();
  1060. clearButton.show();
  1061. }
  1062. $('#timepickerTemplate .tsSingle,#booked-customTimePickerTemplates .customSingle').on('change','select[name="startTime"]',function(){
  1063. var thisSelectBox = $(this);
  1064. var thisSelectBoxVal = thisSelectBox.val();
  1065. if (thisSelectBoxVal == 'allday'){
  1066. thisSelectBox.parent().find('select[name="endTime"]').val('2400').hide();
  1067. } else {
  1068. thisSelectBox.parent().find('select[name="endTime"]').val('').show();
  1069. }
  1070. });
  1071. /* Click the Clear button */
  1072. $('#bookedTimeslotsWrap').on('click','a.booked-clear-timeslots',function(e){
  1073. e.preventDefault();
  1074. var thisButton = $(this);
  1075. var dayName = thisButton.parent().attr('data-day');
  1076. var parentBlock = $('#bookedTimeslotsWrap').find('td.addTimeslot[data-day="'+dayName+'"]');
  1077. var day = thisButton.parents('th').attr('data-day');
  1078. var calendar_id = $('table.booked-timeslots').attr('data-calendar-id');
  1079. clear_timelots_confirm = confirm(booked_js_vars.i18n_clear_timeslots_confirm);
  1080. if (clear_timelots_confirm == true){
  1081. $.ajax({
  1082. url : booked_js_vars.ajax_url,
  1083. type : 'post',
  1084. data : {'action':'booked_admin_clear_timeslots','day':day,'calendar_id':calendar_id},
  1085. beforeSend: function(){
  1086. savingState(true);
  1087. },
  1088. success: function(data) {
  1089. reset_add_timeslot_button();
  1090. $.ajax({
  1091. url : booked_js_vars.ajax_url,
  1092. type : 'post',
  1093. data : {'action':'booked_admin_load_timeslots','day':day,'calendar_id':calendar_id},
  1094. success : function(html){
  1095. $('td.dayTimeslots[data-day="'+day+'"]').html( html );
  1096. }
  1097. });
  1098. }
  1099. });
  1100. }
  1101. });
  1102. /* Click the Add button */
  1103. $('#bookedTimeslotsWrap').on('click','a.booked-add-timeslot',function(e){
  1104. e.preventDefault();
  1105. var thisButton = $(this);
  1106. var clearButton = thisButton.parent().find('.booked-clear-timeslots');
  1107. var dayName = thisButton.parent().attr('data-day');
  1108. var parentBlock = $('#bookedTimeslotsWrap').find('td.addTimeslot[data-day="'+dayName+'"]');
  1109. var allTimeslotParents = $('#bookedTimeslotsWrap td.addTimeslot');
  1110. if (thisButton.hasClass('button-primary')){
  1111. var activeTab = $('.addTimeslotTab.active').attr('href');
  1112. if (activeTab == '#Bulk'){
  1113. // Bulk add
  1114. var $button = $(this),
  1115. day = $button.parents('td').attr('data-day'),
  1116. startTime = $('.tsBulk').find('select[name=startTime]').val(),
  1117. startTimeText = $('.tsBulk').find('select[name=startTime] :selected').text(),
  1118. endTime = $('.tsBulk').find('select[name=endTime]').val(),
  1119. endTimeText = $('.tsBulk').find('select[name=endTime] :selected').text(),
  1120. interval = $('.tsBulk').find('select[name=interval]').val(),
  1121. time_between = $('.tsBulk').find('select[name=time_between]').val(),
  1122. intervalText = $('.tsBulk').find('select[name=interval] :selected').text(),
  1123. count = $('.tsBulk').find('select[name=count]').val(),
  1124. calendar_id = $('table.booked-timeslots').attr('data-calendar-id'),
  1125. countText = $('.tsBulk').find('select[name=count] :selected').text();
  1126. var formData = $('#bulk-timeslot-form').serializeObject();
  1127. formData['action'] = 'booked_admin_add_timeslots';
  1128. formData['day'] = day;
  1129. formData['calendar_id'] = calendar_id;
  1130. if (startTime && endTime && interval && count){
  1131. if (endTime <= startTime){
  1132. alert(booked_js_vars.i18n_time_error);
  1133. return false;
  1134. }
  1135. appt_add_confirm = confirm(booked_js_vars.i18n_bulk_add_confirm);
  1136. if (appt_add_confirm == true){
  1137. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1138. type : 'post',
  1139. url : booked_js_vars.ajax_url,
  1140. data : formData,
  1141. beforeSend: function(){
  1142. savingState(true);
  1143. },
  1144. success: function(data) {
  1145. reset_add_timeslot_button();
  1146. $.ajax({
  1147. url : booked_js_vars.ajax_url,
  1148. type : 'post',
  1149. data : {'action':'booked_admin_load_timeslots','day':day,'calendar_id':calendar_id},
  1150. success : function(html){
  1151. $('td.dayTimeslots[data-day="'+day+'"]').html( html );
  1152. }
  1153. });
  1154. }
  1155. });
  1156. }
  1157. } else {
  1158. alert(booked_js_vars.i18n_all_fields_required);
  1159. }
  1160. } else {
  1161. // Single add
  1162. var $button = $(this),
  1163. day = $button.parents('td').attr('data-day'),
  1164. startTime = $('.tsSingle').find('select[name=startTime] :selected').val(),
  1165. startTimeText = $('.tsSingle').find('select[name=startTime] :selected').text(),
  1166. endTime = $('.tsSingle').find('select[name=endTime] :selected').val(),
  1167. endTimeText = $('.tsSingle').find('select[name=endTime] :selected').text(),
  1168. count = $('.tsSingle').find('select[name=count] :selected').val(),
  1169. calendar_id = $('table.booked-timeslots').attr('data-calendar-id'),
  1170. countText = $('.tsSingle').find('select[name=count] :selected').text();
  1171. var formData = $('#single-timeslot-form').serializeObject();
  1172. formData['action'] = 'booked_admin_add_timeslot';
  1173. formData['day'] = day;
  1174. formData['calendar_id'] = calendar_id;
  1175. if (startTime && endTime && count){
  1176. if (endTime <= startTime && startTime != 'allday'){
  1177. alert(booked_js_vars.i18n_time_error);
  1178. return false;
  1179. }
  1180. if (startTime == '0000' && endTime == '2400' || startTime == 'allday' && endTime == '2400'){
  1181. appt_add_confirm = confirm(booked_js_vars.i18n_single_add_confirm + ':\n'+booked_js_vars.i18n_all_day+' x'+count);
  1182. } else {
  1183. appt_add_confirm = confirm(booked_js_vars.i18n_single_add_confirm + ':\n'+startTimeText+' '+booked_js_vars.i18n_to+' '+endTimeText+' x'+count);
  1184. }
  1185. if (appt_add_confirm == true){
  1186. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1187. type : 'post',
  1188. url : booked_js_vars.ajax_url,
  1189. data : formData,
  1190. beforeSend: function(){
  1191. savingState(true);
  1192. },
  1193. success: function(data) {
  1194. reset_add_timeslot_button();
  1195. $.ajax({
  1196. url : booked_js_vars.ajax_url,
  1197. type : 'post',
  1198. data : {'action':'booked_admin_load_timeslots','day':day,'calendar_id':calendar_id},
  1199. success : function(html){
  1200. $('td.dayTimeslots[data-day="'+day+'"]').html( html );
  1201. }
  1202. });
  1203. }
  1204. });
  1205. }
  1206. } else {
  1207. alert(booked_js_vars.i18n_all_fields_required);
  1208. }
  1209. }
  1210. } else {
  1211. reset_add_timeslot_button();
  1212. allTimeslotParents.removeClass('active');
  1213. allTimeslotParents.find('a.button').html(booked_js_vars.i18n_add).removeClass('button-primary');
  1214. $('#timepickerTemplate').appendTo('#booked-defaults').hide();
  1215. parentBlock.addClass('active');
  1216. thisButton.html(booked_js_vars.i18n_add).addClass('button-primary');
  1217. init_timeslot_tabs();
  1218. var thisForm = $('#timepickerTemplate').prependTo(parentBlock).show();
  1219. clearButton.hide();
  1220. thisButton.appendTo(parentBlock);
  1221. }
  1222. });
  1223. $('#bookedTimeslotsWrap').on('change','select[name=startTime]',function(e) {
  1224. var endTimeSelect = $(this).parent().find('select[name=endTime]');
  1225. var startTimeVal = $(this).val();
  1226. endTimeSelect.find('option').removeAttr('disabled');
  1227. endTimeSelect.find('option').each(function() {
  1228. var thisVal = $(this).val();
  1229. if (thisVal <= startTimeVal){
  1230. $(this).attr('disabled',true);
  1231. }
  1232. });
  1233. });
  1234. var preventMultiClicks;
  1235. // Change Timeslot Count
  1236. $('#bookedTimeslotsWrap').on('click', '.slotsBlock .changeCount', function(e) {
  1237. e.preventDefault();
  1238. if (!currentlySaving){
  1239. var $button = $(this),
  1240. $timeslot = $button.parents('.timeslot');
  1241. $countText = $button.parent().find('.count'),
  1242. day = $button.parents('td').attr('data-day'),
  1243. timeslot = $button.parents('.timeslot').attr('data-timeslot'),
  1244. countAdjust = $button.attr('data-count'),
  1245. calendar_id = $('table.booked-timeslots').attr('data-calendar-id'),
  1246. currentCount = $countText.find('em').text();
  1247. clearTimeout(preventMultiClicks);
  1248. newCount = parseInt(currentCount) + parseInt(countAdjust);
  1249. if (newCount < 1) {
  1250. newCount = 1;
  1251. } else {
  1252. if (newCount != 1) { slot_text = booked_js_vars.i18n_slots; } else { slot_text = booked_js_vars.i18n_slot; }
  1253. $countText.html('<em>' + newCount + '</em> ' + slot_text);
  1254. preventMultiClicks = setTimeout(function(){
  1255. $timeslot.css({'opacity':0.5});
  1256. savingState(true);
  1257. currentlySaving = true;
  1258. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1259. type : 'post',
  1260. url : booked_js_vars.ajax_url,
  1261. data : {
  1262. 'action' : 'booked_admin_adjust_default_timeslot_count',
  1263. 'newCount' : newCount,
  1264. 'calendar_id' : calendar_id,
  1265. 'day' : day,
  1266. 'timeslot' : timeslot
  1267. },
  1268. success: function(data) {
  1269. currentlySaving = false;
  1270. $timeslot.css({'opacity':1});
  1271. }
  1272. });
  1273. },350);
  1274. }
  1275. }
  1276. return false;
  1277. });
  1278. // Delete Timeslot
  1279. $('#bookedTimeslotsWrap').on('click', '.timeslot .delete', function(e) {
  1280. e.preventDefault();
  1281. var $button = $(this),
  1282. $timeslot = $button.parents('.timeslot'),
  1283. day = $button.parents('td').attr('data-day'),
  1284. timeslot = $button.parents('.timeslot').attr('data-timeslot'),
  1285. calendar_id = $('table.booked-timeslots').attr('data-calendar-id'),
  1286. startText = $timeslot.find('.start').html(),
  1287. endText = $timeslot.find('.end').html();
  1288. confirm_ts_delete = confirm(booked_js_vars.i18n_confirm_ts_delete);
  1289. if (confirm_ts_delete == true){
  1290. $timeslot.slideUp('fast',function(){
  1291. $(this).remove();
  1292. });
  1293. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1294. type : 'post',
  1295. url : booked_js_vars.ajax_url,
  1296. data : {
  1297. 'action' : 'booked_admin_delete_timeslot',
  1298. 'day' : day,
  1299. 'calendar_id' : calendar_id,
  1300. 'timeslot' : timeslot
  1301. },
  1302. beforeSend: function(){
  1303. savingState(true);
  1304. },
  1305. success: function(data) {
  1306. // Do nothing
  1307. }
  1308. });
  1309. }
  1310. });
  1311. // Time Slots Calendar Switcher
  1312. $('#booked-timeslotsSwitcher').on('change','select[name="bookedTimeslotsDisplayed"]',function(e){
  1313. var calendar_id = $(this).val(),
  1314. allTimeslotParents = $('#bookedTimeslotsWrap td.addTimeslot');
  1315. allTimeslotParents.find('select').val('');
  1316. allTimeslotParents.removeClass('active');
  1317. allTimeslotParents.find('a.button').html(booked_js_vars.i18n_add).removeClass('button-primary');
  1318. $('#timepickerTemplate').appendTo('#booked-defaults').hide();
  1319. savingState(true);
  1320. $('table.booked-timeslots tbody').addClass('faded');
  1321. $.ajax({
  1322. url : booked_js_vars.ajax_url,
  1323. type : 'post',
  1324. data : {'action':'booked_admin_load_full_timeslots','calendar_id':calendar_id},
  1325. success : function(html){
  1326. $('#bookedTimeslotsWrap').html( html );
  1327. init_timeslot_tabs();
  1328. $('table.booked-timeslots tbody').removeClass('faded');
  1329. }
  1330. });
  1331. });
  1332. // Custom Fields Calendar Switcher
  1333. $('#booked-cfSwitcher').on('change','select[name="bookedCustomFieldsDisplayed"]',function(e){
  1334. var calendar_id = $(this).val();
  1335. $('#booked_customFields_Wrap').addClass('faded');
  1336. $.ajax({
  1337. url : booked_js_vars.ajax_url,
  1338. type : 'post',
  1339. data : {'action':'booked_admin_load_full_customfields','calendar_id':calendar_id},
  1340. success : function(html){
  1341. $('#booked_customFields_Wrap').html( html );
  1342. $('#booked_customFields_Wrap').removeClass('faded');
  1343. init_booked_custom_fields();
  1344. }
  1345. });
  1346. });
  1347. // Calendar Switcher
  1348. $('.booked-calendarSwitcher').on('change','select[name="bookedCalendarDisplayed"]',function(e){
  1349. var calendar_id = $(this).val(),
  1350. currentMonth = $('table.booked-calendar').attr('data-monthShown');
  1351. savingState(true);
  1352. $.ajax({
  1353. url : booked_js_vars.ajax_url,
  1354. type : 'post',
  1355. data : {'action':'booked_admin_calendar_month','gotoMonth':currentMonth,'calendar_id':calendar_id},
  1356. success : function(html){
  1357. $('.booked-admin-calendar-wrap').html( html );
  1358. adjust_calendar_boxes();
  1359. }
  1360. });
  1361. });
  1362. // Calendar Next/Prev Click
  1363. $('body').on('click', '.booked-admin-calendar-wrap .page-right, .booked-admin-calendar-wrap .page-left, .booked-admin-calendar-wrap .monthName a', function(e) {
  1364. e.preventDefault();
  1365. var $button = $(this),
  1366. gotoMonth = $button.attr('data-goto'),
  1367. calendar_id = $('table.booked-calendar').attr('data-calendar-id');
  1368. savingState(true);
  1369. $.ajax({
  1370. url : booked_js_vars.ajax_url,
  1371. type : 'post',
  1372. data : {'action':'booked_admin_calendar_month','gotoMonth':gotoMonth,'calendar_id':calendar_id},
  1373. success : function(html){
  1374. $('.booked-admin-calendar-wrap').html( html );
  1375. adjust_calendar_boxes();
  1376. }
  1377. });
  1378. return false;
  1379. });
  1380. // Calendar Date Click
  1381. $('.booked-admin-calendar-wrap').on('click', 'tr.week td', function(e) {
  1382. e.preventDefault();
  1383. var $thisDate = $(this),
  1384. $thisRow = $thisDate.parent(),
  1385. date = $thisDate.attr('data-date'),
  1386. calendar_id = $('table.booked-calendar').attr('data-calendar-id'),
  1387. colspanSetting = $thisRow.find('td').length;
  1388. if ($thisDate.hasClass('blur')){
  1389. // Do nothing.
  1390. } else if ($thisDate.hasClass('active')){
  1391. $thisDate.removeClass('active');
  1392. $('tr.entryBlock').remove();
  1393. } else {
  1394. $('tr.week td').removeClass('active');
  1395. $thisDate.addClass('active');
  1396. $('tr.entryBlock').remove();
  1397. $thisRow.after('<tr class="entryBlock booked-loading"><td colspan="'+colspanSetting+'"></td></tr>');
  1398. $('tr.entryBlock').find('td').spin('booked');
  1399. $.ajax({
  1400. url : booked_js_vars.ajax_url,
  1401. type : 'post',
  1402. data : {'action':'booked_admin_calendar_date','date':date,'calendar_id':calendar_id},
  1403. success : function(html){
  1404. $('tr.entryBlock').find('td').html( html );
  1405. $('tr.entryBlock').removeClass('booked-loading');
  1406. $('tr.entryBlock').find('.booked-appt-list').fadeIn(300);
  1407. $('tr.entryBlock').find('.booked-appt-list').addClass('shown');
  1408. $('.bookedAppointmentTab.active').fadeIn(300);
  1409. }
  1410. });
  1411. }
  1412. return false;
  1413. });
  1414. // Delete Appointment Click from Calendar
  1415. $('.booked-admin-calendar-wrap').on('click', 'tr.entryBlock .delete', function(e) {
  1416. e.preventDefault();
  1417. var $button = $(this),
  1418. $thisParent = $button.parents('.timeslot'),
  1419. $thisTimeslot = $button.parents('.timeslot'),
  1420. $activeTD = $('td.active'),
  1421. $addlParent = $thisTimeslot.parents('.additional-timeslots'),
  1422. appt_id = $thisTimeslot.attr('data-appt-id'),
  1423. date = $activeTD.attr('data-date'),
  1424. calendar_id = $button.attr('data-calendar-id');
  1425. if (!appt_id){
  1426. appt_id = $button.parents('.appt-block').attr('data-appt-id');
  1427. $thisParent = $button.parents('.appt-block');
  1428. }
  1429. confirm_appt_delete = confirm(booked_js_vars.i18n_confirm_appt_delete);
  1430. if (confirm_appt_delete == true){
  1431. $thisParent.slideUp('fast',function(){
  1432. $(this).remove();
  1433. if ($addlParent.length){
  1434. if (!$addlParent.find('.timeslot').length){
  1435. $addlParent.remove();
  1436. }
  1437. } else {
  1438. if (!$thisTimeslot.find('.appt-block').length){
  1439. $thisTimeslot.find('strong').remove();
  1440. }
  1441. }
  1442. });
  1443. $thisTimeslot.addClass('faded');
  1444. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1445. type : 'post',
  1446. url : booked_js_vars.ajax_url,
  1447. data : {
  1448. 'action' : 'booked_admin_delete_appt',
  1449. 'appt_id' : appt_id
  1450. },
  1451. success: function(data) {
  1452. $.ajax({
  1453. url : booked_js_vars.ajax_url,
  1454. type : 'post',
  1455. data : {'action':'booked_admin_calendar_date','date':date,'calendar_id':calendar_id},
  1456. success : function(html){
  1457. $('tr.entryBlock').find('td').html( html );
  1458. $('tr.entryBlock').find('.booked-appt-list').show();
  1459. $('tr.entryBlock').find('.booked-appt-list').addClass('shown');
  1460. $('.bookedAppointmentTab.active').fadeIn(300);
  1461. }
  1462. });
  1463. $.ajax({
  1464. url : booked_js_vars.ajax_url,
  1465. type : 'post',
  1466. data : {'action':'booked_admin_refresh_date_square','date':date,'calendar_id':calendar_id},
  1467. success : function(html){
  1468. $activeTD.replaceWith(html);
  1469. adjust_calendar_boxes();
  1470. }
  1471. });
  1472. }
  1473. });
  1474. }
  1475. return false;
  1476. });
  1477. // Approve Appointment in Calendar
  1478. $('.booked-admin-calendar-wrap').on('click', 'tr.entryBlock .approve', function(e) {
  1479. e.preventDefault();
  1480. var $button = $(this),
  1481. $thisParent = $button.parents('.timeslot'),
  1482. appt_id = $thisParent.attr('data-appt-id');
  1483. if (!appt_id){
  1484. $thisParent = $button.parents('.appt-block');
  1485. appt_id = $button.attr('data-appt-id');
  1486. }
  1487. confirm_appt_approve = confirm(booked_js_vars.i18n_confirm_appt_approve);
  1488. if (confirm_appt_approve == true){
  1489. $(document).trigger("booked-on-calendar-approve", appt_id);
  1490. $button.remove();
  1491. $thisParent.find('.pending-text').remove();
  1492. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1493. type : 'post',
  1494. url : booked_js_vars.ajax_url,
  1495. data : {
  1496. 'action' : 'booked_admin_approve_appt',
  1497. 'appt_id' : appt_id
  1498. },
  1499. success: function(data) {
  1500. // Do nothing
  1501. }
  1502. });
  1503. }
  1504. return false;
  1505. });
  1506. // User Info Click
  1507. $('body').on('click', '.booked-pending-appt-list .user, .booked-admin-calendar-wrap tr.entryBlock .user', function(e) {
  1508. e.preventDefault();
  1509. var $thisLink = $(this),
  1510. user_id = $thisLink.attr('data-user-id'),
  1511. appt_id = $thisLink.parent().attr('data-appt-id');
  1512. create_booked_modal();
  1513. $.ajax({
  1514. url : booked_js_vars.ajax_url,
  1515. type : 'post',
  1516. data : {'action':'booked_admin_user_info_modal','user_id':user_id,'appt_id':appt_id},
  1517. success : function(html){
  1518. $('.bm-window').html( html );
  1519. var bookedModal = $('.booked-modal');
  1520. var bmWindow = bookedModal.find('.bm-window');
  1521. bmWindow.css({'visibility':'hidden'});
  1522. bookedModal.removeClass('bm-loading');
  1523. resize_booked_modal();
  1524. bmWindow.hide();
  1525. bmWindow.find('.booked_appt_date').datepicker({
  1526. showOn: "button",
  1527. buttonText: booked_js_vars.i18n_change_date,
  1528. dateFormat: "yy-mm-dd",
  1529. beforeShow: function(input, inst) {
  1530. $('#ui-datepicker-div').removeClass();
  1531. $('#ui-datepicker-div').addClass('booked_custom_date_picker');
  1532. },
  1533. onSelect: function(selected) {
  1534. bmWindow.find('.ui-datepicker-trigger').attr('disabled',true);
  1535. var appt_id = $('#editAppointmentForm').data('appt-id');
  1536. booked_update_timeslot_select_field( appt_id, selected );
  1537. booked_datepicker_show_formatted_date( 'booked_appt_date', selected );
  1538. }
  1539. });
  1540. setTimeout(function(){
  1541. bmWindow.find('.ui-datepicker-trigger').addClass('button');
  1542. bmWindow.css({'visibility':'visible'});
  1543. bmWindow.show();
  1544. },50);
  1545. }
  1546. });
  1547. return false;
  1548. });
  1549. $('.booked-admin-calendar-wrap').on('click', '#bookedAppointmentTabs li a', function(e) {
  1550. e.preventDefault();
  1551. var $thisTab = $(this);
  1552. var tabName = $thisTab.attr('href').split('#calendar-');
  1553. tabName = tabName[1];
  1554. $('#bookedAppointmentTabs li').removeClass('active');
  1555. $('.bookedAppointmentTab').hide();
  1556. $('.bookedAppointmentTab').removeClass('active');
  1557. $thisTab.parent().addClass('active');
  1558. $('#bookedCalendarAppointmentsTab-'+tabName).fadeIn(100);
  1559. $('#bookedCalendarAppointmentsTab-'+tabName).addClass('active');
  1560. return false;
  1561. });
  1562. // New Appointment Click
  1563. $('.booked-admin-calendar-wrap').on('click', 'tr.entryBlock button.new-appt', function(e) {
  1564. e.preventDefault();
  1565. var $button = $(this),
  1566. timeslot = $button.attr('data-timeslot'),
  1567. title = $button.attr('data-title'),
  1568. date = $button.attr('data-date'),
  1569. $thisTimeslot = $button.parents('.timeslot'),
  1570. calendar_id = $button.attr('data-calendar-id');
  1571. booked_load_calendar_date_booking_options = {'action':'booked_admin_new_appointment_form','date':date,'title':title,'timeslot':timeslot,'calendar_id':calendar_id};
  1572. $(document).trigger("booked-before-loading-calendar-booking-options");
  1573. create_booked_modal();
  1574. $.ajax({
  1575. url : booked_js_vars.ajax_url,
  1576. type : 'post',
  1577. data : booked_load_calendar_date_booking_options,
  1578. success : function(html){
  1579. $('.bm-window').html( html );
  1580. $('select#userList').chosen();
  1581. var bookedModal = $('.booked-modal');
  1582. var bmWindow = bookedModal.find('.bm-window');
  1583. bmWindow.css({'visibility':'hidden'});
  1584. bookedModal.removeClass('bm-loading');
  1585. $(document).trigger("booked-on-new-app");
  1586. resize_booked_modal();
  1587. bmWindow.hide();
  1588. setTimeout(function(){
  1589. bmWindow.css({'visibility':'visible'});
  1590. bmWindow.show();
  1591. },50);
  1592. }
  1593. });
  1594. return false;
  1595. });
  1596. // New Appointment Click
  1597. $('.booked-admin-calendar-wrap').on('click', 'tr.entryBlock button.disable-slot', function(e) {
  1598. e.preventDefault();
  1599. var $button = $(this),
  1600. timeslot = $button.attr('data-timeslot'),
  1601. title = $button.attr('data-title'),
  1602. date = $button.attr('data-date'),
  1603. $thisTimeslot = $button.parents('.timeslot'),
  1604. $thisDate = $button.parents('.bookedAppointmentTab'),
  1605. calendar_id = $button.attr('data-calendar-id');
  1606. $thisDate.find('.disable-slot').attr('disabled',true);
  1607. booked_load_calendar_date_booking_options = {'action':'booked_admin_disable_slot','date':date,'title':title,'timeslot':timeslot,'calendar_id':calendar_id};
  1608. $.ajax({
  1609. url : booked_js_vars.ajax_url,
  1610. type : 'post',
  1611. data : booked_load_calendar_date_booking_options,
  1612. success : function(result){
  1613. if ( result == 'disabled' ){
  1614. $thisTimeslot.addClass('booked-disabled');
  1615. $thisTimeslot.find( '.new-appt' ).attr( 'disabled',true );
  1616. $button.text( booked_js_vars.i18n_enable );
  1617. } else if ( result == 'enabled' ){
  1618. $thisTimeslot.removeClass('booked-disabled');
  1619. $thisTimeslot.find( '.new-appt' ).attr( 'disabled',false );
  1620. $button.text( booked_js_vars.i18n_disable );
  1621. }
  1622. $thisDate.find('.disable-slot').attr('disabled',false);
  1623. }
  1624. });
  1625. return false;
  1626. });
  1627. // Delete Appointment from Pending List
  1628. $('.booked-pending-appt-list').on('click', '.pending-appt .delete', function(e) {
  1629. e.preventDefault();
  1630. var $button = $(this),
  1631. $thisParent = $button.parents('.pending-appt'),
  1632. appt_id = $thisParent.attr('data-appt-id');
  1633. confirm_appt_delete = confirm(booked_js_vars.i18n_confirm_appt_delete);
  1634. if (confirm_appt_delete == true){
  1635. var currentPendingCount = parseInt($('li.toplevel_page_booked-appointments').find('li.current').find('span.update-count').html());
  1636. currentPendingCount = parseInt(currentPendingCount - 1);
  1637. if (currentPendingCount < 1){
  1638. $('li.toplevel_page_booked-appointments').find('li.current').find('span.update-plugins').remove();
  1639. $('.no-pending-message').slideDown('fast');
  1640. $('.booked-pending-cap').slideUp('fast');
  1641. } else {
  1642. $('li.toplevel_page_booked-appointments').find('li.current').find('span.update-count').html(currentPendingCount);
  1643. }
  1644. $thisParent.slideUp('fast',function(){
  1645. $(this).remove();
  1646. });
  1647. savingState(true);
  1648. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1649. type : 'post',
  1650. url : booked_js_vars.ajax_url,
  1651. data : {
  1652. 'action' : 'booked_admin_delete_appt',
  1653. 'appt_id' : appt_id
  1654. },
  1655. success: function(data) {
  1656. savingState(false);
  1657. }
  1658. });
  1659. }
  1660. return false;
  1661. });
  1662. // Approve Appointment from Pending List
  1663. $('.booked-pending-appt-list').on('click', '.pending-appt .approve', function(e) {
  1664. e.preventDefault();
  1665. var $button = $(this),
  1666. $thisParent = $button.parents('.pending-appt'),
  1667. appt_id = $thisParent.attr('data-appt-id');
  1668. confirm_appt_approve = confirm(booked_js_vars.i18n_confirm_appt_approve);
  1669. if (confirm_appt_approve == true){
  1670. var currentPendingCount = parseInt($('li.toplevel_page_booked-appointments').find('li.current').find('span.update-count').html());
  1671. currentPendingCount = parseInt(currentPendingCount - 1);
  1672. if (currentPendingCount < 1){
  1673. $('li.toplevel_page_booked-appointments').find('li.current').find('span.update-plugins').remove();
  1674. $('.no-pending-message').slideDown('fast');
  1675. $('.booked-pending-cap').slideUp('fast');
  1676. } else {
  1677. $('li.toplevel_page_booked-appointments').find('li.current').find('span.update-count').html(currentPendingCount);
  1678. }
  1679. $thisParent.slideUp('fast',function(){
  1680. $(this).remove();
  1681. });
  1682. savingState(true);
  1683. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1684. type : 'post',
  1685. url : booked_js_vars.ajax_url,
  1686. data : {
  1687. 'action' : 'booked_admin_approve_appt',
  1688. 'appt_id' : appt_id
  1689. },
  1690. success: function(data) {
  1691. savingState(false);
  1692. }
  1693. });
  1694. }
  1695. return false;
  1696. });
  1697. // Approve All Appointment from Pending List
  1698. $('.booked-pending-cap').on('click', '.approve-all', function(e) {
  1699. e.preventDefault();
  1700. var $button = $(this);
  1701. confirm_appt_approve = confirm(booked_js_vars.i18n_confirm_appt_approve_all);
  1702. if (confirm_appt_approve == true){
  1703. savingState(true);
  1704. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1705. type : 'post',
  1706. url : booked_js_vars.ajax_url,
  1707. data : {
  1708. 'action' : 'booked_admin_approve_all'
  1709. },
  1710. success: function(data) {
  1711. $('li.toplevel_page_booked-appointments').find('li.current').find('span.update-plugins').remove();
  1712. $('.booked-pending-appt-list .pending-appt:not(.no-pending-message)').remove();
  1713. $('.booked-pending-appt-list .no-pending-message').slideDown('fast');
  1714. $('.booked-pending-cap').slideUp('fast');
  1715. savingState(false);
  1716. }
  1717. });
  1718. }
  1719. return false;
  1720. });
  1721. // Delete All Appointment from Pending List
  1722. $('.booked-pending-cap').on('click', '.delete-all', function(e) {
  1723. e.preventDefault();
  1724. var $button = $(this);
  1725. confirm_appt_approve = confirm(booked_js_vars.i18n_confirm_appt_delete_all);
  1726. if (confirm_appt_approve == true){
  1727. savingState(true);
  1728. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1729. type : 'post',
  1730. url : booked_js_vars.ajax_url,
  1731. data : {
  1732. 'action' : 'booked_admin_delete_all'
  1733. },
  1734. success: function(data) {
  1735. $('li.toplevel_page_booked-appointments').find('li.current').find('span.update-plugins').remove();
  1736. $('.booked-pending-appt-list .pending-appt:not(.no-pending-message)').remove();
  1737. $('.booked-pending-appt-list .no-pending-message').slideDown('fast');
  1738. $('.booked-pending-cap').slideUp('fast');
  1739. savingState(false);
  1740. }
  1741. });
  1742. }
  1743. return false;
  1744. });
  1745. var totalPendings = $('.booked-pending-appt-list').find('.pending-appt').length;
  1746. var passedPendings = $('.booked-pending-appt-list').find('.pending-appt.passed').length;
  1747. if (totalPendings > 1 && !passedPendings){
  1748. $('.booked-pending-cap .button.delete-past').hide();
  1749. } else if (totalPendings == 1) {
  1750. $('.booked-pending-cap').slideUp('fast');
  1751. }
  1752. // Delete Past Appointments from Pending List
  1753. $('.booked-pending-cap').on('click', '.delete-past', function(e) {
  1754. e.preventDefault();
  1755. var $button = $(this);
  1756. confirm_appt_approve = confirm(booked_js_vars.i18n_confirm_appt_delete_past);
  1757. if (confirm_appt_approve == true){
  1758. var currentPendingCount = parseInt($('li.toplevel_page_booked-appointments').find('li.current').find('span.update-count').html());
  1759. var pendingsToRemove = $('.booked-pending-appt-list').find('.pending-appt.passed').length;
  1760. currentPendingCount = parseInt(currentPendingCount - pendingsToRemove);
  1761. if (currentPendingCount < 1){
  1762. $('li.toplevel_page_booked-appointments').find('li.current').find('span.update-plugins').remove();
  1763. $('.booked-pending-appt-list .no-pending-message').slideDown('fast');
  1764. $('.booked-pending-cap').slideUp('fast');
  1765. } else {
  1766. $('li.toplevel_page_booked-appointments').find('li.current').find('span.update-count').html(currentPendingCount);
  1767. }
  1768. savingState(true);
  1769. booked_js_vars.ajaxRequests.push = $.bookedAjaxQueue({
  1770. type : 'post',
  1771. url : booked_js_vars.ajax_url,
  1772. data : {
  1773. 'action' : 'booked_admin_delete_past'
  1774. },
  1775. success: function(data) {
  1776. $('.booked-pending-cap .button.delete-past').hide();
  1777. $('.booked-pending-appt-list .pending-appt.passed').remove();
  1778. savingState(false);
  1779. }
  1780. });
  1781. }
  1782. return false;
  1783. });
  1784. $('body').on('touchstart click','.bm-overlay, .bm-window .close, form.booked-form .cancel',function(e){
  1785. e.preventDefault();
  1786. close_booked_modal();
  1787. return false;
  1788. });
  1789. $('body').on('change','form.booked-settings-form input,form.booked-form input,form.booked-settings-form select',function(){
  1790. var condition = $(this).attr('data-condition'),
  1791. thisVal = $(this).val();
  1792. if (condition && $('.condition-block').length) {
  1793. if ( $(this).is(':checkbox') && $(this).is(':checked') ){
  1794. $('.condition-block.'+condition).fadeIn(250);
  1795. resize_booked_modal();
  1796. } else if ( $(this).is(':checkbox') && !$(this).is(':checked') ){
  1797. $('.condition-block.'+condition).hide();
  1798. resize_booked_modal();
  1799. } else {
  1800. $('.condition-block.'+condition).hide();
  1801. $('[data-condition-val="'+thisVal+'"]').fadeIn(250);
  1802. resize_booked_modal();
  1803. }
  1804. }
  1805. });
  1806. $('body')
  1807. .on('focusin', 'form.booked-form input', function() {
  1808. if(this.title==this.value) {
  1809. $(this).addClass('hasContent');
  1810. this.value = '';
  1811. }
  1812. }).on('focusout', 'form.booked-form input', function(){
  1813. if(this.value==='') {
  1814. $(this).removeClass('hasContent');
  1815. this.value = this.title;
  1816. }
  1817. });
  1818. // Adjust the calendar sizing when resizing the window
  1819. $win.resize(function(){
  1820. adjust_calendar_boxes();
  1821. resize_booked_modal();
  1822. });
  1823. // Adjust the calendar sizing on load
  1824. adjust_calendar_boxes();
  1825. // Saving state updater
  1826. function savingState(show,savingStateObj){
  1827. if (typeof savingStateObj === 'undefined'){
  1828. var savingStateObj = $('li.active .savingState, .topSavingState.savingState, .calendarSavingState, .cf-updater.savingState, .cts-updater.savingState, .cal-updater.savingState');
  1829. }
  1830. var $stuffToHide = $('.monthName');
  1831. var $stuffToTransparent = $('table.booked-calendar tbody');
  1832. if (show){
  1833. savingStateObj.fadeIn(200);
  1834. $stuffToHide.hide();
  1835. $stuffToTransparent.animate({'opacity':0.2},100);
  1836. } else {
  1837. savingStateObj.hide();
  1838. $stuffToHide.show();
  1839. $stuffToTransparent.animate({'opacity':1},0);
  1840. }
  1841. }
  1842. function init_timeslot_tabs(){
  1843. /* Add Timeslot Tabs */
  1844. if ($('.addTimeslotTab').length){
  1845. // Tabs
  1846. var timeslotTabs = $('.timeslotTabs');
  1847. $('.tsTabContent').hide();
  1848. var activeTab = timeslotTabs.find('.active').attr('href');
  1849. activeTab = activeTab.split('#');
  1850. activeTab = activeTab[1];
  1851. $('.tsTabContent.ts'+activeTab).show();
  1852. timeslotTabs.find('a').on('click', function(e) {
  1853. e.preventDefault();
  1854. $('.tsTabContent').hide();
  1855. timeslotTabs.find('a').removeClass('active');
  1856. $(this).addClass('active');
  1857. var activeTab = $(this).attr('href');
  1858. activeTab = activeTab.split('#');
  1859. activeTab = activeTab[1];
  1860. $('.tsTabContent.ts'+activeTab).show();
  1861. });
  1862. }
  1863. }
  1864. function updateCustomTimeslotEncodedField(){
  1865. var formData = JSON.stringify($('form#customTimeslots').serializeObject());
  1866. $('#custom_timeslots_encoded').val(formData);
  1867. }
  1868. $(document).ajaxStop(function() {
  1869. savingState(false);
  1870. });
  1871. });
  1872. })(jQuery, window, document);
  1873. // Reload the timeslots select options
  1874. function booked_update_timeslot_select_field( appt_id, selectedDate ){
  1875. jQuery('.bm-window').find('.booked_appt_timeslot').attr('disabled',true);
  1876. booked_js_vars.ajaxRequests.push = jQuery.bookedAjaxQueue({
  1877. type : 'post',
  1878. url : booked_js_vars.ajax_url,
  1879. data : {
  1880. 'action' : 'booked_admin_get_timeslots_select',
  1881. 'date' : selectedDate,
  1882. 'appt_id' : appt_id
  1883. },
  1884. success: function(html) {
  1885. jQuery('.bm-window').find('.booked_appt_timeslot').replaceWith(html);
  1886. }
  1887. });
  1888. }
  1889. // Format the Datepicker Date
  1890. function booked_datepicker_show_formatted_date( dateField, selectedDate ){
  1891. var dateFieldObj = jQuery( '.' + dateField );
  1892. formatSpan = jQuery( '.' + dateField + '-formatted' );
  1893. formatSpan.css({ 'opacity':0.5 });
  1894. booked_js_vars.ajaxRequests.push = jQuery.bookedAjaxQueue({
  1895. type : 'post',
  1896. url : booked_js_vars.ajax_url,
  1897. data : {
  1898. 'action' : 'booked_date_formatting',
  1899. 'date' : selectedDate
  1900. },
  1901. success: function(date) {
  1902. formatSpan.html(date);
  1903. formatSpan.css({ 'opacity':1 });
  1904. jQuery('.bm-window').find('.ui-datepicker-trigger').attr('disabled',false);
  1905. }
  1906. });
  1907. }
  1908. // Create Booked Modal
  1909. function create_booked_modal(){
  1910. var windowHeight = jQuery(window).height();
  1911. var windowWidth = jQuery(window).width();
  1912. if (windowWidth > 720){
  1913. var maxModalHeight = windowHeight - 295;
  1914. } else {
  1915. var maxModalHeight = windowHeight;
  1916. }
  1917. jQuery('body input, body textarea, body select').blur();
  1918. jQuery('body').addClass('booked-noScroll');
  1919. jQuery('<div class="booked-modal bm-loading"><div class="bm-overlay"></div><div class="bm-window"><div style="height:100px"></div></div></div>').appendTo('body');
  1920. jQuery('.booked-modal .bm-window').spin('booked_white');
  1921. jQuery('.booked-modal .bm-window').css({'max-height':maxModalHeight+'px'});
  1922. }
  1923. function resize_booked_modal(){
  1924. var windowHeight = jQuery(window).height();
  1925. var windowWidth = jQuery(window).width();
  1926. if (jQuery('.booked-modal .bm-window .booked-scrollable').length){
  1927. var realModalHeight = jQuery('.booked-modal .bm-window .booked-scrollable')[0].scrollHeight;
  1928. } else {
  1929. var realModalHeight = 0;
  1930. }
  1931. var minimumWindowHeight = realModalHeight + 43 + 240;
  1932. var modalScrollableHeight = realModalHeight - 43;
  1933. var maxModalHeight;
  1934. var maxFormHeight;
  1935. if (windowHeight < minimumWindowHeight){
  1936. modalScrollableHeight = windowHeight - 240 - 43;
  1937. } else {
  1938. modalScrollableHeight = realModalHeight;
  1939. }
  1940. if (windowWidth > 720){
  1941. maxModalHeight = modalScrollableHeight - 25;
  1942. maxFormHeight = maxModalHeight - 15;
  1943. } else {
  1944. maxModalHeight = windowHeight - 43;
  1945. maxFormHeight = maxModalHeight - 43 - 60;
  1946. }
  1947. var modalNegMargin = (maxModalHeight + 83) / 2;
  1948. jQuery('.booked-modal').css({'margin-top':'-'+modalNegMargin+'px'});
  1949. jQuery('.booked-modal .bm-window').css({'max-height':maxModalHeight+'px'});
  1950. jQuery('.booked-modal .bm-window .booked-scrollable').css({'max-height':maxFormHeight+'px'});
  1951. }
  1952. function close_booked_modal(){
  1953. jQuery('.booked-modal').fadeOut(200);
  1954. jQuery('.booked-modal').addClass('bm-closing');
  1955. jQuery('body').removeClass('booked-noScroll');
  1956. setTimeout(function(){
  1957. jQuery('.booked-modal').remove();
  1958. },300);
  1959. }
  1960. // Function to adjust calendar sizing
  1961. function adjust_calendar_boxes(){
  1962. var boxesWidth = jQuery('.booked-calendar tbody tr.week td').width();
  1963. boxesHeight = boxesWidth * 0.8;
  1964. jQuery('.booked-calendar tbody tr.week td').height(boxesHeight);
  1965. jQuery('.booked-calendar tbody tr.week td .date').css('line-height',boxesHeight+'px');
  1966. jQuery('.tooltip:not(.tooltipstered)').tooltipster({
  1967. theme: 'tooltipster-light',
  1968. animation: 'grow',
  1969. speed: 200,
  1970. delay: 100,
  1971. offsetY: -13
  1972. });
  1973. }
  1974. // Serialize Function
  1975. (function($) {
  1976. // jQuery on an empty object, we are going to use this as our Queue
  1977. var bookedAjaxQueue = $({});
  1978. $.bookedAjaxQueue = function( ajaxOpts ) {
  1979. var jqXHR,
  1980. dfd = $.Deferred(),
  1981. promise = dfd.promise();
  1982. // queue our ajax request
  1983. bookedAjaxQueue.queue( doRequest );
  1984. // add the abort method
  1985. promise.abort = function( statusText ) {
  1986. // proxy abort to the jqXHR if it is active
  1987. if ( jqXHR ) {
  1988. return jqXHR.abort( statusText );
  1989. }
  1990. // if there wasn't already a jqXHR we need to remove from queue
  1991. var queue = bookedAjaxQueue.queue(),
  1992. index = $.inArray( doRequest, queue );
  1993. if ( index > -1 ) {
  1994. queue.splice( index, 1 );
  1995. }
  1996. // and then reject the deferred
  1997. dfd.rejectWith( ajaxOpts.context || ajaxOpts, [ promise, statusText, "" ] );
  1998. return promise;
  1999. };
  2000. // run the actual query
  2001. function doRequest( next ) {
  2002. jqXHR = $.ajax( ajaxOpts )
  2003. .done( dfd.resolve )
  2004. .fail( dfd.reject )
  2005. .then( next, next );
  2006. }
  2007. return promise;
  2008. };
  2009. })(jQuery);