1/*! 2 * WHMCS Ajax Driven Modal Framework 3 * 4 * @copyright Copyright (c) WHMCS Limited 2005-2019 5 * @license http://www.whmcs.com/license/ WHMCS Eula 6 */ 7var ajaxModalSubmitEvents = []; 8jQuery(document).ready(function(){ 9 jQuery(document).on('click', '.open-modal', function(e) { 10 e.preventDefault(); 11 var url = jQuery(this).attr('href'), 12 modalSize = jQuery(this).data('modal-size'), 13 modalClass = jQuery(this).data('modal-class'), 14 modalTitle = jQuery(this).data('modal-title'), 15 submitId = jQuery(this).data('btn-submit-id'), 16 submitLabel = jQuery(this).data('btn-submit-label'), 17 hideClose = jQuery(this).data('btn-close-hide'), 18 disabled = jQuery(this).attr('disabled'), 19 successDataTable = jQuery(this).data('datatable-reload-success'); 20 21 if (!disabled) { 22 openModal(url, '', modalTitle, modalSize, modalClass, submitLabel, submitId, hideClose, successDataTable); 23 } 24 }); 25 26 // define modal close reset action 27 jQuery('#modalAjax').on('hidden.bs.modal', function (e) { 28 if (jQuery(this).hasClass('modal-feature-highlights')) { 29 var dismissForVersion = jQuery('#cbFeatureHighlightsDismissForVersion').is(':checked'); 30 WHMCS.http.jqClient.post( 31 'whatsnew.php', 32 { 33 dismiss: "1", 34 until_next_update: dismissForVersion ? '1' : '0', 35 token: csrfToken 36 } 37 ); 38 } 39 40 jQuery('#modalAjax').find('.modal-body').empty(); 41 jQuery('#modalAjax').children('div.modal-dialog').removeClass('modal-lg'); 42 jQuery('#modalAjax').removeClass().addClass('modal whmcs-modal fade'); 43 jQuery('#modalAjax .modal-title').html('Title'); 44 jQuery('#modalAjax .modal-submit').html('Submit') 45 .removeClass() 46 .addClass('btn btn-primary modal-submit') 47 .removeAttr('id') 48 .removeAttr('disabled'); 49 jQuery('#modalAjax .loader').show(); 50 }); 51}); 52 53function openModal(url, postData, modalTitle, modalSize, modalClass, submitLabel, submitId, hideClose, successDataTable) { 54 //set the text of the modal title 55 jQuery('#modalAjax .modal-title').html(modalTitle); 56 57 // set the modal size via a class attribute 58 if (modalSize) { 59 jQuery('#modalAjax').children('div[class="modal-dialog"]').addClass(modalSize); 60 } 61 // set the modal class 62 if (modalClass) { 63 jQuery('#modalAjax').addClass(modalClass); 64 } 65 66 // set the modal class 67 if (modalClass) { 68 jQuery('#modalAjax').addClass(modalClass); 69 } 70 71 // set the text of the submit button 72 if(!submitLabel){ 73 jQuery('#modalAjax .modal-submit').hide(); 74 } else { 75 jQuery('#modalAjax .modal-submit').show().html(submitLabel); 76 // set the button id so we can target the click function of it. 77 if (submitId) { 78 jQuery('#modalAjax .modal-submit').attr('id', submitId); 79 } 80 } 81 82 if (hideClose) { 83 jQuery('#modalAjaxClose').hide(); 84 } 85 86 jQuery('#modalAjax .modal-body').html(''); 87 88 jQuery('#modalSkip').hide(); 89 jQuery('#modalAjax .modal-submit').prop('disabled', true); 90 91 // show modal 92 jQuery('#modalAjax').modal('show'); 93 94 // fetch modal content 95 WHMCS.http.jqClient.post(url, postData, function(data) { 96 updateAjaxModal(data); 97 }, 'json').fail(function() { 98 jQuery('#modalAjax .modal-body').html('An error occurred while communicating with the server. Please try again.'); 99 jQuery('#modalAjax .loader').fadeOut(); 100 }).always(function () { 101 if (successDataTable) { 102 var modalForm = jQuery('#modalAjax').find('form'); 103 modalForm.data('successDataTable', successDataTable); 104 } 105 }); 106 107 //define modal submit button click 108 if (submitId) { 109 /** 110 * Reloading ajax modal multiple times on the same page can add 111 * multiple "on" click events which submits the same form over 112 * and over. 113 * Remove the on click event with "off" to avoid multiple growl 114 * and save events being run. 115 * 116 * @see http://api.jquery.com/off/ 117 */ 118 var submitButton = jQuery('#' + submitId); 119 submitButton.off('click'); 120 submitButton.on('click', submitIdAjaxModalClickEvent); 121 } 122} 123 124function submitIdAjaxModalClickEvent () 125{ 126 if (jQuery(this).hasClass('disabled')) { 127 return; 128 } 129 var canContinue = true, 130 btn = jQuery(this); 131 btn.addClass('disabled'); 132 jQuery('#modalAjax .loader').show(); 133 if (ajaxModalSubmitEvents.length) { 134 jQuery.each(ajaxModalSubmitEvents, function (index, value) { 135 var fn = window[value]; 136 if (canContinue && typeof fn === 'function') { 137 canContinue = fn(); 138 } 139 }); 140 } 141 if (!canContinue) { 142 btn.removeClass('disabled'); 143 jQuery('#modalAjax .loader').hide(); 144 return; 145 } 146 var modalForm = jQuery('#modalAjax').find('form'); 147 var modalBody = jQuery('#modalAjax .modal-body'); 148 var modalErrorContainer = jQuery(modalBody).find('.admin-modal-error'); 149 150 jQuery(modalErrorContainer).slideUp(); 151 152 var modalPost = WHMCS.http.jqClient.post( 153 modalForm.attr('action'), 154 modalForm.serialize(), 155 function(data) { 156 if (modalForm.data('successDataTable')) { 157 data.successDataTable = modalForm.data('successDataTable'); 158 } 159 updateAjaxModal(data); 160 }, 161 'json' 162 ).fail(function(xhr) { 163 var data = xhr.responseJSON; 164 var genericErrorMsg = 'An error occurred while communicating with the server. Please try again.'; 165 if (data && data.data) { 166 data = data.data; 167 if (data.errorMsg) { 168 if (modalErrorContainer.length > 0) { 169 jQuery(modalErrorContainer) 170 .html(data.errorMsg) 171 .slideDown(); 172 } else { 173 jQuery.growl.warning({title: data.errorMsgTitle, message: data.errorMsg}); 174 } 175 } else if (data.data.body) { 176 jQuery(modalBody).html(data.body); 177 } else { 178 jQuery(modalBody).html(genericErrorMsg); 179 } 180 } else { 181 jQuery(modalBody).html(genericErrorMsg); 182 } 183 jQuery('#modalAjax .loader').fadeOut(); 184 }).always(function () { 185 btn.removeClass('disabled'); 186 }); 187} 188 189function updateAjaxModal(data) { 190 if (data.reloadPage) { 191 if (typeof data.reloadPage === 'string') { 192 window.location = data.reloadPage; 193 } else { 194 window.location.reload(); 195 } 196 return; 197 } 198 if (data.successDataTable) { 199 WHMCS.ui.dataTable.getTableById(data.successDataTable, undefined).ajax.reload(); 200 } 201 if (data.redirect) { 202 window.location = data.redirect; 203 dialogClose(); 204 } 205 if (data.successWindow && typeof window[data.successWindow] === "function") { 206 window[data.successWindow](); 207 } 208 if (data.dismiss) { 209 dialogClose(); 210 } 211 if (data.successMsg) { 212 jQuery.growl.notice({ title: data.successMsgTitle, message: data.successMsg }); 213 } 214 if (data.errorMsg) { 215 var inModalErrorContainer = jQuery('#modalAjax .modal-body .admin-modal-error'); 216 217 if (inModalErrorContainer.length > 0 && !data.dismiss) { 218 jQuery(inModalErrorContainer) 219 .html(data.errorMsg) 220 .slideDown(); 221 } else { 222 jQuery.growl.warning({title: data.errorMsgTitle, message: data.errorMsg}); 223 } 224 } 225 if (data.title) { 226 jQuery('#modalAjax .modal-title').html(data.title); 227 } 228 if (data.body) { 229 jQuery('#modalAjax .modal-body').html(data.body); 230 } else { 231 if (data.url) { 232 WHMCS.http.jqClient.post(data.url, '', function(data2) {
233 jQuery('#modalAjax').find('.modal-body').html(data2.body); 234 }, 'json').fail(function() { 235 jQuery('#modalAjax').find('.modal-body').html('An error occurred while communicating with the server. Please try again.'); 236 jQuery('#modalAjax').find('.loader').fadeOut(); 237 }); 238 } 239 } 240 if (data.submitlabel) { 241 jQuery('#modalAjax .modal-submit').html(data.submitlabel).show(); 242 if (data.submitId) { 243 jQuery('#modalAjax').find('.modal-submit').attr('id', data.submitId); 244 } 245 } 246 247 if (data.submitId) { 248 /** 249 * Reloading ajax modal multiple times on the same page can add 250 * multiple "on" click events which submits the same form over 251 * and over. 252 * Remove the on click event with "off" to avoid multiple growl 253 * and save events being run. 254 * 255 * @see http://api.jquery.com/off/ 256 */ 257 var submitButton = jQuery('#' + data.submitId); 258 submitButton.off('click'); 259 submitButton.on('click', submitIdAjaxModalClickEvent); 260 } 261 262 jQuery('#modalAjax .loader').fadeOut(); 263 jQuery('#modalAjax .modal-submit').removeProp('disabled'); 264} 265 266// backwards compat for older dialog implementations 267 268function dialogSubmit() { 269 jQuery('#modalAjax .modal-submit').prop("disabled", true); 270 jQuery('#modalAjax .loader').show(); 271 var postUrl = jQuery('#modalAjax').find('form').attr('action'); 272 WHMCS.http.jqClient.post(postUrl, jQuery('#modalAjax').find('form').serialize(), 273 function(data) { 274 updateAjaxModal(data); 275 }, 'json').fail(function() { 276 jQuery('#modalAjax .modal-body').html('An error occurred while communicating with the server. Please try again.'); 277 jQuery('#modalAjax .loader').fadeOut(); 278 }); 279} 280 281function dialogClose() { 282 jQuery('#modalAjax').modal('hide'); 283} 284 285function addAjaxModalSubmitEvents(functionName) { 286 if (functionName) { 287 ajaxModalSubmitEvents.push(functionName); 288 } 289} 290 291function removeAjaxModalSubmitEvents(functionName) { 292 if (functionName) { 293 var index = ajaxModalSubmitEvents.indexOf(functionName); 294 if (index >= 0) { 295 ajaxModalSubmitEvents.splice(index, 1); 296 } 297 } 298}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.