admin-warning.php
4 years ago
customizer.css
5 years ago
customizer.js
6 years ago
form.php
2 years ago
style.css
8 years ago
widget.php
2 years ago
customizer.js
440 lines
| 1 | /* global jQuery, jpSimplePaymentsStrings, confirm, _ */ |
| 2 | /* eslint no-var: 0, quote-props: 0 */ |
| 3 | |
| 4 | ( function ( api, wp, $ ) { |
| 5 | var $document = $( document ); |
| 6 | |
| 7 | $document.ready( function () { |
| 8 | $document.on( 'widget-added', function ( event, widgetContainer ) { |
| 9 | if ( widgetContainer.is( '[id*="jetpack_simple_payments_widget"]' ) ) { |
| 10 | initWidget( widgetContainer ); |
| 11 | } |
| 12 | } ); |
| 13 | |
| 14 | $document.on( 'widget-synced widget-updated', function ( event, widgetContainer ) { |
| 15 | //this fires for all widgets, this prevent errors for non SP widgets |
| 16 | if ( ! widgetContainer.is( '[id*="jetpack_simple_payments_widget"]' ) ) { |
| 17 | return; |
| 18 | } |
| 19 | |
| 20 | event.preventDefault(); |
| 21 | |
| 22 | syncProductLists(); |
| 23 | |
| 24 | var widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); |
| 25 | |
| 26 | enableFormActions( widgetForm ); |
| 27 | |
| 28 | updateProductImage( widgetForm ); |
| 29 | } ); |
| 30 | } ); |
| 31 | |
| 32 | function initWidget( widgetContainer ) { |
| 33 | var widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); |
| 34 | |
| 35 | //Add New Button |
| 36 | widgetForm |
| 37 | .find( '.jetpack-simple-payments-add-product' ) |
| 38 | .on( 'click', showAddNewForm( widgetForm ) ); |
| 39 | //Edit Button |
| 40 | widgetForm |
| 41 | .find( '.jetpack-simple-payments-edit-product' ) |
| 42 | .on( 'click', showEditForm( widgetForm ) ); |
| 43 | //Select an Image |
| 44 | widgetForm |
| 45 | .find( |
| 46 | '.jetpack-simple-payments-image-fieldset .placeholder, .jetpack-simple-payments-image > img' |
| 47 | ) |
| 48 | .on( 'click', selectImage( widgetForm ) ); |
| 49 | //Remove Image Button |
| 50 | widgetForm |
| 51 | .find( '.jetpack-simple-payments-remove-image' ) |
| 52 | .on( 'click', removeImage( widgetForm ) ); |
| 53 | //Save Product button |
| 54 | widgetForm |
| 55 | .find( '.jetpack-simple-payments-save-product' ) |
| 56 | .on( 'click', saveChanges( widgetForm ) ); |
| 57 | //Cancel Button |
| 58 | widgetForm |
| 59 | .find( '.jetpack-simple-payments-cancel-form' ) |
| 60 | .on( 'click', clearForm( widgetForm ) ); |
| 61 | //Delete Selected Product |
| 62 | widgetForm |
| 63 | .find( '.jetpack-simple-payments-delete-product' ) |
| 64 | .on( 'click', deleteProduct( widgetForm ) ); |
| 65 | //Input, Select and Checkbox change |
| 66 | widgetForm.find( 'select, input, textarea, checkbox' ).on( |
| 67 | 'change input propertychange', |
| 68 | _.debounce( function () { |
| 69 | disableFormActions( widgetForm ); |
| 70 | }, 250 ) |
| 71 | ); |
| 72 | } |
| 73 | |
| 74 | function syncProductLists() { |
| 75 | var request = wp.ajax.post( 'customize-jetpack-simple-payments-buttons-get', { |
| 76 | 'customize-jetpack-simple-payments-nonce': |
| 77 | api.settings.nonce[ 'customize-jetpack-simple-payments' ], |
| 78 | customize_changeset_uuid: api.settings.changeset.uuid, |
| 79 | } ); |
| 80 | |
| 81 | request.done( function ( data ) { |
| 82 | var selectedProduct = 0; |
| 83 | |
| 84 | $( document ) |
| 85 | .find( 'select.jetpack-simple-payments-products' ) |
| 86 | .each( function ( index, select ) { |
| 87 | var $select = $( select ); |
| 88 | selectedProduct = $select.val(); |
| 89 | |
| 90 | $select.find( 'option' ).remove(); |
| 91 | $select.append( |
| 92 | $.map( data, function ( product ) { |
| 93 | return $( '<option>', { value: product.ID, text: product.post_title } ); |
| 94 | } ) |
| 95 | ); |
| 96 | $select.val( selectedProduct ); |
| 97 | } ); |
| 98 | } ); |
| 99 | } |
| 100 | |
| 101 | function showForm( widgetForm ) { |
| 102 | //reset validations |
| 103 | widgetForm.find( '.invalid' ).removeClass( 'invalid' ); |
| 104 | //disable widget title and product selector |
| 105 | widgetForm |
| 106 | .find( '.jetpack-simple-payments-widget-title' ) |
| 107 | .add( '.jetpack-simple-payments-products' ) |
| 108 | //disable add and edit buttons |
| 109 | .add( '.jetpack-simple-payments-add-product' ) |
| 110 | .add( '.jetpack-simple-payments-edit-product' ) |
| 111 | //disable save, delete and cancel until the widget update event is fired |
| 112 | .add( '.jetpack-simple-payments-save-product' ) |
| 113 | .add( '.jetpack-simple-payments-cancel-form' ) |
| 114 | .add( '.jetpack-simple-payments-delete-product' ) |
| 115 | .attr( 'disabled', 'disabled' ); |
| 116 | //show form |
| 117 | widgetForm.find( '.jetpack-simple-payments-form' ).show(); |
| 118 | } |
| 119 | |
| 120 | function hideForm( widgetForm ) { |
| 121 | //enable widget title and product selector |
| 122 | widgetForm |
| 123 | .find( '.jetpack-simple-payments-widget-title' ) |
| 124 | .add( '.jetpack-simple-payments-products' ) |
| 125 | .removeAttr( 'disabled' ); |
| 126 | //hide the form |
| 127 | widgetForm.find( '.jetpack-simple-payments-form' ).hide(); |
| 128 | } |
| 129 | |
| 130 | function changeFormAction( widgetForm, action ) { |
| 131 | widgetForm.find( '.jetpack-simple-payments-form-action' ).val( action ).change(); |
| 132 | } |
| 133 | |
| 134 | function showAddNewForm( widgetForm ) { |
| 135 | return function ( event ) { |
| 136 | event.preventDefault(); |
| 137 | |
| 138 | showForm( widgetForm ); |
| 139 | changeFormAction( widgetForm, 'add' ); |
| 140 | }; |
| 141 | } |
| 142 | |
| 143 | function showEditForm( widgetForm ) { |
| 144 | return function ( event ) { |
| 145 | event.preventDefault(); |
| 146 | |
| 147 | showForm( widgetForm ); |
| 148 | changeFormAction( widgetForm, 'edit' ); |
| 149 | }; |
| 150 | } |
| 151 | |
| 152 | function clearForm( widgetForm ) { |
| 153 | return function ( event ) { |
| 154 | event.preventDefault(); |
| 155 | |
| 156 | hideForm( widgetForm ); |
| 157 | widgetForm |
| 158 | .find( '.jetpack-simple-payments-add-product, .jetpack-simple-payments-edit-product' ) |
| 159 | .attr( 'disabled', 'disabled' ); |
| 160 | changeFormAction( widgetForm, 'clear' ); |
| 161 | }; |
| 162 | } |
| 163 | |
| 164 | function enableFormActions( widgetForm ) { |
| 165 | var isFormVisible = widgetForm.find( '.jetpack-simple-payments-form' ).is( ':visible' ); |
| 166 | var isProductSelectVisible = widgetForm |
| 167 | .find( '.jetpack-simple-payments-products' ) |
| 168 | .is( ':visible' ); //areProductsVisible ? |
| 169 | var isEdit = widgetForm.find( '.jetpack-simple-payments-form-action' ).val() === 'edit'; |
| 170 | |
| 171 | if ( isFormVisible ) { |
| 172 | widgetForm |
| 173 | .find( '.jetpack-simple-payments-save-product' ) |
| 174 | .add( '.jetpack-simple-payments-cancel-form' ) |
| 175 | .removeAttr( 'disabled' ); |
| 176 | } else { |
| 177 | widgetForm.find( '.jetpack-simple-payments-add-product' ).removeAttr( 'disabled' ); |
| 178 | } |
| 179 | |
| 180 | if ( isFormVisible && isEdit ) { |
| 181 | widgetForm.find( '.jetpack-simple-payments-delete-product' ).removeAttr( 'disabled' ); |
| 182 | } |
| 183 | |
| 184 | if ( isProductSelectVisible && ! isFormVisible ) { |
| 185 | widgetForm.find( '.jetpack-simple-payments-edit-product' ).removeAttr( 'disabled' ); |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | function disableFormActions( widgetForm ) { |
| 190 | widgetForm |
| 191 | .find( '.jetpack-simple-payments-add-product' ) |
| 192 | .add( '.jetpack-simple-payments-edit-product' ) |
| 193 | .add( '.jetpack-simple-payments-save-product' ) |
| 194 | .add( '.jetpack-simple-payments-cancel-form' ) |
| 195 | .add( '.jetpack-simple-payments-delete-product' ) |
| 196 | .attr( 'disabled', 'disabled' ); |
| 197 | } |
| 198 | |
| 199 | function selectImage( widgetForm ) { |
| 200 | return function ( event ) { |
| 201 | event.preventDefault(); |
| 202 | |
| 203 | var imageContainer = widgetForm.find( '.jetpack-simple-payments-image' ); |
| 204 | |
| 205 | var mediaFrame = new wp.media.view.MediaFrame.Select( { |
| 206 | title: 'Choose Product Image', |
| 207 | multiple: false, |
| 208 | library: { type: 'image' }, |
| 209 | button: { text: 'Choose Image' }, |
| 210 | } ); |
| 211 | |
| 212 | mediaFrame.on( 'select', function () { |
| 213 | var selection = mediaFrame.state().get( 'selection' ).first().toJSON(); |
| 214 | //hide placeholder |
| 215 | widgetForm.find( '.jetpack-simple-payments-image-fieldset .placeholder' ).hide(); |
| 216 | |
| 217 | //load image from media library |
| 218 | imageContainer.find( 'img' ).attr( 'src', selection.url ).show(); |
| 219 | |
| 220 | //show image and remove button |
| 221 | widgetForm.find( '.jetpack-simple-payments-image' ).show(); |
| 222 | |
| 223 | //set hidden field for the selective refresh |
| 224 | widgetForm.find( '.jetpack-simple-payments-form-image-id' ).val( selection.id ).change(); |
| 225 | } ); |
| 226 | |
| 227 | mediaFrame.open(); |
| 228 | }; |
| 229 | } |
| 230 | |
| 231 | function removeImage( widgetForm ) { |
| 232 | return function ( event ) { |
| 233 | event.preventDefault(); |
| 234 | |
| 235 | //show placeholder |
| 236 | widgetForm.find( '.jetpack-simple-payments-image-fieldset .placeholder' ).show(); |
| 237 | |
| 238 | //hide image and remove button |
| 239 | widgetForm.find( '.jetpack-simple-payments-image' ).hide(); |
| 240 | |
| 241 | //set hidden field for the selective refresh |
| 242 | widgetForm.find( '.jetpack-simple-payments-form-image-id' ).val( '' ).change(); |
| 243 | }; |
| 244 | } |
| 245 | |
| 246 | function updateProductImage( widgetForm ) { |
| 247 | var newImageId = parseInt( |
| 248 | widgetForm.find( '.jetpack-simple-payments-form-image-id' ).val(), |
| 249 | 10 |
| 250 | ); |
| 251 | var newImageSrc = widgetForm.find( '.jetpack-simple-payments-form-image-src' ).val(); |
| 252 | |
| 253 | var placeholder = widgetForm.find( '.jetpack-simple-payments-image-fieldset .placeholder' ); |
| 254 | var image = widgetForm.find( '.jetpack-simple-payments-image > img' ); |
| 255 | var imageControls = widgetForm.find( '.jetpack-simple-payments-image' ); |
| 256 | |
| 257 | if ( newImageId && newImageSrc ) { |
| 258 | image.attr( 'src', newImageSrc ); |
| 259 | placeholder.hide(); |
| 260 | imageControls.show(); |
| 261 | } else { |
| 262 | placeholder.show(); |
| 263 | image.removeAttr( 'src' ); |
| 264 | imageControls.hide(); |
| 265 | } |
| 266 | } |
| 267 | |
| 268 | function decimalPlaces( number ) { |
| 269 | var parts = number.split( '.' ); |
| 270 | if ( parts.length > 2 ) { |
| 271 | return null; |
| 272 | } |
| 273 | |
| 274 | return parts[ 1 ] ? parts[ 1 ].length : 0; |
| 275 | } |
| 276 | |
| 277 | function isFormValid( widgetForm ) { |
| 278 | widgetForm.find( '.invalid' ).removeClass( 'invalid' ); |
| 279 | |
| 280 | var errors = false; |
| 281 | |
| 282 | var postTitle = widgetForm.find( '.jetpack-simple-payments-form-product-title' ).val(); |
| 283 | if ( ! postTitle ) { |
| 284 | widgetForm.find( '.jetpack-simple-payments-form-product-title' ).addClass( 'invalid' ); |
| 285 | errors = true; |
| 286 | } |
| 287 | |
| 288 | var productPrice = widgetForm.find( '.jetpack-simple-payments-form-product-price' ).val(); |
| 289 | if ( ! productPrice || isNaN( productPrice ) || parseFloat( productPrice ) <= 0 ) { |
| 290 | widgetForm.find( '.jetpack-simple-payments-form-product-price' ).addClass( 'invalid' ); |
| 291 | errors = true; |
| 292 | } |
| 293 | |
| 294 | // Japan's Yen is the only supported currency with a zero decimal precision. |
| 295 | var precision = |
| 296 | widgetForm.find( '.jetpack-simple-payments-form-product-currency' ).val() === 'JPY' ? 0 : 2; |
| 297 | var priceDecimalPlaces = decimalPlaces( productPrice ); |
| 298 | if ( priceDecimalPlaces === null || priceDecimalPlaces > precision ) { |
| 299 | widgetForm.find( '.jetpack-simple-payments-form-product-price' ).addClass( 'invalid' ); |
| 300 | errors = true; |
| 301 | } |
| 302 | |
| 303 | var productEmail = widgetForm.find( '.jetpack-simple-payments-form-product-email' ).val(); |
| 304 | var isProductEmailValid = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test( |
| 305 | productEmail |
| 306 | ); |
| 307 | if ( ! productEmail || ! isProductEmailValid ) { |
| 308 | widgetForm.find( '.jetpack-simple-payments-form-product-email' ).addClass( 'invalid' ); |
| 309 | errors = true; |
| 310 | } |
| 311 | |
| 312 | return ! errors; |
| 313 | } |
| 314 | |
| 315 | function saveChanges( widgetForm ) { |
| 316 | return function ( event ) { |
| 317 | event.preventDefault(); |
| 318 | var productPostId = widgetForm.find( '.jetpack-simple-payments-form-product-id' ).val(); |
| 319 | |
| 320 | if ( ! isFormValid( widgetForm ) ) { |
| 321 | return; |
| 322 | } |
| 323 | |
| 324 | disableFormActions( widgetForm ); |
| 325 | |
| 326 | widgetForm.find( '.spinner' ).show(); |
| 327 | |
| 328 | var request = wp.ajax.post( 'customize-jetpack-simple-payments-button-save', { |
| 329 | 'customize-jetpack-simple-payments-nonce': |
| 330 | api.settings.nonce[ 'customize-jetpack-simple-payments' ], |
| 331 | customize_changeset_uuid: api.settings.changeset.uuid, |
| 332 | params: { |
| 333 | product_post_id: productPostId, |
| 334 | post_title: widgetForm.find( '.jetpack-simple-payments-form-product-title' ).val(), |
| 335 | post_content: widgetForm |
| 336 | .find( '.jetpack-simple-payments-form-product-description' ) |
| 337 | .val(), |
| 338 | image_id: widgetForm.find( '.jetpack-simple-payments-form-image-id' ).val(), |
| 339 | currency: widgetForm.find( '.jetpack-simple-payments-form-product-currency' ).val(), |
| 340 | price: widgetForm.find( '.jetpack-simple-payments-form-product-price' ).val(), |
| 341 | multiple: widgetForm |
| 342 | .find( '.jetpack-simple-payments-form-product-multiple' ) |
| 343 | .is( ':checked' ) |
| 344 | ? 1 |
| 345 | : 0, |
| 346 | email: widgetForm.find( '.jetpack-simple-payments-form-product-email' ).val(), |
| 347 | }, |
| 348 | } ); |
| 349 | |
| 350 | request.done( function ( data ) { |
| 351 | var select = widgetForm.find( 'select.jetpack-simple-payments-products' ); |
| 352 | var productOption = select.find( 'option[value="' + productPostId + '"]' ); |
| 353 | |
| 354 | if ( productOption.length > 0 ) { |
| 355 | productOption.text( data.product_post_title ); |
| 356 | } else { |
| 357 | select.append( |
| 358 | $( '<option>', { |
| 359 | value: data.product_post_id, |
| 360 | text: data.product_post_title, |
| 361 | } ) |
| 362 | ); |
| 363 | select.val( data.product_post_id ).change(); |
| 364 | } |
| 365 | |
| 366 | widgetForm.find( '.jetpack-simple-payments-products-fieldset' ).show(); |
| 367 | widgetForm.find( '.jetpack-simple-payments-products-warning' ).hide(); |
| 368 | |
| 369 | changeFormAction( widgetForm, 'clear' ); |
| 370 | hideForm( widgetForm ); |
| 371 | } ); |
| 372 | |
| 373 | request.fail( function ( data ) { |
| 374 | var validCodes = { |
| 375 | post_title: 'product-title', |
| 376 | price: 'product-price', |
| 377 | email: 'product-email', |
| 378 | }; |
| 379 | |
| 380 | data.forEach( function ( item ) { |
| 381 | if ( validCodes.hasOwnProperty( item.code ) ) { |
| 382 | widgetForm |
| 383 | .find( '.jetpack-simple-payments-form-' + validCodes[ item.code ] ) |
| 384 | .addClass( 'invalid' ); |
| 385 | } |
| 386 | } ); |
| 387 | |
| 388 | enableFormActions( widgetForm ); |
| 389 | } ); |
| 390 | }; |
| 391 | } |
| 392 | |
| 393 | function deleteProduct( widgetForm ) { |
| 394 | return function ( event ) { |
| 395 | event.preventDefault(); |
| 396 | |
| 397 | if ( ! confirm( jpSimplePaymentsStrings.deleteConfirmation ) ) { |
| 398 | return; |
| 399 | } |
| 400 | |
| 401 | var formProductId = parseInt( |
| 402 | widgetForm.find( '.jetpack-simple-payments-form-product-id' ).val(), |
| 403 | 10 |
| 404 | ); |
| 405 | if ( ! formProductId ) { |
| 406 | return; |
| 407 | } |
| 408 | |
| 409 | disableFormActions( widgetForm ); |
| 410 | |
| 411 | widgetForm.find( '.spinner' ).show(); |
| 412 | |
| 413 | var request = wp.ajax.post( 'customize-jetpack-simple-payments-button-delete', { |
| 414 | 'customize-jetpack-simple-payments-nonce': |
| 415 | api.settings.nonce[ 'customize-jetpack-simple-payments' ], |
| 416 | customize_changeset_uuid: api.settings.changeset.uuid, |
| 417 | params: { |
| 418 | product_post_id: formProductId, |
| 419 | }, |
| 420 | } ); |
| 421 | |
| 422 | request.done( function () { |
| 423 | var productList = widgetForm.find( 'select.jetpack-simple-payments-products' )[ 0 ]; |
| 424 | productList.remove( productList.selectedIndex ); |
| 425 | productList.dispatchEvent( new Event( 'change' ) ); |
| 426 | |
| 427 | if ( $( productList ).has( 'option' ).length === 0 ) { |
| 428 | //hide products select and label |
| 429 | widgetForm.find( '.jetpack-simple-payments-products-fieldset' ).hide(); |
| 430 | //show empty products list warning |
| 431 | widgetForm.find( '.jetpack-simple-payments-products-warning' ).show(); |
| 432 | } |
| 433 | |
| 434 | changeFormAction( widgetForm, 'clear' ); |
| 435 | hideForm( widgetForm ); |
| 436 | } ); |
| 437 | }; |
| 438 | } |
| 439 | } )( wp.customize, wp, jQuery ); |
| 440 |