<form class="m-5 box" action="javascript:void(0);">
<div class="field">
<label class="label">Minimum</label>
<div class="control">
<input class="input" type="number" placeholder="ex. 0" id="fizzbuzz-min" value="0">
</div>
</div>
<div class="field">
<label class="label">Maximum</label>
<div class="control">
<input class="input" type="number" placeholder="ex. 100" id="fizzbuzz-max" value="100">
</div>
</div>
<div class="field">
<label class="checkbox">
<input type="checkbox" id="fizzbuzz-reverse">
<s>I agree to the Terms and Conditions wait what</s> Reverse order
</label>
</div>
<div class="field">
<div class="control">
<button class="button is-primary" id="fizzbuzz-load">Load</button>
</div>
</div>
</form>
<button class="button is-primary m-5" id="fizzbuzz-increase">Increase</button>
<button class="button is-primary mt-5 mr-5" id="fizzbuzz-decrease">Decrease</button>
<button class="button is-link mt-5 mr-5" id="fizzbuzz-complete">Complete the run</button>
<button class="button is-danger mt-5" id="fizzbuzz-reset">Reset</button>
<button class="button is-danger mt-5 ml-5" id="fizzbuzz-clear">Clear logs</button>
<div id="fizzbuzz-logs" class="container m-5 box"></div>
function FizzBuzz(options = {}) {
options = Object.assign(options || {}, {
wordmap: [{ word: "Fizz", divisor: 3 }, { word: "Buzz", divisor: 5 }],
counter: 0,
minimum: 0,
maximum: 100,
reverse: false,
increaseElement: document.getElementById("fizzbuzz-increase"),
decreaseElement: document.getElementById("fizzbuzz-decrease"),
completeElement: document.getElementById("fizzbuzz-complete"),
resetElement: document.getElementById("fizzbuzz-reset"),
clearElement: document.getElementById("fizzbuzz-clear"),
logsElement: document.getElementById("fizzbuzz-logs"),
formMinElement: document.getElementById("fizzbuzz-min"),
formMaxElement: document.getElementById("fizzbuzz-max"),
formReverseElement: document.getElementById("fizzbuzz-reverse"),
formLoadButton: document.getElementById("fizzbuzz-load"),
});
const getCounter = () => +localStorage.getItem("fizzbuzz");
const setCounter = number => localStorage.setItem("fizzbuzz", number.toString());
const clearCounter = () => localStorage.removeItem("fizzbuzz");
const outputResult = data => options.logsElement.innerHTML += data + "<br>";
const getCurrentPosInfo = () =>
`<strong>Direction:</strong> ${
options.reverse ? "backwards" : "forwards"
}; <strong>Previous</strong>: ${
fizzBuzzIndividual(options.counter - 1)
}; <strong>Current</strong>: ${
fizzBuzzIndividual(options.counter)
}; <strong>Next</strong>: ${
fizzBuzzIndividual(options.counter + 1)
};`;
if (getCounter()) options.counter = getCounter();
function toggleButtons() {
if (options.counter >= options.maximum) {
options.increaseElement.setAttribute("disabled", "true");
options.decreaseElement.removeAttribute("disabled");
} else {
options.increaseElement.removeAttribute("disabled");
}
if (options.counter <= options.minimum) {
options.decreaseElement.setAttribute("disabled", "true");
options.increaseElement.removeAttribute("disabled");
} else {
options.decreaseElement.removeAttribute("disabled");
}
}
function fizzBuzzIndividual(number) {
if (number === 0) return "0";
else {
const matches = options.wordmap
.filter(word => remainder(number, word.divisor) === 0)
.map(word => word.word);
return matches.length > 0 ? matches.join("") : number;
}
}
function recurseFizzBuzz(
minimum = 0,
point = 0,
maximum = 100,
reverseOrder = false
) {
let fizzBuzzed = [];
const inner = (min, start, max) => {
const fizzBuzzed = [];
if (start !== (reverseOrder ? min : max)) {
fizzBuzzed.push(fizzBuzzIndividual(start, options.wordmap));
fizzBuzzed.push(...inner(min, start + (reverseOrder ? -1 : 1), max));
} else fizzBuzzed.push("Done!");
return fizzBuzzed;
};
fizzBuzzed = inner(minimum, point, maximum);
options.counter = maximum;
toggleButtons();
return fizzBuzzed;
}
function remainder(number1, number2) {
const quotient = Math.floor(number1 / number2);
const product = quotient * number2;
return number1 - product;
}
options.increaseElement.addEventListener("click", () => {
if (options.counter < options.maximum) options.counter++;
toggleButtons();
setCounter(options.counter);
outputResult(getCurrentPosInfo());
});
options.decreaseElement.addEventListener("click", () => {
if (options.counter > options.minimum) options.counter--;
toggleButtons();
setCounter(options.counter);
outputResult(getCurrentPosInfo());
});
options.completeElement.addEventListener("click", () => {
options.reverse ? options.counter-- : options.counter++;
setCounter(options.counter);
recurseFizzBuzz(
options.minimum,
options.counter,
options.maximum,
options.reverse
).forEach(outputResult);
});
options.resetElement.addEventListener("click", () => {
options.counter = options.minimum;
clearCounter();
toggleButtons();
});
options.clearElement.addEventListener("click", () => (options.logsElement.innerHTML = ""));
options.formLoadButton.addEventListener("click", () => {
const min = +options.formMinElement.value;
const max = +options.formMaxElement.value;
if (min >= max) {
outputResult("<strong><span style='color:red'>Error</span>: the start"
+ " number must be smaller than the end number.</strong>");
return;
}
options.minimum = +options.formMinElement.value;
options.maximum = +options.formMaxElement.value;
options.counter = options.reverse ? options.maximum : options.minimum;
options.reverse = options.formReverseElement.checked;
toggleButtons();
});
toggleButtons();
}
FizzBuzz();
This Pen doesn't use any external JavaScript resources.