144 lines
6.0 KiB
JavaScript
144 lines
6.0 KiB
JavaScript
/*
|
|
* RecoReco -- keep the "days before" field within one period of the selected frequency.
|
|
*
|
|
* The Recurring schedule modal is injected by AJAX, so we react to the frequency <select> both when
|
|
* it appears (MutationObserver) and when it changes (delegated event). Daily -> field disabled (0);
|
|
* weekly -> max 6; monthly -> max 27; yearly -> max 364. The server clamps too, so this is only the
|
|
* UI guard.
|
|
*/
|
|
(function () {
|
|
"use strict";
|
|
|
|
var CAPS = { daily: 0, weekly: 6, monthly_day: 27, monthly_dow: 27, yearly: 364 };
|
|
|
|
function apply(select) {
|
|
// "days before" ceiling / disable by frequency.
|
|
var input = document.querySelector('input[name="recoreco_days_before"]');
|
|
if (input) {
|
|
var max = CAPS.hasOwnProperty(select.value) ? CAPS[select.value] : 27;
|
|
|
|
if (max === 0) {
|
|
input.value = 0;
|
|
input.setAttribute("max", "0");
|
|
input.disabled = true;
|
|
} else {
|
|
input.disabled = false;
|
|
input.setAttribute("max", String(max));
|
|
if (parseInt(input.value, 10) > max) {
|
|
input.value = max;
|
|
}
|
|
}
|
|
}
|
|
|
|
// The last-day/weekday checkbox only means something for monthly and yearly.
|
|
var lastday = document.querySelector(".recoreco-lastday");
|
|
if (lastday) {
|
|
var monthlyOrYearly = select.value === "monthly_day" || select.value === "monthly_dow" || select.value === "yearly";
|
|
lastday.style.display = monthlyOrYearly ? "" : "none";
|
|
}
|
|
}
|
|
|
|
// "Follow FinanceBuddy installments": when on, the current/limit fields mirror FinanceBuddy's
|
|
// live installment current/total and are disabled (so they do not post, keeping FinanceBuddy the
|
|
// single source of truth); when off, they restore RecoReco's own stored values.
|
|
function applyFollow(checkbox) {
|
|
var group = checkbox.closest(".recoreco-limit-group");
|
|
if (!group) { return; }
|
|
|
|
var count = group.querySelector('input[name="recoreco_count"]');
|
|
var limit = group.querySelector('input[name="recoreco_limit"]');
|
|
if (!count || !limit) { return; }
|
|
|
|
if (checkbox.checked) {
|
|
count.value = group.getAttribute("data-fb-current");
|
|
limit.value = group.getAttribute("data-fb-total");
|
|
} else {
|
|
count.value = group.getAttribute("data-rr-count");
|
|
limit.value = group.getAttribute("data-rr-limit");
|
|
}
|
|
|
|
count.disabled = checkbox.checked;
|
|
limit.disabled = checkbox.checked;
|
|
}
|
|
|
|
// Trigger column: it can never be the target, so hide+disable that option and reset to Any if it
|
|
// was selected; the invert checkbox only means something for a specific column.
|
|
function applyTrigger() {
|
|
var target = document.querySelector('select[name="recoreco_target_column"]');
|
|
var trigger = document.querySelector('select[name="recoreco_trigger_column"]');
|
|
var invert = document.querySelector('input[name="recoreco_trigger_invert"]');
|
|
if (!target || !trigger) { return; }
|
|
|
|
for (var i = 0; i < trigger.options.length; i++) {
|
|
var isTarget = trigger.options[i].value === target.value;
|
|
trigger.options[i].hidden = isTarget;
|
|
trigger.options[i].disabled = isTarget;
|
|
}
|
|
if (trigger.value === target.value) { trigger.value = "any"; }
|
|
|
|
if (invert) {
|
|
var invertDisabled = (trigger.value === "any");
|
|
invert.disabled = invertDisabled;
|
|
var invertLabel = invert.closest("label");
|
|
if (invertLabel) { invertLabel.style.opacity = invertDisabled ? "0.5" : ""; }
|
|
}
|
|
}
|
|
|
|
// Move-mode makes copies moot, so grey out "Link copies to the template" while it is checked
|
|
// (disabled -> it won't post, so the saved value is 0).
|
|
function applyMove() {
|
|
var move = document.querySelector('input[name="recoreco_move"]');
|
|
var link = document.querySelector('input[name="recoreco_link_copies"]');
|
|
if (!move || !link) { return; }
|
|
|
|
link.disabled = move.checked;
|
|
var label = link.closest("label");
|
|
if (label) { label.style.opacity = move.checked ? "0.5" : ""; }
|
|
}
|
|
|
|
// Italicize the card's current column in the target/trigger dropdowns, so you can see where it
|
|
// sits right now. (<option> styling is honored by Chrome/Firefox; Safari may ignore it.)
|
|
function applyCurrentItalic() {
|
|
var form = document.querySelector('form[data-recoreco-current]');
|
|
if (!form) { return; }
|
|
|
|
var current = form.getAttribute("data-recoreco-current");
|
|
var selects = form.querySelectorAll('select[name="recoreco_target_column"], select[name="recoreco_trigger_column"]');
|
|
for (var s = 0; s < selects.length; s++) {
|
|
for (var i = 0; i < selects[s].options.length; i++) {
|
|
if (selects[s].options[i].value === current) {
|
|
selects[s].options[i].style.fontStyle = "italic";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
document.addEventListener("change", function (e) {
|
|
if (e.target && e.target.name === "recoreco_frequency") {
|
|
apply(e.target);
|
|
}
|
|
if (e.target && e.target.name === "recoreco_follow_finance") {
|
|
applyFollow(e.target);
|
|
}
|
|
if (e.target && (e.target.name === "recoreco_target_column" || e.target.name === "recoreco_trigger_column")) {
|
|
applyTrigger();
|
|
}
|
|
if (e.target && e.target.name === "recoreco_move") {
|
|
applyMove();
|
|
}
|
|
});
|
|
|
|
if (window.MutationObserver) {
|
|
new MutationObserver(function () {
|
|
var select = document.querySelector('select[name="recoreco_frequency"]:not([data-recoreco-init])');
|
|
if (select) {
|
|
select.setAttribute("data-recoreco-init", "1");
|
|
apply(select);
|
|
applyTrigger();
|
|
applyMove();
|
|
applyCurrentItalic();
|
|
}
|
|
}).observe(document.body, { childList: true, subtree: true });
|
|
}
|
|
})();
|