Recurring Events Creator: Cordellia Yokum Create repeating events from existing events: Daily Monthly (third Tuesday of every month) Weekly ( every ‘Monday’) *Note: No source link was provided for this script. Source Code /* Base specific */ const table = base.getTable('Events'); function assignDate(existingRecord, date) { return {fields: { Name: existingRecord.getCellValue('Name'), Date: date, Notes: existingRecord.getCellValue('Notes'), }}; } /* And this is just the working bit */ const daysOfWeek = [ {label: 'Sunday', value: '0'}, {label: 'Monday', value: '1'}, {label: 'Tuesday', value: '2'}, {label: 'Wednesday', value: '3'}, {label: 'Thursday', value: '4'}, {label: 'Friday', value: '5'}, {label: 'Saturday', value: '6'}, ]; const months = [ {label: 'January', value: '0'}, {label: 'February', value: '1'}, {label: 'March', value: '2'}, {label: 'April', value: '3'}, {label: 'May', value: '4'}, {label: 'June', value: '5'}, {label: 'July', value: '6'}, {label: 'August', value: '7'}, {label: 'September', value: '8'}, {label: 'October', value: '9'}, {label: 'November', value: '10'}, {label: 'December', value: '11'}, ]; const freq = []; for (let i = 1; i <= 50; i++) { freq.push(i.toString()); } output.markdown(`# ? Let's make some recurring events!`); const record = await input.recordAsync('Select Event', table); let eventDate = record.getCellValue('Date'); output.clear(); output.markdown(`## ? You selected '**${record.name}**'`); const repeatFreq = await input.buttonsAsync(`How frequently does ${record.name} occur?`, ['Daily', 'Weekly', 'Monthly',]); const newRecords = []; switch (repeatFreq) { case 'Weekly': { const repeatDay = await input.buttonsAsync('Repeats every...', daysOfWeek); const repeatWeeks = await input.buttonsAsync('for X weeks.', freq); const niceDay = dayOfWeekNumberToString(repeatDay); output.clear(); output.markdown(`# ? We will make '**${record.name}**' an event every **${niceDay}** for **${repeatWeeks}** weeks. On these dates:`); /* Add events to newRecords array */ eventDate = shiftDay(eventDate, parseInt(repeatDay, 10)); for (let i = 1; i <= parseInt(repeatWeeks, 10); i++) { const newDate = addDays(eventDate, (7 * i)); newRecords.push(assignDate(record, newDate)); output.text(newDate.toLocaleString()); } break; } case 'Daily': { const repeatWeeks = await input.buttonsAsync('For how many days?', freq); output.clear(); output.markdown(`# ? We will make '**${record.name}**' an event every day. On these dates:`); /* Add events to newRecords array */ for (let i = 1; i <= parseInt(repeatWeeks, 10); i++) { const newDate = addDays(eventDate, i); newRecords.push(assignDate(record, newDate)); output.text(newDate.toLocaleString()); } break; } case 'Monthly': { const repeatTiming = await input.buttonsAsync('Which week of the month?', ['First', 'Second', 'Third', 'Last']); const repeatDay = await input.buttonsAsync(`on the ${repeatTiming}...`, daysOfWeek); const repeatStartMonth = await input.buttonsAsync('Starting in...', months); const repeatWeeks = await input.buttonsAsync('For how many months?.', freq); const niceDay = dayOfWeekNumberToString(repeatDay); output.clear(); eventDate = shiftYear(eventDate,parseInt(repeatStartMonth, 10)); output.markdown(`# ? We will make '**${record.name}**' an event every **${niceDay}** for **${repeatWeeks}** months starting **${eventDate.toLocaleString()}**. On these dates:`); /* Add events to newRecords array */ const r = parseInt(repeatWeeks, 10); const m = parseInt(repeatStartMonth, 10); for (let i = 0; i < r; i++) { const newDate = shiftMonthly(eventDate, (m + i), parseInt(repeatDay, 10), repeatTiming); newRecords.push(assignDate(record, newDate)); output.text(newDate.toLocaleString()); } break; } default: throw new Error('Unrecognized repeat frequency'); } /* Confirm before creating records */ const creationConfirmation = await input.buttonsAsync('Is that right?', [{label: '?♀️ Cancel', value: 'stop'}, {label: '?DO IT! Create those EVENTS!', value: 'go', variant: 'danger'}]); output.clear(); switch (creationConfirmation) { case 'stop': { output.markdown("# ? We won't make a repeating event."); break; } case 'go': { await table.createRecordsAsync(newRecords); output.markdown(`# ? Check out your new events in '${table.name}'!`); break; } default: throw new Error('Unknown selection'); } /* Functions */ function dayOfWeekNumberToString(v) { const result = daysOfWeek.find(day => day.value === v); return result.label; } function addDays(date, days) { const result = new Date(date); result.setDate(result.getDate() + days); return result; } function shiftDay(date, newDay) { const d = new Date(date); const day = d.getDay(); const dif = newDay - day; return addDays(date, dif); } function shiftYear(date, month) { let result = new Date(date); if((month - result.getMonth()) < 0 ){ result.setFullYear(result.getFullYear() + 1); } return result; } function shiftMonthly(date, month, dy, timing) { let result = new Date(date); let modifier = 0; result.setDate(1); result.setMonth(month); switch (timing) { case 'First': break; case 'Second': modifier = 7; break; case 'Third': modifier = 14; break; case 'Last': modifier = -7; result.setMonth(month + 1); break; default: throw new Error('Unexpected timing'); } let firstday = result.getDay() === dy; while (firstday === false) { result = addDays(result, 1); firstday = result.getDay() === dy; } return addDays(result, modifier); }