Your IP : 3.145.65.133
/*! rater-js. [c] 2018 Fredrik Olsson. MIT License */
let css = require('./style.css');
module.exports = function(options) {
//private fields
let showToolTip = true;
if (typeof options.element === "undefined" || options.element === null) {
throw new Error("element required");
}
if (typeof options.showToolTip !== "undefined") {
showToolTip = !!options.showToolTip;
}
if (typeof options.step !== "undefined") {
if (options.step <= 0 || options.step > 1) {
throw new Error("step must be a number between 0 and 1");
}
}
let elem = options.element;
let reverse = options.reverse;
let stars = options.max || 5;
let starSize = options.starSize || 16;
let step = options.step || 1;
let onHover = options.onHover;
let onLeave = options.onLeave;
let rating = null;
let myRating;
elem.classList.add("star-rating");
let div = document.createElement("div");
div.classList.add("star-value");
if(reverse) {
div.classList.add("rtl");
}
div.style.backgroundSize = starSize + "px";
elem.appendChild(div);
elem.style.width = starSize * stars + "px";
elem.style.height = starSize + "px";
elem.style.backgroundSize = starSize + "px";
let callback = options.rateCallback;
let disabled = !!options.readOnly;
let disableText;
let isRating = false;
let isBusyText = options.isBusyText;
let currentRating;
let ratingText;
if (typeof options.disableText !== "undefined") {
disableText = options.disableText;
}else {
disableText = "{rating}/{maxRating}";
}
if (typeof options.ratingText !== "undefined") {
ratingText = options.ratingText;
}else {
ratingText = "{rating}/{maxRating}";
}
if (options.rating) {
setRating(options.rating);
}else {
var dataRating = elem.dataset.rating;
if (dataRating) {
setRating( + dataRating);
}
}
if ( ! rating) {
elem.querySelector(".star-value").style.width = "0px";
}
if (disabled) {
disable();
}
//private methods
function onMouseMove(e) {
onMove(e,false);
}
/**
* Called by eventhandlers when mouse or touch events are triggered
* @param {MouseEvent} e
*/
function onMove(e, isTouch) {
if (disabled === true || isRating === true) {
return;
}
let xCoor = null;
let percent;
let width = elem.offsetWidth;
let parentOffset = elem.getBoundingClientRect();
if (reverse) {
if(isTouch) {
xCoor = e.changedTouches[0].pageX - parentOffset.left;
} else {
xCoor = e.pageX - window.scrollX - parentOffset.left;
}
let relXRtl = width - xCoor;
let valueForDivision = width / 100;
percent = relXRtl / valueForDivision;
} else {
if(isTouch) {
xCoor = e.changedTouches[0].pageX - parentOffset.left;
} else {
xCoor = e.offsetX;
}
percent = xCoor / width * 100;
}
if (percent < 101) {
if (step === 1) {
currentRating = Math.ceil((percent / 100) * stars);
}else {
let rat = (percent / 100) * stars;
for (let i = 0; ; i += step) {
if (i >= rat) {
currentRating = i;
break;
}
}
}
//todo: check why this happens and fix
if(currentRating > stars) {
currentRating = stars;
}
elem.querySelector(".star-value").style.width = currentRating/stars * 100 + "%";
if (showToolTip) {
let toolTip = ratingText.replace("{rating}", currentRating);
toolTip = toolTip.replace("{maxRating}", stars);
elem.setAttribute("title", toolTip);
}
if (typeof onHover === "function") {
onHover(currentRating, rating);
}
}
}
/**
* Called when mouse is released. This function will update the view with the rating.
* @param {MouseEvent} e
*/
function onStarOut(e) {
if (!rating) {
elem.querySelector(".star-value").style.width = "0%";
elem.removeAttribute("data-rating");
}else {
elem.querySelector(".star-value").style.width = rating/stars * 100 + "%";
elem.setAttribute("data-rating", rating);
}
if (typeof onLeave === "function") {
onLeave(currentRating, rating);
}
}
/**
* Called when star is clicked.
* @param {MouseEvent} e
*/
function onStarClick(e) {
if (disabled === true) {
return;
}
if (isRating === true) {
return;
}
if (typeof callback !== "undefined") {
isRating = true;
myRating = currentRating;
if (typeof isBusyText === "undefined") {
elem.removeAttribute("title");
}else {
elem.setAttribute("title", isBusyText);
}
elem.classList.add("is-busy");
callback.call(this, myRating, function() {
if (disabled === false) {
elem.removeAttribute("title");
}
isRating = false;
elem.classList.remove("is-busy");
});
}
}
/**
* Disables the rater so that it's not possible to click the stars.
*/
function disable() {
disabled = true;
elem.classList.add("disabled");
if (showToolTip && !!disableText) {
let toolTip = disableText.replace("{rating}", !!rating ? rating : 0);
toolTip = toolTip.replace("{maxRating}", stars);
elem.setAttribute("title", toolTip);
}else {
elem.removeAttribute("title");
}
}
/**
* Enabled the rater so that it's possible to click the stars.
*/
function enable() {
disabled = false;
elem.removeAttribute("title");
elem.classList.remove("disabled");
}
/**
* Sets the rating
*/
function setRating(value) {
if (typeof value === "undefined") {
throw new Error("Value not set.");
}
if (value === null) {
throw new Error("Value cannot be null.");
}
if (typeof value !== "number") {
throw new Error("Value must be a number.");
}
if (value < 0 || value > stars) {
throw new Error("Value too high. Please set a rating of " + stars + " or below.");
}
rating = value;
elem.querySelector(".star-value").style.width = value/stars * 100 + "%";
elem.setAttribute("data-rating", value);
}
/**
* Gets the rating
*/
function getRating() {
return rating;
}
/**
* Set the rating to a value to inducate it's not rated.
*/
function clear() {
rating = null;
elem.querySelector(".star-value").style.width = "0px";
elem.removeAttribute("title");
}
/**
* Remove event handlers.
*/
function dispose() {
elem.removeEventListener("mousemove", onMouseMove);
elem.removeEventListener("mouseleave", onStarOut);
elem.removeEventListener("click", onStarClick);
elem.removeEventListener("touchmove", handleMove, false);
elem.removeEventListener("touchstart", handleStart, false);
elem.removeEventListener("touchend", handleEnd, false);
elem.removeEventListener("touchcancel", handleCancel, false);
}
elem.addEventListener("mousemove", onMouseMove);
elem.addEventListener("mouseleave", onStarOut);
let module = {
setRating:setRating,
getRating:getRating,
disable:disable,
enable:enable,
clear:clear,
dispose:dispose,
get element() {
return elem;
}
};
/**
* Handles touchmove event.
* @param {TouchEvent} e
*/
function handleMove(e) {
e.preventDefault();
onMove(e, true);
}
/**
* Handles touchstart event.
* @param {TouchEvent} e
*/
function handleStart(e) {
e.preventDefault();
onMove(e,true);
}
/**
* Handles touchend event.
* @param {TouchEvent} e
*/
function handleEnd(evt) {
evt.preventDefault();
onMove(evt,true);
onStarClick.call(module);
}
/**
* Handles touchend event.
* @param {TouchEvent} e
*/
function handleCancel(e) {
e.preventDefault();
onStarOut(e);
}
elem.addEventListener("click", onStarClick.bind(module));
elem.addEventListener("touchmove", handleMove, false);
elem.addEventListener("touchstart", handleStart, false);
elem.addEventListener("touchend", handleEnd, false);
elem.addEventListener("touchcancel", handleCancel, false);
return module;
}