Expert-Guided Booking

Real Flights,
Real People,
Book Today

Trusted travel agents ready to guide you. Personalized service on United, Delta, American & British Airways.

Call to Book Your Flight
Real travel experts Hassle-free booking Flexible changes
Ref # D3FSM8 Quote this when you call

We book these airlines

50K+
Flights booked
4.9★
Customer rating
<60s
Avg. wait time
24/7
Agents available
// Set default depart date to today + 7 days const defaultDepart = new Date(); defaultDepart.setDate(defaultDepart.getDate() + 7); departInput.value = defaultDepart.toISOString().split('T')[0]; // Set default return date to depart + 7 days const defaultReturn = new Date(defaultDepart); defaultReturn.setDate(defaultReturn.getDate() + 7); returnInput.value = defaultReturn.toISOString().split('T')[0]; returnInput.min = departInput.value; departInput.addEventListener('change', () => { if (returnInput.value && returnInput.value < departInput.value) { returnInput.value = departInput.value; } returnInput.min = departInput.value; syncToMoja(); }); // ── Trip type toggle ── let tripType = 'One Way'; function setTripType(type) { tripType = type; if (type === 'Round Trip') { roundBtn.classList.add('active'); oneBtn.classList.remove('active'); datesRow.classList.add('round-trip'); } else { oneBtn.classList.add('active'); roundBtn.classList.remove('active'); datesRow.classList.remove('round-trip'); } syncToMoja(); } roundBtn.addEventListener('click', () => setTripType('Round Trip')); oneBtn.addEventListener('click', () => setTripType('One Way')); // ── Moja sync ────────────────────────────────────────────────────────────── // Three-layer approach to guarantee tags land on the session before the call: // // Layer 1 — _moja_tags queue: safe pre-init, replayed when snippet loads. // Layer 2 — direct mergeCustomTags(): bypasses queue timing entirely. // Layer 3 — immediate sendHeartbeat(): pushes tags to backend right now. // // On CTA click we run all three so the agent sees the data when the call // comes in, even if the visitor calls within seconds of selecting airports. // ────────────────────────────────────────────────────────────────────────── function buildTags() { return { trip_type: tripType, from_airport: fromSel.value || '(not selected)', to_airport: toSel.value || '(not selected)', depart_date: departInput.value || '', return_date: tripType === 'Round Trip' ? (returnInput.value || '') : '', passengers: passengersSel.value || '1', }; } function syncToMoja(forceSend) { const tags = buildTags(); // Layer 1: _moja_tags queue (works pre-init and post-init) window._moja_tags = window._moja_tags || []; window._moja_tags.push(tags); // Layer 2 & 3: direct API — only available after Moja has initialised try { const T = window.MojaTracker; if (T && T.initialized && T.dataCollector && T.apiClient) { // Merge immediately into the visitor data object T.dataCollector.mergeCustomTags(tags); // Fire heartbeat right now (not waiting for the 500 ms debounce) // This writes the tags to the Moja backend session before the call lands. if (forceSend) { const sid = T.dataCollector.getSnippetId(); const vid = T.dataCollector.getVisitorId(); if (sid && vid) { T.apiClient.sendHeartbeat(sid, vid).catch(() => {}); } } } } catch (e) {} } // Sync on every form change [fromSel, toSel, returnInput, passengersSel].forEach(el => { el.addEventListener('change', () => syncToMoja(false)); }); // On CTA click: force an immediate heartbeat so the agent sees the data ctaBtn.addEventListener('click', () => syncToMoja(true)); // Poll until MojaTracker is initialised, then push the current form state. // This handles the race where Moja loads and runs BEFORE our inline script, // leaving the pre-init queue empty. let mojaPollCount = 0; const mojaPoller = setInterval(() => { mojaPollCount++; if (mojaPollCount > 50) { clearInterval(mojaPoller); return; } // give up after 10s if (window.MojaTracker && window.MojaTracker.initialized) { clearInterval(mojaPoller); syncToMoja(false); // push current state now that Moja is ready } }, 200);