133 lines
4.8 KiB
JavaScript
133 lines
4.8 KiB
JavaScript
|
|
(function ($) {
|
|
|
|
var pluginName = "starRating";
|
|
var defaultOptions = {
|
|
starCount: 5,
|
|
readOnly: false,
|
|
interval: 1,
|
|
size: '30px'
|
|
};
|
|
|
|
var methods = {
|
|
initialize: function(opts) {
|
|
return this.each(function() {
|
|
var $input = $(this);
|
|
var attrOpts = {};
|
|
var inputData = $input.data();
|
|
|
|
if (inputData[pluginName.toLowerCase()] === true) {
|
|
if (console && console.log) {
|
|
console.log("star rating has already been initialized; skipping...");
|
|
}
|
|
return;
|
|
}
|
|
|
|
$input.attr("data-" + pluginName.toLowerCase(), "true");
|
|
|
|
if (inputData.interval) {
|
|
attrOpts.interval = inputData.interval;
|
|
}
|
|
|
|
if (inputData.starcount) {
|
|
attrOpts.starCount = inputData.starcount;
|
|
}
|
|
|
|
if (inputData.size) {
|
|
attrOpts.size = inputData.size;
|
|
}
|
|
|
|
if ($input.is(":disabled")) {
|
|
attrOpts.readOnly = true;
|
|
}
|
|
|
|
var options = _.extend({}, defaultOptions, attrOpts, opts);
|
|
|
|
var $widget = $("<span />").addClass("star-rating").css({'font-size': options.size});
|
|
var $emptySet = $("<span />").addClass("empty-set").appendTo($widget);
|
|
var $filledSet = $("<span />").addClass("filled-set").appendTo($widget);
|
|
|
|
options.$input = $input;
|
|
options.$emptySet = $emptySet;
|
|
|
|
for (var x = 1; x <= options.starCount; x++) {
|
|
$emptySet.append(
|
|
$("<span />").addClass("star empty")
|
|
);
|
|
|
|
$filledSet.append(
|
|
$("<span />").addClass("star full")
|
|
);
|
|
}
|
|
|
|
$widget.data(pluginName + ".options", options);
|
|
|
|
$input.data(pluginName, true).hide().after($widget);
|
|
|
|
privateMethods.updateStars($widget);
|
|
|
|
if (!options.readOnly) {
|
|
$widget
|
|
.on("click." + pluginName, function(e) {
|
|
var value = privateMethods.calculateRating($widget, e.pageX);
|
|
privateMethods.setValue($widget, value);
|
|
})
|
|
.on("mousemove." + pluginName, function(e) {
|
|
var value = privateMethods.calculateRating($widget, e.pageX);
|
|
privateMethods.updateStars($widget, value);
|
|
})
|
|
.on("mouseleave." + pluginName, function (e) {
|
|
privateMethods.updateStars($widget);
|
|
});
|
|
}
|
|
|
|
$input
|
|
.on("change." + pluginName, function() {
|
|
privateMethods.updateStars($widget);
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
var privateMethods = {
|
|
updateStars: function($widget, value) {
|
|
var options = $widget.data(pluginName + ".options");
|
|
value = (value == null ? (parseFloat(options.$input.val() || 0)) : value);
|
|
$widget.find(".filled-set").css({width: privateMethods.calculateWidth($widget, value)});
|
|
},
|
|
|
|
setValue: function($widget, value) {
|
|
var options = $widget.data(pluginName + ".options");
|
|
options.$input.val(value);
|
|
privateMethods.updateStars($widget);
|
|
},
|
|
|
|
calculateWidth: function($widget, value) {
|
|
var options = $widget.data(pluginName + ".options");
|
|
var width = options.$emptySet.width();
|
|
return ((value / options.starCount) * 100).toString() + "%";
|
|
},
|
|
|
|
// Given a screen X coordinate, calculates the nearest valid value for this rating widget
|
|
calculateRating: function($widget, screenX) {
|
|
var options = $widget.data(pluginName + ".options");
|
|
var offset = options.$emptySet.offset();
|
|
var width = options.$emptySet.width();
|
|
var ratio = (screenX - offset.left) / width;
|
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
|
|
return Math.ceil(options.starCount * (1 / options.interval) * ratio) / (1 / options.interval);
|
|
}
|
|
};
|
|
|
|
$.fn[pluginName] = function(method) {
|
|
if (methods[method]) {
|
|
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
|
} else if (typeof method === 'object' || ! method) {
|
|
return methods.initialize.apply(this, arguments);
|
|
} else {
|
|
$.error('Method ' + method + ' does not exist on jQuery.' + pluginName);
|
|
}
|
|
};
|
|
|
|
})(jQuery); |