Fragrance Hair Care Makeup Skincare
${product?.brand}
${getTitle(product.familyName, product.name)}
${JSON.parse(product.display_attributes?.tags || '[]').length > 0 ? `
${JSON.parse(product.display_attributes?.tags || '[]').map(tag => { return `${tag} ` }).join('')}
` : ''}
${product.validRating ? `
${generateRating(product.rating)}
${product.reviewCount}
` : ''}
`; }); const container = document.querySelector('.CollectionsGrid__ProductCards.CollectionsGrid__ProductCards--3-Col'); if (container) { if (!append) { container.innerHTML = ''; } const productsEl = fragmentFromString(productsHTML); HSS.registerListeners('Landing Page Event', productsEl); container.appendChild(productsEl); registerGTMForAll(); document.dispatchEvent(new CustomEvent("swym:collections-loaded")); } }; const onClickPage = (page, isActive) => { if (!isActive) { updateState({ pageNumber: page }); } }; const buildPagination = (metadata) => { const store = window.store; const state = store.get('state'); const activePage = state.pageNumber || 1; if (metadata?.maxPage === 1) { return ''; } let paginationHTML = `
`; // Add Previous button const isPrevDisabled = activePage === 1 ? 'disabled' : ''; paginationHTML += ` `; // Add page buttons with ellipsis for hidden pages for (let i = 1; i <= metadata?.maxPage; i++) { const isActive = i === activePage ? 'aria-current="page"' : ''; const isHidden = Math.abs(i - activePage) > 2 && i !== 1 && i !== metadata?.maxPage ? 'hidden' : ''; if (isHidden && i < activePage - 2) { if (!paginationHTML.includes("...
")) { paginationHTML += ` ...
`; } continue; } paginationHTML += ` `; } // Add Next button const isNextDisabled = activePage === metadata?.maxPage ? 'disabled' : ''; paginationHTML += ` `; paginationHTML += ` `; return paginationHTML; }; const updatePagination = (metadata, itemsPerPage, activePage) => { const paginationContainer = document.querySelector('#mb-pagination-desktop'); if (paginationContainer) { paginationContainer.innerHTML = buildPagination(metadata); window.scrollTo(0, 0); } }; const onClearAllFilters = () => { const store = window.store; const state = store.get('state'); updateState({ filters: [], pageNumber: 1, }); }; const handleCheck = (filterElement, from) => { const filterId = filterElement.getAttribute('data-id'); const filterValue = filterElement.getAttribute('data-value'); let isSelected = filterElement.checked ? true : false; // Update all matching elements const elements = document.querySelectorAll(`[data-id="${filterId}"][data-value="${filterValue}"]`); elements.forEach((input) => { input.checked = isSelected; }); // Update state in the store const store = window.store; const state = store.get('state'); const filterIndex = state.filters.findIndex((f) => f.id === filterId); let updatedFilters = [...state.filters]; if (filterIndex > -1) { const existingValueIndex = updatedFilters[filterIndex].values.findIndex((v) => v.value === filterValue); if (existingValueIndex > -1) { updatedFilters[filterIndex].values[existingValueIndex].selected = isSelected; } else { updatedFilters[filterIndex].values.push({ value: filterValue, selected: isSelected, }); } } else { updatedFilters.push({ id: filterId, values: [ { value: filterValue, selected: isSelected, }, ], }); } // Call updateState with the updated filters and other properties updateState({ filters: updatedFilters, pageNumber: 1, }); } const buildFilterLabel = (id, name, facetId, selected) => { return `
${name} `; }; let expandedFilterIds = []; let expandedFilterMobileIds = []; const onExpandFilterDesktop = (el) => { const getId = el.getAttribute('data-id'); const filterWrapper = el.closest('.Filters__Category').querySelector('.Filters__FiltersWrapper'); if (!filterWrapper) { console.log('filterWrapper not found'); return; } const isMobile = window.innerWidth < 769; if (filterWrapper.classList.contains('Filters__FiltersWrapper--open')) { if (isMobile) { expandedFilterMobileIds = expandedFilterMobileIds.filter(id => id !== getId); } else { expandedFilterIds = expandedFilterIds.filter(id => id !== getId); } } else { if (isMobile) { expandedFilterMobileIds.push(getId); } else { expandedFilterIds.push(getId); } } filterWrapper.classList.toggle('Filters__FiltersWrapper--open'); el.querySelector('.Filters__Arrow').classList.toggle('Filters__Arrow--open'); } const buildFilterCategory = (facet, isMobile) => { const labels = facet?.values?.map(value => buildFilterLabel(value.value, value.value, facet.id, value.selected)).join(''); const isExpandedMobile = expandedFilterMobileIds.includes(facet?.id); const isExpandedDesktop = expandedFilterIds.includes(facet?.id); const isExpanded = isMobile ? isExpandedMobile : isExpandedDesktop; return `
${facet.name.toUpperCase() === 'BRAND' ? `
` : ''}
${labels}
`; }; const buildFilters = (facets, isMobile) => { return facets?.filter(facet => !!facet?.values?.length)?.map(facet => buildFilterCategory(facet, isMobile)).join(''); }; const updateFilters = (facets) => { const isMobile = window.innerWidth < 769; const filterContainer = document.querySelector('#bm-filter-container'); const filterContainerMobile = document.querySelector('#bm-filter-container-mobile'); if (filterContainer) { filterContainer.innerHTML = buildFilters(facets, isMobile); } if (filterContainerMobile) { filterContainerMobile.innerHTML = buildFilters(facets, isMobile); } const filterDesktopCount = document.querySelector('#bm-filter-count-desktop'); const selectedFacetsCount = facets.reduce((count, facet) => { if (!facet?.values) return count; return count + facet?.values?.filter(value => value.selected).length; }, 0); if (filterDesktopCount) { if (selectedFacetsCount > 0) { filterDesktopCount.innerHTML = `(${selectedFacetsCount})`; } else { filterDesktopCount.innerHTML = ''; } } updateTopSelectedChips(); }; const updateTopSelectedChips = () => { const store = window.store; const state = store.get('state'); const facets = state.filters; const hasAtLeastOneSelected = facets?.some(facet => facet?.values?.some(value => value.selected === true)); const diableBtn = document.querySelector('#opt-clear-btn'); if (!hasAtLeastOneSelected) { const container = document.querySelector('#bm-filter-chips'); const containerMobile = document.querySelector('#bm-filter-chips-mobile'); if (container) { container.innerHTML = ''; } if (containerMobile) { containerMobile.innerHTML = ''; containerMobile.style.display = 'none' } if (diableBtn) { diableBtn.setAttribute('disabled', 'true'); } return; } if (diableBtn) { diableBtn.removeAttribute('disabled'); } let selectedChips = `
`; facets.forEach((facet, index) => { const selectedValues = (facet.values || []).filter( (value) => value.selected === true, ); if (selectedValues.length > 0) { selectedValues.forEach((v) => { let title; try { title = v.value.replace(" to ", " - "); } catch (err) { title = v.value || ''; } selectedChips += ` `; }); } }); selectedChips += `
`; selectedChips += ``; const container = document.querySelector('#bm-filter-chips'); const containerMobile = document.querySelector('#bm-filter-chips-mobile'); if (container) { container.innerHTML = selectedChips; } if (containerMobile) { containerMobile.innerHTML = selectedChips; containerMobile.style.display = 'flex' } }; const updatePriceRange = (products) => { products?.forEach((product) => { const calculatedSavings = calculateSavings( product?.regularPrice, product?.salePrice ); const priceRanges = product?.family_attributes?.priceRanges; const salePriceRanges = product?.family_attributes?.salePriceRanges; if (priceRanges?.length === 2 && salePriceRanges?.length === 2) { const initialSaleRange = parseFloat(salePriceRanges[0]); const finalSaleRange = parseFloat(salePriceRanges[1]); const initialPriceRange = parseFloat(priceRanges[0]); const finalPriceRange = parseFloat(priceRanges[1]); const rangeContainer = document.querySelector(`#optBMPrice-${product?.sku}`); if (rangeContainer && (initialSaleRange !== initialPriceRange || finalSaleRange !== finalPriceRange || (initialSaleRange === initialPriceRange && finalSaleRange === finalPriceRange))) { rangeContainer.innerHTML = `
$${initialSaleRange} - $${finalSaleRange}
${calculatedSavings?.save > 0 ? `
$${product?.regularPrice} (${Math.round(calculatedSavings?.savingsPercentage)}% off)
` : ''} `; } } }); }; const getPageData = async (metadataOnly = false) => { const productsPerPage = '24'; try { const store = window.store; const state = store.get('state'); const { pageNumber, maxPageNumber, sort, sortDirection, filters, pageSize, facets: previousFactes } = state; let body = { o: searchOrgId, p: searchPageId, pageSize, pageNum: pageNumber, sort, sortDirection, facets: filters, }; const selectedFilters = filters?.filter(facet => facet?.values?.some(value => value.selected === true))?.map(selected => { const findFacet = previousFactes?.find(it => it?.id === selected?.id); if (findFacet) { return ({ ...selected, name: findFacet?.name }) } return selected; }); const data = await HSS.search(body); // Loop through data.results and add "validRating" data?.results?.forEach((product) => { product.validRating = Math.round(product.rating) > 3 || (Math.round(product.rating) < 3 && product.reviewCount > 5); }); if (!metadataOnly) { updateProducts(data?.results, false); } const priorityOrder = [ "SORT BY", "BRAND", "PRICE", "TYPE", "BENEFIT", "CONCERN", "INGREDIENT PREFERENCE", "SIZE", "SHOP BY" ]; const facets = data.metadata.facets?.filter(facet => !!facet?.values?.length && facet.values.length > 1); selectedFilters.forEach(item => { const existingFacet = facets.find(facet => facet?.id === item?.id); if (existingFacet) { const uniqueValues = item.values.filter( newValue => !existingFacet.values.some(existingValue => existingValue.value === newValue.value) ); existingFacet.values = [...existingFacet.values, ...uniqueValues]; } else { facets.push(item); } }); facets.sort((a, b) => { const indexA = priorityOrder.indexOf(a?.name?.toUpperCase()); const indexB = priorityOrder.indexOf(b?.name?.toUpperCase()); if (indexA !== -1 && indexB !== -1) { // Both are in the priority list, sort by their order return indexA - indexB; } else if (indexA !== -1) { // Only a is in the priority list, it should come first return -1; } else if (indexB !== -1) { // Only b is in the priority list, it should come first return 1; } else { // Neither is in the priority list, sort alphabetically return a?.name?.localeCompare(b?.name); } }) const filteredFacets = updateState({ maxPageNumber: data.metadata.maxPage, totalResults: data.metadata.totalResults, facets: facets }, false) updateProductsCount(data?.metadata?.totalResults || 0); //updatePriceRange(data.results); updatePagination(data?.metadata, pageSize, pageNumber); updateFilters(facets) console.log(facets, 'facets') } catch (ex) { console.log('---PageData Error---', ex); } }; const onSearchBrand = (inputElement) => { const store = window.store; const state = store.get('state'); const facets = state.facets; const searchTerm = inputElement.value.toLowerCase(); // Convert search term to lowercase for case-insensitive matching // Find the 'Brand' facet from the provided data const brandFacet = facets.find(facet => facet.name === 'Brand'); if (!brandFacet) return; // Filter the brand values based on the search term const filteredBrands = brandFacet.values.filter(value => value.value.toLowerCase().includes(searchTerm) ); // Build the labels for the filtered brands const labels = filteredBrands.map(value => buildFilterLabel(value.value, value.value, brandFacet.id, value.selected) ).join(''); // Update the DOM with the filtered brands const brandFilterWrapper = document.querySelectorAll(`.facet-${brandFacet.name}`); if (brandFilterWrapper) { brandFilterWrapper.forEach(it => { it.innerHTML = labels; }) } }; const onClear = () => { // Clear the input field value const searchInput = document.querySelectorAll('.search-brand'); if (searchInput) { searchInput.forEach(input => { input.value = ''; onSearchBrand(input); }) } }; document.addEventListener('DOMContentLoaded', async () => { registerGTMForAll(); HSS.initSearch(hssUrl); let isMetaOnly = true; await getPageData(isMetaOnly); }); document.addEventListener('DOMContentLoaded', async () => { const store = window.store; const state = store.get('state'); const sort = state.sort || null; const sortDirection = state.sortDirection || null; const combinedSort = sort && sortDirection && sortDirection !== 'undefined' ? `${sort}_${sortDirection}` : ''; const finalSort = combinedSort ? combinedSort : sort; //Featured const DefaultSort = 'featured'; //Price, High to Low const price_desc = 'price_desc' //Price, Low To High const price_asc = 'price_asc' //Top Rated const rating = 'rating' const sortBtn = document.querySelectorAll('#mb-sort-label'); if (!finalSort) { const findDefaultInput = `input[name="sort-"][value="featured"]`; const featuredSort = document.querySelectorAll(findDefaultInput); if (!!featuredSort.length) { featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Featured'; }) } return; } const featuredSort = document.querySelectorAll(`input[name="sort-"][value="${finalSort}"]`); if (!featuredSort.length) { const findDefaultInput = `input[name="sort-"][value="featured"]`; const featuredSort = document.querySelectorAll(findDefaultInput); if (featuredSort.length) { featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Featured'; }) } return; } switch (finalSort) { case DefaultSort: featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Featured'; }) break; case price_desc: featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Price, High to Low'; }) break; case price_asc: featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Price, Low to High'; }) break; case rating: featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Top Rated'; }) break; default: if (!!featuredSort.length) { featuredSort.forEach((sort) => { sort.checked = true; }); sortBtn.forEach(btn => { btn.innerHTML = 'Featured'; }) } break; } }) document.addEventListener('DOMContentLoaded', async () => { function swymCallbackFn(swat){ document.addEventListener("swym:collections-loaded", function(){ swat.initializeActionButtons(".CollectionsGrid__ProductCards.CollectionsGrid__ProductCards--3-Col"); }) } if(!window.SwymCallbacks){ window.SwymCallbacks = []; } window.SwymCallbacks.push(swymCallbackFn); })
Bumble and Bumble
Don't Blow It Hairstyler
BestSeller
Bumble and Bumble
Styling Creme
Bumble and Bumble
Brilliantine
Bumble and Bumble
Sumo Clay
R+Co
Velvet Curtain Cotton Touch Texture Balm
Moroccanoil
Molding Cream
Oribe
Supershine Moisturizing Cream
BestSeller
Bumble and Bumble
Sumotech
Oribe
Imperial Blowout Transformative Styling Crème
BestSeller
Virtue
6-In-1 Styling Paste
BestSeller
Bumble and Bumble
Semisumo Wax
Oribe
Rough Luxury Soft Molding Paste
BestSeller
Christophe Robin
Luscious Curl Defining Cream
Philip Kingsley
Maximizer Strand Plumping Cream
Rahua
Control Cream Anti-Frizz Curl Styler
Achieve effortlessly tousled tresses and runway-ready volume with our curated collection of hair texturizing creams. Perfect for those who crave a touch of drama in their daily 'do, these creams are your secret weapon for adding that enviable oomph to your locks. Whether you're channeling beachy waves or a chic, lived-in look, these styling saviors offer the perfect balance of hold and movement. Elevate your hair game with confidence, knowing you're just a dollop away from fabulous texture and style that speaks volumes.
Related Products
Olaplex
No.3 Hair Perfector 8.5 fl oz
Briogeo
Don't Despair, Repair! Deep Conditioning Mask 2 fl oz
Oribe
Dry Texturizing Spray 2.2 oz
Olaplex
No. 0 Intensive Bond Building Hair Treatment
Related links Hair Styling Cream Curl Smoothing Creams Hair Creams For Blowdrying Conditioners For Hair Texture Creams For Wavy Hair Hair Mousses For Texture Textured Hair Care Hydrating Hair Cream Hair Products For Texture Texturizing Hair Spray