From 35dc05de97677d57123617a7c4e78aad1611b28d Mon Sep 17 00:00:00 2001 From: erdgeist Date: Thu, 16 Jul 2026 16:43:11 +0200 Subject: managed RRULE constructs now include week selection Improve the humanizer to also understand weekly patters that an editor can manually select, on top of the single week rules. Extend template and javascript controller to reflect these changes. --- public/javascripts/admin_interface.js | 46 +++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'public/javascripts') diff --git a/public/javascripts/admin_interface.js b/public/javascripts/admin_interface.js index 9ce0b9e..3988016 100644 --- a/public/javascripts/admin_interface.js +++ b/public/javascripts/admin_interface.js @@ -415,8 +415,10 @@ rrule_builder = { }); $("#rrule_monthly_ordinal").bind("change", function() { $("#rrule_ordinal_fields").toggle($(this).is(":checked")); + rrule_builder.toggle_custom_ordinal_fields(); rrule_builder.sync(); }); + $("#rrule_ordinal").bind("change", rrule_builder.toggle_custom_ordinal_fields); $("#rrule_exclude_month").bind("change", function() { $("#rrule_excluded_month").toggle($(this).is(":checked")); rrule_builder.sync(); @@ -433,6 +435,12 @@ rrule_builder = { $("#rrule_monthly_options").show(); }, + toggle_custom_ordinal_fields : function() { + $("#rrule_custom_ordinal_fields").toggle( + $("#rrule_monthly_ordinal").is(":checked") && $("#rrule_ordinal").val() === "custom" + ); + }, + sync : function() { var freq = $("input[name='rrule_freq']:checked").val(); var parts = []; @@ -448,7 +456,16 @@ rrule_builder = { } else { parts.push("FREQ=MONTHLY"); if ($("#rrule_monthly_ordinal").is(":checked")) { - parts.push("BYDAY=" + $("#rrule_ordinal").val() + $("#rrule_ordinal_day").val()); + var ordinal = $("#rrule_ordinal").val(); + if (ordinal === "custom") { + var customDays = []; + $("input[id^='rrule_custom_ordinal_']:checked").each(function() { + customDays.push($(this).attr("id").replace("rrule_custom_ordinal_", "") + $("#rrule_ordinal_day").val()); + }); + if (customDays.length > 0) parts.push("BYDAY=" + customDays.join(",")); + } else { + parts.push("BYDAY=" + ordinal + $("#rrule_ordinal_day").val()); + } } } @@ -483,8 +500,33 @@ rrule_builder = { } else if (parts.FREQ === "MONTHLY") { $("input[name='rrule_freq'][value='monthly']").prop("checked", true); rrule_builder.show_monthly_options(); + var ordinalDays = parts.BYDAY && parts.BYDAY.split(","); + var customOrdinalDay = null; + var customOrdinals = []; + var customOrdinalsValid = ordinalDays && ordinalDays.length > 0; + if (customOrdinalsValid) { + ordinalDays.forEach(function(value) { + var customMatch = value.match(/^([1-5])([A-Z]{2})$/); + if (!customMatch || (customOrdinalDay && customOrdinalDay !== customMatch[2])) { + customOrdinalsValid = false; + return; + } + customOrdinalDay = customMatch[2]; + customOrdinals.push(customMatch[1]); + }); + } + var match = parts.BYDAY && parts.BYDAY.match(/^(-?\d+)([A-Z]{2})$/); - if (match) { + if (customOrdinalsValid && (customOrdinals.length > 1 || customOrdinals[0] === "5")) { + $("#rrule_monthly_ordinal").prop("checked", true); + $("#rrule_ordinal_fields").show(); + $("#rrule_ordinal").val("custom"); + $("#rrule_ordinal_day").val(customOrdinalDay); + customOrdinals.forEach(function(ordinal) { + $("#rrule_custom_ordinal_" + ordinal).prop("checked", true); + }); + rrule_builder.toggle_custom_ordinal_fields(); + } else if (match) { $("#rrule_monthly_ordinal").prop("checked", true); $("#rrule_ordinal_fields").show(); $("#rrule_ordinal").val(match[1]); -- cgit v1.3