Last active
February 15, 2024 12:32
-
-
Save diegoversiani/9d4086b8031f3f10c91ebace608092e9 to your computer and use it in GitHub Desktop.
Detect quantity field updates (redacted for brevity)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Manage cart items ajax actions. | |
* | |
* DEPENDS ON: | |
* - jQuery // Interact with WooCommerce events | |
*/ | |
(function (root, factory) { | |
if ( typeof define === 'function' && define.amd ) { | |
define([], factory(root)); | |
} else if ( typeof exports === 'object' ) { | |
module.exports = factory(root); | |
} else { | |
root.CartAjax = factory(root); | |
} | |
})(typeof global !== 'undefined' ? global : this.window || this.global, function (root) { | |
'use strict'; | |
var $ = jQuery; | |
var _hasJQuery = ( $ != null ); | |
var _publicMethods = {}; | |
var _settings = { | |
quantityInputSelector: '.cart_item input.qty', | |
quantitySpinnerButtonSelector: '.cart_item .fc-number-spin-button', | |
quantityAttribute: 'data-quantity', | |
updateWaitTime: 500, | |
fragmentsUpdateEvent: 'wc_fragment_refresh', | |
fragmentsReplacedEvent: 'wc_fragments_refreshed', | |
}; | |
/** | |
* METHODS | |
*/ | |
/** | |
* Returns a function, that, as long as it continues to be invoked, will not | |
* be triggered. The function will be called after it stops being called for | |
* N milliseconds. If `immediate` is passed, trigger the function on the | |
* leading edge, instead of the trailing. | |
* | |
* @param {[type]} func Function to be executed. | |
* @param {[type]} wait Wait time in milliseconds. | |
* @param {[type]} immediate Trigger the function on the leading edge. | |
* | |
* @return function Function to be executed, incapsulated in a timed function. | |
*/ | |
var debounce = function ( func, wait, immediate ) { | |
var timeout; | |
return function() { | |
var context = this, args = arguments; | |
var later = function() { | |
timeout = null; | |
if (!immediate) func.apply( context, args ); | |
}; | |
var callNow = immediate && !timeout; | |
clearTimeout( timeout ); | |
timeout = setTimeout( later, wait ); | |
if ( callNow ) func.apply( context, args ); | |
}; | |
}; | |
/** | |
* Set the quantity attribute value for quantity fields. | |
*/ | |
var setAllQuantityAttributes = function() { | |
var quantityFields = document.querySelectorAll( _settings.quantityInputSelector ); | |
for ( var i = 0; i < quantityFields.length; i++ ) { | |
var input = quantityFields[ i ]; | |
input.setAttribute( _settings.quantityAttribute, input.value ); | |
} | |
}; | |
/** | |
* Check whether the product quantity field value has changed. | |
* | |
* @param HTMLElement qtyField The product quantity field. | |
* | |
* @return bool Whether the product quantity value has changed. | |
*/ | |
var hasQuantityChanged = function( qtyField ) { | |
if ( qtyField.getAttribute( _settings.quantityAttribute ) != qtyField.value ) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Maybe update cart items quantity and other attributes for all products in cart. | |
*/ | |
var debouncedMaybeUpdateQuantities; | |
var maybeUpdateCartItemQuantities = function( e ) { | |
// Bail if target is not a quantity field or buttons | |
if ( ! e.target.matches( _settings.quantityInputSelector ) && ! e.target.matches( _settings.quantitySpinnerButtonSelector ) ) { return; } | |
var allQuantityFields = document.querySelectorAll( _settings.quantityInputSelector ); | |
for ( var i = 0; i < allQuantityFields.length; i++ ) { | |
var qtyField = allQuantityFields[i]; | |
// Maybe trigger update item | |
if ( hasQuantityChanged( qtyField ) ) { | |
// PROCESS UPDATE | |
} | |
} | |
} | |
/** | |
* Initialize component and set related handlers. | |
*/ | |
_publicMethods.init = function( ) { | |
// Set quantity attribute for quantity fields at initialization | |
setAllQuantityAttributes(); | |
// Add event listeners for quantity updates | |
debouncedMaybeUpdateQuantities = debounce( maybeUpdateCartItemQuantities, _settings.updateWaitTime ); | |
document.addEventListener( 'click', debouncedMaybeUpdateQuantities, true ); | |
document.addEventListener( 'keydown', debouncedMaybeUpdateQuantities, true ); | |
document.addEventListener( 'change', debouncedMaybeUpdateQuantities, true ); | |
// After fragments has been updated | |
if ( _hasJQuery ) { | |
$( document.body ).on( _settings.fragmentsReplacedEvent, setAllQuantityAttributes ); | |
} | |
}; | |
// | |
// Public APIs | |
// | |
return _publicMethods; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment