|
64 | 64 | </div> |
65 | 65 | </div> |
66 | 66 |
|
| 67 | + <fieldset class="border rounded p-3 mb-3"> |
| 68 | + <legend class="float-none w-auto px-2 fs-6 text-muted">Repeat</legend> |
| 69 | + |
| 70 | + <div class="mb-3"> |
| 71 | + <label for="repeat_freq" class="form-label">Repeats</label> |
| 72 | + <select class="form-select" id="repeat_freq" name="repeat_freq" data-recurrence-freq> |
| 73 | + <option value="none" selected>Does not repeat</option> |
| 74 | + <option value="daily">Daily</option> |
| 75 | + <option value="weekly">Weekly</option> |
| 76 | + <option value="monthly">Monthly</option> |
| 77 | + <option value="yearly">Yearly</option> |
| 78 | + </select> |
| 79 | + </div> |
| 80 | + |
| 81 | + <div data-recurrence-options style="display: none;"> |
| 82 | + <div class="mb-3"> |
| 83 | + <label for="repeat_interval" class="form-label">Every</label> |
| 84 | + <div class="input-group"> |
| 85 | + <input type="number" class="form-control" id="repeat_interval" name="repeat_interval" min="1" value="1"> |
| 86 | + <span class="input-group-text" data-recurrence-unit>day(s)</span> |
| 87 | + </div> |
| 88 | + </div> |
| 89 | + |
| 90 | + <div class="mb-3" data-recurrence-byday-group style="display: none;"> |
| 91 | + <label class="form-label d-block">Repeat on</label> |
| 92 | + <div class="btn-group flex-wrap" role="group" aria-label="Weekdays"> |
| 93 | + <?php foreach( [ 'MO' => 'Mon', 'TU' => 'Tue', 'WE' => 'Wed', 'TH' => 'Thu', 'FR' => 'Fri', 'SA' => 'Sat', 'SU' => 'Sun' ] as $code => $label ): ?> |
| 94 | + <input type="checkbox" class="btn-check" id="byday_<?= $code ?>" value="<?= $code ?>" data-recurrence-byday autocomplete="off"> |
| 95 | + <label class="btn btn-outline-secondary btn-sm" for="byday_<?= $code ?>"><?= $label ?></label> |
| 96 | + <?php endforeach; ?> |
| 97 | + </div> |
| 98 | + <input type="hidden" name="repeat_byday" id="repeat_byday" value=""> |
| 99 | + </div> |
| 100 | + |
| 101 | + <div class="mb-3"> |
| 102 | + <label for="repeat_end" class="form-label">Ends</label> |
| 103 | + <select class="form-select" id="repeat_end" name="repeat_end" data-recurrence-end> |
| 104 | + <option value="never" selected>Never</option> |
| 105 | + <option value="until">On date</option> |
| 106 | + <option value="count">After number of occurrences</option> |
| 107 | + </select> |
| 108 | + </div> |
| 109 | + |
| 110 | + <div class="mb-3" data-recurrence-until-group style="display: none;"> |
| 111 | + <label for="repeat_until" class="form-label">End date</label> |
| 112 | + <input type="date" class="form-control" id="repeat_until" name="repeat_until"> |
| 113 | + </div> |
| 114 | + |
| 115 | + <div class="mb-3" data-recurrence-count-group style="display: none;"> |
| 116 | + <label for="repeat_count" class="form-label">Number of occurrences</label> |
| 117 | + <input type="number" class="form-control" id="repeat_count" name="repeat_count" min="1"> |
| 118 | + </div> |
| 119 | + </div> |
| 120 | + </fieldset> |
| 121 | + |
67 | 122 | <div class="mb-3"> |
68 | 123 | <label for="location" class="form-label">Location</label> |
69 | 124 | <input type="text" class="form-control" id="location" name="location" placeholder="e.g., Main Auditorium, 123 Main St, Sarasota, FL"> |
@@ -384,3 +439,48 @@ function generateSlug() { |
384 | 439 | } |
385 | 440 | }); |
386 | 441 | </script> |
| 442 | + |
| 443 | +<script> |
| 444 | +// Recurrence controls: toggle option visibility and sync BYDAY selection. |
| 445 | +(function() { |
| 446 | + var freq = document.querySelector('[data-recurrence-freq]'); |
| 447 | + if( !freq ) { return; } |
| 448 | + |
| 449 | + var options = document.querySelector('[data-recurrence-options]'); |
| 450 | + var bydayGroup = document.querySelector('[data-recurrence-byday-group]'); |
| 451 | + var unit = document.querySelector('[data-recurrence-unit]'); |
| 452 | + var endSelect = document.querySelector('[data-recurrence-end]'); |
| 453 | + var untilGroup = document.querySelector('[data-recurrence-until-group]'); |
| 454 | + var countGroup = document.querySelector('[data-recurrence-count-group]'); |
| 455 | + var bydayInput = document.getElementById('repeat_byday'); |
| 456 | + var bydayChecks = document.querySelectorAll('[data-recurrence-byday]'); |
| 457 | + |
| 458 | + var units = { daily: 'day(s)', weekly: 'week(s)', monthly: 'month(s)', yearly: 'year(s)' }; |
| 459 | + |
| 460 | + function syncByday() { |
| 461 | + if( !bydayInput ) { return; } |
| 462 | + var selected = []; |
| 463 | + bydayChecks.forEach(function(box) { if( box.checked ) { selected.push(box.value); } }); |
| 464 | + bydayInput.value = selected.join(','); |
| 465 | + } |
| 466 | + |
| 467 | + function refresh() { |
| 468 | + var value = freq.value; |
| 469 | + var repeats = value !== 'none'; |
| 470 | + if( options ) { options.style.display = repeats ? 'block' : 'none'; } |
| 471 | + if( bydayGroup ) { bydayGroup.style.display = value === 'weekly' ? 'block' : 'none'; } |
| 472 | + if( unit && units[value] ) { unit.textContent = units[value]; } |
| 473 | + if( endSelect ) { |
| 474 | + if( untilGroup ) { untilGroup.style.display = endSelect.value === 'until' ? 'block' : 'none'; } |
| 475 | + if( countGroup ) { countGroup.style.display = endSelect.value === 'count' ? 'block' : 'none'; } |
| 476 | + } |
| 477 | + } |
| 478 | + |
| 479 | + freq.addEventListener('change', refresh); |
| 480 | + if( endSelect ) { endSelect.addEventListener('change', refresh); } |
| 481 | + bydayChecks.forEach(function(box) { box.addEventListener('change', syncByday); }); |
| 482 | + |
| 483 | + refresh(); |
| 484 | + syncByday(); |
| 485 | +})(); |
| 486 | +</script> |
0 commit comments