Cinema Clock
Choose location
  Log in / Sign up
 my.username@
    Share this page

    Welcome to Cinema Clock!

    Please specify your location to see Movies in Cinemas located near you.
    Specify my location
    /** * CinemaClock Movie List Handler * Improved implementation for handling movie list filtering and display */ // Movie data model - centralized data structure const MovieListManager = { // Core data data: { cinemas: {}, // Cinema IDs within selected radius movies: {}, // All movie data indexed by ID dates: [], // Available dates selectedDates: [], // User selected dates showOnlyFavorites: false, // Show only favorites toggle state }, // Filter states filters: { genres: {}, // {genreCode: true/false} languages: {}, // {languageCode: true/false} classifications: {}, // {classificationCode: true/false} special: { parentsBabies: false, sensoryFriendly: false, withCaptions: false, withAudioDescription: false } }, // Sort preferences sorting: { currentSort: 'alpha', // 'alpha', 'value', or 'date' sortMaps: { alpha: [], // Movie IDs ordered alphabetically value: [], // Movie IDs ordered by value/rating date: [] // Movie IDs ordered by release date } }, // Initialize the manager init: function() { this.loadDataFromDOM(); this.loadUserPreferences(); this.setupEventListeners(); this.applyFiltersAndUpdate(); }, // Load all necessary data from DOM and variables loadDataFromDOM: function() { // Load dates const uniqueDatesString = sessionStorage.getItem('ccnpdates'); this.data.dates = uniqueDatesString ? JSON.parse(uniqueDatesString) : []; // Check if dates are valid, if not, use the initial dates if (!this.data.dates.length) { this.data.dates = Array.from(datesWeek); sessionStorage.setItem('ccnpdates', JSON.stringify(this.data.dates)); } this.data.selectedDates = [...this.data.dates]; // Load cinemas based on selected radius const ccradtids = localStorage.getItem('ccradtids'); if (ccradtids) { const cinemaIds = JSON.parse(ccradtids).map(item => parseInt(item, 10)); cinemaIds.forEach(id => this.data.cinemas[id] = true); } // Load sort maps this.sorting.sortMaps.alpha = this.processMovieIds(moviesalpha); this.sorting.sortMaps.value = this.processMovieIds(moviesval); this.sorting.sortMaps.date = this.processMovieIds(moviesdate); // Index movies and their features from DOM elements document.querySelectorAll('.movieblock').forEach(movieBlock => { const movieId = movieBlock.id.replace('efilm', ''); const genres = Array.from(movieBlock.classList) .filter(cls => cls.startsWith('gen')) .map(cls => cls.replace('gen', '')); const languages = Array.from(movieBlock.classList) .filter(cls => languageclasses.includes(cls)); const classifications = Array.from(movieBlock.classList) .filter(cls => cls.startsWith('r')); const specialFeatures = { parentsBabies: movieBlock.classList.contains('genbab'), sensoryFriendly: movieBlock.classList.contains('gensen'), withCaptions: movieBlock.classList.contains('gencap'), // Placeholder, need to be added withAudioDescription: movieBlock.classList.contains('genad') // Placeholder, need to be added }; // Store movie data this.data.movies[movieId] = { id: movieId, element: movieBlock, genres: genres, languages: languages, classifications: classifications, specialFeatures: specialFeatures, showingDates: this.getMovieShowingDates(movieId) }; }); }, // Get all dates a movie is showing based on midTd data getMovieShowingDates: function(movieId) { const movieDates = new Set(); const movieIdWithPrefix = "fi" + movieId; // Search through midTd to find all dates this movie plays Object.keys(midTd).forEach(key => { if (midTd[key].includes(movieIdWithPrefix)) { const match = key.match(/d(\d+)/); if (match && datesWeek.has(match[1])) { movieDates.add(match[1]); } } }); return Array.from(movieDates); }, // Process movie IDs from DOM strings processMovieIds: function(idArray) { return idArray.map(id => id.replace('#efilm', '')); }, // Load user preferences from cookies loadUserPreferences: function() { // Load sort preference const sortPreference = getCookie('sortfilms'); if (sortPreference) { this.sorting.currentSort = sortPreference; } // Load show only favorites setting const showFavorites = getCookie('ccmovinfav'); this.data.showOnlyFavorites = (showFavorites === '1'); // Load genre filters const filtg = getCookie('filtg').split("."); filtg.forEach(genre => { if (genre) this.filters.genres[genre] = true; }); // Load language filters const filtl = getCookie('filtl').split("."); filtl.forEach(lang => { if (lang) this.filters.languages[lang] = true; }); // Load classification filters const filtr = getCookie('filtr').split("."); filtr.forEach(classification => { if (classification) this.filters.classifications[classification] = true; }); // Special features are not stored in cookies yet, we'll add that }, // Save user preferences to cookies saveUserPreferences: function() { // Save genre filters const genreFilters = Object.keys(this.filters.genres).filter(key => this.filters.genres[key]); setCookie('filtg', genreFilters.join('.'), 1024); // Save language filters const langFilters = Object.keys(this.filters.languages).filter(key => this.filters.languages[key]); setCookie('filtl', langFilters.join('.'), 1024); // Save classification filters const classFilters = Object.keys(this.filters.classifications).filter(key => this.filters.classifications[key]); setCookie('filtr', classFilters.join('.'), 1024); // Save sort preference setCookie('sortfilms', this.sorting.currentSort, 1024); // Save favorite cinema setting setCookie('ccmovinfav', this.data.showOnlyFavorites ? '1' : '', this.data.showOnlyFavorites ? 1024 : 0); // Save selected dates sessionStorage.setItem('ccnpdates', JSON.stringify(this.data.selectedDates)); }, // Set up event listeners for all interactive elements setupEventListeners: function() { // We'll keep existing click handlers in the HTML, but update their functions // This section is mostly informational since we don't modify the HTML }, // Apply all current filters and update the display applyFiltersAndUpdate: function() { const visibleMovies = this.getVisibleMovies(); this.updateMovieVisibility(visibleMovies); this.updateFilterUI(); this.saveUserPreferences(); this.updateMoviesHeader(); }, // Get movies that should be visible based on all current filters getVisibleMovies: function() { const result = {}; const allMovieIds = Object.keys(this.data.movies); // Handle special feature filters first (they override other filters) if (this.filters.special.parentsBabies) { allMovieIds.forEach(id => { if (this.data.movies[id].specialFeatures.parentsBabies) { result[id] = true; } }); return result; } if (this.filters.special.sensoryFriendly) { allMovieIds.forEach(id => { if (this.data.movies[id].specialFeatures.sensoryFriendly) { result[id] = true; } }); return result; } // Apply cinema filters first allMovieIds.forEach(id => { // Check if movie is showing in selected cinemas on selected dates let movieShowsInSelectedCinema = false; // See if this movie has any showtime in the selected cinema and dates this.data.selectedDates.forEach(date => { Object.keys(this.data.cinemas).forEach(cinemaId => { const key = `t${cinemaId}d${date}`; if (midTd[key] && midTd[key].includes(`fi${id}`)) { movieShowsInSelectedCinema = true; } }); }); if (!movieShowsInSelectedCinema) return; // Filter by favorites if enabled if (this.data.showOnlyFavorites) { const movieInFavorites = document.querySelector(`#efilm${id}`).classList.contains('infavcin'); if (!movieInFavorites) return; } // Apply genre filters if any const activeGenreFilters = Object.keys(this.filters.genres).filter(g => this.filters.genres[g]); if (activeGenreFilters.length > 0) { const matchesGenre = activeGenreFilters.some(genre => this.data.movies[id].genres.includes(genre) ); if (!matchesGenre) return; } // Apply language filters if any const activeLangFilters = Object.keys(this.filters.languages).filter(l => this.filters.languages[l]); if (activeLangFilters.length > 0) { const matchesLanguage = activeLangFilters.some(lang => this.data.movies[id].languages.includes(lang) ); if (!matchesLanguage) return; } // Apply classification filters if any const activeClassFilters = Object.keys(this.filters.classifications).filter(c => this.filters.classifications[c]); if (activeClassFilters.length > 0) { const matchesClassification = activeClassFilters.some(classification => this.data.movies[id].classifications.includes(classification) ); if (!matchesClassification) return; } // When the user has selected dates and the withCaptions filter if (this.filters.special.withCaptions) { const selectedCinemas = Object.keys(this.data.cinemas); const selectedDates = this.data.selectedDates; // Get movies with captions on selected dates in selected cinemas const captionedMovies = getMoviesWithFeatureOnDates( 'withCaptions', selectedDates, selectedCinemas ); // Update UI to show these movies and their caption dates Object.keys(captionedMovies).forEach(movieElementId => { // Use the full element ID to find the movie element const movieElement = document.getElementById(movieElementId); if (movieElement) { // Format dates for display const formattedDates = captionedMovies[movieElementId].dates.map(date => { return formatDate(date); // Your date formatting function }).join(', '); // Add caption note let noteElement = movieElement.querySelector('.special-feature-note'); if (!noteElement) { noteElement = document.createElement('div'); noteElement.className = 'special-feature-note'; movieElement.appendChild(noteElement); } noteElement.textContent = `Captioned showings: ${formattedDates}`; } }); } // Handle audio description filter if (this.filters.special.withAudioDescription && !this.data.movies[id].specialFeatures.withAudioDescription) { return; } // If we reach here, the movie passed all filters result[id] = true; }); return result; }, // Update movie elements visibility based on filter results updateMovieVisibility: function(visibleMovies) { // First, remove all filter-related classes document.querySelectorAll('.movieblock').forEach(movie => { movie.classList.remove('thisFilmPlays', 'thisFilmNotPlays'); movie.classList.remove('filteredgenre', 'filteredlang', 'filteredclass', 'filterednonfavcin', 'filteredOne'); movie.classList.remove('tofiltergenre', 'tofilterlang', 'tofilterclass'); }); // Apply visibility classes Object.keys(this.data.movies).forEach(id => { const movieEl = document.getElementById(`efilm${id}`); if (visibleMovies[id]) { movieEl.classList.add('thisFilmPlays'); } else { movieEl.classList.add('thisFilmNotPlays'); } }); // Sort the visible movies this.sortMovies(); // Show or hide special showtimes blocks if (this.filters.special.parentsBabies) { document.querySelectorAll("div.showtimeblock").forEach(el => el.style.display = "none"); document.querySelectorAll("div.showtimeblock.bab").forEach(el => el.style.display = "block"); } else if (this.filters.special.sensoryFriendly) { document.querySelectorAll("div.showtimeblock").forEach(el => el.style.display = "none"); document.querySelectorAll("div.showtimeblock.sen").forEach(el => el.style.display = "block"); } else { document.querySelectorAll("div.showtimeblock.bab, div.showtimeblock.sen").forEach(el => el.style.display = "none"); } }, // Update UI elements related to filtering updateFilterUI: function() { // Count active filters let filterCount = 0; // Count genre filters const activeGenres = Object.keys(this.filters.genres).filter(g => this.filters.genres[g]); filterCount += activeGenres.length; // Count language filters const activeLangs = Object.keys(this.filters.languages).filter(l => this.filters.languages[l]); filterCount += activeLangs.length; // Count classification filters const activeClasses = Object.keys(this.filters.classifications).filter(c => this.filters.classifications[c]); filterCount += activeClasses.length; // Count special filters if (this.filters.special.parentsBabies) filterCount++; if (this.filters.special.sensoryFriendly) filterCount++; if (this.filters.special.withCaptions) filterCount++; if (this.filters.special.withAudioDescription) filterCount++; // Update filter note visibility if (filterCount > 1) { document.getElementById("firstfilter").style.display = "none"; document.getElementById("clearfilters").style.display = "inline"; } else if (filterCount > 0) { document.getElementById("firstfilter").style.display = "inline"; document.getElementById("clearfilters").style.display = "none"; } else { document.getElementById("firstfilter").style.display = "none"; document.getElementById("clearfilters").style.display = "none"; } // Handle special filter notes const specialFilterActive = this.filters.special.parentsBabies || this.filters.special.sensoryFriendly; if (specialFilterActive && filterCount > 0) { const noteEl = document.getElementById('activefiltersonenote'); noteEl.style.display = 'block'; if (this.filters.special.parentsBabies) { const message = filterCount > 1 ? 'Note: The Parents & babies filter makes all other filters inactive.' : 'Note: The Parents & babies filter makes the other filter inactive.'; noteEl.innerHTML = message; } else if (this.filters.special.sensoryFriendly) { const message = filterCount > 1 ? 'Note: The Sensory-friendly filter makes all other filters inactive.' : 'Note: The Sensory-friendly filter makes the other filter inactive.'; noteEl.innerHTML = message; } } else { document.getElementById('activefiltersonenote').style.display = 'none'; } // Update available filter options based on currently visible movies this.updateAvailableFilters(); }, // Update which filter options should be available based on current selection updateAvailableFilters: function() { const visibleMovies = this.getVisibleMovies(); // Update available genres genresavailable.forEach(genre => { const hasMoviesWithGenre = Object.keys(visibleMovies).some(id => this.data.movies[id].genres.includes(genre) ); const genreEl = document.getElementById(`filgen${genre}`); if (genreEl) { if (hasMoviesWithGenre) { genreEl.classList.remove("inactive"); } else { genreEl.classList.add("inactive"); } } }); // Update available languages languageclassesavailable.forEach(lang => { const hasMoviesWithLang = Object.keys(visibleMovies).some(id => this.data.movies[id].languages.includes(lang) ); const langEl = document.getElementById(`fil${lang}`); if (langEl) { if (hasMoviesWithLang) { langEl.classList.remove("inactive"); } else { langEl.classList.add("inactive"); } } }); // Update available ratings const ratings = ['g', 'pg', '13', 'pg13', '14a', '16', '18', '18a', 'r', 'nc17']; ratings.forEach(rating => { const hasMoviesWithRating = Object.keys(visibleMovies).some(id => { const ratingClass = `r${filtrat}${rating}`; return this.data.movies[id].classifications.includes(ratingClass); }); const ratingEl = document.getElementById(`filr${rating}`); if (ratingEl) { if (hasMoviesWithRating) { ratingEl.classList.remove("inactive"); } else { ratingEl.classList.add("inactive"); } } }); }, // Sort the movies list according to current sort preference sortMovies: function() { const sortOrder = this.sorting.sortMaps[this.sorting.currentSort]; const movieContainer = document.getElementById('allmovies'); const movieBank = document.getElementById('moviebank'); // If we have other hidden movies, move them to bank if (othermovieshide && othermovieshide.length) { othermovieshide.forEach(selector => { const elements = document.querySelectorAll(selector); elements.forEach(el => { movieBank.appendChild(el); }); }); } // Empty the container while (movieContainer.firstChild) { movieContainer.removeChild(movieContainer.firstChild); } // Add movies in correct order sortOrder.forEach(id => { const movieElement = document.getElementById(`efilm${id}`); if (movieElement) { movieContainer.appendChild(movieElement); } }); // Show the container movieContainer.style.display = 'block'; // Handle scroll position const scrollPos = sessionStorage.getItem("nowplayingscroll"); if (scrollPos) { const scrollValue = parseInt(scrollPos); if (scrollValue < document.documentElement.scrollHeight) { window.scrollTo(0, scrollValue); } } // Save scroll position when scrolling window.onscroll = function() { sessionStorage.setItem("nowplayingscroll", window.pageYOffset); }; }, // Update the dates selection based on user interaction updateDates: function(date, clickedElement) { if (clickedElement.classList.contains("disabled")) { return; } const allActive = this.allDatesActive(); if (allActive) { // If all are active, clicking one should deactivate all others this.data.selectedDates = this.data.dates.filter(d => d === date); this.data.dates.forEach(d => { const element = document.getElementById(`datesel${d}`); if (element && d !== date && !element.classList.contains("disabled")) { element.classList.remove("active"); } }); } else { // Toggle the clicked date if (this.data.selectedDates.includes(date)) { // Remove date this.data.selectedDates = this.data.selectedDates.filter(d => d !== date); clickedElement.classList.remove("active"); } else { // Add date this.data.selectedDates.push(date); clickedElement.classList.add("active"); } // If no dates selected, select all if (this.data.selectedDates.length === 0) { this.data.selectedDates = [...this.data.dates]; this.data.dates.forEach(d => { const element = document.getElementById(`datesel${d}`); if (element) { element.classList.add("active"); } }); } } // Update date note this.updateDateNote(); // Apply filters and update display this.applyFiltersAndUpdate(); }, // Update the date note (showing that future dates may have incomplete listings) updateDateNote: function() { const anyFirstThreeActive = ['0401', '0402', '0403'].some(date => this.data.selectedDates.includes(date) ); const noteEl = document.getElementById('showingOnlyDateNote'); if (anyFirstThreeActive) { noteEl.innerHTML = ' '; noteEl.classList.add('hidden'); } else { noteEl.innerHTML = 'Movie list for future dates is incomplete; cinemas may add more films later.'; noteEl.classList.remove('hidden'); } }, // Check if all non-disabled date buttons are active allDatesActive: function() { return this.data.dates.every(date => { const element = document.getElementById(`datesel${date}`); return !element || element.classList.contains("disabled") || element.classList.contains("active"); }); }, // Toggle a single genre filter toggleGenreFilter: function(genreCode, genreText) { const isActive = this.filters.genres[genreCode] === true; if (isActive) { // Remove the filter delete this.filters.genres[genreCode]; // Remove from the active filters UI const activeFilterEl = document.querySelector(`.activefiltergen${genreCode}`); if (activeFilterEl) activeFilterEl.remove(); // Update the filter UI const filterItem = document.getElementById(`filgen${genreCode}`); if (filterItem) { filterItem.classList.remove('filteractive'); const checkmark = filterItem.querySelector('.glyp.check'); if (checkmark) checkmark.classList.remove('checked'); } } else { // Add the filter this.filters.genres[genreCode] = true; // Add to the active filters UI const filterVars = `'${genreCode}','${genreText}'`; const activeFiltersContainer = document.getElementById('activefiltersgenre'); if (activeFiltersContainer) { const filterButton = document.createElement('a'); filterButton.className = `buttonfilter activefiltergen${genreCode}`; filterButton.setAttribute('onclick', `filterOneGenre(${filterVars})`); filterButton.innerHTML = `Genre: ${genreText}
    `; activeFiltersContainer.appendChild(filterButton); } // Update the filter UI const filterItem = document.getElementById(`filgen${genreCode}`); if (filterItem) { filterItem.classList.add('filteractive'); const checkmark = filterItem.querySelector('.glyp.check'); if (checkmark) checkmark.classList.add('checked'); } } // Close the filter dropdown with a delay document.getElementById('filtergenrelist').addEventListener('mouseleave', function() { document.getElementById('filtergenrelist').style.display = 'none'; document.getElementById('filtergenrelist').removeEventListener('mouseleave', arguments.callee); }); this.applyFiltersAndUpdate(); }, // Toggle a single language filter toggleLanguageFilter: function(langCode, langText) { const isActive = this.filters.languages[langCode] === true; if (isActive) { // Remove the filter delete this.filters.languages[langCode]; // Remove from the active filters UI const activeFilterEl = document.querySelector(`.activefilterlan${langCode}`); if (activeFilterEl) activeFilterEl.remove(); // Update the filter UI const filterItem = document.getElementById(`fil${langCode}`); if (filterItem) { filterItem.classList.remove('filteractive'); const checkmark = filterItem.querySelector('.glyp.check'); if (checkmark) checkmark.classList.remove('checked'); } } else { // Add the filter this.filters.languages[langCode] = true; // Add to the active filters UI const filterVars = `'${langCode}','${langText}'`; const activeFiltersContainer = document.getElementById('activefilterslang'); if (activeFiltersContainer) { const filterButton = document.createElement('a'); filterButton.className = `buttonfilter activefilterlan${langCode}`; filterButton.setAttribute('onclick', `filtLang(${filterVars})`); filterButton.innerHTML = `Language: ${langText}
    `; activeFiltersContainer.appendChild(filterButton); } // Update the filter UI const filterItem = document.getElementById(`fil${langCode}`); if (filterItem) { filterItem.classList.add('filteractive'); const checkmark = filterItem.querySelector('.glyp.check'); if (checkmark) checkmark.classList.add('checked'); } } // Close the filter dropdown with a delay document.getElementById('filterlanglist').addEventListener('mouseleave', function() { document.getElementById('filterlanglist').style.display = 'none'; document.getElementById('filterlanglist').removeEventListener('mouseleave', arguments.callee); }); this.applyFiltersAndUpdate(); }, // Toggle a single classification filter toggleClassificationFilter: function(regClass, classCode, classText) { const fullCode = `r${regClass}${classCode}`; const isActive = this.filters.classifications[fullCode] === true; if (isActive) { // Remove the filter delete this.filters.classifications[fullCode]; // Remove from the active filters UI const activeFilterEl = document.querySelector(`.activefilterclass${classCode}`); if (activeFilterEl) activeFilterEl.remove(); // Update the filter UI const filterItem = document.getElementById(`filr${classCode}`); if (filterItem) { filterItem.classList.remove('filteractive'); const checkmark = filterItem.querySelector('.glyp.check'); if (checkmark) checkmark.classList.remove('checked'); } } else { // Add the filter this.filters.classifications[fullCode] = true; // Add to the active filters UI const filterVars = `'${regClass}','${classCode}','${classText}'`; const activeFiltersContainer = document.getElementById('activefiltersclass'); if (activeFiltersContainer) { const filterButton = document.createElement('a'); filterButton.className = `buttonfilter activefilterclass${classCode}`; filterButton.setAttribute('onclick', `filterOneClass(${filterVars})`); filterButton.innerHTML = `Rating: ${classText}
    `; activeFiltersContainer.appendChild(filterButton); } // Update the filter UI const filterItem = document.getElementById(`filr${classCode}`); if (filterItem) { filterItem.classList.add('filteractive'); const checkmark = filterItem.querySelector('.glyp.check'); if (checkmark) checkmark.classList.add('checked'); } } // Close the filter dropdown with a delay document.getElementById('filterothlist').addEventListener('mouseleave', function() { document.getElementById('filterothlist').style.display = 'none'; document.getElementById('filterothlist').removeEventListener('mouseleave', arguments.callee); }); this.applyFiltersAndUpdate(); }, // Toggle a special feature filter toggleSpecialFilter: function(code, text) { let key; // Map code to feature key switch(code) { case 'b': key = 'parentsBabies'; break; case 's': key = 'sensoryFriendly'; break; case 'c': key = 'withCaptions'; break; case 'a': key = 'withAudioDescription'; break; default: return; } const isActive = this.filters.special[key]; // Toggle the filter this.filters.special[key] = !isActive; // Update UI const filterItem = document.getElementById(`filoth${code}`); if (filterItem) { if (this.filters.special[key]) { filterItem.classList.add('filteractive'); const checkmark = filterItem.querySelector('.glyp.check'); if (checkmark) checkmark.classList.add('checked'); // Add to active filters const filterVars = `'${code}','${text}'`; const activeFiltersContainer = document.getElementById('activefiltersone'); const filterButton = document.createElement('a'); filterButton.className = `buttonfilter activefilteroth${code}`; filterButton.setAttribute('onclick', `filterOneOnly(${filterVars})`); filterButton.innerHTML = `${text}
    `; activeFiltersContainer.appendChild(filterButton); } else { filterItem.classList.remove('filteractive'); const checkmark = filterItem.querySelector('.glyp.check'); if (checkmark) checkmark.classList.remove('checked'); // Remove from active filters const activeFilterEl = document.querySelector(`.activefilteroth${code}`); if (activeFilterEl) activeFilterEl.style.display = 'none'; } } // Close the filter dropdown document.getElementById('filterothlist').style.display = 'none'; this.applyFiltersAndUpdate(); }, // Toggle between showing all cinemas or only favorites toggleFavorites: function(showOnlyFav) { this.data.showOnlyFavorites = (showOnlyFav === '1'); // Update UI if (showOnlyFav === '1') { document.querySelector('a.incinall').classList.remove('buttopinv'); document.querySelector('a.incinfav').classList.add('buttopinv'); // Mark movies showing in favorite cinemas const umall = getCookie('um'); const movieIds = umall.split('.'); movieIds.forEach(id => { // Clean the ID (remove non-digits) const cleanId = id.replace(/\D/g,''); if (cleanId > 0) { const selector = `div.fi${cleanId}`; document.querySelectorAll(selector).forEach(el => { el.classList.add('infavcin'); }); } }); // Mark babies/sensory shows in favorite cinemas const ucall = getCookie('uc'); const cinemaIds = ucall.split('.'); cinemaIds.forEach(id => { if (id > 0) { // Mark parent & babies screenings const babSelector = `.babinkino${id}`; document.querySelectorAll(babSelector).forEach(el => { el.classList.add('infavcinbab'); }); // Mark sensory friendly screenings const senSelector = `.seninkino${id}`; document.querySelectorAll(senSelector).forEach(el => { el.classList.add('infavcinsen'); }); } }); // Save the preference setCookie('ccmovinfav','1',1024); } else { // Update UI for showing all cinemas document.querySelector('a.incinfav').classList.remove('buttopinv'); document.querySelector('a.incinall').classList.add('buttopinv'); document.querySelectorAll('div.movieblock').forEach(el => { el.classList.remove('infavcin'); }); document.getElementById('showingOnlyOneGenreNoteNM').style.display = 'none'; // Remove the cookie setCookie('ccmovinfav','',0); } // Apply filters and update display this.applyFiltersAndUpdate(); }, // Clear all filters clearAllFilters: function() { // Reset all filter buttons document.querySelectorAll('a.btn.btnccinv.fouroptions.filter').forEach(el => { el.classList.remove('active'); }); // Reset all filter states this.filters.genres = {}; this.filters.languages = {}; this.filters.classifications = {}; this.filters.special = { parentsBabies: false, sensoryFriendly: false, withCaptions: false, withAudioDescription: false }; // Reset filter UI document.getElementById('activefilterslang').innerHTML = ''; document.getElementById('activefiltersclass').innerHTML = ''; document.getElementById('activefiltersgenre').innerHTML = ''; document.getElementById('activefiltersone').innerHTML = ''; document.getElementById('activefiltersother').innerHTML = ''; // Remove checked marks document.querySelectorAll('.glyp.check.checked').forEach(el => { el.classList.remove('checked'); }); // Remove filter active states document.querySelectorAll('div.fltritm').forEach(el => { el.classList.remove('filteractive'); }); // Apply updates this.applyFiltersAndUpdate(); }, // Change the current sort order changeSort: function(sortBy) { if (this.sorting.currentSort !== sortBy) { this.sorting.currentSort = sortBy; this.saveUserPreferences(); this.applyFiltersAndUpdate(); } // Update UI for sort buttons document.querySelectorAll('a.headoptions.sort').forEach(el => { el.classList.remove('buttopinv'); }); let selector; if (sortBy === 'value') { selector = '#headswitchersortv'; } else if (sortBy === 'date') { selector = '#headswitchersortd'; } else { selector = '#headswitchersorta'; } document.querySelector(selector).classList.add('buttopinv'); document.getElementById('filtergenrelist').style.display = 'none'; }, // Update the header with movie count updateMoviesHeader: function() { // Count visible movies const visibleCount = document.querySelectorAll('.movieblock.thisFilmPlays').length; // Update the counter in the header const moviesCountEl = document.getElementById('moviescount'); if (moviesCountEl) { moviesCountEl.textContent = `${visibleCount} Movie${visibleCount !== 1 ? 's' : ''} Playing`; } } }; // Export these global functions that will be used by the existing event handlers // These act as bridges between the existing HTML event handlers and our new code /** * Toggle a date's selection state * @param {string} date - Date string in MMDD format * @param {HTMLElement} clickedElement - The DOM element that was clicked */ function toggleDateFromUniqueDates(date, clickedElement) { MovieListManager.updateDates(date, clickedElement); } /** * Sort the movies by the specified criteria * @param {string} sortBy - Sort criteria ('alpha', 'value', or 'date') */ function sortmoviesby(sortBy) { MovieListManager.changeSort(sortBy); } /** * Update the option bar UI when a sorting option is clicked * @param {HTMLElement} theElement - The clicked element * @param {string} sortBy - Sort criteria */ function sortmoviesbyclick(theElement, sortBy) { updateoptionbar(theElement); sortmoviesby(sortBy); } /** * Toggle showing only movies in favorite cinemas * @param {string} onlyinfav - '1' to show only favorites, '0' to show all */ function showOnlyInFavourite(onlyinfav) { MovieListManager.toggleFavorites(onlyinfav); } /** * Filter movies by genre * @param {string} oneGenre - Genre code * @param {string} oneGenreText - Genre display text */ function filterOneGenre(oneGenre, oneGenreText) { MovieListManager.toggleGenreFilter(oneGenre, oneGenreText); } /** * Filter movies by language * @param {string} oneLang - Language code * @param {string} oneLangText - Language display text */ function filtLang(oneLang, oneLangText) { MovieListManager.toggleLanguageFilter(oneLang, oneLangText); } /** * Filter movies by classification/rating * @param {string} regClass - Region classification * @param {string} oneClass - Classification code * @param {string} oneClassText - Classification display text */ function filterOneClass(regClass, oneClass, oneClassText) { MovieListManager.toggleClassificationFilter(regClass, oneClass, oneClassText); } /** * Filter movies by special features (parents & babies, sensory-friendly) * @param {string} oneOth - Special feature code * @param {string} oneOthText - Special feature display text */ function filterOneOnly(oneOth, oneOthText) { MovieListManager.toggleSpecialFilter(oneOth, oneOthText); } /** * Clear all active filters */ function clearAllFilters() { MovieListManager.clearAllFilters(); } /** * Update the movie list after cinema radius selection */ function updateMovieList() { // Re-load cinema IDs from localStorage const ccradtids = localStorage.getItem('ccradtids'); const ccradtidsA = JSON.parse(ccradtids); const utids = ccradtidsA.map(item => parseInt(item, 10)); // Update cinema IDs in our manager MovieListManager.data.cinemas = {}; utids.forEach(id => { MovieListManager.data.cinemas[id] = true; }); // Apply filters and update MovieListManager.applyFiltersAndUpdate(); } // Initialize the movie list manager when the page loads document.addEventListener('DOMContentLoaded', function() { // Add the captions and audio description options to the filter menu const filterOthList = document.getElementById('filterothlist'); if (filterOthList) { // Add the captions option at the top of the list const captionsOption = document.createElement('div'); captionsOption.id = 'filothc'; captionsOption.className = 'fltritm'; captionsOption.onclick = function() { filterOneOnly('c', 'With Captions'); }; captionsOption.innerHTML = 'With Captions'; filterOthList.insertBefore(captionsOption, filterOthList.firstChild); // Add the audio description option at the top of the list const audioDescOption = document.createElement('div'); audioDescOption.id = 'filotha'; audioDescOption.className = 'fltritm'; audioDescOption.onclick = function() { filterOneOnly('a', 'With Audio Description'); }; audioDescOption.innerHTML = 'With Audio Description'; filterOthList.insertBefore(audioDescOption, filterOthList.firstChild); } // Initialize the toggle switch for favorite cinemas const toggleSwitch = document.getElementById('toggleSwitch'); if (toggleSwitch) { toggleSwitch.addEventListener('click', function() { // Check if user has favorite cinemas const ufavC = getCookie('uc'); if (ufavC.length <= 1) { return; // No favorite cinemas, do nothing } // Toggle state const currentState = toggleSwitch.classList.contains('active'); toggleSwitch.classList.toggle('active'); // Update format labels document.getElementById('format12').classList.toggle('active'); document.getElementById('format24').classList.toggle('active'); // Update cookie and apply filter const newState = toggleSwitch.classList.contains('active') ? '1' : '0'; showOnlyInFavourite(newState); }); } // Initialize our movie list manager MovieListManager.init(); });
    Cinema Clock

    Thank you for using Cinema Clock. We appreciate! :)

    This message shows when your browser is blocking ads.

    Cinema Clock is made possible by displaying ads.

    Please consider supporting us by allowing ads or by becoming a Premium Member.