PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
← All changes | assets/js/listing.js +58 -18 3.0.2.6 → 3.0.16 View file →
@@ -15,18 +15,75 @@
15 15 init();
16 16 }
17 17
18 18 function init() {
19 - initFilterToggles();
19 + // Filter sidebar toggles (.yatra-filter-title click → toggle .open
20 + // on the section) live in listing-filters.js. Keeping a second
21 + // copy here meant TWO toggles fired per click, leaving the
22 + // section in its original state — i.e. the arrow appeared dead.
20 23 initViewToggle();
21 24 initPriceRange();
22 25 initAdvancedSearch();
23 26 initTravelersSelect();
27 + initStretchedCardClicks();
24 28 // Search functionality moved to shortcode-specific JS
25 29 // initHorizontalSearchDropdowns();
26 30 // initDurationSlider();
27 31 }
28 32
33 + // Whole-card click target for the destination / activity / trip-category
34 + // shortcode-as-block "category" cards. Trip listing cards intentionally
35 + // opt out — those have multiple visible CTAs (View Details button, image
36 + // link, title link, favorite, category/activity chips) and shouldn't
37 + // hijack ambient clicks; the user navigates via the explicit controls.
38 + //
39 + // CSS-only "stretched link" (title link ::after with inset:0) is the
40 + // canonical implementation and remains in place for screen-reader and
41 + // crawler semantics — but in some layouts an intermediate ancestor with
42 + // `position: relative` traps the absolute overlay, leaving the upper
43 + // portion of the card non-clickable. This delegated click handler is the
44 + // belt-and-braces fallback: it catches any click that didn't already land
45 + // on a real interactive element and forwards it to the card's primary
46 + // link. Modifier keys (ctrl/cmd/middle-click) open in a new tab to match
47 + // the browser's normal `<a>` behavior.
48 + function initStretchedCardClicks() {
49 + const cardSelector = '.yatra-category-card';
50 + const linkSelector = 'a.yatra-category-card-title-link';
51 + // Click targets that should be allowed to handle their own event.
52 + const interactive = 'a, button, input, select, textarea, label, [role="button"], [data-no-card-click]';
53 +
54 + document.addEventListener('click', function (event) {
55 + // Allow native links/buttons to do their thing.
56 + if (event.target.closest(interactive)) {
57 + return;
58 + }
59 + const card = event.target.closest(cardSelector);
60 + if (!card) return;
61 +
62 + const link = card.querySelector(linkSelector);
63 + if (!link || !link.href) return;
64 +
65 + // Cmd/Ctrl/middle-click → new tab. Plain click → same tab.
66 + if (event.metaKey || event.ctrlKey || event.shiftKey || event.button === 1) {
67 + window.open(link.href, '_blank', 'noopener');
68 + } else {
69 + window.location.href = link.href;
70 + }
71 + });
72 +
73 + // Keyboard parity: Enter on a focused card root navigates to the link.
74 + document.addEventListener('keydown', function (event) {
75 + if (event.key !== 'Enter') return;
76 + if (event.target.closest(interactive)) return;
77 + const card = event.target.closest(cardSelector);
78 + if (!card) return;
79 + const link = card.querySelector(linkSelector);
80 + if (link && link.href) {
81 + window.location.href = link.href;
82 + }
83 + });
84 + }
85 +
29 86 // Advanced search toggle
30 87 function initAdvancedSearch() {
31 88 const toggleBtn = document.getElementById('advancedToggle');
32 89 const advancedOptions = document.getElementById('advancedOptions');
@@ -98,25 +155,8 @@
98 155 });
99 156
100 157 dropdown.addEventListener('click', function(e) {
101 158 e.stopPropagation();
102 - });
103 - }
104 -
105 - // Filter section toggles
106 - function initFilterToggles() {
107 - const filterTitles = document.querySelectorAll('.yatra-filter-title');
108 -
109 - filterTitles.forEach(title => {
110 - title.addEventListener('click', function() {
111 - const section = this.closest('.yatra-filter-section');
112 - section.classList.toggle('open');
113 - });
114 - });
115 -
116 - // Open all filter sections by default
117 - document.querySelectorAll('.yatra-filter-section').forEach(section => {
118 - section.classList.add('open');
119 159 });
120 160 }
121 161
122 162 // View toggle (grid/list): one grid per page; localStorage key is per grid id (not global).