@@ -168,17 +168,22 @@ document.addEventListener("DOMContentLoaded", () => {
168168 const duration = endTime . getTime ( ) - startTime . getTime ( ) ;
169169
170170 if ( duration < 0 ) {
171+ // invalid duration
171172 endInput . setCustomValidity ( "End time must be after start time." ) ;
172173 return ;
173174 }
174175
176+ // update the duration input
175177 endInput . setCustomValidity ( "" ) ;
176178 eventDuration = duration ;
177179 durationInput . value = formatDuration ( eventDuration ) ;
180+
181+ // sync accross all end times
178182 syncEndTimes ( ) ;
179183 }
180184
181185 function updateFutureStartTimes ( changedInput ) {
186+ // update all future start times based on the changed input
182187 const allEntries = Array . from ( timeFields . querySelectorAll ( ".time-entry" ) ) ;
183188 const currentIndex = allEntries . findIndex ( entry => entry . contains ( changedInput ) ) ;
184189
@@ -194,6 +199,7 @@ document.addEventListener("DOMContentLoaded", () => {
194199 }
195200
196201 for ( let i = currentIndex + 1 ; i < allEntries . length ; i ++ ) {
202+ // update the start time of the next entries
197203 const prevStartInput = allEntries [ i - 1 ] . querySelector ( "input[name='start_time[]']" ) ;
198204 const currStartInput = allEntries [ i ] . querySelector ( "input[name='start_time[]']" ) ;
199205 const currEndInput = allEntries [ i ] . querySelector ( "input[name='end_time[]']" ) ;
@@ -209,34 +215,42 @@ document.addEventListener("DOMContentLoaded", () => {
209215 }
210216
211217 timeFields . addEventListener ( "input" , ( event ) => {
218+ // handle input changes in time fields
212219 const input = event . target ;
213220
214221 if ( input . name === "start_time[]" ) {
222+ // if start time changes, update future start times and end times
215223 updateFutureStartTimes ( input ) ;
216224 const entry = input . closest ( ".time-entry" ) ;
217225 const endTimeInput = entry . querySelector ( "input[name='end_time[]']" ) ;
218226 const startTime = new Date ( input . value ) ;
227+ if ( eventDuration <= 0 ) return ; // if no valid duration, do not update end time
219228 endTimeInput . value = formatDateTimeInput ( new Date ( startTime . getTime ( ) + eventDuration ) ) ;
220229 validateEndTime ( endTimeInput ) ;
221230 } else if ( input . name === "end_time[]" ) {
231+ // if end time changes, update duration and validate end time
222232 updateDuration ( input ) ;
223233 validateEndTime ( input ) ;
224234 }
225235 } ) ;
226236
227237 durationInput . addEventListener ( "input" , ( ) => {
238+ // handle duration input changes
228239 duration = parseDuration ( durationInput . value ) ;
229240 if ( duration > 0 ) {
241+ // if valid duration, update the event duration and sync end times
230242 eventDuration = duration ;
231243 syncEndTimes ( ) ;
232244 durationInput . setCustomValidity ( "" ) ;
233245 } else {
246+ // invalid
234247 durationInput . setCustomValidity ( "Please provide a valid duration in DD:HH:MM format." ) ;
235248 }
236249 } ) ;
237250
238251 if ( addTimeButton ) {
239252 addTimeButton . addEventListener ( "click" , ( event ) => {
253+ // add a new time entry
240254 const allEntries = timeFields . querySelectorAll ( ".time-entry" ) ;
241255
242256 const lastEntry = allEntries [ allEntries . length - 1 ] ;
@@ -245,6 +259,7 @@ document.addEventListener("DOMContentLoaded", () => {
245259
246260 let delta = 7 * 24 * 60 * 60 * 1000 ; // default is a week
247261 if ( allEntries . length > 1 ) {
262+ // if multiple entries, set the delta to the duration of the previous entry
248263 const penultimateEntry = allEntries [ allEntries . length - 2 ] ;
249264 const penultimateStartInput = penultimateEntry . querySelector ( "input[name='start_time[]']" ) ;
250265 delta = new Date ( prevStartInput . value ) . getTime ( ) - new Date ( penultimateStartInput . value ) . getTime ( ) ;
@@ -253,8 +268,9 @@ document.addEventListener("DOMContentLoaded", () => {
253268 const newStartTime = new Date ( new Date ( prevStartInput . value ) . getTime ( ) + delta ) ;
254269 const newEndTime = eventDuration > 0 ? new Date ( newStartTime . getTime ( ) + eventDuration ) : NaN ;
255270
271+ // create a new time entry element and add
256272 const newEntry = document . createElement ( "div" ) ;
257- newEntry . className = "row g-3 time-entry" ;
273+ newEntry . className = "row g-3 mt-0 time-entry" ;
258274 newEntry . innerHTML = `
259275 <div class="form-floating col-md-4">
260276 <input type="datetime-local" name="start_time[]" id="start_time" class="form-control" value="${ formatDateTimeInput ( newStartTime ) } " required>
@@ -271,14 +287,17 @@ document.addEventListener("DOMContentLoaded", () => {
271287 </div>
272288
273289 <div class="col-md-4 d-flex align-items-center">
274- <button type="button" class="btn btn-danger remove-time-entry"><i class="ph-bold ph-trash"></i> Remove</button>
290+ <button type="button" class="btn btn-danger d-flex align-items-center gap-1 remove-time-entry">
291+ <i class="ph-bold ph-trash"></i> Remove
292+ </button>
275293 </div>
276294 ` ;
277295 timeFields . appendChild ( newEntry ) ;
278296 } ) ;
279297 }
280298
281299 timeFields . addEventListener ( "click" , ( event ) => {
300+ // handle click events for removing time entries
282301 if ( ! event . target . classList . contains ( "remove-time-entry" ) ) return ;
283302
284303 const entry = event . target . closest ( ".time-entry" ) ;
@@ -287,28 +306,34 @@ document.addEventListener("DOMContentLoaded", () => {
287306 entry . remove ( ) ;
288307
289308 if ( precedingEntry && precedingEntry . classList . contains ( "time-entry" ) ) {
309+ // if there is a preceding entry update all subsequent start times
290310 const startTimeInput = precedingEntry . querySelector ( "input[name='start_time[]']" ) ;
291311 if ( startTimeInput ) updateFutureStartTimes ( startTimeInput ) ;
292- } else if ( document . quwrySelector ( ".time-entry" ) ) {
312+ } else if ( document . querySelector ( ".time-entry" ) ) {
313+ // if no preceding entry, update the first entry's start time
293314 const firstEntry = document . querySelector ( ".time-entry" ) . querySelector ( "input[name='start_time[]']" ) ;
294315 if ( firstEntry ) updateFutureStartTimes ( firstEntry ) ;
295316 }
296317 } ) ;
297318
298319 function initialiseTimes ( ) {
320+ // initialise the time fields with the first entry's values
321+
299322 const firstEntry = timeFields . querySelector ( ".time-entry" ) ;
300323 if ( ! firstEntry ) return ;
301324
302325 const startTimeInput = firstEntry . querySelector ( "input[name='start_time[]']" ) ;
303326 const endTimeInput = firstEntry . querySelector ( "input[name='end_time[]']" ) ;
304327
305328 if ( startTimeInput . value && endTimeInput . value ) {
329+ // if start and end times are set, calculate the duration
306330 const initialDuration = new Date ( endTimeInput . value ) . getTime ( ) - new Date ( startTimeInput . value ) . getTime ( ) ;
307331 if ( initialDuration >= 0 ) {
308332 eventDuration = initialDuration ;
309333 durationInput . value = formatDuration ( eventDuration ) ;
310334 }
311335 } else {
336+ // otherwise attempt to use the duration input
312337 const initialDuration = parseDuration ( durationInput . value ) ;
313338 if ( initialDuration > 0 ) {
314339 eventDuration = initialDuration ;
@@ -319,6 +344,7 @@ document.addEventListener("DOMContentLoaded", () => {
319344 }
320345 }
321346
347+ // validate end times
322348 document . querySelectorAll ( "input[name='end_time[]']" ) . forEach ( validateEndTime ) ;
323349 }
324350
0 commit comments