The following has evaluated to null or missing: ==> serviceLocator.findService("com.bosch.autoparts.product.nav.service.BapProductNavService") [in template "20097#20123#649649" at line 1, column 33] ---- Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign BapProductNavService = servic... [in template "20097#20123#649649" at line 1, column 1] ----
1<#assign BapProductNavService = serviceLocator.findService("com.bosch.autoparts.product.nav.service.BapProductNavService")>
2<#assign countryCode = locale.getCountry()?lower_case>
3<#if countryCode == "mx">
4<#assign listAssetCategory = BapProductNavService.getNavigationCategory(themeDisplay, "product categories mx")>
5<#else>
6<#assign listAssetCategory = BapProductNavService.getNavigationCategory(themeDisplay, "product categories")>
7</#if>
8<#assign siteUrl = themeDisplay.getScopeGroup().getFriendlyURL()>
9<#assign pageURL = themeDisplay.getLayout().getFriendlyURL()>
10<#assign categoryBaseUrl = propsUtil.get("category-page-base-url")>
11<#assign productsPageUrl = propsUtil.get("products-page-url-"+themeDisplay.getLanguageId())>
12
13<div id="bap-navigation" role="navigation">
14 <#if entries?has_content>
15 <div id="main-nav-container">
16 <div id="parent-nav-container" class="container">
17
18 <div class="navbar-expand-md navbar-light ">
19 <div class="navbar-toggler-container">
20 <button class="navbar-toggler" id="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
21 <i class="bap-icon bap-list-view-mobile"> </i>
22 </button>
23
24 <button type="button" id="close" class="close" aria-label="Close">
25 <i class="bap-icon bap-close" aria-hidden="true"> </i>
26 </button>
27 </div>
28 <a
29 href="${themeDisplay.getPortalURL()}"
30 class="auto-parts"
31 >
32 <@liferay.language key="label-auto-parts" />
33 </a>
34 </div>
35 <div class="border-bottom-mob" id="nav-mob-line" style="display:none" ></div>
36
37 <ul class="nav nav-tabs d-none d-lg-block" id="myTab" role="list">
38 <li class="nav-item" onClick="openSecondLevel()">
39 <a
40 class="nav-link"
41 id="products-tab"
42 data-toggle="tab"
43 href="#bap-products"
44 >
45 <span><@liferay.language key="label-products" /></span>
46 <i class="bap-icon bap-right"> </i>
47 </a>
48 </li>
49
50 <#list entries as entry>
51 <#if entry.hasChildren()>
52 <li class="nav-item" onClick="openSecondLevel()">
53 <a
54 class="nav-link"
55 id="${entry.getName()?replace(' ', '')?lower_case}-tab"
56 data-toggle="tab"
57 href="#${entry.getName()?replace(' ', '')?lower_case}"
58 >
59
60 <span>${entry.getName()}</span>
61 <i class="bap-icon bap-right"> </i>
62 </a>
63 </li>
64 <#else>
65 <#assign
66 active_class = ""
67 />
68
69 <#if pageURL?replace('/', '')?lower_case == entry.getName()?lower_case >
70 <#assign
71 active_class = "active"
72 />
73 </#if>
74
75 <li class="nav-item">
76 <a
77 class="nav-link ${active_class}"
78 ${entry.getTarget()}
79 id="${entry.getName()?replace(' ', '')?lower_case}-tab"
80 href="${entry.getURL()}"
81 >${entry.getName()}</a>
82 </li>
83 </#if>
84 </#list>
85 <li class="auto-parts-lg">
86 <a
87 href="${themeDisplay.getPortalURL()}"
88 class="auto-parts"
89 >
90 <@liferay.language key="label-auto-parts" />
91 </a>
92 </li>
93 </ul>
94 </div>
95 </div>
96 </#if>
97 <div id="child-nav-container" class="container">
98 <div class="tab-content">
99 <#if entries?has_content>
100
101 <#list entries as entry>
102 <div class="tab-pane fade" id="${entry.getName()?replace(' ', '')?lower_case}" role="tabpanel" aria-labelledby="${entry.getName()?replace(' ', '')?lower_case}">
103 <#list entry.getChildren()?chunk(4) as row>
104 <div class="row col-md-12">
105 <#list row as page>
106 <div class="col-md-3">
107 <#if page.hasChildren()>
108 <a id="${page.getName()?replace(' ', '')?lower_case}-tab"
109 href="#${page.getName()?replace(' ', '')?lower_case}-pane"
110 data-toggle="tab"
111 >
112 <span>${page.getName()}</span>
113 <i class="bap-icon bap-right"> </i>
114 </a>
115 <#else>
116 <a
117 id="${page.getName()?replace(' ', '')?lower_case}-tab" ${page.getTarget()}
118 href="${page.getURL()}"
119 >${page.getName()}</a>
120 </#if>
121 </div>
122 </#list>
123 </div>
124 </#list>
125 </div>
126 </#list>
127
128 <#list entries as entry>
129 <#list entry.getChildren() as child>
130 <div class="tab-pane fade" id="${child.getName()?replace(' ', '')?lower_case}-pane" role="tabpanel" aria-labelledby="${child.getName()?replace(' ', '')?lower_case}">
131 <div class="row col-md-12">
132 <div class="col-md-3">
133 <a href="#${entry.getName()?replace(' ', '')?lower_case}"
134 data-toggle="tab"
135 >${child.getName()}</a>
136 </div>
137 </div>
138 <#list child.getChildren()?chunk(4) as row>
139 <div class="row col-md-12">
140 <#list row as grandchild>
141 <div class="col-md-3">
142 <a href="${grandchild.getURL()}" ${grandchild.getTarget()}>${grandchild.getName()}</a>
143 </div>
144 </#list>
145 </div>
146 </#list>
147 </div>
148 </#list>
149 </#list>
150
151 </#if>
152
153 <#-- TOP LEVEL PRODUCT NAV -->
154
155 <div class="tab-pane fade" id="bap-products" role="tabpanel" aria-labelledby="products">
156 <div class="row">
157 <div class="col-md-12 back-icon-mobile">
158 <a id="back-close">
159 <i class="bap-icon bap-arrow-left"> </i>
160 </a>
161 </div>
162 <#list listAssetCategory as assetCategory>
163 <#if assetCategory.getParentCategoryId() == 0 >
164 <div class="col-md-3">
165 <#if assetCategory.isLeafNode()>
166 <a href="${categoryBaseUrl}${assetCategory.getUrl()}"
167 >${assetCategory.getName()}</a>
168 <#else>
169 <a href="#${assetCategory.getName()?replace(' ', '')?lower_case}-pane"
170 data-toggle="tab"
171 >
172 <span>${assetCategory.getName()}</span>
173 <i class="bap-icon bap-right"> </i>
174 </a>
175 </#if>
176
177 </div>
178 </#if>
179 </#list>
180 <div class="col-md-12 view-all-link">
181 <a class="catalog-url" href="${productsPageUrl}">
182 <span><@liferay.language key="label-view-all" /></span> <i class="bap-icon bap-right"> </i>
183 </a>
184 </div>
185 </div>
186 </div>
187
188 <#-- SECONDARY LEVEL PRODUCT NAV -->
189
190 <#list listAssetCategory as assetCategory>
191 <#if assetCategory.getParentCategoryId() == 0 >
192 <div class="tab-pane fade" id="${assetCategory.getName()?replace(' ', '')?lower_case}-pane" role="tabpanel" aria-labelledby="${assetCategory.getName()?replace(' ', '')?lower_case}">
193 <div class="row">
194 <div class="back-icon">
195 <a class="tertiary-back-arrow"
196 href="#bap-products"
197 data-toggle="tab"
198 > <i class="bap-icon bap-left"> </i> </a>
199 <a class="tertiary-back-data"
200 href="${categoryBaseUrl}${assetCategory.getUrl()}"
201 > ${assetCategory.getName()}</a>
202 </div>
203 </div>
204 <div class="back-icon-mobile">
205 <div class="row">
206 <a
207 href="#bap-products"
208 data-toggle="tab"
209 >
210 <i class="bap-icon bap-arrow-left"> </i>
211 </a>
212 <a class="tertiary-back-data"
213 href="${categoryBaseUrl}${assetCategory.getUrl()}"
214 > ${assetCategory.getName()}</a>
215 </div>
216 </div>
217 <div class="row">
218 <#list listAssetCategory as childAssetCategory>
219 <#if childAssetCategory.getParentCategoryId() == assetCategory.getCategoryId() >
220 <div class="col-md-3">
221 <a href="${categoryBaseUrl}${childAssetCategory.getUrl()}">${childAssetCategory.getName()}</a>
222 </div>
223 </#if>
224 </#list>
225 </div>
226 </div>
227 </#if>
228 </#list>
229 </div>
230 </div>
231</div>
232
233<script>
234 $(function() {
235 $('.tab-pane a').on('click', function(){
236 $('.tab-pane a').removeClass('active');
237 });
238
239
240 $('#navbar-toggler').on('click', function(){
241 handleHamburgerButton();
242 });
243
244
245 $('.nav-item').on('click', function(){
246 if ( $('#myTab').css('display') == 'none' || $('#myTab').css("visibility") == "hidden"){
247 $('#myTab').removeClass("d-none d-lg-block");
248 }else{
249 $('#myTab').addClass("d-none d-lg-block");
250 }
251
252 $('.tab-content').show();
253 $('#navbar-toggler').hide();
254 $('#close').show();
255 $("#nav-mob-line").hide();
256
257 //Priti
258 if($('#bap-products.active').length > 0){
259 $("#main-nav-container").removeClass("bottom-border");
260 }
261 else{
262 $("#main-nav-container").addClass("bottom-border");
263 }
264 });
265
266
267 $('#close').on('click', function(){
268 handleCloseButton();
269 });
270
271 $('#back-close').on('click', function(){
272 handleBackButton();
273 });
274
275 $('#bap-navigation a').on('click', function() {
276 if (window.matchMedia('screen and (max-width: 768px)').matches) {
277 $(window).scrollTop($('#bap-navigation').offset().top - 50);
278 }
279 });
280 });
281
282 function handleHamburgerButton(){
283 if ( $('#myTab').css('display') == 'none' || $('#myTab').css("visibility") == "hidden"){
284 $('#myTab').removeClass("d-none d-lg-block");
285 $("#nav-mob-line").show();
286 }else{
287 $('#myTab').addClass("d-none d-lg-block");
288 $("#nav-mob-line").hide();
289 }
290 $('.tab-content').hide();
291 }
292
293 function handleCloseButton(){
294 if($(window).width() < 767){
295 $('.nav-link.active').removeClass("active");
296 $('.tab-pane.fade.active.show').removeClass("active show");
297 $('#navbar-toggler').show();
298 $('#close').hide();
299 $("#main-nav-container").removeClass("bottom-border");
300 }
301 }
302
303 function handleBackButton(){
304 if($(window).width() < 767){
305 $('.nav-link.active').removeClass("active");
306 $('.tab-pane.fade.active.show').removeClass("active show");
307 $('#myTab').removeClass("d-none d-md-block");
308 $('#navbar-toggler').show();
309 $('#close').hide();
310 $("#nav-mob-line").show();
311 $("#main-nav-container").removeClass("bottom-border");
312 }
313 }
314
315 function openSecondLevel(){
316 $('#navbar-toggler').hide();
317 $('#close').show();
318 }
319
320 $(document).on('click', '#bap-navigation .nav-link.active', function() {
321 var href = $(this).attr('href').substring(1);
322 $(this).toggleClass('active');
323 $('.tab-pane[id="' + href + '"]').removeClass('active');
324 $(".tab-content").find(".tab-pane.fade.active").removeClass('active');
325 if($(window).width() > 767){
326 $("#main-nav-container").removeClass("bottom-border");
327 }
328 });
329
330 $(document).mouseup(function(e)
331 {
332 var parentNavContainer = $("#parent-nav-container");
333 var childNavContainer = $("#child-nav-container");
334
335 if (!parentNavContainer.is(e.target) && parentNavContainer.has(e.target).length === 0
336 && !childNavContainer.is(e.target) && childNavContainer.has(e.target).length === 0
337 )
338 {
339 $("#products-tab").removeClass('active');
340 $("#main-nav-container").removeClass("bottom-border");
341 $('#myTab').addClass("d-none d-lg-block");
342 $("#nav-mob-line").hide();
343 $("#bap-navigation .tab-content").find(".tab-pane.fade.active").removeClass('active');
344 }
345 });
346
347</script>
Note: WIP - We are using hard-coded values for now.