PageSourceSearch

https://www.melhoresdestinos.com.br/wp-content/themes/md2023/js23/listagem-viaje-com-desconto.js?ver=2025-003y

js melhoresdestinos.com.br collected 2026-09-24 08:59:58 UTC 17,088 bytes, 489 lines download raw bytes

1function renderCategories() {
2    var html = "";
3    html +=  "<div class='grupo-destinos'>";
4
5    data.categories.forEach(function (item) {
6      html +=  "<div class='item-vcd' link='"+item.link+"'name='"+item.name+"'>";
7      html +=     "<img src='"+ item.image +"' alt='"+ item.name +"'>";
8      html +=     "<div class='texto-item-vcd'>";
9      html +=       "<div>";
10      html +=         "<div class='regiao-vcd'>"+ item.name +"</div>";
11      html +=         item.description
12      html +=       "</div>";
13      html +=      "</div>";
14      html +=      "<div class='preco-vcd'>";
15      html +=        "<div>";
16      html +=          "<span><div class='idaevolta'>Ida + volta</div>A partir de</span> <i>R$</i><b> "+ numeroComPontos(item.cheapest_itinerary_price) +"</b>";
17      html +=         "</div>";
18      html +=       "</div>";
19      html +=   "</div>";
20    });
21    html +=   "</div>";
22
23    document.getElementsByClassName("render-categories")[0].innerHTML = html;
24    ativarTrechos('item-vcd');
25
26}
27
28function renderCity() {
29  var html = "";
30  html +=  "<div class='grupo-subcategorias'>";
31  html +=   "<div class='item-subcategoria-vcd header-lista-subcategorias'>";
32  html +=  "<div class='texto-header-subcategoria'>";
33  if(data.cities[0] && data.cities[0].from_city_name){
34    //html +=  "Trecho";
35    html +=  "<div class='trechos'><div>Origem</div><div>Destino</div></div>";
36  }else {
37    html +=  "Destino";
38  }
39  html +=  "</div>";
40  html +=  "<div class='preco-header-subcategoria-vcd'>";
41  html +=  "  <div>";
42  html +=  "    Ida + volta<br>a partir de";
43  html +=  "  </div>";
44  html +=  "</div>";
45  html +=  "</div>";
46
47  data.cities.forEach(function (item) {
48
49    html +=  "  <div class= 'item-subcategoria-vcd' link='"+item.link+"'name='"+item.to_city_name+"'>";
50    html +=  " <div class='texto-sub-categoria'>";
51    if(item.from_city_name){
52      html +=  "<div class='trechos'><div>"+ item.from_city_name +"</div><div>"+ item.to_city_name +"</div></div>";
53    }else {
54      html +=  item.to_city_name;
55    }
56    html +=  " </div>";
57    html +=  "  <div class='preco-subcategoria-vcd'>";
58    html +=  "    <div>";
59    html +=  "     <i>R$</i><b>"+ numeroComPontos(item.total_price) +"</b>";
60    html +=  "   </div>";
61    html +=  " </div>";
62    html +=  "</div>";
63  });
64  html +=   "</div>";
65
66  document.getElementsByClassName("render-categories")[0].innerHTML = html;
67
68  if(data.cities[0] && data.cities[0].link.includes("itinerary_prices")){
69    ativarTarifas();
70  } else {
71    ativarTrechos('item-subcategoria-vcd');
72  }
73}
74
75
76
77function getOrigin(){
78
79  ajax_get(url_servidor+'/api/v1/airports/origins', function(origins) {
80
81    new autoComplete({
82        selector: 'input[name=origem-vcd]',
83        minChars: 3,
84        delay: 150,
85        source: function(term, suggest){
86            term = term.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
87            var matches = [];
88            for (i=0; i<origins.origins.length; i++) {
89              if (~origins.origins[i].city_name.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().indexOf(term) || ~origins.origins[i].iata_code.toLowerCase().indexOf(term)) {
90                matches.push(origins.origins[i]);
91              }
92          }
93            suggest(matches);
94        },
95        renderItem: function (item, search){
96            search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
97            var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
98            var originList = item.city_name+' ('+item.iata_code+')';
99            return '<div class="autocomplete-suggestion city" data-langname="'+originList+'" data-lang="city" data-val="'+search+'"><!--img src="img/city.png"--> '+originList.replace(re, "<b>$1</b>")+'</div>';
100        },
101        onSelect: function(e, term, item){
102        document.getElementById('origem-vcd').value = item.getAttribute('data-langname');
103        let origem = ""+item.getAttribute('data-langname').match(/\([A-Z]*\)/);
104        filter.from_city_name = origem.substring(1,4);
105
106        searchParams = new URLSearchParams(filter.link.split('?')[1]);
107        filter.link = filter.link.split('?')[0];
108        if (filter.from_city_name) {
109          searchParams.delete("from_iata_code");
110          searchParams.set('from_iata_code', filter.from_city_name);
111        }
112        if (filter.month) {
113          searchParams.delete("month");
114          searchParams.set('month', filter.month);
115        }
116
117        filter.link = filter.link +'?'+ searchParams.toString();
118
119        loading();
120        updatePageUrl(filter.link);
121        renderBreadcrumb();
122        ajax_get(filter.link, function(json_data) {
123          data = json_data;
124          if (data == null) {
125              return false;
126          }
127          if(data.categories) {
128            renderCategories();
129          } else if (data.cities) {
130            renderCity();
131          }
132        });
133        }
134    });
135
136    if (filter.from_city_name) {
137      var origemSelecionada = origins.origins.find(function(o){ return o.iata_code === filter.from_city_name; });
138      if (origemSelecionada) {
139        document.getElementById('origem-vcd').value = origemSelecionada.city_name + ' (' + origemSelecionada.iata_code + ')';
140      }
141    }
142
143  });
144}
145
146function getMonths(){
147  var trechos = document.getElementById('mes-vcd');
148
149  for (let i = 0; i <= 12; i++) {
150    let newDate = new Date().setMonth(new Date().getMonth()+i);
151    newDate = new Date(newDate);
152    var option = document.createElement("option");
153    var monthName = newDate.toLocaleString('pt-BR', { month: 'long' });
154    option.text = monthName[0].toUpperCase() + monthName.substring(1) + " de " + newDate.getFullYear();
155    option.value = newDate.getFullYear()+"-"+((newDate.getMonth() + 1));
156    trechos.add(option);
157  }
158}
159
160function ativarTrechos(className){
161  var trechos = document.getElementsByClassName(className);
162
163  for (var i=0; i< trechos.length; i++) {
164      trechos[i].addEventListener('click', function () {
165          let link = this.getAttribute('link');
166          let name = this.getAttribute('name');
167          loading();
168          breadcrumb.push({name: name, link: link });
169          renderBreadcrumb();
170          ajax_get(link, function(json_data) {
171            updatePageUrl(link);
172            let cabecalho_vcd = document.getElementsByClassName('cabecalho-vcd')[0];
173            if(window.scrollY > (cabecalho_vcd.offsetHeight + cabecalho_vcd.offsetTop)){
174              document.getElementsByClassName('faixa-vcd')[0].scrollIntoView();
175            }
176            filter.link = link;
177            data = json_data;
178            if (data == null) {
179                return false;
180            }
181            if(data.categories) {
182              renderCategories();
183            } else if (data.cities) {
184              renderCity();
185            }
186          });
187      });
188  }
189}
190
191function ativarBreadcrumb(){
192  var itens = document.getElementsByClassName('item-breadcrumb');
193
194  for (var i=0; i< itens.length; i++) {
195    itens[i].addEventListener('click', function () {
196      let link = this.getAttribute('link');
197      let name = this.getAttribute('name');
198      loading();
199      for (let i = 0; i < breadcrumb.length; i++) {
200          if (breadcrumb[i].name === name) {
201            breadcrumb.splice(i+1);
202          }
203      }
204      renderBreadcrumb();
205      ajax_get(link, function(json_data) {
206        updatePageUrl(link);
207        filter.link = link;
208        data = json_data;
209        if (data == null) {
210            return false;
211        }
212        if(data.categories) {
213          renderCategories();
214        } else if (data.cities) {
215          renderCity();
216        }
217      });
218    });
219  }
220}
221
222function ativarTarifas(){
223  var trechos = document.getElementsByClassName('item-subcategoria-vcd');
224
225  for (var i=0; i< trechos.length; i++) {
226      trechos[i].addEventListener('click', function () {
227          var link = this.getAttribute('link');
228          var separetorLinkToParams = link.split("?");
229          var fragmentsUrl = separetorLinkToParams[0].split("/");
230          var from = fragmentsUrl[fragmentsUrl.length - 2]
231          var to = fragmentsUrl[fragmentsUrl.length - 1]
232          var params = separetorLinkToParams[1];
233          window.location.href = "/voos?rota="+ from +"/"+to+"/-/&"+params;
234      });
235  }
236}
237
238function renderBreadcrumb(){
239  var html = "";
240  html += "<ul>";
241  if (breadcrumb.length > 1){
242
243    breadcrumb.forEach(function (item) {
244      let searchParams = new URLSearchParams(item.link.split('?')[1]);
245      item.link = item.link.split('?')[0];
246      searchParams.delete("from_iata_code");
247      searchParams.delete("month");
248      if (filter.from_city_name) {
249        searchParams.set('from_iata_code', filter.from_city_name);
250      }
251      if (filter.month) {
252        searchParams.set('month', filter.month);
253      }
254      item.link = item.link +'?'+ searchParams.toString();
255      html +=  "<li class='item-breadcrumb' link='"+item.link+"'name='"+item.name+"'>"+item.name+"</div>";
256    })
257  }
258  html += "</ul>";
259
260  document.getElementsByClassName("breadcrumb")[0].innerHTML = html;
261  ativarBreadcrumb();
262}
263
264var data = {};
265var filter = {from_city_name: null, month: null, link: null};
266var breadcrumb = [];
267
268function loading(){
269  document.getElementsByClassName("render-categories")[0].innerHTML = '<img src="/wp-content/themes/md2018/img/loading.gif" id="aviao" class="aviao-maluco" style="display: block; margin-left: auto; margin-right: auto; width: 15%;" alt="carregando...">';
270}
271
272/* ---- Sincronização do estado de navegação com a url da página ---- */
273/* Permite acessar/compartilhar um link e cair direto no ponto da navegação em que se parou */
274
275var VCD_URL_PARAMS = ['vcd_category_id', 'vcd_to_iata_code', 'vcd_from_iata_code', 'vcd_month'];
276
277// Lê os parâmetros vcd_* da url da página e monta o link da api correspondente
278function getVcdLinkFromLocation(){
279  var pageParams = new URLSearchParams(window.location.search);
280  var apiParams = new URLSearchParams();
281
282  if (pageParams.get('vcd_category_id'))   apiParams.set('category_id', pageParams.get('vcd_category_id'));
283  if (pageParams.get('vcd_to_iata_code'))  apiParams.set('to_iata_code', pageParams.get('vcd_to_iata_code'));
284  if (pageParams.get('vcd_from_iata_code')) apiParams.set('from_iata_code', pageParams.get('vcd_from_iata_code'));
285  if (pageParams.get('vcd_month'))         apiParams.set('month', pageParams.get('vcd_month'));
286
287  var querystring = apiParams.toString();
288  return {
289    link: url_servidor + '/api/v1/twd/web/categories' + (querystring ? '?' + querystring : ''),
290    from_iata_code: pageParams.get('vcd_from_iata_code'),
291    month: pageParams.get('vcd_month'),
292    has_params: querystring.length > 0
293  };
294}
295
296// Espelha o link da api atual (categoria/destino/origem/mês) nos parâmetros vcd_* da url da página
297function updatePageUrl(link, replace){
298  var apiParams = new URLSearchParams(link.split('?')[1] || '');
299  var pageParams = new URLSearchParams(window.location.search);
300
301  VCD_URL_PARAMS.forEach(function(param){ pageParams.delete(param); });
302
303  if (apiParams.get('category_id'))    pageParams.set('vcd_category_id', apiParams.get('category_id'));
304  if (apiParams.get('to_iata_code'))   pageParams.set('vcd_to_iata_code', apiParams.get('to_iata_code'));
305  if (apiParams.get('from_iata_code')) pageParams.set('vcd_from_iata_code', apiParams.get('from_iata_code'));
306  if (apiParams.get('month'))          pageParams.set('vcd_month', apiParams.get('month'));
307
308  var novaBusca = pageParams.toString();
309  var novaUrl = window.location.pathname + (novaBusca ? '?' + novaBusca : '') + window.location.hash;
310
311  if (replace) {
312    window.history.replaceState({ link: link, breadcrumb: breadcrumb }, '', novaUrl);
313  } else {
314    window.history.pushState({ link: link, breadcrumb: breadcrumb }, '', novaUrl);
315  }
316}
317
318// Reconstrói o breadcrumb de um link da api subindo pela cadeia de parent_category_link
319function buildBreadcrumbFromLink(link, callback){
320  ajax_get(link, function(leafData){
321    if (leafData == null) {
322      callback([{ name: 'Início', link: url_servidor + '/api/v1/twd/web/categories' }], leafData);
323      return;
324    }
325
326    var trilha = [];
327    var nomeAtual = leafData.to_city_name || leafData.to_name;
328    if (nomeAtual) {
329      trilha.unshift({ name: nomeAtual, link: link });
330    }
331
332    function subirNivel(parentLink){
333      if (!parentLink) {
334        trilha.unshift({ name: 'Início', link: url_servidor + '/api/v1/twd/web/categories' });
335        callback(trilha, leafData);
336        return;
337      }
338      ajax_get(parentLink, function(parentData){
339        if (parentData != null && parentData.to_name) {
340          trilha.unshift({ name: parentData.to_name, link: parentLink });
341        }
342        subirNivel(parentData ? parentData.parent_category_link : null);
343      });
344    }
345
346    subirNivel(leafData.parent_category_link);
347  });
348}
349
350
351/* Busca os dados para inicializar o viaje com desconto*/
352document.addEventListener("DOMContentLoaded", function(event) {
353
354  // Recupera o estado de navegação (categoria/destino/origem/mês) salvo na url da página, se houver
355  let estadoInicial = getVcdLinkFromLocation();
356  filter.from_city_name = estadoInicial.from_iata_code;
357  filter.month = estadoInicial.month;
358
359  getOrigin();
360  getMonths();
361
362  if (filter.month) {
363    document.getElementById('mes-vcd').value = filter.month;
364  }
365
366  window.onpopstate = function(event) {
367
368    let estado = getVcdLinkFromLocation();
369    let url_trechos = estado.link;
370
371    filter.from_city_name = estado.from_iata_code;
372    filter.month = estado.month;
373    document.getElementById('mes-vcd').value = filter.month || '';
374
375    let cabecalho_vcd = document.getElementsByClassName('cabecalho-vcd')[0];
376    if(window.scrollY > (cabecalho_vcd.offsetHeight + cabecalho_vcd.offsetTop)){
377      document.getElementsByClassName('faixa-vcd')[0].scrollIntoView();
378    }
379
380    loading();
381    buildBreadcrumbFromLink(url_trechos, function(trilha, json_data){
382      breadcrumb = trilha;
383      filter.link = url_trechos;
384      data = json_data;
385      renderBreadcrumb();
386      if (data == null) {
387          return false;
388      }
389      if(data.categories) {
390        renderCategories();
391      } else if (data.cities) {
392        renderCity();
393      }
394    });
395};
396
397  document.getElementById('mes-vcd').addEventListener('change', function(){
398    filter.month = this.value;
399
400    searchParams = new URLSearchParams(filter.link.split('?')[1]);
401    filter.link = filter.link.split('?')[0];
402    if (filter.from_city_name) {
403      searchParams.delete("from_iata_code");
404      searchParams.set('from_iata_code', filter.from_city_name);
405    }
406
407    searchParams.delete("month");
408    if (filter.month) {
409      searchParams.set('month', filter.month);
410    }
411
412    filter.link = filter.link +'?'+ searchParams.toString();
413    loading();
414    updatePageUrl(filter.link);
415    renderBreadcrumb();
416    ajax_get(filter.link, function(json_data) {
417      data = json_data;
418      if (data == null) {
419          return false;
420      }
421      if(data.categories) {
422        renderCategories();
423      } else if (data.cities) {
424        renderCity();
425      }
426    });
427  })
428
429  document.getElementById('origem-vcd').onblur = function(){
430    if (this.value.length == 0){
431      loading();
432
433      searchParams = new URLSearchParams(filter.link.split('?')[1]);
434      filter.link = filter.link.split('?')[0];
435      searchParams.delete("from_iata_code");
436      filter.from_city_name = null;
437      if (filter.month) {
438        searchParams.delete("month");
439        searchParams.set('month', filter.month);
440      }
441
442      filter.link = filter.link +'?'+ searchParams.toString();
443      updatePageUrl(filter.link);
444      renderBreadcrumb();
445      ajax_get(filter.link, function(json_data) {
446        data = json_data;
447        if (data == null) {
448            return false;
449        }
450        if(data.categories) {
451          renderCategories();
452        } else if (data.cities) {
453          renderCity();
454        }
455      });
456    }
457 }
458
459  let url_trechos = url_servidor +'/api/v1/twd/web/categories';
460
461  if (estadoInicial.has_params) {
462    // A página foi acessada com um estado de navegação salvo na url: rola até o bloco e recupera direto nesse ponto
463    document.getElementsByClassName('faixa-vcd')[0].scrollIntoView();
464    loading();
465    buildBreadcrumbFromLink(estadoInicial.link, function(trilha, json_data){
466      breadcrumb = trilha;
467      filter.link = estadoInicial.link;
468      data = json_data;
469      renderBreadcrumb();
470      window.history.replaceState({ link: estadoInicial.link, breadcrumb: breadcrumb }, '', window.location.href);
471      if (data == null) {
472          return false;
473      }
474      if(data.categories) {
475        renderCategories();
476      } else if (data.cities) {
477        renderCity();
478      }
479    });
480  } else {
481    // Estado inicial: conteúdo já veio renderizado pelo php
482    filter.link = url_trechos;
483    breadcrumb.push({name: 'Início', link: url_trechos});
484    renderBreadcrumb();
485    ativarTrechos('item-vcd');
486    window.history.replaceState({ link: url_trechos, breadcrumb: breadcrumb }, '', window.location.href);
487  }
488
489});

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.