steveosoule
8/8/2015 - 12:16 AM

Miva - AJAX Add to Basket with Promises & Deferrerds

Miva - AJAX Add to Basket with Promises & Deferrerds

var mvAddToCart = {
	isSubmitting: false,
	$mainForm: $('.js-product-form--main'),
	$addonForm: $('.js-product-form--addon'),
	deferreds: [],
	init: function(){
		$('.js-product-form--main').on('submit', mvAddToCart.submit);
		$('.js-product-form--addon').on('submit', mvAddToCart.submit);
		mvAddToCart.button.$element = mvAddToCart.$mainForm.find('.js-btn__add-to-cart--primary');
		mvAddToCart.button.html = mvAddToCart.button.$element.html();

		$('.js-addon--is-included').each(function(){
			var $checkbox = $(this);

			if( $checkbox.is(':checked') ){
				$( $checkbox.closest('label').data('target') ).slideDown('fast');
			} else {
				$( $checkbox.closest('label').data('target') ).slideUp('fast');
			}
		});
	},
	button: {
		$element: {},
		html: '',
		set: {
			submitting: function(){
				mvAddToCart.button.$element.prop('disabled', true);
				mvAddToCart.button.$element.html('<span class="fa fa-spin fa-cog"></span> Processing...');
			},
			default: function(){
				mvAddToCart.button.$element.prop('disabled', false);
				mvAddToCart.button.$element.html( mvAddToCart.button.html );
			}
		}
	},
	lastAjax: {},
	submit: function(e){
		e.preventDefault();

		if( mvAddToCart.isSubmitting ){
			return;
		}
		mvAddToCart.isSubmitting = true;
		mvAddToCart.button.set.submitting();

		mvAddToCart.getDeferreds();

		$.when.apply($, mvAddToCart.deferreds )
			.always( mvAddToCart.submitDone )
			.fail( mvAddToCart.submitFailure );
	},
	getDeferreds: function(){
		var deferreds = [];

		deferreds.push(
			$.ajax({
				url: mvAddToCart.$mainForm.attr('action'),
				type: mvAddToCart.$mainForm.prop('method'),
				data: mvAddToCart.$mainForm.serialize()
			})
		);

		$('.js-product-form--addon').each(function(){
			var $form = $(this);
			if( !$form.find('.js-addon--is-included').is(':checked') ){
				return;
			}

			deferreds.push(
				$.ajax({
					url: mvAddToCart.$addonForm.attr('action'),
					type: mvAddToCart.$addonForm.prop('method'),
					data: mvAddToCart.$addonForm.serialize()
				})
			);
		});

		mvAddToCart.deferreds = deferreds;

		return deferreds;
	},
	submitDone: function(){
		$.each(mvAddToCart.deferreds, function(i, jqXHR){
			var content = $.trim(jqXHR.responseText),
				$content = $(content);
			if( jqXHR.status !== 200 ){
				console.error('HTTP Request error');
			}

			if( (i + 1) === mvAddToCart.deferreds.length ){
				$('.navbar-off-canvas__desktop-basket').html( $content.find('.navbar-off-canvas__desktop-basket').html() );
			}

		});

		mvAddToCart.isSubmitting = false;
		mvAddToCart.button.set.default();
		mvAddToCart.deferreds = [];
	},
	submitFailure: function(){
		console.error('Failed adding product to cart');
	}
};
mvAddToCart.init();