An error occurred while processing the template.
The following has evaluated to null or missing:
==> cpCatalogEntry [in template "49724393377863#35335#234150" at line 55, column 26]
----
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: cpDefinitionId = cpCatalogEntry.getCP... [in template "49724393377863#35335#234150" at line 55, column 9]
----
1<#assign
2 defaultImgMap = {
3 "Default": {
4 "image": "/documents/d/guest/default_logo.png",
5 "color": "gray"
6 },
7 "Livestream": {
8 "image": "/documents/d/guest/icon-desktop-svg",
9 "color": "purple"
10 },
11 "Recorded":{
12 "image": "/documents/d/guest/icon-play",
13 "color": "red"
14 },
15 "In Person":{
16 "image": "/documents/d/guest/icon-persons",
17 "color": "green"
18 },
19 "Download": {
20 "image": "/documents/d/guest/icon-download-black",
21 "color": "border-color"
22 },
23 "Self-paced": {
24 "image": "/documents/d/guest/icon-mouse-white",
25 "color": "black"
26 },
27 "Bank subscription": {
28 "image": "/documents/d/guest/icon-bank",
29 "color": "blue"
30 }
31 }
32/>
33
34<!--Parent Assignment-->
35<#setting url_escaping_charset='UTF-8'>
36<#assign
37 commerceContext = renderRequest.getAttribute("COMMERCE_CONTEXT")
38 account = commerceContext.getAccountEntry()
39 accountId = account.getAccountEntryId()
40 chanelId = commerceContext.getCommerceChannelId()
41
42 attendenceWebinarStructuredContentId = 1087266
43 attendenceSeminarStructuredContentId = 237233
44 cpeWebinarStructuredContentId = 237244
45 cpeSeminarStructuredContentId = 1087351
46 cpePersonStructuredContentId = 1087403
47 cocStructuredContentId = 237255
48 policyStructuredContentId = 237266
49 recordingStructuredContentId = 1087301
50 videoStructuredContentId = 1087312
51 nasbaStructuredContentId = 1087327
52/>
53
54<#assign
55 cpDefinitionId = cpCatalogEntry.getCPDefinitionId()
56 productId = cpCatalogEntry.getCProductId()
57 productName = cpCatalogEntry.getName()
58 productShortDescription = cpCatalogEntry.getShortDescription()
59 productDescription = cpCatalogEntry.getDescription()
60 friendlyURL = cpContentHelper.getFriendlyURL(cpCatalogEntry, themeDisplay)
61 defaultImageURL = cpContentHelper.getDefaultImageFileURL(accountId, cpDefinitionId)
62 defaultImageFileVersion = cpContentHelper.getCPDefinitionImageFileVersion(cpDefinitionId, request)
63 productDetail = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${chanelId}/products/${productId}?accountId=${accountId}&nestedFields=categories,productSpecifications")
64 defaultImageURL = productDetail.urlImage?replace('https://localhost', '')
65 fileEntryIdAttr = 'data-fileentryid="' + defaultImageFileVersion.fileEntryId + '"'
66 specifications = productDetail.productSpecifications
67 customFields = productDetail.customFields
68 productCategories = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${chanelId}/products/${productId}/categories?pageSize=100")
69 categories = productCategories.items
70 extRefCode = productDetail.externalReferenceCode
71 filterValue = extRefCode?url
72 url = "/c/agendas/?fields=informationRawText,information,startTime,endTime&filter=r_productAgendaItem_CPDefinitionERC%20eq%20%27${filterValue}%27&sort=startTime"
73 agendaData = restClient.get(url)
74 productsku= restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${chanelId}/products/${productId}/skus?pageSize=40")
75 productOptions= restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${chanelId}/products/${productId}/product-options?pageSize=40")
76
77 attendenceWebinar= restClient.get("/headless-delivery/v1.0/structured-contents/${attendenceWebinarStructuredContentId}")
78 attendenceSeminar= restClient.get("/headless-delivery/v1.0/structured-contents/${attendenceSeminarStructuredContentId}")
79 cpeWebinar= restClient.get("/headless-delivery/v1.0/structured-contents/${cpeWebinarStructuredContentId}")
80 cpeSeminar= restClient.get("/headless-delivery/v1.0/structured-contents/${cpeSeminarStructuredContentId}")
81 cpePerson= restClient.get("/headless-delivery/v1.0/structured-contents/${cpePersonStructuredContentId}")
82 coc= restClient.get("/headless-delivery/v1.0/structured-contents/${cocStructuredContentId}")
83 policy= restClient.get("/headless-delivery/v1.0/structured-contents/${policyStructuredContentId}")
84 recording= restClient.get("/headless-delivery/v1.0/structured-contents/${recordingStructuredContentId}")
85 video= restClient.get("/headless-delivery/v1.0/structured-contents/${videoStructuredContentId}")
86 nasba= restClient.get("/headless-delivery/v1.0/structured-contents/${nasbaStructuredContentId}")
87
88 filter = "productId eq ${productId}"
89 encodedFilter = filter?url
90 contentMappingURL = "/c/productcontentlinks/?filter=" + encodedFilter
91 contentMapping = restClient.get(contentMappingURL)
92 infoObj = {}
93 tags = productDetail.tags
94 featuredSpecificationKeys = ["fit", "weight", "material"]
95 eventTypeName = ""
96 startDate = ""
97 startTime = ""
98 endDate = ""
99 endTime = ""
100 deliverymethodArray = [{"id": "", "value": ""}]
101 audiencemethodArray = [{"id": "", "value": ""}]
102 nasbadeliverymethodArray = [{"id": "", "value": ""}]
103 locationAddress = ""
104 hasSkus = "false"
105/>
106
107<!-- SKU Area -->
108 <#assign priceFormatted = ""/>
109 <#assign displayMapValue = {} />
110 <#assign displayMapName = {} />
111 <#assign defaultSKUKey = ''/>
112 <#assign dropdownKeys = ["nonmember:live","nonmember:ondemand","nonmember:live-ondemand"] />
113 <#assign memberdropdownKeys = ["icba-member:live","icba-member:ondemand","icba-member:live-ondemand"] />
114 <#assign tableColumnNames = [] />
115 <#assign tableRowNames = [] />
116 <#assign numberOfOptions = 0 />
117 <#assign priceList = [] />
118
119 <!-- Create Option Map for multiple option products-->
120<#assign productOptionMap = {"unlimited-webinar-pass:live": "",
121"unlimited-webinar-pass:ondemand": "",
122"unlimited-webinar-pass:live-ondemand": "",
123"nonmember:live": "",
124"nonmember:ondemand": "",
125"nonmember:live-ondemand": "",
126"icba-member:live": "",
127"icba-member:ondemand": "",
128"icba-member:live-ondemand": "",
129"bank-director-program-subscriber:live": "",
130"bank-director-program-subscriber:ondemand": "",
131"bank-director-program-subscriber:live-ondemand": "",
132"icba-bank-director-program-subscriber:live": "",
133"icba-bank-director-program-subscriber:ondemand": "",
134"icba-bank-director-program-subscriber:live-ondemand": ""} />
135
136<!-- Create Option Map for single Option products-->
137<#assign productOptionMapSingle = {"unlimited-webinar-pass": "",
138"nonmember": "",
139"icba-member": "",
140"bank-director-program-subscriber": "",
141"icba-bank-director-program-subscriber": "",
142"nonbanker": ""} />
143
144<#assign productskuJson = jsonFactoryUtil.createJSONObject(productsku)/>
145 <#if productskuJson?has_content && productskuJson.has("items")>
146 <#assign itemsArray = productskuJson.getJSONArray("items")/>
147<#if itemsArray?has_content && itemsArray.length() gt 0>
148 <#assign hasSkus = "true">
149 <#list 0..itemsArray.length() - 1 as index>
150 <#if itemsArray.getJSONObject(index)?has_content>
151 <#assign item = itemsArray.getJSONObject(index) />
152 <#assign price = item.price.priceFormatted>
153 <#assign ccustomFields = item.getJSONArray("customFields") />
154 <#assign urlValue = ""/>
155 <#if ccustomFields?has_content>
156 <#list 0..ccustomFields.length() - 1 as j>
157 <#assign ccustomField = ccustomFields.getJSONObject(j) />
158 <#assign urlValue = ccustomField.getJSONObject("customValue").getString("data")/>
159 </#list>
160 </#if>
161 <#assign skuOptions = item.getJSONArray("skuOptions") />
162 <#if skuOptions?has_content>
163 <#assign nameKey = "" />
164 <#assign numberOfOptions = skuOptions.length() />
165 <#if skuOptions.length() != 1 >
166 <!-- Handle Product with Multiple Options to create matrix table -->
167 <#list 0..skuOptions.length() - 1 as i>
168 <#assign skuOption = skuOptions.getJSONObject(i) />
169 <#assign skuOptionKey = skuOption.getString("skuOptionKey") />
170 <#if skuOptionKey == "registration-options">
171 <#assign skuOptionValueKey = skuOption.skuOptionValueKey />
172 <#list 0..skuOptions.length() - 1 as j>
173 <#assign subskuOption = skuOptions.getJSONObject(j) />
174 <#assign subskuOptionKey = subskuOption.skuOptionKey />
175 <#if subskuOptionKey != skuOptionKey>
176 <#assign displayName = subskuOption.skuOptionValueNames?remove_beginning('["')?remove_ending('"]') />
177 <#assign rowdisplayName = skuOption.skuOptionValueNames?remove_beginning('["')?remove_ending('"]') />
178 <#if !tableRowNames?seq_contains(rowdisplayName) >
179 <#assign tableRowNames = tableRowNames + [rowdisplayName] />
180 </#if>
181 <#if !tableColumnNames?seq_contains(displayName) >
182 <#assign tableColumnNames = tableColumnNames + [displayName] />
183 </#if>
184 <#assign priceList = priceList + [price] />
185 <#assign skukey = skuOptionValueKey + ":" + subskuOption.skuOptionValueKey />
186 <#assign productOptionMap = productOptionMap + { skukey: price }>
187 <#assign displayName = subskuOption.skuOptionValueNames?remove_beginning('["')?remove_ending('"]') />
188 <#assign displayMapValue += {skukey:urlValue} />
189 <#assign displayMapName += {skukey:displayName} />
190 <#assign defaultSKUKey = skukey/>
191 </#if>
192 </#list>
193
194 </#if>
195 </#list>
196 <!-- Handle products with a single SKU -->
197 <#else>
198 <#if !tableColumnNames?seq_contains("Price") >
199 <#assign tableColumnNames = tableColumnNames + ["Price"] />
200 </#if>
201 <#list 0..skuOptions.length() - 1 as i>
202 <#assign skuOption = skuOptions.getJSONObject(i) />
203 <#assign skuOptionKey = skuOption.getString("skuOptionKey") />
204 <#assign skuOptionValueKey = skuOption.skuOptionValueKey />
205 <#assign rowdisplayName = skuOption.skuOptionValueNames?remove_beginning('["')?remove_ending('"]') />
206 <#if !tableRowNames?seq_contains(rowdisplayName) >
207 <#assign tableRowNames = tableRowNames + [rowdisplayName] />
208 </#if>
209 <#assign priceList = priceList + [price] />
210 <#assign skukey = skuOptionValueKey />
211 <#assign displayMapValue += {skukey:urlValue} />
212 <#assign displayMapName += {skukey:rowdisplayName} />
213 <#assign defaultSKUKey = skukey/>
214 <#assign productOptionMapSingle = productOptionMapSingle + { skukey: price }>
215 </#list>
216 </#if>
217 </#if>
218 </#if>
219 </#list>
220 </#if>
221</#if>
222
223<!-- Category area-->
224<#assign isInstitute = "false" />
225<#assign isSeminar = "false" />
226<#assign isForum = "false" />
227<#assign isLivestream = "false" />
228<#assign isOnlineCourse = "false" />
229<#assign isInPerson = "false" />
230<!-- Predefine all needed variables so they persist across scopes -->
231<#assign start = "", end = "", startDateStr = "", endDateStr = "", startTime = "", endTime = "", year = "", dateDisplay = "", timeDisplay = "", locationDisplay = "" />
232<#assign isWebinar = "false" />
233<#assign isEvent = "false" />
234<#assign isPerson = "false" />
235<#assign isPriceTypeFree = "false" />
236<#assign isPriceTypeSubs = "false" />
237<#assign isPriceTypeMB = "false" />
238
239
240<!-- Ends -->
241<#if categories?has_content>
242 <#list categories as category>
243 <#if category.vocabulary?replace(' ', '') = 'deliverymethod'>
244 <#assign deliverymethodArray += [{"id": category.id, "value": category.name}] />
245 <#elseif category.vocabulary?replace(' ', '') = 'icbaaudience'>
246 <#assign audiencemethodArray += [{"id": category.id, "value": category.name}] />
247 <#elseif category.vocabulary?replace(' ', '') = 'nasbadeliverymethod'>
248 <#assign nasbadeliverymethodArray += [{"id": category.id, "value": category.name}] />
249 <#else>
250 <#assign infoObj = infoObj + {category.vocabulary?replace(' ', ''): {"id": category.id, "value": category.name}} />
251 </#if>
252 </#list>
253 <#assign infoObj = infoObj + {"deliverymethod": deliverymethodArray} />
254 <#assign infoObj = infoObj + {"icbaaudience": audiencemethodArray} />
255 <#assign infoObj = infoObj + {"nasbadeliverymethod": nasbadeliverymethodArray} />
256</#if>
257
258<#list customFields as customField>
259 <!-- ${customField.name} -->
260 <#assign infoObj = infoObj + {(customField.name): customField.customValue.data} />
261</#list>
262
263<#if categories?has_content>
264 <#list categories as category>
265 <#if category.vocabulary = 'price type' && category.name == "Free">
266 <#assign isPriceTypeFree = "true" />
267 </#if>
268 <#if category.vocabulary = 'price type' && category.name == "Subscription">
269 <#assign isPriceTypeSubs = "true" />
270 </#if>
271 <#if category.vocabulary = 'price type' && category.name == "Member Benefit">
272 <#assign isPriceTypeMB = "true" />
273 </#if>
274 <#if category.vocabulary = 'delivery method' && category.name = 'In Person'>
275 <#assign isInPerson = "true" />
276 </#if>
277 <#if category.vocabulary = 'delivery method' && category.name = 'Livestream'>
278 <#if infoObj["Event End Date"]?has_content>
279 <#assign end = infoObj["Event End Date"]?datetime("yyyy-MM-dd'T'HH:mm:ss'Z'") />
280 <#assign today = .now?datetime> <!-- Today's date without time -->
281 <#assign showLiveStream = end < today />
282 <!-- Ensure 'end' is valid before performing the comparison -->
283 <#if !showLiveStream>
284 <#assign isLivestream = "true" />
285 </#if>
286 </#if>
287 </#if>
288 <#if category.vocabulary = 'event type' && category.name = 'Institute'>
289 <#assign isInstitute = "true" />
290 </#if>
291
292 <#if category.vocabulary = 'event type' && category.name = 'Seminar'>
293 <#assign isSeminar = "true" />
294 </#if>
295 <#if category.vocabulary = 'product type' && category.name = 'Webinar'>
296 <#assign isWebinar = "true" />
297 </#if>
298 <#if category.vocabulary = 'product type' && category.name = "Online Course">
299 <#assign isOnlineCourse = "true" />
300 </#if>
301 <#if category.vocabulary = 'product type' && category.name == "Event">
302 <#assign isEvent = "true" />
303 </#if>
304 <#if category.vocabulary = 'event type'>
305 <#assign eventTypeName = category.name />
306 </#if>
307 </#list>
308</#if>
309
310
311<div class="education-details-sec">
312 <div class="product-main-info">
313 <div class="top-row">
314
315 <#if infoObj.deliverymethod??>
316 <div class="education-card-categories">
317
318 <#assign seenFormats = []>
319
320 <#list infoObj.deliverymethod as format>
321
322 <#if format.value != "" && !seenFormats?seq_contains(format.value)>
323
324 <#if format.value == "Livestream">
325 <#if isLivestream == "true">
326 <span class="category">
327 <img src="${defaultImgMap[format.value]['image']}" alt="" class="category-img bg-${defaultImgMap[format.value]['color']}" />
328 <span class="category-name">${format.value}</span>
329 </span>
330
331 <#assign seenFormats = seenFormats + [format.value]>
332 </#if>
333 <#else>
334 <span class="category">
335 <img src="${defaultImgMap[format.value]['image']}" alt="" class="category-img bg-${defaultImgMap[format.value]['color']}" />
336 <span class="category-name">${format.value}</span>
337 </span>
338
339 <#assign seenFormats = seenFormats + [format.value]>
340 </#if>
341
342 </#if>
343 </#list>
344 </div>
345</#if>
346 <!-- Only display certificate if -->
347 <#if isInstitute == "true">
348 <div class="certification-info">
349 <span class="certification-info-text">Earn Professional Certification</span>
350 <div class="certification-info-img"><i class="certification-info-img"></i></div>
351 </div>
352 </#if>
353 </div>
354 <h1 class="product-title product-title-name header-xl">${productName}</h1>
355 <#if infoObj.deliverymethod??>
356 <#list infoObj.deliverymethod as format>
357 <#if format.value != "">
358 <#if format.value == "In Person">
359 <#assign isPerson = "true"/>
360 </#if>
361 </#if>
362 </#list>
363 </#if>
364 <#if isOnlineCourse == "true" || isWebinar == "true" || isPerson == "true" || isEvent == "true">
365 <div class="meta-info">
366 <#-- Parse date and time -->
367 <#if infoObj["Event Start Date"]?has_content>
368
369
370
371
372
373 <#assign start = infoObj["Event Start Date"]?datetime("yyyy-MM-dd'T'HH:mm:ss'Z'")/>
374 <#assign startDateStr = start?string("MMM d")/>
375 <#assign year = start?string("yyyy")/>
376 <#assign startTime = start?string("h:mm") + " " + start?string("a")?lower_case/>
377 </#if>
378
379 <#if infoObj["Event End Date"]?has_content>
380 <#assign end = infoObj["Event End Date"]?datetime("yyyy-MM-dd'T'HH:mm:ss'Z'")/>
381 <#assign endDateStr = end?string("MMM d")/>
382 <#assign endTime = end?string("h:mm") + " " + end?string("a")?lower_case/>
383 </#if>
384 <ul>
385 <#if isWebinar == "true" || isEvent == "true">
386 <#if isLivestream == "true" || isPerson == "true">
387 <#if start?has_content && end?has_content>
388 <#if start?string("yyyyMMdd") == end?string("yyyyMMdd")>
389 <#assign dateDisplay = startDateStr + ", " + year/>
390 <#assign timeDisplay = startTime + "–" + endTime/>
391 <#else>
392 <#assign dateDisplay = startDateStr + "–" + endDateStr + ", " + year/>
393 <#assign timeDisplay = startTime/>
394 </#if>
395
396 </#if>
397 <li>${dateDisplay}</li>
398 <#if isWebinar == "true">
399 <li> | </li>
400 <li>${timeDisplay} <#if infoObj["Time Zone"]?? && infoObj["Time Zone"]?has_content>${infoObj["Time Zone"]?first}</#if></li>
401 </#if>
402 <li> | </li>
403 </#if>
404
405 </#if>
406 <#if isInPerson = "true">
407 <#if infoObj["Location City"]?has_content || infoObj["Location State"]?has_content>
408 <li>
409 </#if>
410 <#if infoObj["Location City"]?has_content>${infoObj["Location City"]}</#if>
411 <#if infoObj["Location State"]?has_content>, ${infoObj["Location State"]}</#if>
412 <#if infoObj["Location City"]?has_content || infoObj["Location State"]?has_content>
413 </li>
414 <li> | </li>
415 </#if>
416 </#if>
417 <#if isWebinar == "true">
418
419 <li class="fw-700">Webinar</li>
420 </#if>
421 <#if isOnlineCourse == "true">
422 <li class="fw-700">Online Course</li>
423 </#if>
424 <#if isEvent = "true">
425 <li class="fw-700">${eventTypeName}</li>
426 </#if>
427 <#if infoObj["CPE Credits"]?has_content>
428
429
430
431<#assign hasRecorded = false>
432<#assign hasLivestream = false>
433
434<#if infoObj.deliverymethod??>
435 <#list infoObj.deliverymethod as format>
436 <#if format.value == "Recorded">
437 <#assign hasRecorded = true>
438 </#if>
439 <#if format.value == "Livestream">
440 <#assign hasLivestream = true>
441 </#if>
442 </#list>
443</#if>
444
445
446<#if !hasRecorded || hasLivestream>
447<li> | </li>
448 <li class="credits-info">
449 <div class="education-card-credits">
450 CPE Credits: ${infoObj["CPE Credits"]}
451 </div>
452 </li>
453</#if>
454 </#if>
455 </ul>
456 </div>
457 </#if>
458
459 <div class="product-summary" aria-hidden="true">
460 ${productDescription}
461 </div>
462 <#if productDescription?has_content>
463 <a href="#" class="btn btn-link read-more-btn">Read More</a>
464 </#if>
465
466<!-- Populate Learning Format Dropdown if Webinar with Multiple Options -->
467
468<#assign labelMapping = {
469 "Live": "Livestream",
470 "On-demand": "Recorded",
471 "Live + On-demand": "Livestream + Recorded"
472}>
473
474<#if displayMapValue?has_content && dropdownKeys?? && numberOfOptions gt 1 >
475 <#if isWebinar == "true" && !infoObj["Alternate URL"]?has_content>
476 <div class="product-delivery-wrapper">
477 <label for="delivery-method" class="label">Learning Format</label>
478 <select class="form-control" id="delivery-method">
479 <option value="">Select Learning Format</option>
480
481 <#if tableRowNames?seq_contains("ICBA Member")>
482 <#list memberdropdownKeys as k>
483 <#if displayMapValue[k]?? && displayMapName[k]??>
484
485 <#assign originalLabel = displayMapName[k]>
486 <#assign newLabel = labelMapping[originalLabel]!originalLabel>
487
488 <option value="${displayMapValue[k]}">${newLabel}</option>
489 </#if>
490 </#list>
491 <#elseif tableRowNames?seq_contains("Non-Member")>
492 <#list dropdownKeys as k>
493 <#if displayMapValue[k]?? && displayMapName[k]??>
494
495 <#assign originalLabel = displayMapName[k]>
496 <#assign newLabel = labelMapping[originalLabel]!originalLabel>
497
498 <option value="${displayMapValue[k]}">${newLabel}</option>
499 </#if>
500 </#list>
501 </#if>
502 </select>
503 </div>
504 </#if>
505</#if>
506 <div class="product-delivery-ctas">
507 <#if hasSkus == "true">
508 <!-- Check if Alt Reg Button text is set -->
509 <#if !infoObj["Alternate Text"]?has_content>
510 <#if isWebinar == "true" || isEvent == "true">
511 <button id="productRegistrationBtn" class="btn btn-lg btn-primary btn-arrow-right w-100" onclick="navigateToRegistration()">Register Now</button>
512 <#elseif isPriceTypeSubs == "true">
513 <button id="productRegistrationBtn" class="btn btn-lg btn-primary btn-arrow-right w-100" onclick="navigateToRegistration()">Subscribe Now</button>
514 <#elseif isPriceTypeMB == "true" || isPriceTypeFree == "Free">
515 <button id="productRegistrationBtn" class="btn btn-lg btn-primary btn-arrow-right w-100" onclick="navigateToRegistration()">Access Now</button>
516 <#else>
517 <button id="productRegistrationBtn" class="btn btn-lg btn-primary btn-arrow-right w-100" onclick="navigateToRegistration()">Buy Now</button>
518 </#if>
519 <#if isSeminar = "true" || isInstitute = "true">
520 <button class="btn btn-lg btn-link icon-pdf w-100" onclick="navigateToRegForm()">Printable Registration Form</button>
521 </#if>
522 <#else>
523 <#if infoObj["Alternate Text"]?has_content>
524 <button id="productRegistrationBtn" class="btn btn-lg btn-primary btn-arrow-right w-100" onclick="navigateToRegistration()">${infoObj["Alternate Text"]}</button>
525 </#if>
526 <#if isSeminar = "true" || isInstitute = "true">
527 <button class="btn btn-lg btn-link icon-pdf w-100" onclick="navigateToRegForm()">Printable Registration Form</button>
528 </#if>
529 </#if>
530
531 <!-- Check if an Alternate URL is set and use that URL -->
532 <#if infoObj["Alternate URL"]?has_content>
533 <#assign displayMapValue = displayMapValue + {defaultSKUKey: infoObj["Alternate URL"]}>
534 </#if>
535 <#else>
536 <!-- Check if hubspot form should be displayed -->
537 <#if infoObj["Alternate URL"]?has_content>
538 <#assign displayMapValue = displayMapValue + {defaultSKUKey: infoObj["Alternate URL"]}>
539 <#if !infoObj["Alternate Text"]?has_content>
540 <button id="productRegistrationBtn" class="btn btn-lg btn-primary btn-arrow-right w-100" onclick="navigateToRegistration()">Register Now</button>
541 <#else>
542 <button id="productRegistrationBtn" class="btn btn-lg btn-primary btn-arrow-right w-100" onclick="navigateToRegistration()">${infoObj["Alternate Text"]}</button>
543 </#if>
544 <#else>
545 <div class="hubspot-form-wrap">
546 <p><strong>
547 This event is not currently available, please provide your contact information if you wish to be notified when it becomes available.
548 </strong></p>
549 <script>
550 hbspt.forms.create({
551 portalId: "5005401",
552 formId: "0865c866-46eb-4be6-944a-fb19a76a7a68",
553 });
554 window.addEventListener('hs-form-event:on-ready', function(event) {
555 HubSpotFormsV4.getFormFromEvent(event).setFieldValue('0-1/hidden_event_url', window.location.href);
556 });
557 </script>
558 </div>
559 </#if>
560 </#if>
561 </div>
562 </div>
563 <!-- Agenda -->
564 <#if isWebinar == "true" || isEvent == "true">
565 <#if infoObj["AgendaId"]?has_content>
566<#assign agendaString = infoObj["AgendaId"]?string/>
567<@liferay_journal["journal-article"]
568 articleId="${agendaString}"
569 ddmTemplateKey="728470"
570 groupId=45248
571 />
572</#if>
573 </#if>
574 <!-- Pricing -->
575<#if isPriceTypeFree != "true" && (priceList?? && (priceList?size > 0))>
576 <div class="product-info-wrapper product-pricing-info">
577 <h2 class="product-info-title"><button type="button" data-bs-toggle="collapse"
578 data-bs-target="#pricing-div" role="button" aria-expanded="true"
579 aria-controls="pricing-div">Pricing</button></h2>
580 <div class="product-info-div collapse show" id="pricing-div">
581 <div class="table-responsive">
582 <#assign columnSize = tableColumnNames?size />
583
584 <#if numberOfOptions == 2>
585 <table class="table custom-table">
586 <thead>
587 <tr>
588 <th>Audience</th>
589 <th>Livestream </th>
590 <th>Recorded </th>
591 <th>Livestream + Recorded </th>
592 </tr>
593 </thead>
594 <tbody>
595 <tr>
596 <td>
597 <h3>ICBA Member</h3>
598 </td>
599 <td>${productOptionMap["icba-member:live"]}</td>
600 <td>${productOptionMap["icba-member:ondemand"]}</td>
601 <td>${productOptionMap["icba-member:live-ondemand"]}</td>
602 </tr>
603
604 <tr>
605 <td>
606 <h3>Non-Member</h3>
607 </td>
608 <td>${productOptionMap["nonmember:live"]}</td>
609 <td>${productOptionMap["nonmember:ondemand"]}</td>
610 <td>${productOptionMap["nonmember:live-ondemand"]}</td>
611 </tr>
612
613 <tr>
614 <td>
615 <h3>Unlimited Webinar Pass</h3>
616 </td>
617 <td>${productOptionMap["unlimited-webinar-pass:live"]}</td>
618 <td>${productOptionMap["unlimited-webinar-pass:ondemand"]}</td>
619 <td>${productOptionMap["unlimited-webinar-pass:live-ondemand"]}</td>
620 </tr>
621 </tbody>
622
623 </table>
624 <#else>
625 <table class="table custom-table">
626 <thead>
627 <tr>
628 <th>Audience</th>
629 <#list tableColumnNames as columnName >
630 <th> ${columnName} <!--<i class="icon-info"></i>--></th>
631 </#list>
632 </tr>
633 </thead>
634 <tbody>
635 <#if priceList?? && (priceList?size > 0) && tableRowNames??>
636
637 <!-- 1. ICBA Member -->
638 <#assign icbaMemberRows = [] />
639 <#list tableRowNames as row>
640 <#if row?starts_with("ICBA Member")>
641 <#assign icbaMemberRows = icbaMemberRows + [row] />
642 </#if>
643 </#list>
644 <#list icbaMemberRows?sort as row>
645 <tr>
646 <td><h3>${row}</h3></td>
647 <td>${priceList[tableRowNames?seq_index_of(row)]}</td>
648 </tr>
649 </#list>
650
651 <!-- 2. ICBA Bank Director Program Subscriber -->
652 <#assign directorRows = [] />
653 <#list tableRowNames as row>
654 <#if row?starts_with("ICBA Bank Director Program Subscriber")>
655 <#assign directorRows = directorRows + [row] />
656 </#if>
657 </#list>
658 <#list directorRows?sort as row>
659 <tr>
660 <td><h3>${row}</h3></td>
661 <td>${priceList[tableRowNames?seq_index_of(row)]}</td>
662 </tr>
663 </#list>
664
665 <!-- 3. Non-Member -->
666 <#assign nonMemberRows = [] />
667 <#list tableRowNames as row>
668 <#if row?starts_with("Non-Member")>
669 <#assign nonMemberRows = nonMemberRows + [row] />
670 </#if>
671 </#list>
672 <#list nonMemberRows?sort as row>
673 <tr>
674 <td><h3>${row}</h3></td>
675 <td>${priceList[tableRowNames?seq_index_of(row)]}</td>
676 </tr>
677 </#list>
678
679 <!-- 4. Non-Banker* -->
680 <#assign nonBankerRows = [] />
681 <#list tableRowNames as row>
682 <#if row?starts_with("Non-Banker*")>
683 <#assign nonBankerRows = nonBankerRows + [row] />
684 </#if>
685 </#list>
686 <#list nonBankerRows?sort as row>
687 <tr>
688 <td><h3>${row}</h3></td>
689 <td>${priceList[tableRowNames?seq_index_of(row)]}</td>
690 </tr>
691 </#list>
692
693 <!-- 5. Unlimited Webinar Pass -->
694 <#assign unlimitedPassRows = [] />
695 <#list tableRowNames as row>
696 <#if row?starts_with("Unlimited Webinar Pass")>
697 <#assign unlimitedPassRows = unlimitedPassRows + [row] />
698 </#if>
699 </#list>
700 <#list unlimitedPassRows?sort as row>
701 <tr>
702 <td><h3>${row}</h3></td>
703 <td>${priceList[tableRowNames?seq_index_of(row)]}</td>
704 </tr>
705 </#list>
706
707 <!-- 6. Certification Fee -->
708 <#assign certificationRows = [] />
709 <#list tableRowNames as row>
710 <#if row?starts_with("Certification Fee")>
711 <#assign certificationRows = certificationRows + [row] />
712 </#if>
713 </#list>
714 <#list certificationRows?sort as row>
715 <tr>
716 <td><h3>${row}</h3></td>
717 <td>${priceList[tableRowNames?seq_index_of(row)]}</td>
718 </tr>
719 </#list>
720
721 <!-- Render any remaining rows not handled above -->
722 <#list tableRowNames as row>
723 <#if !row?starts_with("ICBA Member") &&
724 !row?starts_with("ICBA Bank Director Program Subscriber") &&
725 !row?starts_with("Non-Member") &&
726 !row?starts_with("Non-Banker*") &&
727 !row?starts_with("Unlimited Webinar Pass") &&
728 !row?starts_with("Certification Fee") >
729 <tr>
730 <td>
731 <h3>${row}</h3>
732 </td>
733 <td>
734 ${priceList[row_index]}
735 </td>
736 </tr>
737 </#if>
738 </#list>
739 </#if>
740 </tbody>
741</table>
742</#if>
743 </div>
744 <#if isForum = "true">
745 <div class="mb-20">
746 <a class="btn btn-link icon-pdf btn-arrow-right" href="/documents/d/asset-library-45247/icba-education-registration-form">Printable Registration Form</a>
747 <a class="btn btn-link btn-arrow-right" href="https://myicba.icba.org/eweb/dynamicpage.aspx?webcode=CSCBundles&Action=Add&cst_key=00000000-0000-0000-0000-000000000000&ObjectKeyFrom=1A83491A-9853-4C87-86A4-F7D95601C2E2&DoNotSave=Yes&DoNotAdd=Yes&ParentObject=CentralizedOrderEntry&ParentDataObject=Order%20Entry%20Bundle&key=271A2B6B-EE9F-4ACD-BB61-B9B9076B0BA2">Register for all four of the 2025 Bank
748 Director Forums</a>
749 </div>
750 </#if>
751
752 <div class="disclaimer">
753 <#if isSeminar = "true" || isInstitute = "true" || isWebinar = "true">
754 <p>
755 *Attendance may be subject to ICBA approval.
756 <br/>For attendance and cancellation policies see Disclaimers
757 </p>
758 </#if>
759 </div>
760 </div>
761 </div>
762 </#if>
763 <!-- Location -->
764 <#if isInPerson == "true">
765 <div class="product-info-wrapper product-location-info">
766 <h2 class="product-info-title"><button type="button" data-bs-toggle="collapse"
767 data-bs-target="#location-div" role="button" aria-expanded="true"
768 aria-controls="location-div">Location</button></h2>
769 <div class="product-info-div collapse show" id="location-div">
770 <div class="row">
771 <#assign columnTwo = 'col-md-12' />
772 <#if infoObj["Location Image"]?has_content>
773 <#assign columnTwo = 'col-md-8' />
774 <div class="col-md-4">
775 <div class="location-image">
776 <div class="slider-carousel-wrapper" data-slick-slider-wrapper="true">
777 <div data-slick-slider="true" data-infinite="false" data-slides-to-show="1"
778 data-slides-to-scroll="1" data-fade="true">
779 <div>
780 <img src="${infoObj["Location Image"]}" alt="" class="img-fluid" />
781 </div>
782 </div>
783 </div>
784 </div>
785 </div>
786 </#if>
787 <div class="${columnTwo}">
788 <h3 class="location-title">
789 <#if infoObj["Location Name"]?has_content>
790 ${infoObj["Location Name"]}
791 </#if>
792 </h3>
793 <p class="location-address">
794 <#if infoObj["Location Address"]?has_content>
795 ${infoObj["Location Address"]}
796 </#if>
797 <#if infoObj["Location City"]?has_content>
798 ${infoObj["Location City"]}
799 </#if>
800 <#if infoObj["Location State"]?has_content>
801 ${infoObj["Location State"]}
802 </#if>
803 </p>
804 <p class="location-summary">
805 <#if infoObj["Location Description"]?has_content>
806 ${infoObj["Location Description"]}
807 </#if>
808 </p>
809
810
811
812 </div>
813 </div>
814 <div class="mt-3">
815 <#if infoObj["Booking Link"]?has_content>
816 <a href="${infoObj["Booking Link"]}" class="btn btn-primary btn-lg btn-arrow-right" target="_blank">ICBA Booking Link</a>
817 </#if>
818 </div>
819
820 <div class="disclaimer">
821 <p>
822 <#if infoObj["Location Disclaimer"]?has_content>
823 ${infoObj["Location Disclaimer"]}
824 </#if>
825 </p>
826 </div>
827 </div>
828 </div>
829 </#if>
830 <!-- End -->
831 <!-- Who should Attend -->
832 <#if isWebinar == "true" || isEvent == "true">
833 <div class="product-info-wrapper product-attendees-info">
834 <h2 class="product-info-title"><button type="button" data-bs-toggle="collapse"
835 data-bs-target="#attendees-div" role="button" aria-expanded="true"
836 aria-controls="attendees-div">Who Should Participate</button></h2>
837 <div class="product-info-div collapse show" id="attendees-div">
838 <div class="table-responsive">
839 <table class="table custom-table">
840 <tbody>
841 <tr>
842 <td>
843 <p><strong>Who should attend: </strong></p>
844 </td>
845 <td>
846 <#if infoObj.icbaaudience?? && infoObj.icbaaudience?size gt 0>
847 <#assign formatList = []>
848 <#list infoObj.icbaaudience as format>
849 <#if format.value?has_content>
850 <#assign formatList += [format.value]>
851 </#if>
852 </#list>
853 ${formatList?join(", ")}
854 </#if>
855 </td>
856 </tr>
857 <tr>
858 <td>
859 <p><strong>Prerequisites:</strong></p>
860 </td>
861 <td>
862 <#if infoObj["Prerequisites"]?has_content>
863 <p>${infoObj["Prerequisites"]}</p>
864 </#if>
865 </td>
866 </tr>
867 <tr>
868 <td>
869 <p><strong>Advanced Preparation:</strong></p>
870 </td>
871 <td>
872 <#if infoObj["Advanced Preparation"]?has_content>
873 <p>${infoObj["Advanced Preparation"]}</p>
874 </#if>
875 </td>
876 </tr>
877 <tr>
878 <td>
879 <p><strong>Program Level:</strong></p>
880 </td>
881 <td>
882 <#if infoObj["Program Level"]?has_content>
883 <p>${infoObj["Program Level"]}</p>
884 </#if>
885 </td>
886 </tr>
887 <tr>
888 <td>
889 <p><strong>Field of Study:</strong></p>
890 </td>
891 <td>
892 <#if infoObj["Field of Study"]?has_content>
893 <p>${infoObj["Field of Study"]}</p>
894 </#if>
895 </td>
896 </tr>
897 <tr>
898 <td>
899 <p><strong>Delivery Method:</strong></p>
900 </td>
901 <td>
902 <#if infoObj.nasbadeliverymethod?? && infoObj.nasbadeliverymethod?size gt 0>
903 <#assign formatList = []>
904 <#list infoObj.nasbadeliverymethod as format>
905 <#if format.value?has_content>
906 <#assign formatList += [format.value]>
907 </#if>
908 </#list>
909 ${formatList?join(", ")}
910 </#if>
911 </td>
912 </tr>
913 <tr>
914 <td>
915 <p><strong>Continuing Professional<br />Education (CPE) Credit Hours:</strong></p>
916 </td>
917 <td>
918 <#if infoObj["CPE Credits"]?has_content>
919 <p>${infoObj["CPE Credits"]} hrs</p>
920 </#if>
921 </td>
922 </tr>
923 </tbody>
924 </table>
925 </div>
926 </div>
927 </div>
928 </#if>
929
930 <!-- Instructor -->
931<#if isWebinar == "true" || isEvent == "true">
932 <#if infoObj["InstructorId"]?has_content>
933 <div class="product-info-wrapper product-instructors-info">
934 <h2 class="product-info-title"><button type="button" data-bs-toggle="collapse"
935 data-bs-target="#instructors-div" role="button" aria-expanded="true"
936 aria-controls="instructors-div">Instructors</button></h2>
937 <div class="product-info-div collapse show" id="instructors-div">
938 <div class="row">
939 <!-- Article Structure Type -->
940 <#assign instructorString = infoObj["InstructorId"]?string/>
941 <#assign instructorIdList = instructorString?split(",")/>
942 <#list instructorIdList as iid>
943 <div class="col-md-6">
944 <@liferay_journal["journal-article"]
945 articleId="${iid}"
946 ddmTemplateKey="716972"
947 groupId=45248
948 />
949 </div>
950 </#list>
951 </div>
952 </div>
953 </div>
954 </#if>
955 </#if>
956 <!--End-->
957 <!-- Disclaimers -->
958 <#if isWebinar == "true" || isEvent == "true" || isPerson == "true">
959 <div class="product-info-wrapper product-disclaimers-info">
960 <h2 class="product-info-title">
961 <button type="button" data-bs-toggle="collapse" data-bs-target="#disclaimers-div" role="button" aria-expanded="true" aria-controls="disclaimers-div">Disclaimers</button>
962 </h2>
963 <div class="product-info-div collapse show" id="disclaimers-div">
964 <h3>Attendance and Cancellation Policy</h3>
965 <#-- Loop through contentFields to get the "content" field -->
966 <#if isSeminar == "true" || isInstitute == "true">
967 <#list attendenceSeminar.contentFields as field>
968 <#if field.name == "content">
969 ${htmlUtil.unescape(field.contentFieldValue.data)}
970 </#if>
971 </#list>
972 </#if>
973 <#if isWebinar == "true">
974 <#list attendenceWebinar.contentFields as field>
975 <#if field.name == "content">
976 ${htmlUtil.unescape(field.contentFieldValue.data)}
977 </#if>
978 </#list>
979 </#if>
980
981 <hr />
982
983 <h3>Continuing Professional Education Credit (CPE) Requirements</h3>
984 <#if isSeminar == "true" || isInstitute == "true" && isPerson=="false">
985 <#list cpeSeminar.contentFields as cpefield>
986 <#if cpefield.name == "content">
987 ${htmlUtil.unescape(cpefield.contentFieldValue.data)}
988 </#if>
989 </#list>
990 </#if>
991 <#if isWebinar == "true">
992 <#list cpeWebinar.contentFields as cpefield>
993 <#if cpefield.name == "content">
994 ${htmlUtil.unescape(cpefield.contentFieldValue.data)}
995 </#if>
996 </#list>
997 </#if>
998 <#if isPerson == "true">
999 <#list cpePerson.contentFields as cpefield>
1000 <#if cpefield.name == "content">
1001 ${htmlUtil.unescape(cpefield.contentFieldValue.data)}
1002 </#if>
1003 </#list>
1004 </#if>
1005 <hr />
1006
1007 <h3>${coc.title}</h3>
1008 <#list coc.contentFields as cocfield>
1009 <#if cocfield.name == "content">
1010 ${htmlUtil.unescape(cocfield.contentFieldValue.data)}
1011 </#if>
1012 </#list>
1013 <a href="/code-of-conduct">Read Full Policy</a>
1014
1015 <hr />
1016
1017 <h3>${policy.title}</h3>
1018 <#list policy.contentFields as policyfield>
1019 <#if policyfield.name == "content">
1020 ${htmlUtil.unescape(policyfield.contentFieldValue.data)}
1021 </#if>
1022 </#list>
1023 <hr />
1024
1025 <h3>${recording.title}</h3>
1026 <#list recording.contentFields as recordingfield>
1027 <#if recordingfield.name == "content">
1028 ${htmlUtil.unescape(recordingfield.contentFieldValue.data)}
1029 </#if>
1030 </#list>
1031 <hr />
1032
1033 <h3>${video.title}</h3>
1034 <#list video.contentFields as videofield>
1035 <#if videofield.name == "content">
1036 ${htmlUtil.unescape(videofield.contentFieldValue.data)}
1037 </#if>
1038 </#list>
1039 <hr />
1040
1041 <h3>${nasba.title}</h3>
1042 <#list nasba.contentFields as nasbafield>
1043 <#if nasbafield.name == "content">
1044 ${htmlUtil.unescape(nasbafield.contentFieldValue.data)}
1045 </#if>
1046 </#list>
1047 </div>
1048 </div>
1049 </#if>
1050 </div>
1051
1052 <!-- End -->
1053<#if hasSkus == "true" || infoObj["Alternate URL"]?has_content>
1054 <script>
1055 function navigateToRegistration(){
1056 var defaultURL = '${displayMapValue[defaultSKUKey]}';
1057
1058 var deliveryMethod = document.getElementById("delivery-method");
1059 if(deliveryMethod){
1060 defaultURL = deliveryMethod.value;
1061 }
1062 window.location.href = defaultURL;
1063 }
1064 </script>
1065</#if>
1066<!-- Handle Registration Form button click -->
1067<script>
1068 function navigateToRegForm(){
1069
1070 window.open('/documents/d/asset-library-45247/icba-education-registration-form', '_blank');
1071 }
1072 </script>
1073
1074<#if isWebinar == "true" && numberOfOptions gt 1 && !infoObj["Alternate URL"]?has_content>
1075<script>
1076
1077 const delveryMethodSelect = document.getElementById('delivery-method');
1078 const registrationButton = document.getElementById('productRegistrationBtn');
1079 registrationButton.classList.add("disabled");
1080 if(delveryMethodSelect){
1081 delveryMethodSelect.onchange = function() {
1082 const selectedValue = delveryMethodSelect.value;
1083
1084 if(selectedValue){
1085 registrationButton.classList.remove("disabled");
1086 } else {
1087 registrationButton.classList.add("disabled");
1088 }
1089 }
1090 };
1091
1092</script>
1093</#if>