Skip to content

Instantly share code, notes, and snippets.

@steveosoule
Created August 30, 2017 19:14
Show Gist options
  • Save steveosoule/b6e1774f6d7628abcb468c0dcdfbb1c9 to your computer and use it in GitHub Desktop.
Save steveosoule/b6e1774f6d7628abcb468c0dcdfbb1c9 to your computer and use it in GitHub Desktop.
Miva - Quick Order Form
// ---- Quick OrderForm --- //
(function quick_order_form(){
var $button = $('#js-quick-add-button, .js-quick-add-button'),
form_selector = '.js-quick-add-form',
$container = $('.js-quick-add'),
doing_adpr = 0;
var init = function(){
$(document).on('submit', form_selector, function(e){
e.preventDefault();
adpr();
});
$button.on('click', adpr);
$(document).on('input', '.js-quick-add-product-code', debounced_search);
$(document).on('blur', '.js-quick-add-quantity', clean_quantity);
$('#js-quick-add-more-forms').on('click', function(){
var $new_form = $(form_selector).first().clone().insertAfter( $(form_selector).last() );
// var $new_form = $last_form.clone(true);
$new_form = $(form_selector).last();
$new_form.find('.js-quick-add-product-code').val('');
$new_form.find('.js-quick-add-quantity').val('0');
$new_form.find('.js-quick-add-datalist').html('');
$new_form.find('.js-quick-add-attributes').html('');
// $last_form.after( $new_form[0].outerHTML );
});
};
var debounced_search = debounce(function(e){
search(this)
}, 250);
var search = function(input){
var $input = $(input),
$form = $(input.form);
$.ajax({
url: $input.data('search-url'),
type: 'GET',
data: {
Search: $input.val()
}
})
.done(function(response) {
var $response = $(response),
$datalist = $response.filter('#datalist'),
$options = $datalist.find('option'),
$attributes = $response.filter('#attributes');
$form.find('.js-quick-add-datalist').html( $datalist.html() );
if( $options.length === 1 ){
$input.val( $options.val() );
$form.find('.js-quick-add-datalist').html('');
}
$form.find('.js-quick-add-attributes').html( $attributes.html() );
})
.fail(function() {
$form.find('.js-quick-add-datalist').html('');
$form.find('.js-quick-add-attributes').html('');
});
};
var clean_quantity = function(){
var quantity = Number(this.value);
if( isNaN(quantity) ){
quantity = 0;
}
if( !(quantity >= 0) ){
quantity = 0;
}
this.value = parseInt(quantity);
};
var adpr = function(){
// Stop double-clicks/submits and wait until we've finished processing all forms
if( doing_adpr > 0 ) return false;
$button.data('text', $button.text());
$button.text('Processing...').prop('disabled', true);
// Get all forms with a Quantity
$adpr_forms = $(form_selector).filter(function(i, form){
return parseInt(form.elements.Quantity.value) > 0;
});
doing_adpr = $adpr_forms.length;
$adpr_forms.each(function(i, form){
var $form = $(form);
$form.addClass('quick-add-form--doing-adpr');
$container.addClass('quick-add--doing-adpr');
$.ajax({
cache: false,
url: $form.prop('action'),
type: $form.prop('method'),
data: $form.serialize()
})
.done(function(response) {
console.log('success', $form.serialize(), arguments );
handle_adpr_response(response, form);
form.reset();
$form.find('.js-quick-add-attributes').html('');
$form.find('.js-quick-add-datalist').html('');
})
.fail(function() {
console.error('error', $form.serialize(), arguments);
})
.always(function() {
$form.removeClass('quick-add-form--doing-adpr');
doing_adpr--;
if( doing_adpr === 0 ){
$button.text( $button.data('text') ).prop('disabled', false);
$container.removeClass('quick-add--doing-adpr');
}
});
});
};
var handle_adpr_response = function(response, form){
var responseMessage = $(form).find('.js-quick-add-messages');
if (response.search(/id="js-BASK"/i) != -1) {
$('html, body').animate({scrollTop: '0px'}, 250);
var miniBasket = $('#js-mini-basket-container'),
responseMiniBasket = $(response).find('#js-mini-basket-container'),
miniBasketCount = responseMiniBasket.contents()[1].getAttribute('data-itemcount'),
miniBasketSubtotal = ' ' + responseMiniBasket.contents()[1].getAttribute('data-subtotal'),
miniBasketLinkCount = $('#js-mini-basket-count, #js-mobile-basket-button .notification'),
miniBasketLinkSubtotal = $('#js-mini-basket-subtotal');
miniBasketLinkCount.text(miniBasketCount); // Update basket quantity (display only)
miniBasketLinkSubtotal.text(miniBasketSubtotal); // Update basket subtotal (display only)
miniBasket.html(responseMiniBasket.contents()).addClass('open');
setTimeout(function () {
miniBasket.removeClass('open');
}, 5000);
// Re-Initialize Attribute Machine (if it is active)
if (typeof attrMachCall !== 'undefined') {
attrMachCall.Initialize();
}
}
else if(response.search(/id="js-PATR"/i) != -1) {
var missingAttrs = [];
form.find('.required').each(function () {
missingAttrs.push(' ' + $(this).attr('title'));
});
responseMessage.html('<div class="message message-info">All <em class="red">Required</em> options have not been selected.<br />Please review the following options: <span class="red">' + missingAttrs + '</span>.</div>').fadeIn().delay(5000).fadeOut();
}
else if(response.search(/id="js-PLMT"/i) != -1) {
responseMessage.html('<div class="message message-info">We do not have enough of the Size/Color you have selected.<br />Please adjust your quantity.</div>').fadeIn().delay(3000).fadeOut();
}
else if(response.search(/id="js-POUT"/i) != -1) {
responseMessage.html('<div class="message message-info">The Size/Color you have selected is out of stock.<br />Please review your options or check back later.</div>').fadeIn().delay(3000).fadeOut();
}
else {
responseMessage.html('<div class="message message-info">Please review options and call us for help if the error persists.</div>').fadeIn().delay(3000).fadeOut();
}
};
init();
})();
<mvt:if expr="g.Search">
<mvt:assign name="l.offset" value="0" />
<mvt:assign name="l.max" value="10" />
<mvt:do file="g.Module_Library_DB" name="l.count" value="Runtime_ProductList_Load_Offset_Search_Sort(g.Search, g.Offset, l.max, '', g.NextOffset, l.settings:products)" />
<div id="datalist">
<mvt:foreach iterator="product" array="products">
<option value="&mvte:product:code;">
</mvt:foreach>
</div>
<mvt:if expr="l.count EQ 1 OR g.Product_Selected">
<mvt:do file="g.Module_Library_DB" name="l.success" value="Runtime_Product_Load_Code( g.Search, l.settings:product )" />
<div id="attributes">
<mvt:item name="product_attributes" param="product:id" />
</div>
</mvt:if>
<mvt:exit/>
</mvt:if>
<mvt:item name="html_profile" />
<head>
<mvt:if expr="NOT ISNULL l.settings:page:title">
<title>&mvt:page:title;</title>
<mvt:else>
<title>&mvt:store:name;: &mvt:page:name;</title>
</mvt:if>
<mvt:item name="head" param="head_tag" />
</head>
<body id="js-&mvte:page:code;" class="single-column <mvt:eval expr="tolower(l.settings:page:code)" />">
<mvt:item name="hdft" param="global_header" />
<div class="row hdft-header">
<mvt:item name="hdft" param="header" />
</div>
<div class="row bg-white main-content-row content-item">
<div class="column whole large-half">
<div class="quick-add js-quick-add">
<div class="row">
<div class="column one-tenth">
QTY.
</div>
<div class="column nine-tenths">
Item Number
</div>
</div>
<mvt:while expr="l.settings:counter LT 5">
<mvt:assign name="l.settings:counter" value="l.settings:counter + 1" />
<form method="POST" action="&mvte:urls:BASK:auto;" class="row quick-add-form form-row js-quick-add-form" autocomplete="off">
<input type="hidden" name="Action" value="ADPR">
<div class="column one-tenth np">
<input type="number" num="0" step="1" name="Quantity" value="0" class="quick-add-quantity js-quick-add-quantity align-center">
</div>
<div class="column nine-tenths">
<input type="text" name="Product_Code" list="quick-add-datalist-&mvt:counter;" class="js-quick-add-product-code" data-search-url="&mvte:urls:QKOF:auto;">
<datalist id="quick-add-datalist-&mvt:counter;" class="js-quick-add-datalist"></datalist>
</div>
<div class="column whole medium-offset-one-tenth nine-tenths">
<div class="js-quick-add-attributes"></div>
</div>
<div class="column whole medium-offset-one-tenth nine-tenths">
<div class="js-quick-add-messages"></div>
</div>
</form>
</mvt:while>
<div class="row">
<div class="column whole breaker"></div>
<div class="column half np">
<button id="js-quick-add-more-forms" class="button button-hollow primary uppercase bold">
Add <span class="small-inline-block hide">More</span> Forms
</button>
</div>
<div class="column half np">
<button id="js-quick-add-button" class="button button-block button-large bg-primary white uppercase bold">
Add <span class="small-inline-block hide">to Cart</span>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="row hdft-footer">
<mvt:item name="hdft" param="footer" />
</div>
<mvt:item name="hdft" param="global_footer" />
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment