Skip to content

Instantly share code, notes, and snippets.

@justin-endler

justin-endler/storeUtil.js

Last active Dec 19, 2015
Embed
What would you like to do?
JavaScript utilities for use in a Drupal Commerce project.
(function($) {
Drupal.behaviors.storeUtil = {
/**
* @param Number negative places to move the decimal left, positive to move it right
* @param String float
* @return String
*/
moveDecimal: function(places, f) {
// Move zero places.
if (!places) {
return f;
}
// Decimal index.
var decimalIndex = f.indexOf('.');
if (decimalIndex == -1) {
decimalIndex = f.length;
}
// Remove decimal.
f = f.replace(/\./g, '');
// Absolute places.
var absPlaces = Math.abs(places),
// Zeros padding.
zeros = 0;
// Pad zeros left.
if (places < 0 && absPlaces > decimalIndex) {
zeros = absPlaces - decimalIndex;
for (var z = 0; z < zeros; z++) {
f = '0' + f;
decimalIndex++;
}
}
// Pad zeros right.
else if (places > (f.length - decimalIndex)) {
zeros = places - (f.length - decimalIndex);
for (var z = 0; z < zeros; z++) {
f += '0';
}
}
decimalIndex = decimalIndex + places;
return f.slice(0, decimalIndex) + '.' + f.slice(decimalIndex);
},
/**
* Return f rounded to places. If places is negative, output a whole number.
*
* @param String float to round
* @param Number places to round to, zero or positive
* @return String
*/
round: function(f, places) {
// Negative places input.
if (places < 0) {
places = 0;
}
// Determine scale.
var scale = '1';
for (var i = 0; i < places; i++ ) {
scale += '0';
}
// Round.
f = parseFloat(f) * parseInt(scale);
f = Math.round(f);
f = String(f);
f = this.moveDecimal(places * -1, f);
return f;
},
/**
* @param String price to round to nearest cent
* @return String
*/
priceRound: function(price) {
// @todo improve rounding to match rounding style config of Drupal Commerce.
return this.round(price, 2);
},
/**
* @param String price or constant
* @param String price or constant
* @return String
*/
multiplyPrice: function(x, y) {
// Only mutliply prices, not more-detailed floats.
x = String(this.round(x, 2));
y = String(this.round(y, 2));
// Get decimal correction.
var xIndex = x.indexOf('.'),
xCorrection = (xIndex !== -1) ? (x.length - 1) - xIndex : 0,
yIndex = y.indexOf('.'),
yCorrection = (yIndex !== -1) ? (y.length - 1) - yIndex : 0,
correction = xCorrection + yCorrection;
// Remove decimal and account for places.
x = x.replace('.', '');
y = y.replace('.', '');
// Multiply.
var xy = String(x * y);
// Correct product decimal.
xy = this.moveDecimal(correction * -1, xy);
return this.priceRound(xy);
},
/**
* @param Object jQuery selection of an img element
* @return Object width and height of img
*/
getImageSize: function(img) {
var c = img.clone(),
utilDiv = $('<div style"position:absolute;left:-9999px"></div>');
// Add the image clone to the DOM.
utilDiv.appendTo('body');
utilDiv.append(c);
// Remove size attributes to ensure getting the actual image size.
c.removeAttr('width');
c.removeAttr('height');
var size = {
'width': c.width(),
'height': c.height()
};
// Remove the image clone from the DOM.
utilDiv.remove();
return size;
},
/**
* Normalize the size of a collection of images by width. Downsizing only.
*
* @param jQuery collection of image elements
* @param Number integer max value to use as a width min
*/
normalizeImgSizes: function(imgs, maxAllowedWidthMin) {
// Get min img width.
var min = 0,
w,
self = this;
if (typeof maxAllowedWidthMin === 'number' && maxAllowedWidthMin > 0) {
min = maxAllowedWidthMin;
}
// Find min.
imgs.each(function() {
var size = self.getImageSize($(this));
w = size.width;
// Get initial min.
if (!min || w < min) {
min = w;
}
});
// Alter size of each doc image.
imgs.width(min).height('auto');
},
/**
* @param jQuery collection of image elements
* @return Number tallest image height in pixels
*/
getTallestImageHeight: function(imgs) {
var self = this,
heights = [];
// Populate heights.
imgs.each(function() {
heights.push(self.getImageSize($(this)).height);
});
// Sort descending.
heights.sort(function(a, b) {
return b - a;
});
// Return largest.
return heights[0];
},
/**
* Return the next value in an object after the first occurence of val.
*
* @param String or Number the base value.
* @param Object
* @return String, Number, or Boolean false if val is not present or there is no next value
*/
getNextValInObject: function(val, obj) {
var foundCurrent = false,
key;
// Find current.
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (val == obj[key]) {
foundCurrent = true;
}
else if (foundCurrent) {
return obj[key];
}
}
}
return false;
},
/**
* Return the previous value in an object before the first occurence of val.
*
* @param String or Number the base value.
* @param Object
* @return String, Number, or Boolean false if val is not present or there is no previous value
*/
getPrevValInObject: function(val, obj) {
var prevKey = false,
key;
// Find current.
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (val == obj[key]) {
if (!prevKey) {
return false;
}
return obj[prevKey];
}
prevKey = key;
}
}
return false;
}
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.