Filter by destination or any station the train calls at
Service Alerts
Live Departures
Loading departures...
No Departures Found
No services were found matching your criteria.
This could be due to:
Time of day (limited services during early morning/late evening)
Public holidays or engineering works
Strike action or service disruptions
Active filters limiting results
Note: Filters only affect this departure board. For comprehensive journey planning,
try our Journey Planner
.
Unable to Load Departures
There was a problem loading the departure information.
Community Reports
No Current Reports
There are no community reports near this station right now, but you can help change that!
By submitting reports, you help fellow passengers stay informed, assist vulnerable travellers
who need real-time updates, and improve everyone's journey experience over time.
`;
return card;
}
// Update community status badge in header
function updateCommunityStatusBadge(reports) {
const badge = document.getElementById('communityStatusBadge');
if (!badge) return;
const highSeverityCount = reports.filter(r => r.severity === 'high').length;
const mediumSeverityCount = reports.filter(r => r.severity === 'medium').length;
// Remove all existing classes
badge.className = 'text-white rounded-full px-3 py-1 text-xs font-medium cursor-pointer hover:opacity-90 transition-opacity';
let statusClass = 'bg-green-500';
let statusIcon = 'fa-check-circle';
if (highSeverityCount > 0) {
statusClass = 'bg-red-500';
statusIcon = 'fa-exclamation-triangle';
} else if (mediumSeverityCount > 0) {
statusClass = 'bg-amber-500';
statusIcon = 'fa-exclamation-circle';
} else if (reports.length > 0) {
statusClass = 'bg-blue-500';
statusIcon = 'fa-info-circle';
}
badge.classList.add(statusClass);
badge.innerHTML = `Community`;
}
// Helper functions
function getLoadingInfo(loading) {
if (loading === null || loading === undefined || loading === '') {
return false;
}
const loadingPercent = parseInt(loading);
if (loadingPercent <= 33) {
return {
text: 'Quiet' ,
color: 'bg-green-500' ,
bgColor: 'bg-green-100 dark:bg-green-900/20' ,
textColor: 'text-green-700 dark:text-green-300' ,
icon: 'fa-user'
};
} else if (loadingPercent <=66) {
return {
text: 'Moderate' ,
color: 'bg-yellow-500' ,
bgColor: 'bg-yellow-100 dark:bg-yellow-900/20' ,
textColor: 'text-yellow-700 dark:text-yellow-300' ,
icon: 'fa-user'
};
} else if (loadingPercent <=80) {
return {
text: 'Busy' ,
color: 'bg-orange-500' ,
bgColor: 'bg-orange-100 dark:bg-orange-900/20' ,
textColor: 'text-orange-700 dark:text-orange-300' ,
icon: 'fa-user-group'
};
} else {
return {
text: 'Very Busy' ,
color: 'bg-red-500' ,
bgColor: 'bg-red-100 dark:bg-red-900/20' ,
textColor: 'text-red-700 dark:text-red-300' ,
icon: 'fa-users'
};
}
}
function getStatusText(departure) {
switch (departure.status) {
case 'onTime' :
return 'On time' ;
case 'delayed' :
return departure.estimatedDeparture ? `Exp ${departure.estimatedDeparture}` : 'Delayed' ;
case 'cancelled' :
return 'Cancelled' ;
case 'departed' :
return departure.actualDeparture ? `Departed at ${departure.actualDeparture}` : 'Departed' ;
case 'arrived' :
return departure.actualArrival ? `Arrived at ${departure.actualArrival}` : 'Arrived' ;
default:
return departure.statusMessage || 'Unknown' ;
}
}
function escapeHtml(text) {
const div=document.createElement('div');
div.textContent=text;
return div.innerHTML;
}
function updateLastUpdated() {
const now=new Date();
const timeString=now.toLocaleTimeString('en-GB', {
hour: '2-digit' ,
minute: '2-digit' ,
second: '2-digit' ,
});
document.getElementById('lastUpdated').textContent=`Updated ${timeString}`;
}
// Main refresh function
async function refreshDepartures() {
if (isLoading) return;
isLoading=true;
const refreshIcon=document.getElementById('refreshIcon');
// Add spin animation
if (refreshIcon) {
refreshIcon.classList.add('spinner');
}
try {
const data=await fetchDepartures();
if (data) {
renderDepartures(data);
renderDisruptions(data);
renderCommunityReports(data);
updateLastUpdated();
lastApiCall=Date.now();
}
} catch (error) {
console.error('Error refreshing departures:', error);
showError(error.message);
} finally {
isLoading=false;
if (refreshIcon) {
refreshIcon.classList.remove('spinner');
}
}
}
// Filter form functionality
function toggleFilterForm() {
const formContent=document.getElementById('filterFormContent');
const toggleIcon=document.getElementById('filterToggleIcon');
const container=document.getElementById('filterFormContainer');
if (formContent.style.display==='none' ) {
formContent.style.display='block' ;
toggleIcon.style.transform='rotate(180deg)' ;
container.classList.remove('filter-form-collapsed');
container.classList.add('filter-form-expanded');
} else {
formContent.style.display='none' ;
toggleIcon.style.transform='rotate(0deg)' ;
container.classList.remove('filter-form-expanded');
container.classList.add('filter-form-collapsed');
}
}
// Modal functions
function openFilterModal() {
document.getElementById('filterModal').classList.remove('hidden');
document.body.style.overflow='hidden' ;
}
function closeFilterModal() {
document.getElementById('filterModal').classList.add('hidden');
document.body.style.overflow='auto' ;
}
function clearFilters() {
document.getElementById('timeFilter').value='' ;
document.getElementById('hoursFilter').value='4' ;
document.getElementById('destinationFilter').value='' ;
document.getElementById('destinationFilterCode').value='' ;
hideStationResults();
}
function applyFilters() {
closeFilterModal();
refreshDepartures();
}
// Close modal on escape key
document.addEventListener('keydown', function(e) {
if (e.key==='Escape' ) {
closeFilterModal();
}
});
// Other existing functions
function scrollToCommunityReports() {
const communitySection=document.querySelector('h3:has(i.fa-users)').closest('.bg-white\\/90');
if (communitySection) {
communitySection.scrollIntoView({
behavior: 'smooth' ,
block: 'center'
});
communitySection.classList.add('ring-4', 'ring-purple-300' , 'ring-opacity-50' );
setTimeout(()=> {
communitySection.classList.remove('ring-4', 'ring-purple-300', 'ring-opacity-50');
}, 2000);
}
}
function viewReport(reportId) {
window.location.href = `/community-reports/report?id=${reportId}`;
}
function createReport() {
window.location.href = `/community-reports/?station=WDH`;
}
function viewDisruptionDetails(incidentId) {
// Open disruption details in new tab/window
window.open(`/service-status/incident/${incidentId}`, '_blank');
}
function switchToPage(page) {
if (page === 'arrivals') {
window.location.href = `/arrivals/WDH`;
}
}
// Toggle disruptions display
function toggleDisruptions() {
disruptionsExpanded = !disruptionsExpanded;
const container = document.getElementById('disruptionsContainer');
const maxToShow = disruptionsExpanded ? allDisruptions.length : Math.min(2, allDisruptions.length);
const disruptionsToShow = allDisruptions.slice(0, maxToShow);
container.innerHTML = '';
disruptionsToShow.forEach(disruption => {
const disruptionCard = createDisruptionCard(disruption);
container.appendChild(disruptionCard);
});
updateExpandButton();
}
function updateExpandButton() {
const expandText = document.getElementById('expandDisruptionsText');
const expandIcon = document.getElementById('expandDisruptionsIcon');
if (disruptionsExpanded) {
expandText.textContent = 'Show Less';
expandIcon.className = 'fa-solid fa-fw fa-chevron-up ml-1';
} else {
const hiddenCount = allDisruptions.length - 2;
expandText.textContent = `Show All (${hiddenCount} more)`;
expandIcon.className = 'fa-solid fa-fw fa-chevron-down ml-1';
}
}
function openDepartureDetails(rid) {
location.href = `/service/${rid}`;
}
// Initialize filters from URL parameters (only on initial load)
function initializeFiltersFromUrl() {
const urlParams = new URLSearchParams(window.location.search);
// Set destination filter
const destParam = urlParams.get('filterCrs');
if (destParam) {
// Find the station by code in the stations data
const stationData = window.stations || stations;
if (stationData) {
const station = stationData.find(s => s.code.toLowerCase() === destParam.toLowerCase());
if (station) {
document.getElementById('destinationFilter').value = station.name;
document.getElementById('destinationFilterCode').value = station.code;
} else {
// If station not found, just set the code
document.getElementById('destinationFilterCode').value = destParam;
}
}
}
// Set time filter
const timeParam = urlParams.get('time');
if (timeParam) {
document.getElementById('timeFilter').value = timeParam;
}
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', function() {
// Initialize filters from URL parameters (only once on page load)
initializeFiltersFromUrl();
// Initialize station search
initializeStationSearch();
// Add event listeners to filter inputs
['timeFilter', 'hoursFilter'].forEach(id => {
const element = document.getElementById(id);
if (element) {
element.addEventListener('change', () => {
// Auto-apply filters when changed
clearTimeout(refreshInterval);
setTimeout(refreshDepartures, 500);
});
}
});
// Add event listener for destination filter code (when station is selected)
const destinationFilterCode = document.getElementById('destinationFilterCode');
if (destinationFilterCode) {
const observer = new MutationObserver(() => {
clearTimeout(refreshInterval);
setTimeout(refreshDepartures, 500);
});
observer.observe(destinationFilterCode, {
attributes: true,
attributeFilter: ['value']
});
}
// Initial load
refreshDepartures();
// Set up auto-refresh every 10 seconds
refreshInterval = setInterval(refreshDepartures, 10000);
});
// Clean up interval on page unload
window.addEventListener('beforeunload', function() {
if (refreshInterval) {
clearInterval(refreshInterval);
}
});
Advertisement
Your connection is slow. Live data may take a little longer to update.
Sign in to trainslive.uk
Your username
or password is incorrect.
Successfully signed
in!
v3.9.1 (07 August 2025)
Version 3.9.0 includes enhanced disruption tracking for Underground lines. You can now see estimated platform wait times and journey times for each line, where available.
Version 3.8.0 introduces several new features and improvements:
New Service Status and Statistics feature for National Rail TOCs
New 24-hour status timeline for Tube status pages
Tube status pages now better reflect when lines are closed, e.g. at night