//
[[lineItem.searchResult['product_title'] ]]  -  [[lineItem.searchResult['variant_title'] ]]  -  [[lineItem.searchResult['sku'] ]]
Unit price:
A line item already exists for that product
// ]]> var template = document.getElementById('line-item-template'); template.innerHTML = template.innerHTML.replace('// ', ''); .bo-app { padding: 20px 0px 10px 0px; border: 1px solid #EEEEEE; } .bo-variant-input-section { display: inline-block; } .bo-quantity-input-section { display: inline-block; } .bo-remove-section { display: inline-block; height: 50px; line-height: 50px; text-align: center; } .bo-svg-container { padding: 5px 0px; } .bo-remove-section svg { height: 25px; width: 25px; } .bo-variant-input { width: 100%; } .bo-line-item { margin-bottom: 20px; } .bo-line-item input { height: 50px !important; width: 100% !important; padding-top: 0px !important; padding-bottom: 0px !important; } .bo-img { margin-left: 0px !important; max-height: 50px !important; width: auto !important; } .bo-img-container { max-height: 50px !important; } .bo-line-item-details { font-size: 1.05rem; } .angucomplete-searching { padding: 0px 5px; font-size: 1.05rem; } .angucomplete-holder{ position: relative; } .angucomplete-dropdown { margin-top: 0px; padding: 20px 10px; background-color: #FCFCFC; border: 1px solid #DDDDDD; max-height: 360px; overflow: scroll; position: absolute; z-index: 999; width: 100%; } .angucomplete-row { min-height: 50px; margin-bottom: 20px; cursor: pointer; } .angucomplete-image-holder { width: calc(16.66666667% - 20px); float: left; padding: 0px 5px; margin: 0px !important; } .angucomplete-image { max-height: 50px !important; width: auto !important; } .angucomplete-title { width: calc(83.33333333% - 20px); float: left; font-size: 1.05rem; padding: 0px 5px; } .bo-add-line-item { position: relative; font-size: 1.05rem; margin-top: 10px; } .bo-cart-controls { margin-top: 20px; font-size: 1.05rem; } .bo-clear-cart, .bo-update-cart { text-align: right; margin-bottom: 10px; } .bo-update-cart-btn { float: right; max-width: 80%; position: relative; bottom: 5px; } .bo-line-item-already-exists-msg { color: red; } .bo-row { padding: 0px 10px; min-height: 50px; } .bo-col-1 { width: calc(8.33333333% - 20px); float: left; } .bo-col-2 { width: calc(16.6666667% - 20px); float: left; } .bo-col-3 { width: calc(25% - 20px); float: left; } .bo-col-4 { width: calc(33.33333333% - 20px); float: left; } .bo-col-5 { width: calc(41.66666667% - 20px); float: left; } .bo-col-6 { width: calc(50% - 20px); float: left; } .bo-col-7 { width: calc(58.33333333% - 20px); float: left; } .bo-col-8 { width: calc(66.66666667% - 20px); float: left; } .bo-col-9 { width: calc(75% - 20px); float: left; } .bo-col-10 { width: calc(83.33333333% - 20px); float: left; } .bo-col-11 { width: calc(91.66666667% - 20px); float: left; } .bo-col-12 { width: calc(100% - 20px); float: left; } .bo-col-1, .bo-col-2, .bo-col-3, .bo-col-4, .bo-col-5, .bo-col-6, .bo-col-7, .bo-col-8, .bo-col-9, .bo-col-10, .bo-col-11, .bo-col-12 { margin: 0px 10px; } (function() { function BulkOrderRootCtrl($scope, $http, $timeout) { $scope.lineItems = []; $scope.cart = null; $scope.hasChanges = false; $http.get('/cart.js').success(function(response) { $scope.cart = response; }); $scope.addLineItem = function(opt_initial) { $scope.lineItems.push({ searchResult: null, expanded: false, quantity: null }); if (!opt_initial) { $scope.hasChanges = true; } }; // Initialize the first empty line item in a timeout. // Certain themes look for number inputs at page load time // and replace them with custom widgets. $timeout(function() { $scope.addLineItem(true); }); $scope.updateCart = function() { $http.post('/cart/update.js', { 'updates': _.reduce($scope.lineItems, function(obj, lineItem) { if (lineItem.searchResult && _.isNumber(lineItem.quantity)) { obj[lineItem.searchResult['variant_id']] = lineItem.quantity; } return obj; }, {}) }) .success(function(response) { $scope.cart = response; $scope.hasChanges = false; $scope.lineItems = _.filter($scope.lineItems, function(lineItem) { return lineItem.quantity > 0; }); }) .error(function(response) { // Handle out of stock here console.log(response); }); }; $scope.clearCart = function() { $http.post('/cart/clear.js') .success(function(response) { $scope.cart = response; $scope.lineItems = []; $scope.hasChanges = false; }); }; $scope.$on('quantity-changed', function() { $scope.hasChanges = true; }); $scope.$on('delete-line-item', function(event, lineItem) { var idx = $scope.lineItems.indexOf(lineItem); if (idx != -1) { $scope.lineItems.splice(idx, 1); } }); $scope.$on('expand-all-variants', function(event, lineItem) { var idx = $scope.lineItems.indexOf(lineItem); if (idx != -1) { var args = [idx, 1]; angular.forEach(lineItem.searchResult['product']['variants'], function(variant) { var imageUrl = ''; if (variant['featured_image'] && variant['featured_image']['src']) { imageUrl = variant['featured_image']['src'] } else if (lineItem.searchResult['product']['featured_image']) { imageUrl = lineItem.searchResult['product']['featured_image']; } args.push({ quantity: lineItem.searchResult['variant_id'] == variant['id'] ? lineItem.quantity : null, expanded: true, searchResult: { 'product_title': lineItem.searchResult['product_title'], 'variant_title': variant['title'], 'variant_id': variant['id'], 'sku': variant['sku'], 'price': variant['price'], 'url': variant['url'], 'product': lineItem.searchResult['product'], 'thumbnail_url': shopifyImageUrl(imageUrl, 'thumb') } }); }); Array.prototype.splice.apply($scope.lineItems, args); } }); } function boLineItem() { return { scope: { lineItem: '=', index: '=', allLineItems: '=' }, templateUrl: 'line-item-template', controller: function($scope) { $scope.showLineItemAlreadyExistsMsg = false; $scope.selectResult = function(result) { $scope.showLineItemAlreadyExistsMsg = false; if ($scope.variantLineItemAlreadyExists(result.originalObject['variant_id'])) { $scope.showLineItemAlreadyExistsMsg = true; } else { $scope.lineItem.searchResult = result.originalObject; } }; $scope.variantLineItemAlreadyExists = function(variantId) { var exists = false; angular.forEach($scope.allLineItems, function(lineItem) { if (lineItem !== $scope.lineItem && lineItem.searchResult['variant_id'] == variantId) { exists = true; } }); return exists; }; $scope.quantityChanged = function() { $scope.$emit('quantity-changed'); }; $scope.deleteLineItem = function() { if (_.isNumber($scope.lineItem.quantity)) { $scope.lineItem.quantity = 0; $scope.quantityChanged(); } else { $scope.$emit('delete-line-item', $scope.lineItem); } }; $scope.numVariants = function() { return $scope.lineItem.searchResult['product']['variants'].length; }; $scope.expandAllVariants = function() { $scope.$emit('expand-all-variants', $scope.lineItem); }; } }; } function boConfigureAngucomplete($timeout) { return { restrict: 'A', link: function(scope, element, attrs) { var input = element.find('input'); input.attr('tabindex', attrs.boTabindex); $timeout(function() { input.focus(); }); } }; } function shopifyImageUrl(url, imageType) { if (url.indexOf('_' + imageType + '.') != -1) { return url; } var dotIdx = url.lastIndexOf('.'); return [url.slice(0, dotIdx), '_', imageType, url.slice(dotIdx, url.length)].join(''); } function shopifyMoneyFormat($shopifyMoneyFormatString, $sce) { return function(cents) { return $sce.trustAsHtml(Shopify.formatMoney(cents, $shopifyMoneyFormatString)); }; } function interpolator($interpolateProvider) { $interpolateProvider.startSymbol('[['); $interpolateProvider.endSymbol(']]'); } // Polyfill for themes that don't include these: function polyfillShopifyBuiltins() { if (!window['Shopify']) { window['Shopify'] = {}; } if (!Shopify.formatMoney) { Shopify.formatMoney = function(cents, format) { if (typeof cents == 'string') cents = cents.replace('.',''); var value = ''; var patt = /\{\{\s*(\w+)\s*\}\}/; var formatString = (format || this.money_format); function addCommas(moneyString) { return moneyString.replace(/(\d+)(\d{3}[\.,]?)/,'$1,$2'); } switch(formatString.match(patt)[1]) { case 'amount': value = addCommas(floatToString(cents/100.0, 2)); break; case 'amount_no_decimals': value = addCommas(floatToString(cents/100.0, 0)); break; case 'amount_with_comma_separator': value = floatToString(cents/100.0, 2).replace(/\./, ','); break; case 'amount_no_decimals_with_comma_separator': value = addCommas(floatToString(cents/100.0, 0)).replace(/\./, ','); break; } return formatString.replace(patt, value); }; if (!window['floatToString']) { window['floatToString'] = function(numeric, decimals) { var amount = numeric.toFixed(decimals).toString(); if(amount.match(/^\.\d+/)) {return "0"+amount; } else { return amount; } } } } } polyfillShopifyBuiltins(); angular.module('bulkOrderAppModule', ['angucomplete-alt'], interpolator) .controller('BulkOrderRootCtrl', BulkOrderRootCtrl) .directive('boLineItem', boLineItem) .directive('boConfigureAngucomplete', boConfigureAngucomplete) .filter('shopifyMoneyFormat', shopifyMoneyFormat) .value('$shopifyMoneyFormatString', BO_MONEY_FORMAT); })();