1<#-- Variables -->
2<#assign specificationName = 'ics' />
3<#assign paramNameSpecificationName = cpSpecificationOptionsSearchFacetDisplayContext.getParameterName() />
4<#assign isDebug = false />
5<#assign showAllSpecificationsName = false />
6<#assign staticHost = getCXConfig("ecom-static-files") />
7
8<#-- ========================= -->
9<#-- Functions freemaker -->
10<#-- ========================= -->
11<#function getCXConfig clientExtensionName field="webApiUrl">
12 <#if !clientExtensionName?has_content><#return "" /></#if>
13 <#local encoded = urlCodec.encodeURL(clientExtensionName) />
14 <#local items = restClient.get("/c/customconfigs/?fields=clientExtensionConfig&filter=clientExtensionName eq '" + encoded + "'").items![] />
15 <#return items?has_content?then(items[0].clientExtensionConfig?eval[field]!"", "") />
16</#function>
17
18
19<#if paramNameSpecificationName == specificationName || showAllSpecificationsName>
20
21 <#assign documents = searchResultsPortletDisplayContext.getDocuments() />
22
23<#if documents?has_content>
24 <#assign doc = documents[0] />
25
26 <div style="background:#f5f5f5;padding:20px;font-family:monospace;">
27 <h3>Campos del primer documento</h3>
28
29 <#list doc.getFields() as field>
30 <p>
31 <strong>${field.getName()}</strong> :
32 <#attempt>
33 ${field.getValue()?string}
34 <#recover>
35 [No se puede mostrar]
36 </#attempt>
37 </p>
38 </#list>
39 </div>
40</#if>
41
42 <#-- Variables -->
43 <#assign facetId = "facet-" + paramNameSpecificationName + "-" + renderResponse.getNamespace() />
44 <#assign facetClass = "facet-" + paramNameSpecificationName + "-combo-search-wrapper" />
45
46 <#-- ========================= -->
47 <#-- TOM SELECT framework -->
48 <#-- ========================= -->
49 <@liferay_util["html-top"] outputKey="tom-select">
50 <link href="${staticHost}/scripts/vendor/tom-select/tom-select.css" rel="stylesheet">
51 <script src="${staticHost}/scripts/vendor/tom-select/tom-select.complete.min.js"></script>
52 </@>
53
54 <#-- ========================= -->
55 <#-- CSS -->
56 <#-- ========================= -->
57 <style>
58 /* ===========================
59 Variables de fuente compartidas
60 =========================== */
61 #${facetId} {
62 --facet-font-family: Inter;
63 --facet-font-size: 14px;
64 --facet-font-weight: 400;
65 --facet-line-height: 18px;
66 --facet-letter-spacing: 0.5px;
67 --facet-color: #66757f;
68 }
69
70 /* ===========================
71 Select original — oculto desde el inicio
72 =========================== */
73 #${facetId}-select {
74 appearance: none;
75 -webkit-appearance: none;
76 visibility: hidden;
77 position: absolute;
78 }
79
80 /* ===========================
81 TomSelect — wrapper oculto hasta inicializar
82 =========================== */
83 #${facetId} .ts-wrapper {
84 width: 100%;
85 margin-bottom: 16px;
86 opacity: 0;
87 transition: opacity 0.1s ease;
88 }
89
90 #${facetId} .ts-wrapper .ts-control {
91 padding: 15.5px 16px;
92 font-family: var(--facet-font-family);
93 font-size: var(--facet-font-size);
94 font-weight: var(--facet-font-weight);
95 line-height: var(--facet-line-height);
96 letter-spacing: var(--facet-letter-spacing);
97 color: var(--facet-color);
98 text-align: left;
99 height: 55px;
100 width: 100%;
101 border-radius: 4px;
102 border: none;
103 background-color: #F5F5F5;
104 background-image: url(/documents/d/global/ico-chevron-down-2);
105 background-repeat: no-repeat;
106 background-position: right 1rem center;
107 background-size: 18px 10px;
108 box-shadow: none;
109 cursor: pointer;
110 box-sizing: border-box;
111 }
112
113 #${facetId} .ts-wrapper .ts-control:focus,
114 #${facetId} .ts-wrapper .ts-control:focus-visible {
115 background-image: url(/documents/d/global/ico-chevron-down-2);
116 background-position: right 1rem center;
117 background-size: 18px 10px;
118 outline: none;
119 box-shadow: none;
120 }
121
122 #${facetId} .ts-wrapper .ts-control .item {
123 padding-right: 0.75rem;
124 overflow: hidden;
125 text-overflow: ellipsis;
126 max-width: calc(100% - 0.75rem);
127 }
128
129 /* Ocultar flecha nativa de TomSelect */
130 #${facetId} .ts-wrapper.single .ts-control::after {
131 display: none;
132 }
133
134 /* Input de búsqueda del dropdown */
135 #${facetId} .ts-dropdown .dropdown-input-wrap .dropdown-input {
136 font-family: var(--facet-font-family);
137 font-size: var(--facet-font-size);
138 font-weight: var(--facet-font-weight);
139 line-height: var(--facet-line-height);
140 letter-spacing: var(--facet-letter-spacing);
141 color: var(--facet-color);
142 padding: 8px 16px;
143 border: none;
144 border-bottom: 1px solid #d9d9d9;
145 background-color: #fff;
146 width: 100%;
147 box-sizing: border-box;
148 }
149
150 #${facetId} .ts-dropdown .dropdown-input-wrap .dropdown-input:focus {
151 outline: none;
152 box-shadow: none;
153 }
154
155 /* Opciones del dropdown */
156 #${facetId} .ts-dropdown .ts-dropdown-content .option {
157 font-family: var(--facet-font-family);
158 font-size: var(--facet-font-size);
159 font-weight: var(--facet-font-weight);
160 line-height: var(--facet-line-height);
161 letter-spacing: var(--facet-letter-spacing);
162 color: var(--facet-color);
163 padding: 8px 16px;
164 }
165
166 #${facetId} .ts-dropdown .ts-dropdown-content .option:hover,
167 #${facetId} .ts-dropdown .ts-dropdown-content .option.active {
168 background-color: #6a9bd3;
169 color: #fff;
170 }
171 </style>
172
173 <div class="checks-container ${facetClass}" id="${facetId}">
174 <div class="d-flex flex-column w-100">
175 <label class="panel-title mb-2" for="${facetId}-select">
176 ${languageUtil.get(locale, "norma." + paramNameSpecificationName)}
177 <#if isDebug>
178 <p style="font-size:11px;color:#999;font-weight:normal;">
179 (total options: ${entries?size})
180 </p>
181 <p style="font-size:11px;color:#999;font-weight:normal;">
182 (facetId: ${facetId})
183 </p>
184 </#if>
185 </label>
186
187 <#-- ========================= -->
188 <#-- SELECT UI -->
189 <#-- ========================= -->
190 <select id="${facetId}-select" data-parameter-name="${paramNameSpecificationName}">
191 <option value="">${languageUtil.get(locale, "search.cualquiera")}</option>
192 <#list entries?sort_by("displayName") as entry>
193 <option value="${htmlUtil.escape(entry.getDisplayName())}"
194 <#if entry.isSelected()>selected</#if>>
195 ${htmlUtil.escape(entry.getDisplayName())} (${entry.getFrequency()})
196 </option>
197 </#list>
198 </select>
199 </div>
200 </div>
201
202 <#-- ========================= -->
203 <#-- SCRIPT -->
204 <#-- ========================= -->
205 <script>
206 (function () {
207 var FACET_ID = '${facetId}';
208 var PARAM_NAME = '${paramNameSpecificationName}';
209
210 function applyUrlFilter(value) {
211 var url = new URL(window.location.href);
212 if (value) {
213 url.searchParams.set(PARAM_NAME, value);
214 } else {
215 url.searchParams.delete(PARAM_NAME);
216 }
217 window.location.href = url.toString();
218 }
219
220 function initFacet() {
221 var select = document.getElementById(FACET_ID + '-select');
222 if (!select) return;
223
224 if (select.tomselect) select.tomselect.destroy();
225 if (select.dataset.bound === 'true') return;
226 select.dataset.bound = 'true';
227
228 new TomSelect(select, {
229 allowEmptyOption: true,
230 maxItems: 1,
231 create: false,
232 render: {
233 no_results: function(data, escape) {
234 return '<div class="no-results">${languageUtil.get(locale, "occurrence-not-found")}</div>';
235 }
236 },
237 plugins: {
238 dropdown_input: {}
239 },
240 onDelete: function(value) {
241 this.isDelete = true;
242 },
243 onChange: function(value) {
244 if (value) {
245 this.lastValidValue = value;
246 applyUrlFilter(value);
247 return;
248 }
249 this.lastValidValue = '';
250 applyUrlFilter('');
251 },
252 onInitialize: function() {
253 this.lastValidValue = this.getValue() || '';
254 this.isDelete = false;
255 var wrapper = document.querySelector('#' + FACET_ID + ' .ts-wrapper');
256 if (wrapper) wrapper.style.opacity = '1';
257 }
258 });
259 }
260
261 if (document.readyState === 'loading') {
262 document.addEventListener('DOMContentLoaded', initFacet);
263 } else {
264 initFacet();
265 }
266 })();
267 </script>
268</#if>