Tickets and fares
Which ticket do you need?
Enter the name of the ticket...
An error occurred while processing the template.
For "." left-hand operand: Expected a hash, but this has evaluated to a string (wrapper: f.t.SimpleScalar): ==> jTitlePrices [in template "20155#20195#881487" at line 11, column 16] ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign num = jTitlePrices.length() - 1 [in template "20155#20195#881487" at line 11, column 1] ----
1<#assign url = themeDisplay.getURLCurrent()>
2<#assign httpComponentsUtil = staticUtil["com.liferay.portal.kernel.util.HttpComponentsUtil"]>
3<#assign strOptionURL = portalUtil.getOriginalServletRequest(request).getParameter("q")!"">
4<#assign strOptionURL = httpComponentsUtil.decodeURL(strOptionURL)>
5<#assign pagination = 8>
6<#attempt>
7 <#assign jTitlePrices = jsonFactoryUtil.createJSONArray(serviceTool.getLlistatBitllets(groupId))>
8<#recover>
9 <#assign jTitlePrices = "">
10</#attempt>
11<#assign num = jTitlePrices.length()-1>
12<#assign counter = 1>
13<#assign Integer = 0>
14<#assign abonaments = abonament.getSiblings()>
15<#assign imagesFolder = themeDisplay.getPathThemeImages()>
16<#assign jsonFilterOptions = jsonFactoryUtil.createJSONObject()>
17<#assign group = serviceLocator.findService("com.liferay.portal.kernel.service.GroupLocalService").getGroup(groupId)>
18<#assign domain = group.getExpandoBridge().getAttribute("MAPS_TMB_DOMAIN")>
19<#assign api_id = group.getExpandoBridge().getAttribute("API_ID")>
20<#assign api_key = group.getExpandoBridge().getAttribute("API_KEY")>
21<#assign equipmentCode = group.getExpandoBridge().getAttribute("ECOMMERCE_EQUIPMENT_CODE")>
22<#assign ecommerceDomain = group.getExpandoBridge().getAttribute("ECOMMERCE_DOMAIN")>
23<#assign ecommerceEndpoint = group.getExpandoBridge().getAttribute("ECOMMERCE_ENDPOINT")>
24<#assign urlCompra = languageUtil.get(locale, "context.ecommerce.url")>
25<#assign travelCardsMap = {
26 "es_ES": {
27 'general' : '0',
28 'niños_y_jovenes' : '1',
29 'gente_mayor_y_personas_con_discapacidad' : '2',
30 'familias_numerosas_y_monoparentales' : '3',
31 'persones_en_paro' : '4',
32 'integrados' : '0',
33 'otros' : '0'
34 },
35 "en_US": {
36 'general' : '0',
37 'children_and_youth' : '1',
38 'senior_citizens_and_disabled' : '2',
39 'large_and_single_parent_families' : '3',
40 'unemployed' : '4',
41 'integrats' : '0',
42 'others' : '0'
43 },
44 "ca_ES": {
45 'general' : '0',
46 'infants_i_joves' : '1',
47 'gent_gran_i_persones_amb_discapacitat' : '2',
48 'families_nombroses_i_monoparentals' : '3',
49 'persones_en_atur' : '4',
50 'integrats' : '0',
51 'altres' : '0'
52 }
53 }>
54<#assign optionURL = travelCardsMap[locale.toString()][strOptionURL]!"">
55<#-- Sorting dels abonaments pel camp ordre_tipus. ------------------------------------------------------------->
56<#assign n = abonaments?size-1>
57<#assign abonaments = tmbPortalUtil.sortListByField(abonament.getSiblings(), "ordre_tipus", "asc")>
58<#--<#assign abonaments = abonament.getSiblings()>-->
59<#-- Filtratge del llistat de bitllets ------------------------------------------------------------------------->
60<div class="bitllets-catalog-new grid__row">
61 <div class="secondary">
62 <div>
63 <p class="bitllets-intro-text">${intro_text.getData()}</p>
64 </div>
65 <#assign select_filtreOpt = []>
66 <#if (select_filtre.getOptions()?size> 0)>
67 <#assign classNameService = serviceLocator.findService("com.liferay.portal.kernel.service.ClassNameLocalService")>
68 <#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")>
69 <#assign structureService = serviceLocator.findService("com.liferay.dynamic.data.mapping.service.DDMStructureLocalService")>
70 <#assign groupId = getterUtil.getLong(groupId)>
71 <#assign structureClassNameId = classNameService.getClassNameId("com.liferay.journal.model.JournalArticle")>
72 <#assign curArticle = journalArticleLocalService.getArticle(groupId, .vars['reserved-article-id'].getData())>
73 <#assign structure = curArticle.getDDMStructure()>
74
75 <div class="tickets-catalog">
76 <section class="collapsible-content js-collapsible is-expanded">
77 <header class="collapsible-content__header">
78 <h2 class="collapsible-content__title js-collapsible__title">
79 <@liferay.language key="label.with.filter"/>
80 </h2>
81 </header>
82 <#assign node0 = jsonFactoryUtil.createJSONObject("{ categories : {} }")>
83 <#assign jsonFilterOptions = jsonFilterOptions.put("0", node0)>
84
85
86 <div class="collapsible-content__body js-collapsible__content">
87 <form action="" class="form form--validate">
88 <#foreach item in select_filtre.getOptions()>
89 <#if item == "1">
90 <#assign select_filtreOpt = select_filtreOpt + [item]>
91 <div class="choose-elements choose-ticket__type">
92 <h3 class="title title--3 "><@liferay.language key="view.t-mobilitat.cataleg.tipus.bitllet2"/></h3>
93 <ul class="option-group__items option-group__items--h">
94 <li class="option-group__item">
95 <label for="f__radio__1" class="radio">
96 <input title="[títol]" id="f__radio__1" name="f__radios__1_cbillets" class="user-success" type="radio" value="0">
97 <@liferay.language key="view.t-mobilitat.cataleg.tipus.bitllet.abonaments1"/>
98 </label>
99 </li>
100 <#assign node1 = jsonFactoryUtil.createJSONObject("{ categories : {} }")>
101 <#assign jsonFilterOptions = jsonFilterOptions.put("1", node1)>
102 <li class="option-group__item form__field__control--correct">
103 <label for="f__radio__2" class="radio">
104 <input title="[títol]" id="f__radio__2" name="f__radios__1_cbillets" class="user-success" type="radio" value="1">
105 <@liferay.language key="view.t-mobilitat.cataleg.tipus.bitllet.visitabarcelona"/>
106 </label>
107 </li>
108 <#assign node2 = jsonFactoryUtil.createJSONObject("{ categories : {} }")>
109 <#assign jsonFilterOptions = jsonFilterOptions.put("2", node2)>
110 <li class="option-group__item">
111 <label for="f__radio__3" class="radio">
112 <input title="[títol]" id="f__radio__3" name="f__radios__1_cbillets" class="user-success checkedFocus" type="radio" value="2">
113 <@liferay.language key="view.t-mobilitat.cataleg.tipus.bitllet.senzills"/>
114 </label>
115 </li>
116 </ul>
117 </div>
118
119 </#if>
120 <#if item == "2">
121 <#assign select_filtreOpt = select_filtreOpt + [item]>
122 <#assign ddmFormFieldsMap = structure.getDDMForm().getDDMFormFieldsMap(true)>
123 <#assign selectValidesaAbonament = ddmFormFieldsMap['select_validesa_abonament']>
124 <#assign ddmOptions = selectValidesaAbonament.getProperties()["options"]>
125 <#assign options = ddmOptions.getOptions()>
126 <select id="validesaTemplate" style="display:none;">
127 <#foreach option in options?keys>
128 <#assign value = options[option].getString(locale)>
129 <option value="${option}">${value}</option>
130 </#foreach>
131 </select>
132 <select id="tipus_abonament_template" style="display:none;">
133 </select>
134
135 <#assign selectGrupAbonament = ddmFormFieldsMap['select_grup_abonament']>
136 <#assign ddmOptions = selectGrupAbonament.getProperties()["options"]>
137 <#assign options = ddmOptions.getOptions()>
138
139 <div class="choose-elements choose-category" style="display: none;">
140 <h3 class="title title--3 "><@liferay.language key="label.group"/></h3>
141 <#assign jsonAllFilter = jsonFilterOptions.getJSONObject('0')>
142 <#assign jsonAllCategories = jsonAllFilter.getJSONObject('categories')>
143 <ul class="option-group__items option-group__items--h" id="f__tipus__abonament_inputs">
144 <#foreach option in options?keys>
145 <#assign value = options[option].getString(locale)>
146 <#assign emptyValidesa = jsonFactoryUtil.createJSONObject('{ validesa : [] }')/>
147 <#assign jsonAllCategories = jsonAllCategories.put(option, emptyValidesa) />
148 <li class="option-group__item" value="${option}">
149 <label for="f__radio_category__${option}" class="radio">
150 <input title="[títol]" id="f__radio_category__${option}" name="f__radios__1_categories" <#if optionURL == option > checked="checked" </#if> class="user-success" type="radio" value="${option}"> ${value}
151 </label>
152 </li>
153 </#foreach>
154 </ul>
155 </div>
156
157 <div class="form__field form__field--select" style="display: none">
158 <div class="form__field__control">
159 <select title="<@liferay.language key='label.categories'/>" id="f__tipus__abonament">
160 <#assign jsonAllFilter = jsonFilterOptions.getJSONObject("0")>
161 <#assign jsonAllCategories = jsonAllFilter.getJSONObject("categories")>
162
163 <#foreach option in options?keys>
164 <#assign value = options[option].getString(locale)>
165 <#assign emptyValidesa = jsonFactoryUtil.createJSONObject("{ validesa : [] }")>
166 <#assign jsonAllCategories = jsonAllCategories.put(option, emptyValidesa)>
167 <option value="${option}" <#if optionURL == option> selected </#if>> ${value}</option>
168 </#foreach>
169 </select>
170 </div>
171 </div>
172
173 <#assign selectValidesaAbonament = ddmFormFieldsMap['select_validesa_abonament']>
174 <#assign ddmOptions = selectValidesaAbonament.getProperties()["options"]>
175 <#assign options = ddmOptions.getOptions()>
176
177 <div class="choose-elements choose-validesa" style="display: none">
178 <h3 class="title title--3 "><@liferay.language key="label.categoria"/></h3>
179 <ul class="option-group__items option-group__items--h" id="f__validesa_inputs">
180 <#foreach option in options?keys>
181 <#assign value = options[option].getString(locale)>
182 <#assign emptyValidesa = jsonFactoryUtil.createJSONObject('{ validesa : [] }')/>
183 <#assign jsonAllCategories = jsonAllCategories.put(option, emptyValidesa) />
184 <li class="option-group__item" value="${option}">
185 <label for="f__radio_validesa__${option}" class="radio">
186 <input title="[títol]" id="f__radio_validesa__${option}" name="f__radios__1_validesa" class="user-success" type="radio" value="${option}"> ${value}
187 </label>
188 </li>
189 </#foreach>
190 </ul>
191 </div>
192
193 <div style="display: none">
194 <h3 class="title title--3 ">
195 <@liferay.language key="label.validity"/>
196 </h3>
197
198 <div class="form__field form__field--select">
199 <div class="form__field__control">
200 <select title="<@liferay.language key='label.all'/>" id="f__validesa" disabled="disabled">
201 <option value="0">
202 <@liferay.language key="label.all"/>
203 </option>
204 </select>
205 </div>
206 </div>
207 </div>
208 </#if>
209 </#foreach>
210 </form>
211 </div>
212 </section>
213 </div>
214 </#if>
215</div>
216<#-- Llistat de bitllets -------------------------------------------------------------------------------------
217-->
218<div class="primary">
219 <h2 class="title-bitllets-primary"><@liferay.language key="label.tickets.title"/></h2>
220 <div class="filters-bitllets">
221 <button class="filter-levels filter-first-level">
222 <span></span>
223 <img class="filter-unit__image" src="${imagesFolder}/basic/10px/svg/close-black.svg" alt="<@liferay.language key='label.close'/>">
224 </button>
225 <button class="filter-levels filter-second-level">
226 <span></span>
227 <img class="filter-unit__image" src="${imagesFolder}/basic/10px/svg/close-black.svg" alt="<@liferay.language key='label.close'/>">
228 </button>
229 <button class="filter-levels filter-third-level">
230 <span></span>
231 <img class="filter-unit__image" src="${imagesFolder}/basic/10px/svg/close-black.svg" alt="<@liferay.language key='label.close'/>">
232 </button>
233 <button class="delete-all-filters">
234 <img class="filter-unit__image" src="${imagesFolder}/basic/12px/svg/delete.svg" alt="<@liferay.language key='label.delete.data'/>">
235 <span><@liferay.language key="label.delete.filters"/><span>
236 </button>
237 </div>
238 <section class="tickets-pop">
239 <div class="distributor distributor--alt distributor--alt-media">
240 <div class="result-notfound-tickets">
241 <span><@liferay.language key="label.notfound.ticket"/></span>
242 </div>
243 <ul id="result-list" class="distributor__items">
244 <#assign lang = locale.getLanguage()>
245 <#assign String = "">
246 <#foreach bitllet in abonaments>
247 <#assign preu = -1>
248 <#assign isZone = "false">
249 <#assign isUnique = false>
250 <#assign showDesde = false>
251 <#assign titolTitle = "">
252 <#if bitllet.en_titol_detall.getData() != "">
253 <#assign titolTitle = bitllet.en_titol_detall.getData()>
254 </#if>
255 <#assign abonamentTypes = "">
256 <#foreach abonType in bitllet.select_grup_abonament.getSiblings()>
257 <#if abonamentTypes != "">
258 <#assign abonamentTypes = abonamentTypes + "," + abonType.getData()>
259 <#else>
260 <#assign abonamentTypes = abonType.getData()>
261 </#if>
262 </#foreach>
263 <#assign validesaTypes = "">
264 <#foreach validType in bitllet.select_validesa_abonament.getSiblings()>
265 <#if validesaTypes != "">
266 <#assign validesaTypes = validesaTypes + "," + validType.getData()>
267 <#else>
268 <#assign validesaTypes = validType.getData()>
269 </#if>
270 </#foreach>
271 <#assign bitllet_tipus = bitllet.bitllet_tipus.getData()!"">
272 <#if bitllet_tipus == "">
273 <#assign bitllet_tipus = "0">
274 </#if>
275 <#assign jsonFilterInfo = jsonFilterOptions.getJSONObject(bitllet_tipus)>
276 <#assign jsonBitllet = jsonFilterInfo.getJSONObject("categories")>
277
278 <#assign jsonAllFilter = jsonFilterOptions.getJSONObject("0")>
279 <#assign jsonAllCategories = jsonAllFilter.getJSONObject("categories")>
280
281
282
283 <#foreach abonType in bitllet.select_grup_abonament.getSiblings()>
284 <#assign validesa_array = []>
285 <#if !jsonBitllet.has(abonType.getData())>
286 <#assign emptyValidesa = jsonFactoryUtil.createJSONObject("{ validesa : [] }")>
287 <#assign jsonBitllet = jsonBitllet.put(abonType.getData(), emptyValidesa)>
288 </#if>
289
290 <#-- Sin filtrar por tipo de billete ni categoría
291 -->
292 <#assign jsonNoFilterInfo = jsonAllCategories.getJSONObject("0")!jsonFactoryUtil.createJSONObject("{ validesa : [] }")>
293 <#assign jsonNoFilterValidesa = jsonNoFilterInfo.getJSONArray("validesa")>
294 <#-- Filtra por categoría pero no por tipo de billete-->
295 <#assign jsonAllCategoryInfo = jsonAllCategories.getJSONObject(abonType.getData())>
296 <#assign jsonAllValidesa = jsonAllCategoryInfo.getJSONArray("validesa")>
297 <#-- Filtra por tipo de billete pero no por categoría
298 -->
299 <#assign jsonBasicCategoryInfo = jsonBitllet.getJSONObject("0")!jsonFactoryUtil.createJSONObject("{ validesa : [] }")>
300 <#assign jsonBasicValidesa = jsonBasicCategoryInfo.getJSONArray("validesa")>
301 <#-- Filtra por categoría y por tipo de billete
302 -->
303 <#assign jsonBitlletCategoryInfo = jsonBitllet.getJSONObject(abonType.getData())>
304 <#assign jsonBCValidesa = jsonBitlletCategoryInfo.getJSONArray("validesa")>
305
306 <#foreach validesaData in bitllet.select_validesa_abonament.getSiblings()>
307 <#assign val = validesaData.getData()>
308 <#assign noFilterValString = jsonNoFilterValidesa.toString()>
309 <#assign noFilterValLength = noFilterValString?length-1>
310 <#assign noFilterValidesa_array = noFilterValString?substring(1, noFilterValLength)?replace("\"", "")?split(",")>
311
312 <#if !noFilterValidesa_array?seq_contains(val)>
313 <#assign jsonNoFilterValidesa = jsonNoFilterValidesa.put(val)>
314 </#if>
315
316 <#assign basicValString = jsonBasicValidesa.toString()>
317 <#assign basicValLength = basicValString?length-1>
318 <#assign basicValidesa_array = basicValString?substring(1, basicValLength)?replace("\"", "")?split(",")>
319
320 <#if !basicValidesa_array?seq_contains(val)>
321 <#assign jsonBasicValidesa = jsonBasicValidesa.put(val)>
322 </#if>
323 <#assign allValString = jsonAllValidesa.toString()>
324 <#assign allValLength = allValString?length-1>
325 <#assign allValidesa_array = allValString?substring(1, allValLength)?replace("\"", "")?split(",")>
326
327 <#if !allValidesa_array?seq_contains(val)>
328 <#assign jsonAllValidesa = jsonAllValidesa.put(val)>
329 </#if>
330
331 <#assign bcValString = jsonBCValidesa.toString()>
332 <#assign bcValLength = bcValString?length-1>
333 <#assign bcValidesa_array = bcValString?substring(1, bcValLength)?replace("\"", "")?split(",")>
334 <#if !bcValidesa_array?seq_contains(val)>
335 <#assign jsonBCValidesa = jsonBCValidesa.put(val)>
336 </#if>
337 </#foreach>
338 </#foreach>
339
340 <li class="distributor__item"
341 data-filter-ticket-type="${abonamentTypes}"
342 data-filter-validity="${validesaTypes}"
343 data-filter-bitllet="${bitllet.bitllet_tipus.getData()}"
344 data-bitllet-code="${bitllet.codi_titol_abonament.getData()}"
345 <#if (counter>pagination)> style="display:none;" </#if>
346 >
347 <div class="list-unit">
348 <div class="list-unit__container">
349
350 <div class="list-unit__media <#if bitllet.venda_online?has_content && bitllet.venda_online.getData() == "true">
351 list-unit__media--app </#if>
352 ">
353 <#if bitllet.imatge_abonament.getData() == "">
354 <img class="list-unit__image" src="${imagesFolder}/figures/img-distribuidora-3col.png" alt="<@liferay.language key="label.image.ticket"/>
355 ">
356 <#else>
357 <img class="list-unit__image" src="${bitllet.imatge_abonament.getData()}" alt="${bitllet.alt.getData()}">
358 </#if>
359 </div>
360 <div class="list-unit__content">
361 <h2 class="list-unit__title">
362 <a class="list-unit__link" title="${titolTitle}" href="${bitllet.url_detall_abonament.getFriendlyUrl()}">
363 ${bitllet.titol_abonament.getData()}
364 </a>
365 </h2>
366 <p class="list-unit__intro">
367 ${bitllet.descripcio_abonament.getData()}</p>
368 <#foreach i in 0..num>
369 <#assign currentCodeTitle = jTitlePrices.getJSONObject(i).getString("id")>
370 <#if bitllet.codi_titol_abonament.getData() == currentCodeTitle>
371 <#assign preu = jTitlePrices.getJSONObject(i).getDouble("preu")>
372 <#if preu == preu?floor>
373 <#assign preu = preu?string(",##0.##")>
374 <#else>
375 <#assign preu = preu?string(",##0.00")>
376 </#if>
377 <#if lang == "en">
378 <#assign preu = preu?replace(",", ".")>
379 <#else>
380 <#assign preu = preu?replace(".", ",")>
381 </#if>
382 <#assign isZone = jTitlePrices.getJSONObject(i).getString("teZones")>
383 <#break>
384 </#if>
385 </#foreach>
386 <#if preu?string == "-1">
387 <#assign preu = "">
388 <#else>
389 <#if bitllet.showDesde?? && bitllet.showDesde?has_content>
390 <#assign showDesde = getterUtil.getBoolean(bitllet.showDesde.getData())>
391 </#if>
392 <#assign fromText = "">
393 <#if showDesde>
394 <#assign fromText = languageUtil.get(locale, 'label.from')>
395 </#if>
396 <#if bitllet.isUnique?? && bitllet.isUnique?has_content>
397 <#assign isUnique = getterUtil.getBoolean(bitllet.isUnique.getData())>
398 </#if>
399 <#assign priceText = "">
400 <#if isUnique>
401 <#assign priceText = languageUtil.get(locale, 'label.price')>
402 </#if>
403
404 <#if lang == "en">
405 <#if isUnique>
406 <#assign preu = priceText + ": <b class='list-unit__meta-price'>€" + preu +"</b>">
407 <#else>
408 <#assign preu = fromText + " <b class='list-unit__meta-price'>€" + preu +"</b>">
409 </#if>
410 <#else>
411 <#if isUnique>
412 <#assign preu = priceText + ": <b class='list-unit__meta-price'>" + preu + " €" + "</b>">
413 <#else>
414 <#assign preu = fromText + " <b class='list-unit__meta-price'>" + preu + " €" + "</b>">
415 </#if>
416 </#if>
417 </#if>
418 <div class="list-unit__block">
419 <p class="list-unit__meta">
420 <#if bitllet.manualPrice??>
421 <#assign manualPrice = getterUtil.getBoolean(bitllet.manualPrice.getData())>
422 </#if>
423 <#if manualPrice?? && manualPrice && bitllet.priceInfo?? && bitllet.priceInfo.getData() != "">
424 <span class="list-unit__tag">
425 ${bitllet.priceInfo.getData()}
426 </span>
427 <#elseif preu != "">
428 <span class="list-unit__tag">
429 ${preu}
430 </span>
431 </#if>
432 </p>
433 <#if bitllet.onlineSell??>
434 <#assign onlineSell = getterUtil.getBoolean(bitllet.onlineSell.getData())>
435 </#if>
436 <div class="list-unit__actions" <#if onlineSell?? && onlineSell>style="display: block;"<#else>style="display: none;"</#if>>
437 <#if bitllet.url_externa_compra_online.getData() != "">
438 <a class="button button--a" tabindex="0" title="${bitllet.titol_abonament.getData()}" data-name-bitllet=""
439 data-titol="${bitllet.codi_titol_abonament.getData()}" data-code="" target="_blank" rel="external" href="${bitllet.url_externa_compra_online.getData()}">
440 <#elseif getterUtil.getBoolean(bitllet.saleTmobilitat.getData())>
441 <a class="button button--a" tabindex="0" title="${bitllet.titol_abonament.getData()}" data-name-bitllet=""
442 data-titol="${bitllet.codi_titol_abonament.getData()}" data-code="" rel="nofollow" onclick="saleMobilitatUrl(this)" onkeydown="handleKeyDown(event, 'sale')">
443 <#else>
444 <a class="button button--a" tabindex="0" title="${bitllet.titol_abonament.getData()}" data-name-bitllet=""
445 data-titol="${bitllet.codi_titol_abonament.getData()}" data-code="" rel="nofollow" onclick="notSaleMobilitatUrl(this)" onkeydown="handleKeyDown(event, 'notsale')">
446 </#if>
447 <@liferay.language key="label.buy.online"/>
448 </a>
449 </div>
450
451 </div>
452 </div>
453 </div>
454 </div>
455 </li>
456 <#assign counter = counter + 1>
457 </#foreach>
458
459 </ul>
460 <#-- Paginació del llistat de bitllets ------------------------------------------------------------------------->
461 <#if (abonaments?size>pagination)>
462 <div class="load-more">
463 <a href="javascript:void(0);" class="button button--a button-more" onclick="paginate();">
464 <@liferay.language key="view.more"/>
465 </a>
466 </div>
467 </#if>
468 </div>
469 </section>
470</div>
471</div>
472
473<script type="text/javascript">
474 var self = this;
475 var jsonOptions;
476 var jsonFilterOptions;
477 TJS.eventPagination = ${pagination};
478 var $firstLevelValue = null;
479 var $secondLevelValue = null;
480 var $thirdLevelValue = null;
481 var $selectedFirstLevel = false;
482 var $selectedSecondLevel = false;
483 var $selectedThirdLevel = false;
484 var $hideOtherFilters = false;
485
486 function initCompraOnline(versionCode){
487 jQuery.ajax({
488 url : "${domain}/${ecommerceEndpoint}/v2/business-parameters/"+versionCode+"/catalog/product/parent-variants?equipmentCode=${equipmentCode}&app_id=${api_id}&app_key=${api_key}",
489 type : "GET",
490 dataType: "json",
491 success: function(data) {
492 var productsNoVariants = data.productsWithoutVariants;
493 var productsWithVariants = data.productsWithVariants;
494
495 for(var i in productsNoVariants){
496 var product = productsNoVariants[i];
497 var ticketCode = product.ticketCode;
498 var productCode = product.code;
499 $('#result-list li.distributor__item[data-bitllet-code="' + ticketCode + '"]').each(function () {
500 $(this).find('.list-unit__actions').show();
501
502 var index = $( "#result-list li.distributor__item" ).index( this );
503 $(this).find('.list-unit__actions .button.button--a').attr('data-name-bitllet', product.originalName);
504 $(this).find('.list-unit__actions .button.button--a').attr('data-code', productCode);
505 Analytics.EnhancedEcommerce.addImpression(productCode, product.originalName, ++index, 'Catàleg de bitllets');
506
507
508 });
509
510 }
511
512 for(var pv in productsWithVariants){
513 var productVariants = productsWithVariants[pv];
514 var productParentVariants = productVariants.productParentVariants;
515 for(var ppv in productParentVariants){
516 var productParent = productParentVariants[ppv];
517 var productWVCode = productParent.variantFieldGroupingValue;
518 $('#result-list li.distributor__item[data-bitllet-code="' + productWVCode + '"]').each(function () {
519 $(this).find('.list-unit__actions').show();
520
521 var index = $( "#result-list li.distributor__item" ).index( this );
522 var productVariantLanguages = productParent.parentProductVariantLanguages;
523 for(var pvl in productVariantLanguages){
524 var language = productVariantLanguages[pvl];
525 if(language.languageCode == "CAT"){
526 $(this).find('.list-unit__actions .button.button--a').attr('data-name-bitllet', language.shortName);
527 $(this).find('.list-unit__actions .button.button--a').attr('data-code', productWVCode);
528 Analytics.EnhancedEcommerce.addImpression(productWVCode, language.shortName, ++index, 'Catàleg de bitllets');
529 break;
530 }
531 }
532
533 });
534 }
535 }
536
537 },
538 error : function(error) {
539 console.log(error);
540 }
541 });
542 }
543
544 function loadEcommerce() {
545 jQuery.ajax({
546 url : "${domain}/${ecommerceEndpoint}/v2/business-parameters/versions?equipmentCode=${equipmentCode}&app_id=${api_id}&app_key=${api_key}",
547 type : "GET",
548 dataType: "json",
549 success: function(data) {
550 if(data.length > 0){
551 initCompraOnline(data[0].versionCode);
552 }
553 },
554 error : function(error) {
555 console.log(error);
556 }
557 });
558 }
559
560 $(document).ready(function() {
561 Analytics.EnhancedEcommerce.loadEC();
562
563 loadEcommerce();
564 var allCategoriesAvailabes = $('#f__tipus__abonament option[value != "0"]').clone();
565 $('#tipus_abonament_template').append(allCategoriesAvailabes);
566
567 <#if select_filtreOpt?seq_contains("2") || select_filtreOpt?seq_contains("1")>
568 jsonFilterOptions = JSON.parse('${jsonFilterOptions}');
569
570 $('#f__validesa').change(function() {
571 loadResults();
572 });
573
574 $('#f__tipus__abonament').change(function() {
575 $('#f__validesa option[value != "0"]').remove();
576 var optionValue = $(this).val();
577
578 var tipusBitllet = ${select_filtreOpt?seq_contains("1")?string("true", "false")} ? $('input[name=f__radios__1_cbillets]:checked').val() : 0;
579
580 var valOptions;
581
582 if($('#f__tipus__abonament').val() == 0){
583 $('#f__validesa option[value != "0"]').remove();
584 valOptions = jsonFilterOptions[tipusBitllet].categories[0];
585 } else{
586 valOptions = jsonFilterOptions[tipusBitllet].categories[optionValue];
587 }
588
589 if(valOptions){
590 var validesaOptions= $('#validesaTemplate option').clone();
591 validesaOptions = jQuery.grep(validesaOptions, function(n, i) {
592 return jQuery.inArray(n.value, valOptions.validesa) >= 0;
593 });
594 $('#f__validesa').append(validesaOptions);
595 }
596
597 loadResults();
598
599 });
600
601 $('input[type=radio][name=f__radios__1_validesa]').change(function() {
602 $selectedThirdLevel = true;
603
604 $thirdLevelValue = ${select_filtreOpt?seq_contains("2")?string("true", "false")} ? $('input[name=f__radios__1_validesa]:checked').val() : 0;
605 loadResults();
606
607 var bitlletText = $('input[name=f__radios__1_validesa]:checked').parent().text().trim();
608 $('.filter-third-level span').text(bitlletText);
609 $('.filter-third-level').css("display", "flex");
610 });
611
612 $('input[type=radio][name=f__radios__1_categories]').change(function() {
613 $selectedSecondLevel = true;
614
615 var optionValue = $(this).val();
616 var tipusBitllet = ${select_filtreOpt?seq_contains("1")?string("true", "false")} ? $('input[name=f__radios__1_cbillets]:checked').val() : 0;
617 $secondLevelValue = ${select_filtreOpt?seq_contains("2")?string("true", "false")} ? $('input[name=f__radios__1_categories]:checked').val() : 0;
618
619 if(!$selectedThirdLevel) {
620 $('.choose-validesa').css("display", "flex");
621 } else {
622 $thirdLevelValue = '0';
623 $('#f__validesa_inputs li input').first().prop("checked", true).trigger("click");
624 var bitlletText = $('input[name=f__radios__1_validesa]:checked').parent().text().trim();
625 $('.filter-third-level span').text(bitlletText);
626 $('.filter-third-level').css("display", "flex");
627 }
628
629 loadResults();
630
631 var bitlletText = $('input[name=f__radios__1_categories]:checked').parent().text().trim();
632 $('.filter-second-level span').text(bitlletText);
633
634 $('.filter-second-level').css("display", "flex");
635 if($('input[name=f__radios__1_validesa]:checked').length > 0) $('.filter-third-level').show();
636 else $('.filter-third-level').css("display", "none");
637 });
638
639 $('input[type=radio][name=f__radios__1_cbillets]').change(function() {
640 $selectedFirstLevel = true;
641
642 var tipusBitllet = $(this).val();
643 hideOtherFilters = tipusBitllet != "0" ? true : false;
644 $firstLevelValue = $('input[name=f__radios__1_cbillets]:checked').val();
645 var options = jsonFilterOptions[tipusBitllet].categories;
646
647 $('#f__tipus__abonament_inputs li').each(function(n) {
648 if(options.hasOwnProperty($(this).val())) {
649 $(this).show();
650 } else {
651 if($(this).val() != 0) {
652 $(this).hide();
653 }
654 }
655 });
656
657 if(hideOtherFilters) {
658 deleteFilter('0');
659 loadResults();
660 } else if(!$selectedSecondLevel) {
661 $('.choose-category').css("display", "flex");
662 loadResults();
663 } else {
664 $secondLevelValue = '0';
665 $('#f__tipus__abonament_inputs li input').first().prop("checked", true).trigger("click");
666 $('input[type=radio][name=f__radios__1_categories]').change();
667 }
668
669 var bitlletText = $('input[name=f__radios__1_cbillets]:checked').parent().text().trim();
670 $('.filter-first-level span').text(bitlletText);
671 $('.filter-first-level').css("display", "flex");
672 if($('input[name=f__radios__1_categories]:checked').length > 0) $('.filter-second-level').css("display", "flex");
673 else $('.filter-second-level').css("display", "none");
674 if($('input[name=f__radios__1_validesa]:checked').length > 0) $('.filter-third-level').css("display", "flex");
675 else $('.filter-third-level').css("display", "none");
676 $('.filters-bitllets').css("display", "flex");
677 });
678
679 loadResults();
680
681 function loadResults() {
682 var tipusSelected = ${select_filtreOpt?seq_contains("1")?string("true", "false")} ? $firstLevelValue : null;
683 var grupSelected = ${select_filtreOpt?seq_contains("2")?string("true", "false")} ? $secondLevelValue : null;
684 var categorySelected = ${select_filtreOpt?seq_contains("2")?string("true", "false")} ? $thirdLevelValue : null;
685
686 $('#result-list li.distributor__item').hide();
687 $('#result-list li.distributor__item').removeClass('active');
688
689 if (!tipusSelected) {
690 $('#result-list li.distributor__item').addClass('active');
691 //$('#result-list li.distributor__item').hide();
692 } else {
693 $('#result-list li.distributor__item').each(function () {
694 let tipusValue = $(this).attr("data-filter-bitllet");
695 let grupValue = $(this).attr("data-filter-ticket-type");
696 let categoryValue = $(this).attr("data-filter-validity");
697
698 if(!grupSelected) {
699 if (tipusValue.indexOf(tipusSelected) != -1) {
700 $(this).addClass('active');
701 }
702 } else if(!categorySelected) {
703 if (tipusValue.indexOf(tipusSelected) != -1 && grupValue.indexOf(grupSelected) != -1 ) {
704 $(this).addClass('active');
705 }
706 } else {
707 if (tipusValue.indexOf(tipusSelected) != -1 && grupValue.indexOf(grupSelected) != -1 && (categoryValue.indexOf(categorySelected) != -1 || categorySelected == 0)) {
708 $(this).addClass('active');
709 }
710 }
711 });
712 }
713
714 resetPagination();
715
716 $('.distributor__item').is(":visible") ? $('.result-notfound-tickets').hide() : $('.result-notfound-tickets').show();
717 }
718 </#if>
719 <#if optionURL != "">
720 $('#filterButton').trigger('click');
721 <#assign optionURL = "">
722 </#if>
723
724 $('input[name=f__radios__1_cbillets]').first().parent().removeClass('checked');
725
726 $('.filter-first-level').click(function() {
727 deleteFilter('1');
728 loadResults();
729 });
730 $('.filter-second-level').click(function() {
731 deleteFilter('2');
732 loadResults();
733 });
734 $('.filter-third-level').click(function() {
735 deleteFilter('3');
736 loadResults();
737 });
738 $('.delete-all-filters').click(function() {
739 deleteFilter('1');
740 loadResults();
741 });
742
743 selectFiltersFromURL();
744 });
745
746 function selectFiltersFromURL() {
747 const paramsNames = {
748 "type": [
749 'tipus',
750 'tipo',
751 'type'
752 ],
753 "group": [
754 'grup',
755 'grupo',
756 'group'
757 ],
758 "category": [
759 'categoria',
760 'categoria',
761 'category'
762 ]
763 }
764 const params = getURLParameters(window.location.href);
765 const type = params[paramsNames["type"][0]] || params[paramsNames["type"][1]] || params[paramsNames["type"][2]];
766 const group = params[paramsNames["group"][0]] || params[paramsNames["group"][1]] || params[paramsNames["group"][2]];
767 const category = params[paramsNames["category"][0]] || params[paramsNames["category"][1]] || params[paramsNames["category"][2]];
768
769 let previous = selectElement($(".choose-elements.choose-ticket__type ul li label"), type, true);
770 previous = selectElement($(".choose-elements.choose-category ul li label"), group, previous);
771 selectElement($(".choose-elements.choose-validesa ul li label"), category, previous);
772 }
773
774 function selectElement(element, filter, previous) {
775 let selected = false;
776 if(element && filter && previous) {
777 element.each(function( index ) {
778 if(filter.toLowerCase() === $(this).text().trim().toLowerCase()) {
779 $(this).click();
780 $(this).addClass('checked');
781 selected = true;
782 }
783 });
784 }
785 return selected;
786 }
787
788 function getURLParameters(url) {
789 let params = {};
790 let parser = document.createElement('a');
791 parser.href = url;
792
793 let query = parser.search.substring(1); // Remove the leading '?'
794 let vars = query.split('&');
795
796 for (let i = 0; i < vars.length; i++) {
797 let pair = vars[i].split('=');
798 params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
799 }
800
801 return params;
802 }
803
804 function handleKeyDown(event, type) {
805 if (event.key === "Enter") {
806 event.preventDefault();
807 if(type == "sale") {
808 saleMobilitatUrl(event.target);
809 } else {
810 notSaleMobilitatUrl(event.target);
811 }
812 }
813 }
814
815 function notSaleMobilitatUrl(button) {
816 var product = $('#result-list li.distributor__item[data-bitllet-code="' + $(button).attr("data-titol") + '"]');
817 var index = $( "#result-list li.distributor__item" ).index( product );
818 Analytics.EnhancedEcommerce.addProduct($(button).attr("data-code"), $(button).attr("data-name-bitllet"), ++index, 'Catàleg de bitllets');
819
820 Analytics.Ecommerce.eventPurchase.purchase('JOTMBE / Catàleg de bitllets', $(button).attr("data-name-bitllet"));
821 var ecommerceURL = '${ecommerceDomain}/${lang}/${urlCompra}/'+$(button).attr("data-titol") + '';
822 window.location.href = ecommerceURL;
823 }
824
825 function saleMobilitatUrl(button) {
826 var product = $('#result-list li.distributor__item[data-bitllet-code="' + $(button).attr("data-titol") + '"]');
827 var index = $( "#result-list li.distributor__item" ).index( product );
828 Analytics.EnhancedEcommerce.addProduct($(button).attr("data-code"), $(button).attr("data-name-bitllet"), ++index, 'Catàleg de bitllets');
829
830 Analytics.Ecommerce.eventPurchase.purchase('JOTMBE / Catàleg de bitllets', $(button).attr("data-name-bitllet"));
831 var ecommerceURL = '${ecommerceDomain}/${lang}';
832 window.location.href = ecommerceURL;
833 }
834
835 function loadValidesa(){
836 var valOptions;
837
838 if($('#f__tipus__abonament').val() == 0){
839 $('#f__validesa option[value != "0"]').remove();
840 valOptions = {"validesa":["1","2","3","4","5","6","7","8","9","10","11"]};
841 }
842 else{
843 valOptions = jsonFilterOptions[tipusBitllet].categories[optionValue];
844 }
845
846 if(valOptions){
847 var validesaOptions= $('#validesaTemplate option').clone();
848 validesaOptions = jQuery.grep(validesaOptions, function(n, i) {
849 return jQuery.inArray(n.value, valOptions.validesa) >= 0;
850 });
851 $('#f__validesa').append(validesaOptions);
852 }
853
854 loadResults();
855 }
856 function paginate() {
857 TJS.velocity.paginate(${pagination}, '#result-list li.active');
858 if (TJS.eventPagination >= $('#result-list li.active').length) {
859 $('.load-more').hide();
860 }
861 return false;
862 }
863
864 function resetPagination() {
865 TJS.eventPagination = ${pagination};
866 $('#result-list li.active:lt(' + ${pagination} + ')').show();
867 if ($('#result-list li.active').length <= ${pagination}) {
868 $('.load-more').hide();
869 } else {
870 $('.load-more').show();
871 }
872 }
873
874 function deleteFilter(level) {
875 if(level == 0) {
876 $('.filter-second-level').css("display", "none");
877 $('.filter-third-level').css("display", "none");
878
879 $('input[name=f__radios__1_categories]:checked').parent().removeClass('checked');
880 $('input[name=f__radios__1_categories]:checked').prop('checked', false);
881
882 $('input[name=f__radios__1_validesa]:checked').parent().removeClass('checked');
883 $('input[name=f__radios__1_validesa]:checked').prop('checked', false);
884
885 $secondLevelValue = null;
886 $thirdLevelValue = null;
887
888 $selectedSecondLevel = false;
889 $selectedThirdLevel = false;
890
891 $('.choose-category').css("display", "none");
892 $('.choose-validesa').css("display", "none");
893 }
894 if(level == 1) {
895 $('.filter-first-level').css("display", "none");
896 $('.filter-second-level').css("display", "none");
897 $('.filter-third-level').css("display", "none");
898 $('.filters-bitllets').css("display", "none");
899
900 $('input[name=f__radios__1_cbillets]:checked').parent().removeClass('checked');
901 $('input[name=f__radios__1_cbillets]:checked').prop('checked', false);
902
903 $('input[name=f__radios__1_categories]:checked').parent().removeClass('checked');
904 $('input[name=f__radios__1_categories]:checked').prop('checked', false);
905
906 $('input[name=f__radios__1_validesa]:checked').parent().removeClass('checked');
907 $('input[name=f__radios__1_validesa]:checked').prop('checked', false);
908
909 $firstLevelValue = null;
910 $secondLevelValue = null;
911 $thirdLevelValue = null;
912
913 $selectedFirstLevel = false;
914 $selectedSecondLevel = false;
915 $selectedThirdLevel = false;
916
917 $('.choose-category').css("display", "none");
918 $('.choose-validesa').css("display", "none");
919 } else if(level == 2) {
920 $('.filter-second-level').css("display", "none");
921 $('.filter-third-level').css("display", "none");
922
923 $('input[name=f__radios__1_categories]:checked').parent().removeClass('checked');
924 $('input[name=f__radios__1_categories]:checked').prop('checked', false);
925
926 $('input[name=f__radios__1_validesa]:checked').parent().removeClass('checked');
927 $('input[name=f__radios__1_validesa]:checked').prop('checked', false);
928
929 $secondLevelValue = null;
930 $thirdLevelValue = null;
931
932 $selectedSecondLevel = false;
933 $selectedThirdLevel = false;
934
935 $('.choose-validesa').css("display", "none");
936 } else if(level == 3) {
937 $('.filter-third-level').css("display", "none");
938
939 $('input[name=f__radios__1_validesa]:checked').parent().removeClass('checked');
940 $('input[name=f__radios__1_validesa]:checked').prop('checked', false);
941
942 $thirdLevelValue = null;
943
944 $selectedThirdLevel = false;
945 }
946 };
947
948</script>
Other tickets to visit Barcelona
We take you to discover the city and its surroundings in our tourist transports.
-
Barcelona Bus Turístic
Visit the most emblematic sites, monuments and attractions of Barcelona on the official tourist bus. -
Catalunya Bus Turístic
Guided excursions to get closer to Montserrat, learn about Dalí's art, experience the city of Girona or do the best shopping. -
Telefèric de Montjuïc
Climb the Montjuïc mountain through 750 meters of air travel while you contemplate the whole city.
You may be also interested in
All the information you need about tickets to travel by public transport in Barcelona and its metropolitan area.
-
Price reduction on fares
Learn about reductions for transport ticket prices and decide which ticket is best for you. -
T-mobilitat
Get around intelligently by public transport. -
Map of zones
The geographic area of the Integrated Fare System of the area of Barcelona includes 296 municipalities distributed in zones. -
Terms and conditions of ticket use
Guide of ticket use to travel on the Barcelona metro and bus. -
Points of sale
Where can you buy public transport tickets? -
Purchase tickets online
You can purchase tickets and travel cards quickly and conveniently through the website or TMB App. -
Validation with bank card
Purchase and validate your single bus ticket in one simple step with your bank card.
Discover the city with the Hola Barcelona app
Download Hola Barcelona and find the best routes, discover the places that interest you most, buy conveniently and store tickets for getting around the city. What are you waiting for?
Close
© OpenStreetMap contributors