// Page Code import wixData from 'wix-data'; import wixUsers from 'wix-users'; let parByHole = Array(18).fill(null); let scoreByHole = Array(18).fill(null); let scorecardUrl = ''; $w.onReady(() => { // Build 18 rows for the repeater const holes = Array.from({ length: 18 }, (_, i) => ({ _id: String(i+1), hole: i + 1 })); $w('#holesRepeater').data = holes; $w('#holesRepeater').onItemReady(($item, itemData) => { const idx = itemData.hole - 1; $item('#holeLabel').text = `Hole ${itemData.hole}`; // Keep inputs numeric $item('#parInput').placeholder = 'Par'; $item('#scoreInput').placeholder = 'Score'; // Initialize from arrays (if user navigates back, etc.) if (parByHole[idx] !== null) $item('#parInput').value = String(parByHole[idx]); if (scoreByHole[idx] !== null) $item('#scoreInput').value = String(scoreByHole[idx]); // Update arrays on change $item('#parInput').onInput(() => { parByHole[idx] = toNum($item('#parInput').value); }); $item('#scoreInput').onInput(() => { scoreByHole[idx] = toNum($item('#scoreInput').value); updateFinalScore(); }); }); // Handle file upload $w('#scorecardUpload').onChange(async () => { if ($w('#scorecardUpload').value.length === 0) return; setStatus('Uploading scorecard...', false); try { const file = await $w('#scorecardUpload').startUpload(); scorecardUrl = file.url; // public URL setStatus('Scorecard uploaded ✅', false); } catch (e) { setStatus('Upload failed. Try again.', true); scorecardUrl = ''; } }); // Submit handler $w('#submitBtn').onClick(async () => { clearStatus(); // Must be logged in (optional—remove if you want public) const user = wixUsers.currentUser; if (!user.loggedIn) { setStatus('Please sign in to submit a round.', true); return; } // Validate const dateVal = $w('#roundDate').value; const course = ($w('#courseName').value || '').trim(); if (!dateVal || !course) { setStatus('Add a date and course name.', true); return; } // Ensure 18 scores present if (!all18(scoreByHole)) { setStatus('Please enter a score for all 18 holes.', true); return; } // Optional: require par too if (!all18(parByHole)) { setStatus('Please enter par for all 18 holes.', true); return; } const finalScore = sumArray(scoreByHole); // Build record const email = await user.getEmail() .catch(() => ''); const toSave = { memberId: user.id, memberEmail: email || '', roundDate: dateVal, courseName: course, parByHole: parByHole.map(n => n ?? 0), scoreByHole: scoreByHole.map(n => n ?? 0), finalScore, scorecardUrl }; // Save try { await wixData.insert('GolfRounds', toSave); setStatus(`Saved! Final Score: ${finalScore}`, false); resetForm(); } catch (e) { setStatus('Could not save. Please try again.', true); console.error(e); } }); }); // Helpers function toNum(v) { const n = Number(String(v).replace(/[^\d.-]/g, '')); return Number.isFinite(n) ? n : null; } function sumArray(arr) { return arr.reduce((a, b) => a + (Number.isFinite(b) ? b : 0), 0); } function all18(arr) { return arr.length === 18 && arr.every(n => Number.isFinite(n)); } function updateFinalScore() { const total = sumArray(scoreByHole); $w('#finalScoreText').text = Number.isFinite(total) && total > 0 ? `Running Total: ${total}` : 'Running Total: —'; } function setStatus(msg, isError) { $w('#statusText').text = msg; $w('#statusText').show(); $w('#statusText').style.color = isError ? '#B00020' : '#146C43'; } function clearStatus() { $w('#statusText').text = ''; $w('#statusText').hide(); } function resetForm() { $w('#roundDate').value = null; $w('#courseName').value = ''; parByHole = Array(18).fill(null); scoreByHole = Array(18).fill(null); scorecardUrl = ''; $w('#scorecardUpload').value = []; // clears UI $w('#holesRepeater').forEachItem(($item, itemData) => { $item('#parInput').value = ''; $item('#scoreInput').value = ''; }); updateFinalScore(); }
top of page
  • Instagram
Dirty_Birdie_Lettering_2-nobg.png
DIRTY BIRDIE GOLF CLUB

ABOUT US

We are the Dirty Birdie Golf Club, a crew of overly ambitious, high-handicap hackers chasing the thrill of a well-struck shot (and a green bomber jacket). Our mission? Keep golf fun, fierce, and full of laughs—especially for those of us who think breaking 100 is cause for celebration.

About Us / Testimonials

DIRTY BIRDIE LEAGUE PLAY

Dirty Birdie Golf Club (84 of 85).jpg

Our club hosts a season-long member's only league! No official handicaps needed, just good swings and great vibes!

JOIN THE FLOCK

If you live in NorCal or San Diego and know what a triple bogey feels like, you're our people!

DBGC SD Photo 1_edited.jpg
Dirty Birdie Golf Club (72 of 85).jpg
DBGC SD Photo 2.jpg
Dirty Birdie Golf Club (33 of 85).jpg

PARTNERS

C1 Full Logo White Square (2).png

Interested in collaborating?

Email: terryll@dirtybirdiegolfclub.com

                                                             © 2025 by Dirty Birdie Golf Club

bottom of page