497 lines
12 KiB
JavaScript
497 lines
12 KiB
JavaScript
/* global wc_cart_params */
|
|
jQuery( function( $ ) {
|
|
|
|
// wc_cart_params is required to continue, ensure the object exists
|
|
if ( typeof wc_cart_params === 'undefined' ) {
|
|
return false;
|
|
}
|
|
|
|
// Utility functions for the file.
|
|
|
|
/**
|
|
* Gets a url for a given AJAX endpoint.
|
|
*
|
|
* @param {String} endpoint The AJAX Endpoint
|
|
* @return {String} The URL to use for the request
|
|
*/
|
|
var get_url = function( endpoint ) {
|
|
return wc_cart_params.wc_ajax_url.toString().replace(
|
|
'%%endpoint%%',
|
|
endpoint
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Check if a node is blocked for processing.
|
|
*
|
|
* @param {JQuery Object} $node
|
|
* @return {bool} True if the DOM Element is UI Blocked, false if not.
|
|
*/
|
|
var is_blocked = function( $node ) {
|
|
return $node.is( '.processing' );
|
|
};
|
|
|
|
/**
|
|
* Block a node visually for processing.
|
|
*
|
|
* @param {JQuery Object} $node
|
|
*/
|
|
var block = function( $node ) {
|
|
$node.addClass( 'processing' ).block( {
|
|
message: null,
|
|
overlayCSS: {
|
|
background: '#fff',
|
|
opacity: 0.6
|
|
}
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Unblock a node after processing is complete.
|
|
*
|
|
* @param {JQuery Object} $node
|
|
*/
|
|
var unblock = function( $node ) {
|
|
$node.removeClass( 'processing' ).unblock();
|
|
};
|
|
|
|
/**
|
|
* Update the .woocommerce div with a string of html.
|
|
*
|
|
* @param {String} html_str The HTML string with which to replace the div.
|
|
*/
|
|
var update_wc_div = function( html_str ) {
|
|
var $html = $.parseHTML( html_str );
|
|
var $new_form = $( 'table.shop_table.cart', $html ).closest( 'form' );
|
|
var $new_totals = $( '.cart_totals', $html );
|
|
|
|
// Error message collection
|
|
var $error = $( '.woocommerce-error', $html );
|
|
var $message = $( '.woocommerce-message', $html );
|
|
|
|
// Remove errors
|
|
$( '.woocommerce-error, .woocommerce-message' ).remove();
|
|
|
|
if ( $new_form.length === 0 ) {
|
|
// No items to display now! Replace all cart content.
|
|
var $cart_html = $( '.cart-empty', $html ).closest( '.woocommerce' );
|
|
$( 'table.shop_table.cart' ).closest( '.woocommerce' ).replaceWith( $cart_html );
|
|
|
|
if ( $error.length > 0 ) {
|
|
show_notice( $error, $( '.cart-empty' ).closest( '.woocommerce' ) );
|
|
} else if ( $message.length > 0 ) {
|
|
show_notice( $message, $( '.cart-empty' ).closest( '.woocommerce' ) );
|
|
}
|
|
} else {
|
|
$( 'table.shop_table.cart' ).closest( 'form' ).replaceWith( $new_form );
|
|
$( 'table.shop_table.cart' ).closest( 'form' ).find( 'input[name="update_cart"]' ).prop( 'disabled', true );
|
|
|
|
if ( $error.length > 0 ) {
|
|
show_notice( $error );
|
|
} else if ( $message.length > 0 ) {
|
|
show_notice( $message );
|
|
}
|
|
|
|
update_cart_totals_div( $new_totals );
|
|
}
|
|
|
|
$( document.body ).trigger( 'updated_wc_div' );
|
|
};
|
|
|
|
/**
|
|
* Update the .cart_totals div with a string of html.
|
|
*
|
|
* @param {String} html_str The HTML string with which to replace the div.
|
|
*/
|
|
var update_cart_totals_div = function( html_str ) {
|
|
$( '.cart_totals' ).replaceWith( html_str );
|
|
$( document.body ).trigger( 'updated_cart_totals' );
|
|
};
|
|
|
|
/**
|
|
* Clear previous notices and shows new one above form.
|
|
*
|
|
* @param {Object} The Notice HTML Element in string or object form.
|
|
*/
|
|
var show_notice = function( html_element, $target ) {
|
|
if ( ! $target ) {
|
|
$target = $( 'table.shop_table.cart' ).closest( 'form' );
|
|
}
|
|
$( '.woocommerce-error, .woocommerce-message' ).remove();
|
|
$target.before( html_element );
|
|
};
|
|
|
|
|
|
/**
|
|
* Object to handle AJAX calls for cart shipping changes.
|
|
*/
|
|
var cart_shipping = {
|
|
|
|
/**
|
|
* Initialize event handlers and UI state.
|
|
*/
|
|
init: function( cart ) {
|
|
this.cart = cart;
|
|
this.toggle_shipping = this.toggle_shipping.bind( this );
|
|
this.shipping_method_selected = this.shipping_method_selected.bind( this );
|
|
this.shipping_calculator_submit = this.shipping_calculator_submit.bind( this );
|
|
|
|
$( document ).on(
|
|
'click',
|
|
'.shipping-calculator-button',
|
|
this.toggle_shipping
|
|
);
|
|
$( document ).on(
|
|
'change',
|
|
'select.shipping_method, input[name^=shipping_method]',
|
|
this.shipping_method_selected
|
|
);
|
|
$( document ).on(
|
|
'submit',
|
|
'form.woocommerce-shipping-calculator',
|
|
this.shipping_calculator_submit
|
|
);
|
|
|
|
$( '.shipping-calculator-form' ).hide();
|
|
},
|
|
|
|
/**
|
|
* Toggle Shipping Calculator panel
|
|
*/
|
|
toggle_shipping: function() {
|
|
$( '.shipping-calculator-form' ).slideToggle( 'slow' );
|
|
return false;
|
|
},
|
|
|
|
/**
|
|
* Handles when a shipping method is selected.
|
|
*
|
|
* @param {Object} evt The JQuery event.
|
|
*/
|
|
shipping_method_selected: function( evt ) {
|
|
var target = evt.currentTarget;
|
|
|
|
var shipping_methods = {};
|
|
|
|
$( 'select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]' ).each( function() {
|
|
shipping_methods[ $( target ).data( 'index' ) ] = $( target ).val();
|
|
} );
|
|
|
|
block( $( 'div.cart_totals' ) );
|
|
|
|
var data = {
|
|
security: wc_cart_params.update_shipping_method_nonce,
|
|
shipping_method: shipping_methods
|
|
};
|
|
|
|
$.ajax( {
|
|
type: 'post',
|
|
url: get_url( 'update_shipping_method' ),
|
|
data: data,
|
|
dataType: 'html',
|
|
success: function( response ) {
|
|
update_cart_totals_div( response );
|
|
},
|
|
complete: function() {
|
|
unblock( $( 'div.cart_totals' ) );
|
|
$( document.body ).trigger( 'updated_shipping_method' );
|
|
}
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Handles a shipping calculator form submit.
|
|
*
|
|
* @param {Object} evt The JQuery event.
|
|
*/
|
|
shipping_calculator_submit: function( evt ) {
|
|
evt.preventDefault();
|
|
|
|
var $form = $( evt.currentTarget );
|
|
|
|
block( $form );
|
|
block( $( 'div.cart_totals' ) );
|
|
|
|
// Provide the submit button value because wc-form-handler expects it.
|
|
$( '<input />' ).attr( 'type', 'hidden' )
|
|
.attr( 'name', 'calc_shipping' )
|
|
.attr( 'value', 'x' )
|
|
.appendTo( $form );
|
|
|
|
// Make call to actual form post URL.
|
|
$.ajax( {
|
|
type: $form.attr( 'method' ),
|
|
url: $form.attr( 'action' ),
|
|
data: $form.serialize(),
|
|
dataType: 'html',
|
|
success: function( response ) {
|
|
update_wc_div( response );
|
|
},
|
|
complete: function() {
|
|
unblock( $form );
|
|
unblock( $( 'div.cart_totals' ) );
|
|
}
|
|
} );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Object to handle cart UI.
|
|
*/
|
|
var cart = {
|
|
/**
|
|
* Initialize cart UI events.
|
|
*/
|
|
init: function() {
|
|
this.update_cart_totals = this.update_cart_totals.bind( this );
|
|
this.cart_submit = this.cart_submit.bind( this );
|
|
this.submit_click = this.submit_click.bind( this );
|
|
this.apply_coupon = this.apply_coupon.bind( this );
|
|
this.remove_coupon_clicked = this.remove_coupon_clicked.bind( this );
|
|
this.quantity_update = this.quantity_update.bind( this );
|
|
this.item_remove_clicked = this.item_remove_clicked.bind( this );
|
|
this.update_cart = this.update_cart.bind( this );
|
|
|
|
$( document ).on(
|
|
'wc_update_cart',
|
|
this.update_cart );
|
|
$( document ).on(
|
|
'click',
|
|
'div.woocommerce > form input[type=submit]',
|
|
this.submit_click );
|
|
$( document ).on(
|
|
'submit',
|
|
'div.woocommerce > form',
|
|
this.cart_submit );
|
|
$( document ).on(
|
|
'click',
|
|
'a.woocommerce-remove-coupon',
|
|
this.remove_coupon_clicked );
|
|
$( document ).on(
|
|
'click',
|
|
'td.product-remove > a',
|
|
this.item_remove_clicked );
|
|
$( document ).on(
|
|
'change input',
|
|
'div.woocommerce > form .cart_item :input',
|
|
this.input_changed );
|
|
|
|
$( 'div.woocommerce > form input[name="update_cart"]' ).prop( 'disabled', true );
|
|
},
|
|
|
|
/**
|
|
* After an input is changed, enable the update cart button.
|
|
*/
|
|
input_changed: function() {
|
|
$( 'div.woocommerce > form input[name="update_cart"]' ).prop( 'disabled', false );
|
|
},
|
|
|
|
/**
|
|
* Update entire cart via ajax.
|
|
*/
|
|
update_cart: function() {
|
|
var $form = $( 'table.shop_table.cart' ).closest( 'form' );
|
|
|
|
block( $form );
|
|
block( $( 'div.cart_totals' ) );
|
|
|
|
// Make call to actual form post URL.
|
|
$.ajax( {
|
|
type: $form.attr( 'method' ),
|
|
url: $form.attr( 'action' ),
|
|
data: $form.serialize(),
|
|
dataType: 'html',
|
|
success: function( response ) {
|
|
update_wc_div( response );
|
|
},
|
|
complete: function() {
|
|
unblock( $form );
|
|
unblock( $( 'div.cart_totals' ) );
|
|
}
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Update the cart after something has changed.
|
|
*/
|
|
update_cart_totals: function() {
|
|
block( $( 'div.cart_totals' ) );
|
|
|
|
$.ajax( {
|
|
url: get_url( 'get_cart_totals' ),
|
|
dataType: 'html',
|
|
success: function( response ) {
|
|
update_cart_totals_div( response );
|
|
},
|
|
complete: function() {
|
|
unblock( $( 'div.cart_totals' ) );
|
|
}
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Handle cart form submit and route to correct logic.
|
|
*
|
|
* @param {Object} evt The JQuery event
|
|
*/
|
|
cart_submit: function( evt ) {
|
|
var $form = $( evt.currentTarget );
|
|
var $submit = $( document.activeElement );
|
|
var $clicked = $( 'input[type=submit][clicked=true]' );
|
|
|
|
if ( 0 === $form.find( 'table.shop_table.cart' ).length ) {
|
|
return false;
|
|
}
|
|
if ( is_blocked( $form ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( $clicked.is( '[name="update_cart"]' ) || $submit.is( 'input.qty' ) ) {
|
|
evt.preventDefault();
|
|
this.quantity_update( $form );
|
|
|
|
} else if ( $clicked.is( '[name="apply_coupon"]' ) || $submit.is( '#coupon_code' ) ) {
|
|
evt.preventDefault();
|
|
this.apply_coupon( $form );
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Special handling to identify which submit button was clicked.
|
|
*
|
|
* @param {Object} evt The JQuery event
|
|
*/
|
|
submit_click: function( evt ) {
|
|
$( 'input[type=submit]', $( evt.target ).parents( 'form' ) ).removeAttr( 'clicked' );
|
|
$( evt.target ).attr( 'clicked', 'true' );
|
|
},
|
|
|
|
/**
|
|
* Apply Coupon code
|
|
*
|
|
* @param {JQuery Object} $form The cart form.
|
|
*/
|
|
apply_coupon: function( $form ) {
|
|
block( $form );
|
|
|
|
var cart = this;
|
|
var $text_field = $( '#coupon_code' );
|
|
var coupon_code = $text_field.val();
|
|
|
|
var data = {
|
|
security: wc_cart_params.apply_coupon_nonce,
|
|
coupon_code: coupon_code
|
|
};
|
|
|
|
$.ajax( {
|
|
type: 'POST',
|
|
url: get_url( 'apply_coupon' ),
|
|
data: data,
|
|
dataType: 'html',
|
|
success: function( response ) {
|
|
show_notice( response );
|
|
$( document.body ).trigger( 'applied_coupon' );
|
|
},
|
|
complete: function() {
|
|
unblock( $form );
|
|
$text_field.val( '' );
|
|
cart.update_cart_totals();
|
|
}
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Handle when a remove coupon link is clicked.
|
|
*
|
|
* @param {Object} evt The JQuery event
|
|
*/
|
|
remove_coupon_clicked: function( evt ) {
|
|
evt.preventDefault();
|
|
|
|
var cart = this;
|
|
var $tr = $( evt.currentTarget ).parents( 'tr' );
|
|
var coupon = $( evt.currentTarget ).attr( 'data-coupon' );
|
|
|
|
block( $tr.parents( 'table' ) );
|
|
|
|
var data = {
|
|
security: wc_cart_params.remove_coupon_nonce,
|
|
coupon: coupon
|
|
};
|
|
|
|
$.ajax( {
|
|
type: 'POST',
|
|
url: get_url( 'remove_coupon' ),
|
|
data: data,
|
|
dataType: 'html',
|
|
success: function( response ) {
|
|
show_notice( response );
|
|
$( document.body ).trigger( 'removed_coupon' );
|
|
unblock( $tr.parents( 'table' ) );
|
|
},
|
|
complete: function() {
|
|
cart.update_cart_totals();
|
|
}
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Handle a cart Quantity Update
|
|
*
|
|
* @param {JQuery Object} $form The cart form.
|
|
*/
|
|
quantity_update: function( $form ) {
|
|
// Provide the submit button value because wc-form-handler expects it.
|
|
$( '<input />' ).attr( 'type', 'hidden' )
|
|
.attr( 'name', 'update_cart' )
|
|
.attr( 'value', 'Update Cart' )
|
|
.appendTo( $form );
|
|
|
|
block( $form );
|
|
block( $( 'div.cart_totals' ) );
|
|
|
|
// Make call to actual form post URL.
|
|
$.ajax( {
|
|
type: $form.attr( 'method' ),
|
|
url: $form.attr( 'action' ),
|
|
data: $form.serialize(),
|
|
dataType: 'html',
|
|
success: update_wc_div,
|
|
complete: function() {
|
|
unblock( $form );
|
|
unblock( $( 'div.cart_totals' ) );
|
|
}
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Handle when a remove item link is clicked.
|
|
*
|
|
* @param {Object} evt The JQuery event
|
|
*/
|
|
item_remove_clicked: function( evt ) {
|
|
evt.preventDefault();
|
|
|
|
var $a = $( evt.currentTarget );
|
|
var $form = $a.parents( 'form' );
|
|
|
|
block( $form );
|
|
block( $( 'div.cart_totals' ) );
|
|
|
|
$.ajax( {
|
|
type: 'GET',
|
|
url: $a.attr( 'href' ),
|
|
dataType: 'html',
|
|
success: update_wc_div,
|
|
complete: function() {
|
|
unblock( $form );
|
|
unblock( $( 'div.cart_totals' ) );
|
|
}
|
|
} );
|
|
}
|
|
};
|
|
|
|
cart_shipping.init( cart );
|
|
cart.init();
|
|
} );
|