PageSourceSearch

https://www.dualibrary.com/static/js/main/change-method-location.js

js dualibrary.com collected 2026-10-03 18:24:16 UTC 20,419 bytes, 582 lines download raw bytes

1
2
3
4// 546040425 
5document.addEventListener('DOMContentLoaded', (event) => {
6
7 // Namaz Timings API
8
9 const islamicDateTodayTxt = document.getElementById("islamicDateTodayTxt");
10 const gregorianDateTodayTxt = document.getElementById("gregorianDateTodayTxt");
11
12 const fajrTimeTxt = document.getElementById("fajrTimeTxt");
13 const sunriseTimeTxt = document.getElementById("sunriseTimeTxt");
14 const sunsetTimeTxt = document.getElementById("sunsetTimeTxt");
15 const zuhr = document.getElementById("dhuhrTimeTxt");
16 const asarTimeTxt = document.getElementById("asarTimeTxt");
17 const maghribTimeTxt = document.getElementById("maghribTimeTxt");
18 const ishaTimeTxt = document.getElementById("ishaTimeTxt");
19 const currentLocationTxt = document.getElementById("currentLocationTxt");
20 const changeLocationLoadOverlay = document.getElementById("changeLocationLoadOverlay");
21 const upcomingPrayerNameTxt = document.getElementById("upcomingPrayerNameTxt");
22 const upcomingPrayerTimeTxt = document.getElementById("upcomingPrayerTimeTxt");
23
24 let countdownInterval;
25
26
27
28 const runPrayerTimeApi = (cityName, countryName) => {
29     changeLocationLoadOverlay.style.display = "block";
30     // console.log("API Requesting...")
31     // Get current date
32     const currentDate = new Date();
33     const day = String(currentDate.getDate()).padStart(2, '0');
34     const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // Months are zero-based
35     const year = currentDate.getFullYear();
36     const formattedDate = `${day}-${month}-${year}`;
37
38     const calculationMethod = localStorage.getItem("calculationMethod");
39     if (calculationMethod) {
40         changeMethodInput.value = calculationMethod;
41     } else {
42         changeMethodInput.value = 1; // Default Method
43         currentMethodTxt.innerText = "University of Islamic Sciences, Karachi";
44         localStorage.setItem("calculationMethod", "1");
45     }
46
47     // Build the API URL with the current date
48     const apiUrl = `https://api.aladhan.com/v1/timingsByAddress/${formattedDate}?address=${encodeURIComponent(cityName)},${encodeURIComponent(countryName)}&method=${calculationMethod}`;
49     // console.log(apiUrl);
50
51     currentLocationTxt.innerText = `${cityName}, ${countryName}`;
52
53     fetch(apiUrl)
54         .then(response => {
55             if (!response.ok) {
56                 throw new Error('Network response was not ok ' + response.statusText);
57             }
58             return response.json();
59         })
60         .then(data => {
61             // console.log('API data:', data);
62
63             // Extract the relevant data
64             const timings = data.data.timings;
65             const gregorianDate = data.data.date.gregorian;
66             const hijriDate = data.data.date.hijri;
67
68             // Format the dates
69             const formattedGregorianDate = `${parseInt(gregorianDate.day)} ${gregorianDate.month.en}, ${gregorianDate.year}`;
70             const formattedHijriDate = `${parseInt(hijriDate.day)} ${hijriDate.month.en}, ${hijriDate.year}`;
71
72             // Convert 24-hour time to 12-hour time with AM/PM
73             const convertTo12HourFormat = (time) => {
74                 const [hour, minute] = time.split(':');
75                 const hourInt = parseInt(hour);
76                 const period = hourInt >= 12 ? 'PM' : 'AM';
77                 const hour12 = hourInt % 12 || 12; // Convert hour to 12-hour format, 0 should be 12
78                 return `${hour12}:${minute} ${period}`;
79             };
80
81             // Set the text content of the elements
82             gregorianDateTodayTxt.textContent = formattedGregorianDate;
83             islamicDateTodayTxt.textContent = formattedHijriDate;
84
85             fajrTimeTxt.textContent = convertTo12HourFormat(timings.Fajr);
86             sunriseTimeTxt.textContent = convertTo12HourFormat(timings.Sunrise);
87             sunsetTimeTxt.textContent = convertTo12HourFormat(timings.Sunset);
88             dhuhrTimeTxt.textContent = convertTo12HourFormat(timings.Dhuhr);
89             asarTimeTxt.textContent = convertTo12HourFormat(timings.Asr);
90             maghribTimeTxt.textContent = convertTo12HourFormat(timings.Maghrib);
91             ishaTimeTxt.textContent = convertTo12HourFormat(timings.Isha);
92
93             changeLocationLoadOverlay.style.display = "none";
94
95             try{
96                 updateUpcomingPrayer(timings);
97             } catch (error){
98                 console.log("Error Occured " + error)
99             }
100             
101             
102             
103         })
104         .catch(error => {
105             console.error('There has been a problem with your fetch operation:', error);
106             changeLocationLoadOverlay.style.display = "none";
107         });
108     
109
110 }
111
112const updateUpcomingPrayer = (timings) => {
113const prayerTimes = [
114 { name: 'Fajr', time: timings.Fajr },
115 { name: 'Sunrise', time: timings.Sunrise },
116 { name: 'Dhuhr', time: timings.Dhuhr },
117 { name: 'Asr', time: timings.Asr },
118 { name: 'Maghrib', time: timings.Maghrib },
119 { name: 'Isha', time: timings.Isha }
120];
121
122const now = new Date();
123const nowHours = now.getHours();
124const nowMinutes = now.getMinutes();
125
126const currentTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), nowHours, nowMinutes);
127
128let nextPrayer;
129let nextPrayerTime;
130
131for (let i = 0; i < prayerTimes.length; i++) {
132 const [hours, minutes] = prayerTimes[i].time.split(':');
133 const prayerTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes);
134
135 if (prayerTime > currentTime) {
136   nextPrayer = prayerTimes[i].name;
137   nextPrayerTime = prayerTime;
138   break;
139 }
140}
141
142if (!nextPrayer) {
143 const [hours, minutes] = prayerTimes[0].time.split(':');
144 nextPrayer = prayerTimes[0].name;
145 nextPrayerTime = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, hours, minutes);
146}
147
148upcomingPrayerNameTxt.innerText = `${nextPrayer} in `;
149
150const updateCountdown = () => {
151 // console.log("RUnning asd")
152 const now = new Date();
153 const diff = nextPrayerTime - now;
154
155 if (diff <= 0) {
156   runPrayerTimeApi(currentLocationTxt.innerText.split(',')[0], currentLocationTxt.innerText.split(',')[1].trim());
157   return;
158 }
159
160 const hours = Math.floor(diff / 1000 / 60 / 60);
161 const minutes = Math.floor((diff / 1000 / 60) % 60);
162 const seconds = Math.floor((diff / 1000) % 60);
163
164 upcomingPrayerTimeTxt.innerText = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
165};
166
167updateCountdown();
168clearInterval(countdownInterval); 
169countdownInterval = setInterval(updateCountdown, 1000); 
170};
171
172
173
174function searchCountry(query, type, resultsElement) {
175 fetch(`/search-cities/?query=${query}&type=${type}`)
176     .then(response => response.json())
177     .then(data => {
178         if (data.results) {
179             resultsElement.querySelector('ul').innerHTML = data.results.map(item => {
180                 return `<li class="country-result-item">${item.country}</li>`;
181             }).join('');
182         }
183     })
184     .catch(error => console.error('Error:', error));
185}
186
187function searchCity(query, type, countryName, resultsElement) {
188 fetch(`/search-cities/?query=${query}&type=${type}&country=${countryName}`)
189     .then(response => response.json())
190     .then(data => {
191         if (data.results) {
192             resultsElement.querySelector('ul').innerHTML = data.results.map(item => {
193                 return `<li class="city-result-item" data-city="${item.name}">${item.name}</li>`;
194             }).join('');
195         }
196     })
197     .catch(error => console.error('Error:', error));
198}
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229    const countryInput = document.getElementById("countryInput"); // Adjust the selector as per your input field
230    const countryResults = document.getElementById('countryResults');
231    const countryCheckedIcon = document.getElementById('countryCheckedIcon');
232    const cityInput = document.getElementById("cityInput"); // Adjust the selector as per your input field
233    const cityResults = document.getElementById('cityResults');
234    const cityCheckedIcon = document.getElementById('cityCheckedIcon');
235    const cityInputContainer = document.getElementById("cityInputContainer");
236    const cityInputX = cityInputContainer.querySelector("input");
237    const selectCountryTxt = document.getElementById("selectCountryTxt");
238    const selectCityTxt = document.getElementById("selectCityTxt");
239    const changeLocationBtn = document.getElementById("changeLocationBtn");
240    const currentLocationBtn = document.getElementById("currentLocationBtn");
241    const changeMethodBtn = document.getElementById("changeMethodBtn");
242    const changeMethodInput = document.getElementById("changeMethodInput");
243    
244    let cityInputValid = false;
245    let countryInputValid = false;
246    let storedMethod = localStorage.getItem("calculationMethod");
247
248    const currentMethodTxt = document.getElementById("currentMethodTxt");
249
250    if (storedMethod && currentMethodTxt) {
251        for (const method of namazCalculationMethods) {
252            if (storedMethod == method.method_id) {
253                currentMethodTxt.innerText = method.name;
254                break;
255            }
256        }
257    }
258   
259
260
261
262    changeMethodBtn.addEventListener("click", () => {
263        localStorage.setItem("calculationMethod", changeMethodInput.value);
264        const selectedMethodName = changeMethodInput.options[changeMethodInput.selectedIndex].text;
265        currentMethodTxt.innerText = selectedMethodName;
266        location.reload();
267    })
268    
269    // Check if user location is in localStorage
270    let storedCity = localStorage.getItem('userLocationCity');
271    let storedCountry = localStorage.getItem('userLocationCountry');
272    
273    if (storedCity == null){
274        storedCity = userDefaultCity;
275        localStorage.setItem('userLocationCity', storedCity );
276    }
277    cityInput.value = storedCity;
278    toggleIcon(cityInput, cityCheckedIcon, true);
279    cityInput.disabled = false;
280    cityInput.classList.remove("disabled-input");
281    cityInputValid = true;
282
283    if (storedCountry == null){
284        storedCountry = userDefaultCountry;
285        localStorage.setItem('userLocationCountry', storedCountry );
286    } 
287    countryInput.value = storedCountry;
288    toggleIcon(countryInput, countryCheckedIcon, true);
289    countryInputValid = true;
290
291    runPrayerTimeApi(storedCity, storedCountry);
292    
293    changeLocationBtn.addEventListener("click", () => {
294        if (countryCheckedIcon.style.display != "block"){
295            // console.log("Select Your Country ", countryCheckedIcon.style.display)
296            countryInputValidity(false);
297        } else if (cityCheckedIcon.style.display != "block"){
298            // console.log("Select Your City")
299            cityInputValidity(false);
300        } else {
301            localStorage.setItem('userLocationCity', cityInput.value );
302            localStorage.setItem('userLocationCountry', countryInput.value );
303
304            const city = cityInput.value;
305            const country = countryInput.value;
306            // Location Changed Successfully
307            runPrayerTimeApi(cityInput.value, countryInput.value);
308            
309            const modalElement = document.getElementById('changeLocationModal');
310            const modal = bootstrap.Modal.getInstance(modalElement) || new bootstrap.Modal(modalElement);
311            modal.hide();
312
313            // Todo 
314            // 1 - Show Flash Message 
315        }
316    })
317
318    currentLocationBtn.addEventListener("click", () => {
319        localStorage.setItem('userLocationCity', userDefaultCity );
320        localStorage.setItem('userLocationCountry', userDefaultCountry );  
321
322        location.reload()
323    })
324    
325
326    cityInputContainer.addEventListener("click", () => {
327        // console.log("clicked")
328        if (cityInput.disabled){
329            // console.log("hshshsh")
330            countryInputValidity(false);
331        } else {
332            // console.log("Searching City")
333            countryInputValidity(true);
334        }
335    })
336
337
338    const countryInputValidity = (value) => {
339
340        if (value){
341            selectCountryTxt.style.display = "none";
342            countryInput.classList.remove("invalid-input");
343        } else {
344            selectCountryTxt.style.display = "block";
345            countryInput.classList.add("invalid-input");
346        }
347    }
348
349    const cityInputValidity = (value) => {
350        // console.log("City Validity ", value)
351        if (value){
352
353            selectCityTxt.style.display = "none";
354            cityInput.classList.remove("invalid-input");
355        } else {
356            selectCityTxt.style.display = "block";
357            cityInput.classList.add("invalid-input");
358        }
359    }
360
361
362
363    // Function to show or hide the icon
364    function toggleIcon(inputElement, iconElement, valid) {
365        if (valid) {
366            iconElement.style.display = 'block';
367            inputElement.classList.add("success-input");
368        } else {
369            inputElement.classList.remove("success-input");
370            iconElement.style.display = 'none';
371
372            // Remove City Input if country is changed
373            if (inputElement == countryInput){
374                cityInput.value = "";
375                cityInput.classList.remove("success-input");
376                cityCheckedIcon.style.display = 'none';
377            } 
378        }
379    }
380
381    const toggleCityInput = (valid) => {
382        valid = !valid;
383        if (valid) {
384            cityInput.classList.add("disabled-input");
385            cityInput.disabled = true;
386        } else {
387            cityInput.classList.remove("disabled-input");
388            cityInput.disabled = false;
389        }
390    }
391
392    const updateChangeBtnStatus = (inputType, valid) => {
393
394        if (inputType === "city"){
395            if (valid){
396                cityInputValid = true;
397            } else {
398                cityInputValid = false;
399            }
400        } else if (inputType === "country"){
401            if (valid){
402                countryInputValid = true;
403            } else {
404                countryInputValid = false;
405            }
406        }
407
408
409        if (countryInputValid && cityInputValid ){
410            // console.log("From Is Valid")
411            changeLocationBtn.classList.remove("disabled-primary-btn");
412        } else {
413            changeLocationBtn.classList.add("disabled-primary-btn");
414            // console.log("Form not Valid")
415        }
416    }
417
418
419
420    // Function to check if the input matches the first result item
421    function isFirstItemMatchCountry(inputElement, resultsElement) {
422        updateChangeBtnStatus();
423        const firstItem = resultsElement.querySelector('ul .country-result-item, ul .city-result-item');
424        if (firstItem && inputElement.value.trim().toLowerCase() === firstItem.textContent.trim().toLowerCase()) {
425            toggleCityInput(true);
426            countryInputValidity(true);
427            // console.log("Contry Matched")
428            updateChangeBtnStatus("country", true);
429            return true;
430        }
431
432        // console.log("Country Falsed! input : ", inputElement.value.trim().toLowerCase(), ", first item is ", firstItem.textContent.trim().toLowerCase())
433        toggleCityInput(false);
434        updateChangeBtnStatus("city", false);
435        return false;
436    }
437
438    function isFirstItemMatchCity(inputElement, resultsElement) {
439        
440        const firstItem = resultsElement.querySelector('ul .country-result-item, ul .city-result-item');
441        if (firstItem && inputElement.value.trim().toLowerCase() === firstItem.dataset.city.toLowerCase()) {
442            updateChangeBtnStatus("city", true);
443            cityInputValidity(true);
444            return true;
445        } else if (firstItem && inputElement.value.trim().toLowerCase() === firstItem.textContent.trim().toLowerCase()){
446            updateChangeBtnStatus("city", true);
447            cityInputValidity(true);
448            return true;
449        }
450        updateChangeBtnStatus("city", false);
451        return false;
452    }
453
454
455
456    // Show country results when the input field is focused
457    countryInput.addEventListener('focus', () => {
458        if (countryInput.value.length > 0){
459            countryResults.style.display = 'block';
460        }
461    });
462
463    // Show city results when the input field is focused
464    cityInput.addEventListener('focus', () => {
465        if (cityInput.value.length > 0){
466            cityResults.style.display = 'block';
467        }
468    });
469
470    // Select the top item from the country results when Enter is pressed
471    countryInput.addEventListener('keydown', (event) => {
472        if (event.key === 'Enter') {
473            event.preventDefault();  // Prevent form submission if inside a form
474            const topItem = document.querySelector('#countryResults .country-result-item');
475            if (topItem) {
476                countryInput.value = topItem.textContent;
477                countryResults.style.display = 'none';
478                toggleIcon(countryInput, countryCheckedIcon, true);
479            }
480        }
481    });
482
483    // Select the top item from the city results when Enter is pressed
484    cityInput.addEventListener('keydown', (event) => {
485        if (event.key === 'Enter') {
486            event.preventDefault();  // Prevent form submission if inside a form
487            const topItem = document.querySelector('#cityResults .city-result-item');
488            if (topItem) {
489                cityInput.value = topItem.textContent;
490                cityResults.style.display = 'none';
491                toggleIcon(cityInput, cityCheckedIcon, true);
492            }
493        }
494    });
495
496    // Search for countries as the user types
497    countryInput.addEventListener('keyup', (event) => {
498        const query = event.target.value.trim();
499        if (query.length > 0) {
500            searchCountry(query, 'country', countryResults);
501            countryResults.style.display = 'block';
502        } else {
503            countryResults.style.display = 'none';
504            toggleIcon(countryInput, countryCheckedIcon, false);
505        }
506        toggleIcon(countryInput, countryCheckedIcon, isFirstItemMatchCountry(countryInput, countryResults));
507    });
508
509    // Search for cities as the user types
510    cityInput.addEventListener('keyup', (event) => {
511        const query = event.target.value.trim();
512        const countryName = countryInput.value.trim();
513        if (query.length > 0) {
514            searchCity(query, 'city', countryName, cityResults);
515            cityResults.style.display = 'block';
516        } else {
517            cityResults.style.display = 'none';
518            toggleIcon(cityInput, cityCheckedIcon, false);
519        }
520        // console.log("trying to Check City")
521        toggleIcon(cityInput, cityCheckedIcon, isFirstItemMatchCity(cityInput, cityResults));
522    });
523
524    // Use event delegation to handle clicks on country result items
525    countryResults.addEventListener('click', (event) => {
526        if (event.target && event.target.matches('.country-result-item')) {
527            countryInput.value = event.target.textContent;
528            countryResults.style.display = 'none';
529            isFirstItemMatchCountry(countryInput, countryResults);
530            toggleIcon(countryInput, countryCheckedIcon, true);
531            updateChangeBtnStatus("country", true);
532        }
533    });
534
535    // Use event delegation to handle clicks on city result items
536    cityResults.addEventListener('click', (event) => {
537        if (event.target && event.target.matches('.city-result-item')) {
538            cityInput.value = event.target.textContent;
539            cityResults.style.display = 'none';
540            toggleIcon(cityInput, cityCheckedIcon, true);
541            updateChangeBtnStatus("city", true);
542        }
543    });
544
545    // Hide the country results when the input field loses focus
546    countryInput.addEventListener('blur', () => {
547        setTimeout(() => {
548            countryResults.style.display = 'none';
549        }, 200); // Delay to allow click event to register
550    });
551
552    // Hide the city results when the input field loses focus
553    cityInput.addEventListener('blur', () => {
554        setTimeout(() => {
555            cityResults.style.display = 'none';
556        }, 200); // Delay to allow click event to register
557    });
558
559    // Prevent the blur event when clicking on the results
560    countryResults.addEventListener('mousedown', (event) => {
561        event.preventDefault();
562    });
563
564    cityResults.addEventListener('mousedown', (event) => {
565        event.preventDefault();
566    });
567
568
569
570
571
572
573   
574
575
576
577
578
579
580
581});
582

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.