Categories - B2B-Marketplace
شريط البحث
Secondary Header Icons
التنقل في الفئات التجارية
حصل خطأ عند معالجة القالب.
The following has evaluated to null or missing: ==> serviceLocator.findService("com.marketplace.category.service.CategoryLocalService") [in template "20096#20121#36178" at line 2, 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 categoryLocalService = servic... [in template "20096#20121#36178" at line 2, column 1] ----
1<#assign assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService")>
2<#assign categoryLocalService = serviceLocator.findService("com.marketplace.category.service.CategoryLocalService") />
3<#assign assetEntryLocalService=serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService") />
4<#assign cpDefinitionLocalService=serviceLocator.findService("com.liferay.commerce.product.service.CPDefinitionLocalService") />
5<#assign assetEntryAssetCategoryRelLocalService = serviceLocator.findService("com.liferay.asset.entry.rel.service.AssetEntryAssetCategoryRelLocalService") />
6<#assign publicSiteURL = themeDisplay.getPortalURL() + themeDisplay.getPathFriendlyURLPublic() + layout.getGroup().friendlyURL />
7
8
9<#function getPublishedProductCount categoryId>
10 <#assign productCount=0 />
11 <#assign assetEntryAssetCategoryRel = assetEntryAssetCategoryRelLocalService.getAssetEntryAssetCategoryRelsByAssetCategoryId(categoryId) />
12 <#list assetEntryAssetCategoryRel as assetEntryCategoryRel>
13 <#assign assetEntry = assetEntryLocalService.fetchAssetEntry(assetEntryCategoryRel.getAssetEntryId()) />
14 <#if assetEntry??>
15 <#assign classPK = assetEntry.getClassPK() />
16 <#assign cpDefinition = cpDefinitionLocalService.getCPDefinition(classPK) />
17 <#if cpDefinition??>
18 <#if cpDefinition.isPublished() && cpDefinition.getStatus() == 0>
19 <#assign productCount = productCount + 1 />
20 </#if>
21 </#if>
22 </#if>
23 </#list>
24 <#return productCount?number />
25</#function>
26
27<#assign subCategoryCount = 0 />
28
29<script>
30 var categoriesMap = new Map();
31</script>
32
33<#macro renderCategories categories>
34 <#list categories as category>
35 <#assign customCategoryObj = categoryLocalService.findByFBYAssetCategoryId(category.getCategoryId()) />
36 <#assign isCategoryActive = customCategoryObj.getIsActive() && customCategoryObj.getCategoryApprovalStatus() == "Approved" />
37 <#if isCategoryActive>
38 <#assign subCategoryList = assetCategoryLocalService.getChildCategories(category.getCategoryId()) />
39 <#assign cUrl = "${publicSiteURL}/market?category=${category.getCategoryId()}" />
40 <#assign productCount = getPublishedProductCount(category.getCategoryId()) />
41
42 <#if productCount gt 0>
43 <script>
44 categoriesMap.set(${category.getCategoryId()}, '${category.getName()}');
45 </script>
46 <a href="${cUrl}" class="text-secondary">${category.getName()}</a>
47 <br>
48 <#else />
49 <span class="text-secondary">${category.getName()}</span><br>
50 </#if>
51
52 <#assign subCategoryCount = subCategoryCount?number + 1 />
53
54 <#if subCategoryList?has_content>
55 <@renderCategories categories=subCategoryList />
56 </#if>
57 </#if>
58 </#list>
59</#macro>
60
61<div class="container">
62 <nav class="navbar navbar-light bg-light category-nav justify-content-between">
63 <a class="navbar-brand"><b>All Category</b></a>
64 <form class="form-inline">
65 <div class="input-group">
66 <div class="input-group-prepend">
67 <span class="input-group-text " id="basic-addon1"> <img src="/o/buycorp-classic-theme/images/icon/search-icon.png" ></span>
68 </div>
69 <input class="form-control clp-search mr-sm-2 p-0" type="search" id="categorySearch" list="searchResults" placeholder="Search By Category Name" aria-label="Search" aria-describedby="basic-addon1">
70 </div>
71 </form>
72 </nav>
73 <div class="search-card d-none">
74 <div id="searchResults"></div>
75 </div>
76
77 <div class="d-flex flex-wrap maxBoxScroll" id="<@portlet.namespace />cpAssetCategoryNavigation">
78 <#if entries?has_content>
79 <#list entries as category>
80 <#assign customCategoryObj = categoryLocalService.findByFBYAssetCategoryId(category.getCategoryId()) />
81 <#assign isCategoryActive = customCategoryObj.getIsActive() && customCategoryObj.getCategoryApprovalStatus() == "Approved" />
82 <#if isCategoryActive>
83 <#assign subCategoryCount = 0 />
84 <div class="card clp-card" >
85 <div class="card-body">
86 <#assign productCount = getPublishedProductCount(category.getCategoryId()?number) />
87 <#assign subCategoryList = assetCategoryLocalService.getChildCategories(category.getCategoryId()) />
88 <#assign cUrl = "${publicSiteURL}/market?category=${category.getCategoryId()}" />
89
90 <#if productCount gt 0>
91 <script>
92 categoriesMap.set(${category.getCategoryId()}, '${category.getName()}');
93 </script>
94 <h3 class="card-title mb-2"><b><a href="${cUrl}"><strong>${category.getName()}</strong></a></b></h3>
95 <#else />
96 <h3 class="card-title mb-2"><b><strong>${category.getName()}</strong></b></h3>
97 </#if>
98
99 <#if subCategoryList?has_content>
100 <@renderCategories categories=subCategoryList />
101 </#if>
102 </div>
103 </div>
104 </#if>
105 </#list>
106 </#if>
107 </div>
108</div>
109
110<script>
111
112 const searchElement = document.getElementById('categorySearch');
113
114 const searchData = (event) => {
115 const filteredMap = new Map(
116 [...categoriesMap].filter(([k, v]) => v.toLowerCase().includes(event.target.value.toLowerCase()))
117 );
118 showResults(filteredMap);
119 };
120
121 const debounce = (callback, waitTime) => {
122 let timer;
123 return (...args) => {
124 clearTimeout(timer);
125 timer = setTimeout(() => {
126 callback(...args);
127 }, waitTime);
128 };
129 };
130
131 const debounceHandler = debounce(searchData, 1000);
132 searchElement.addEventListener('input', debounceHandler);
133
134 var showResults = filteredCategories => {
135
136 let searchResultsList = document.getElementById('searchResults');
137 searchResultsList.innerHTML = '';
138
139 if(searchElement.value.trim().length == 0) {
140 $('.search-card').addClass('d-none');
141 return;
142 }
143
144 $('.search-card').removeClass('d-none');
145
146 if (filteredCategories.size == 0) {
147 let noResultItem = document.createElement('div');
148 noResultItem.textContent = 'No categories found';
149 searchResultsList.appendChild(noResultItem);
150 } else {
151 filteredCategories.forEach((value, key) => {
152 let listItem = document.createElement('li');
153 listItem.setAttribute('categoryid', key);
154
155 let anchor = document.createElement('a');
156 anchor.setAttribute('href', '${publicSiteURL}/market?category=' + key + '');
157 anchor.innerText = value;
158
159 listItem.appendChild(anchor);
160
161 searchResultsList.appendChild(listItem);
162 });
163 }
164
165 };
166
167var showHideCategories = currObj => {
168 let moreCategoriesSection = $(currObj).siblings('.more-categories').eq(0);
169 if (moreCategoriesSection.hasClass('d-none')) {
170 moreCategoriesSection.removeClass('d-none');
171 $(currObj).text('Less');
172 } else {
173 moreCategoriesSection.addClass('d-none');
174 $(currObj).text('More');
175 }
176};
177
178</script>
179
180
181<style>
182 .text-secondary { font-weight: 400; font-size: 12px; line-height:18px; }
183 .card-title { font-weight: 600; font-size: 14px; line-height:20px;}
184 .card-title a:hover { color:#2B4960}
185 .clp-card {border-radius: 8px;width: calc(20% - 20px); min-height:230px; max-height:230px; height:auto; margin: 10px;
186 box-sizing: border-box; border: 1px solid #DDDDDD; overflow-y:auto;}
187 .category-nav { background:transparent !important; margin:30px 0px 30px 0px;}
188 .navbar-brand b {font-family: roboto;font-weight: 600;font-size: 24px; color: #373737; }
189 .clp-search { border-left-style: none;}
190 .input-group-text { background-color: #fff; border-color: #E8E8E8;}
191 .input-group:hover .input-group-text, .input-group:hover .form-control.clp-search
192 { border-color: #888888!important;}
193 .clp-search:focus { border-color: #D9D9D9; }
194 .input-group .clp-search{ min-width: 210px;}
195
196 .search-card {background-color: #fff;border-color: rgba(0, 0, 0, 0.125);border-radius: 0.25rem; border-style: solid;
197 border-width: 0.065rem; margin-bottom: 1.5rem;margin-top: -33px;position: absolute;word-wrap: break-word; right: 86px;
198 min-width: 251px; max-width: 251px; padding: 8px;z-index: 1;list-style-type:none; max-height: 136px; overflow-y:auto;
199}
200 .maxBoxScroll {overflow-y: auto; max-height: 100%;}
201.clp-card::-webkit-scrollbar {width:5px; height: 89px; }
202.clp-card::-webkit-scrollbar-track {background:#bcb7b7; border-radius:20px; }
203.clp-card::-webkit-scrollbar-thumb {background:#DCDCDC; border-radius:29px;}
204
205
206@media screen and (max-width: 1090px) {
207 .clp-card {
208 width: calc(25% - 20px);
209 }
210}
211@media screen and (max-width: 820px) {
212 .clp-card {
213 width: calc(35% - 50px);
214 }
215}
216@media screen and (max-width: 650px) {
217 .clp-card {
218 width: calc(50% - 30px);
219 }
220}
221@media screen and (max-width: 450px) {
222 .clp-card {
223 width: calc(90% - 65px);
224 }
225}
226</style>