Notes
Notes - notes.io |
constructor(el) {
this.el = el;
this.token = null;
this.assetData = null;
this.currentPage = null;
this.storedAssets = getSessionData('AssetInfo') ? JSON.parse(secureHtml(atob(getSessionData("AssetInfo")), { allowedTags: [] })) : [];
this.currentUrl = window.location.href;
this.hashValue = window.location.hash.substring(1);
this.cacheElements();
this.initFilters();
this.bindEvents();
// Run initialization
this.init();
this.assetDataforSorting = [];
this.filterKeyMap = {
usability: 'creativeAssetType',
theme: 'creativeAssetTheme',
style: 'creativeAssetStyle',
format: 'creativeAssetFormat',
orientation: 'creativeAssetOrientation',
purpose: 'creativeAssetPurpose',
category: 'creativeAssetCategory',
subCategory: 'creativeAssetSubCategory',
'measurement unit': 'creativeAssetUnit'
};
this.updateResetButtonVisibility();
}
//async init method to control sequence
async init() {
await this.fetchFilterOptions();
await this.fetchAssets();
await this.fetchFilterCategoryOptions();
}
// Cache DOM elements
cacheElements() {
this.spinner = this.el.querySelector('.spinner-container');
this.checkboxes = this.el.querySelectorAll('.form-check-input');
this.dropdownContainer = this.el.querySelector('.dropdown-container');
this.dropdownApi = this.dropdownContainer?.getAttribute('data-api-url-meta');
this.categoryDropdownApi = this.dropdownContainer?.getAttribute('data-api-url-category');
this.navUrl = this.dropdownContainer?.getAttribute('data-api-nav-url');
this.assetsApiElement = this.el.querySelector('#assets');
this.assetApi = this.assetsApiElement?.getAttribute('data-api-url-assets');
this.singleSelectedItems = this.el.querySelectorAll('.dropdown-item[data-value]');
this.dropdownMenus = this.el.querySelectorAll('.dropdown-menu');
this.filterButton = this.el.querySelector('.btn-filter');
this.dynamicContainer = this.el.querySelector('#dynamic-filters');
this.subCategory = this.el.querySelector('.sub-category');
this.errorMessage = this.el.querySelector('#assets .error-message');
this.campPaginationWrapper = this.el.querySelector('#assets-list-pagination');
this.sortDiv = this.el.querySelector('#dropdownSort');
this.unitDropdown = this.el.querySelector('#dropdownUnit');
}
// Initialize filter state
initFilters() {
this.filters = {
usability: new Set(),
customizable: new Set(),
theme: new Set(),
style: new Set(),
format: new Set(),
orientation: new Set(),
purpose: new Set(),
sort: new Set(),
category: new Set(),
subCategory: new Set(),
};
}
// Fetch filter dropdown options
async fetchFilterOptions() {
try {
const response = await fetch(this.dropdownApi);
const data = await response.json();
this.populateDropdowns(data?.entities[0]?.properties?.elements);
this.updateDropdownReferences();
this.badgeHandler();
this.errorMessage.classList.add('d-none');
} catch (error) {
this.errorMessage.classList.remove('d-none');
console.error('Error fetching filter options:', error);
}
}
// Fetch category dropdown options
async fetchFilterCategoryOptions() {
try {
const response = await fetch(this.categoryDropdownApi);
const data = await response.json();
this.populateCategory(data.entities);
} catch (error) {
console.error('Error fetching filter options:', error);
}
}
// Populate dropdowns (theme, style, format) dynamically with API data
populateDropdowns(data) {
const formatCheckboxLabels = str => str.replace(/([a-z])([0-9])/i, '$1 $2').replace(/^./, char => char.toUpperCase());
// Define dropdowns based on API response
const dropdowns = [
{ type: 'theme', label: 'Theme', values: data.theme.value },
{ type: 'style', label: 'Style', values: data.style.value },
{ type: 'orientation', label: 'Orientation', values: data.orientation.value },
{ type: 'purpose', label: 'Purpose', values: data.purpose.value },
// { type: 'format', label: 'Format', values: data.format.value }
];
dropdowns.forEach(dropdown => {
const dropdownsHTML = document.createElement("div");
dropdownsHTML.className = "dropdown pt-1";
dropdownsHTML.innerHTML = secureHtml(`
<div class="title d-flex gap-half">
<p>${dropdown.label}</p>
<span class="badge rounded-pill bg-primary badge-count">0</span>
</div>
<button class="btn-dropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Select ${dropdown.label.toLowerCase()} <span class="arrow-down cmp-icon-pseudo"></span>
</button>
<ul class="dropdown-menu checkbox-list">
${dropdown.values.map(value => `
<li>
<label class="dropdown-item">
<input type="checkbox" class="form-check-input dynamic-checkbox me-qtr"
data-filter-type="${dropdown.type}" value="${value}">
${formatCheckboxLabels(value)}
</label>
</li>
`).join('')}
</ul>
`);
this.dropdownContainer.insertBefore(dropdownsHTML, this.unitDropdown);
});
}
// Populate category dynamically with API data
populateCategory(data) {
const categories = [];
data.forEach(item => {
const assetCategory = item.properties.elements.assetCategory?.value || '';
const assetSubCategory = item.properties.elements.subcategories?.value || [];
if (assetCategory.trim() !== '') {
categories.push({ assetCategory, assetSubCategory });
}
});
// Create Category dropdown
const categoryDropdown = document.createElement("div");
categoryDropdown.className = "dropdown category pt-1";
categoryDropdown.innerHTML = secureHtml(`
<p>Category</p>
<button class="btn-dropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Select category <span class="arrow-down cmp-icon-pseudo"></span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item btn-reset-individual" role="button" data-filter-type="category">All categories</a>
</li>
${categories.map(cat => `
<li>
<label class="dropdown-item">
<input type="checkbox" class="form-check-input dynamic-checkbox me-qtr"
data-filter-type="${cat.assetCategory}" value="${cat.assetCategory}">
${this.formatCategoryName(cat.assetCategory.charAt(0).toUpperCase() + cat.assetCategory.slice(1))}
</label>
</li>
`).join('')}
</ul>
`);
this.dropdownContainer.insertBefore(categoryDropdown, this.unitDropdown);
// Create Subcategory dropdown (initially hidden)
const subCategoryDropdown = document.createElement("div");
subCategoryDropdown.className = "dropdown sub-category pt-1 d-none";
subCategoryDropdown.innerHTML = secureHtml(`
<p>Sub Category</p>
<button class="btn-dropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Select sub category <span class="arrow-down cmp-icon-pseudo"></span>
</button>
<ul class="dropdown-menu"></ul>
`);
this.dropdownContainer.insertBefore(subCategoryDropdown, this.unitDropdown);
this.bindDynamicCategoryEvents(categories);
initSortedAndHighlightDropdowns();
}
bindEvents() {
this.bindCheckboxEvents();
// Bind single-select dropdowns (Customizable and Usability)
this.singleSelectedItems.forEach(item => {
item.addEventListener('click', (e) => {
e.preventDefault();
const dropdown = item.closest('.dropdown');
const filterType = dropdown.querySelector('p').textContent.toLowerCase().trim();
const value = item.getAttribute('data-value').toLowerCase().trim();
// Update button text
const dropdownBtn = dropdown.querySelector('.btn-dropdown');
const valueMap = {
readytouse: 'Ready to use',
customizable: 'Customizable',
alphabetical: 'Alphabetical',
date: 'Date',
mm: 'Millimeters',
inches: 'Inches'
}
dropdownBtn.innerHTML = secureHtml(`${valueMap[value]} <span class="arrow-down cmp-icon-pseudo"></span>`);
if (filterType === 'sort') {
const activeFilters = Object.entries(this.filters).filter(([_, values]) => values.size > 0);
let filtered = this.assetData;
if (activeFilters.length > 0) {
filtered = this.assetData.filter(asset => {
return activeFilters.every(([key, values]) => {
const property = this.filterKeyMap[key];
let val = asset[property]?.toLowerCase().replace(/s+/g, '');
return val && values.has(val);
});
});
}
this.sortAssets(filtered, value);
return;
}
// Clear previous selection
this.filters[filterType].clear();
this.filters[filterType]?.add(value);
this.filterAssets();
});
});
// Toggle filter visibility
this.filterButton.addEventListener('click', () => this.toggleFilters());
// Prevent dropdown from closing when clicking inside
this.dropdownContainer?.addEventListener('click', e => {
if (e.target.closest('.dropdown-menu.checkbox-list')) {
e.stopPropagation();
}
});
this.bindResetButtons();
}
bindResetButtons() {
// Individual reset buttons
this.el.addEventListener('click', (e) => {
const resetBtn = e.target.closest('.btn-reset-individual');
if (resetBtn) {
e.preventDefault();
e.stopPropagation();
const filterType = resetBtn.dataset.filterType;
this.resetFilterType(filterType);
}
// Global reset button
if (e.target.closest('.btn-reset-all')) {
e.preventDefault();
this.resetAllFilters();
if (window.location.href.includes("cognizant") || window.location.href.includes("localhost")) {
const url = window.location.origin + window.location.pathname;
window.history.replaceState({}, document.title, url);
} else {
return;
}
}
});
}
resetAllFilters() {
// Clear all filter values
Object.keys(this.filters).forEach(filterType => {
this.filters[filterType].clear();
});
// Reset all dropdown UIs
// Usability dropdown
const typeBtn = this.el.querySelector('#dropdownType .btn-dropdown');
if (typeBtn) {
typeBtn.innerHTML = secureHtml(`Select option <span class="arrow-down cmp-icon-pseudo"></span>`);
}
// Checkbox filters
const checkboxes = this.el.querySelectorAll('.dynamic-checkbox');
checkboxes.forEach(checkbox => {
checkbox.checked = false;
});
// Reset all badges count
const badges = this.el.querySelectorAll('.badge-count');
badges.forEach(badge => {
badge.textContent = '0';
badge.style.display = 'none';
})
// Category dropdowns
const categoryBtn = this.el.querySelector('.dropdown.category .btn-dropdown');
if (categoryBtn) {
categoryBtn.innerHTML = secureHtml(`Select category <span class="arrow-down cmp-icon-pseudo"></span>`);
}
const subCategoryBtn = this.el.querySelector('.dropdown.sub-category .btn-dropdown');
if (subCategoryBtn) {
subCategoryBtn.parentElement.classList.add('d-none');
subCategoryBtn.innerHTML = secureHtml(`Select sub category <span class="arrow-down cmp-icon-pseudo"></span>`);
}
// Sort dropdown
const sortBtn = this.el.querySelector('#dropdownSort .btn-dropdown');
if (sortBtn) {
sortBtn.innerHTML = secureHtml(`Select sort <span class="arrow-down cmp-icon-pseudo"></span>`);
}
// Sort dropdown
const unitBtn = this.el.querySelector('#dropdownUnit .btn-dropdown');
if (unitBtn) {
unitBtn.innerHTML = secureHtml(`Select unit <span class="arrow-down cmp-icon-pseudo"></span>`);
}
// Re-filter assets
this.filterAssets();
this.updateResetButtonVisibility();
initSortedAndHighlightDropdowns('.dropdown-menu', true);
}
resetFilterType(filterType) {
// Clear the filter values
this.filters[filterType]?.clear();
// Reset UI elements
if (filterType === 'usability') {
// Reset usability dropdown
const usabilityBtn = this.el.querySelector('#dropdownType .btn-dropdown');
usabilityBtn.innerHTML = secureHtml(`Select option <span class="arrow-down cmp-icon-pseudo"></span>`);
} else if (filterType === 'category') {
// Reset category dropdown
const categoryBtn = this.el.querySelector('.dropdown.category .btn-dropdown');
categoryBtn.innerHTML = secureHtml(`Select category <span class="arrow-down cmp-icon-pseudo"></span>`);
// Also reset subcategory
this.resetFilterType('subCategory');
} else if (filterType === 'subCategory') {
// Reset subcategory dropdown
const subCategoryBtn = this.el.querySelector('.dropdown.sub-category .btn-dropdown');
subCategoryBtn.innerHTML = secureHtml(`Select sub category <span class="arrow-down cmp-icon-pseudo"></span>`);
} else if (filterType === 'measurement unit') {
// Reset subcategory dropdown
const unitBtn = this.el.querySelector('#dropdownUnit .btn-dropdown');
unitBtn.innerHTML = secureHtml(`Select unit <span class="arrow-down cmp-icon-pseudo"></span>`);
} else {
// Uncheck all checkboxes for this filter type
const checkboxes = this.el.querySelectorAll(
`.dynamic-checkbox[data-filter-type="${filterType}"]`
);
checkboxes.forEach(checkbox => {
checkbox.checked = false;
});
}
const dropdown = this.el.querySelector(`.dropdown [data-filter-type="${filterType}"]`)?.closest('.dropdown');
if (dropdown) {
const badge = dropdown.querySelector('.badge-count');
if (badge) {
badge.textContent = '0';
badge.style.display = 'none';
}
}
// Re-filter assets
this.filterAssets();
this.updateResetButtonVisibility();
}
formatCategoryName(selectedCategory) {
const expections = {
Tabledrapes: 'Table drapes',
Nameboards: 'Name boards'
}
return expections[selectedCategory] || selectedCategory.replace(/([a-z])([A-Z])/g, '$1 $2');
}
// To bind category events
bindDynamicCategoryEvents(categories) {
const categoryDropdown = this.el.querySelector('.dropdown.category');
const subCategoryDropdown = this.el.querySelector('.dropdown.sub-category');
const subCategoryMenu = subCategoryDropdown.querySelector('.dropdown-menu');
if (!categoryDropdown || !subCategoryDropdown) return;
const categoryItems = categoryDropdown.querySelectorAll('.dropdown-item');
categoryItems.forEach(item => {
item.addEventListener('click', (e) => {
e.preventDefault();
const selectedCategory = item.getAttribute('data-value');
// Update category filter
this.filters.category.clear();
this.filters.category.add(selectedCategory.trim().toLowerCase()); // Convert to lowercase
// Update category button text
const btn = categoryDropdown.querySelector('.btn-dropdown');
btn.innerHTML = secureHtml(`${this.formatCategoryName(selectedCategory)} <span class="arrow-down cmp-icon-pseudo"></span>`);
// Clear subcategory filter and reset UI
const subBtn = subCategoryDropdown.querySelector('.btn-dropdown');
subBtn.innerHTML = secureHtml(`Select sub category <span class="arrow-down cmp-icon-pseudo"></span>`);
this.filters.subCategory.clear();
// Get corresponding subcategories
const matched = categories.find(cat => cat.assetCategory === selectedCategory);
const subcategories = matched?.assetSubCategory || [];
// Render subcategory options
if (subcategories.length > 0) {
subCategoryMenu.innerHTML = '<li><a class="dropdown-item btn-reset-individual" role="button" data-filter-type="subCategory">All sub-categories</a></li>' + subcategories.map(sub => secureHtml(`
<li><a class="dropdown-item" href="#" data-value="${sub}">${this.formatCategoryName(sub)}</a></li>
`)).join('');
subCategoryDropdown.classList.remove('d-none');
// Bind subcategory click events
} else {
subCategoryDropdown.classList.add('d-none');
}
// Bind subcategory click events
const subItems = subCategoryMenu.querySelectorAll('.dropdown-item');
subItems.forEach(subItem => {
subItem.addEventListener('click', (e) => {
e.preventDefault();
const subVal = subItem.getAttribute('data-value');
this.filters.subCategory.clear();
this.filters.subCategory.add(subVal?.trim().toLowerCase()); // Convert to lowercase
const subBtn = subCategoryDropdown.querySelector('.btn-dropdown');
subBtn.innerHTML = secureHtml(`${this.formatCategoryName(subVal)} <span class="arrow-down cmp-icon-pseudo"></span>`);
this.filterAssets();
});
});
this.filterAssets();
});
// To filter based on redirection with hash value
const hashValueUpdated = this.hashValue.includes('%20') ? this.hashValue.replace('%20', ' ') : this.hashValue;
if (this.hashValue.toLowerCase() && item.getAttribute('data-value').toLowerCase() === hashValueUpdated.toLowerCase()) {
this.filterButton.click();
item.click();
}
});
}
![]() |
Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...
With notes.io;
- * You can take a note from anywhere and any device with internet connection.
- * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
- * You can quickly share your contents without website, blog and e-mail.
- * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
- * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.
Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.
Easy: Notes.io doesn’t require installation. Just write and share note!
Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )
Free: Notes.io works for 14 years and has been free since the day it was started.
You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;
Email: [email protected]
Twitter: http://twitter.com/notesio
Instagram: http://instagram.com/notes.io
Facebook: http://facebook.com/notesio
Regards;
Notes.io Team
