Last active
September 17, 2024 16:14
-
-
Save patrickbolle/ff958c82065f4f83936b9c76cf921d04 to your computer and use it in GitHub Desktop.
filter.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#rk_filter { | |
display: none; /* hide filter by default */ | |
flex-wrap: wrap; | |
justify-content: center; | |
margin: 20px 0; | |
} | |
#rk_filter select { | |
margin: 0 5px; | |
padding: 10px 15px; | |
border: 1px solid #ccc; | |
border-radius: 3px; | |
cursor: pointer; | |
min-width: 150px; | |
} | |
#rk_filter select:focus { | |
outline: none; | |
box-shadow: 0 0 5px #333; | |
} | |
#rk_filter .cancel-filter { | |
margin-left: 5px; | |
padding: 10px 15px; | |
color: white; | |
color: white; | |
border-radius: 3px; | |
cursor: pointer; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log("Recipe Kit | filter.js loaded."); | |
console.log(window.rk_filters); | |
// Helper function to get selected tags from the URL | |
function getSelectedTagsFromURL() { | |
const currentPath = window.location.pathname; | |
const selectedTags = []; | |
if (currentPath.includes("/tagged/")) { | |
const tagsSegment = currentPath.split("/tagged/")[1]; | |
const tags = tagsSegment.split("+"); | |
tags.forEach((tag) => { | |
if (tag) { | |
// Decode the URL-encoded tag and replace hyphens with spaces | |
selectedTags.push( | |
decodeURIComponent(tag.trim()).toLowerCase().replace(/-/g, " ") | |
); | |
} | |
}); | |
} | |
return selectedTags; | |
} | |
// Initialize selectedTag for each filter based on the URL | |
window.rk_filters.forEach((filter) => { | |
const selectedTags = getSelectedTagsFromURL(); | |
const matchingTag = filter.tags.find((tag) => { | |
const normalizedTag = tag.trim().toLowerCase(); | |
return selectedTags.includes(normalizedTag); | |
}); | |
filter.selectedTag = matchingTag || ""; | |
}); | |
function capitalizeTag(tag) { | |
if (!tag) return false; | |
return tag | |
.split(/[\s-]+/) | |
.map( | |
(word) => word.charAt(0).toUpperCase() + word.substring(1).toLowerCase() | |
) | |
.join(" "); | |
} | |
// Helper function to update the default option's text | |
function updateDefaultOptionText(select, filter) { | |
const defaultOption = select.querySelector("option[disabled]"); | |
defaultOption.text = `${filter.name}: ${ | |
capitalizeTag(filter.selectedTag) || window.all_translation || "All" | |
}`; | |
} | |
// Helper function to update the URL | |
function updateURL(filters) { | |
const currentPath = window.location.pathname; | |
let newURL = currentPath; | |
let tags = filters | |
.map((filter) => | |
encodeURIComponent( | |
filter.selectedTag.trim().toLowerCase().replace(/\s+/g, "-") | |
) | |
) | |
.filter((tag) => tag); | |
if (tags.length > 0) { | |
// Remove the existing /tagged/ segment from the URL | |
if (currentPath.includes("/tagged/")) { | |
newURL = currentPath.split("/tagged/")[0]; | |
} | |
// Add /tagged/ and append tags | |
newURL += "/tagged/" + tags.join("+"); | |
} | |
window.location.href = newURL; | |
} | |
// Helper function to create and append a filter dropdown | |
function createFilterDropdown(filter, container) { | |
if ( | |
filter.tags.some((tag) => | |
window.all_tags | |
.map((t) => t.trim().toLowerCase()) | |
.includes(tag.trim().toLowerCase()) | |
) | |
) { | |
const select = document.createElement("select"); | |
select.className = "filter-dropdown"; | |
const option = document.createElement("option"); | |
option.text = `${filter.name}: ${ | |
capitalizeTag(filter.selectedTag) || window.all_translation || "All" | |
}`; | |
option.disabled = true; | |
option.selected = true; | |
select.appendChild(option); | |
filter.tags.forEach((tag) => { | |
if ( | |
window.all_tags | |
.map((t) => t.trim().toLowerCase()) | |
.includes(tag.trim().toLowerCase()) | |
) { | |
const option = document.createElement("option"); | |
const capitalizedTag = tag | |
.trim() | |
.split(" ") | |
.map((word) => word.charAt(0).toUpperCase() + word.slice(1)) | |
.join(" "); // Capitalize each word | |
option.value = tag.trim(); | |
option.text = capitalizedTag; | |
select.appendChild(option); | |
} | |
}); | |
select.addEventListener("change", () => { | |
filter.selectedTag = select.value.trim(); | |
updateDefaultOptionText(select, filter); | |
updateURL(window.rk_filters); | |
}); | |
updateDefaultOptionText(select, filter); // Set default text on page load | |
container.appendChild(select); | |
} | |
} | |
// Helper function to create a 'Cancel Filter' button | |
function createCancelFilterButton(container) { | |
const cancelButton = document.createElement("button"); | |
cancelButton.className = "cancel-filter"; | |
cancelButton.innerText = window.cancel_translation || "Cancel Filter"; | |
cancelButton.addEventListener("click", () => { | |
window.location.href = window.blog; | |
}); | |
container.appendChild(cancelButton); | |
} | |
document.addEventListener("DOMContentLoaded", () => { | |
const currentPath = window.location.pathname; | |
const filterContainer = document.getElementById("rk_filter"); | |
if (window.rk_filters.length > 0) { | |
filterContainer.style.display = "flex"; | |
} | |
window.rk_filters.forEach((filter) => { | |
createFilterDropdown(filter, filterContainer); | |
}); | |
if (currentPath.includes("/tagged/")) { | |
createCancelFilterButton(filterContainer); | |
} | |
if (window.h1_placement == true) { | |
// Try to place the filter below the first H1 tag, if not leave it where it is: | |
// Search for the first h1 tag | |
const h1Element = document.querySelector("h1"); | |
// Grab the rk_filter div element | |
const rkFilter = document.getElementById("rk_filter"); | |
// Check if an h1 tag exists | |
// If no h1 tag is found, keep the rk_filter div in its current location | |
if (h1Element) { | |
// If an h1 tag is found, insert the rk_filter div right after it | |
h1Element.insertAdjacentElement("afterend", rkFilter); | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% liquid | |
assign filter_1_name = block.settings.filter_1_name | |
assign filter_1_tags = block.settings.filter_1_tags | split: ',' | |
assign filter_2_name = block.settings.filter_2_name | |
assign filter_2_tags = block.settings.filter_2_tags | split: ',' | |
assign filter_3_name = block.settings.filter_3_name | |
assign filter_3_tags = block.settings.filter_3_tags | split: ',' | |
assign all_tags = blog.tags | uniq | |
%} | |
<script> | |
window.rk_filters = [ | |
{ | |
name: "{{ filter_1_name }}", | |
tags: {{ filter_1_tags | json }} | |
}, | |
{ | |
name: "{{ filter_2_name }}", | |
tags: {{ filter_2_tags | json }} | |
}, | |
{ | |
name: "{{ filter_3_name }}", | |
tags: {{ filter_3_tags | json }} | |
} | |
].map(filter => { | |
filter.tags = filter.tags.map(tag => tag.trim()); | |
return filter; | |
}); | |
window.all_tags = {{ all_tags | json }} || JSON.parse(localStorage.getItem('all_tags')) || []; | |
window.blog = '{{ blog.url }}'; | |
window.h1_placement = {{ block.settings.h1_placement }}; | |
window.all_translation = '{{ block.settings.all_translation }}'; | |
window.cancel_translation = '{{ block.settings.cancel_translation }}'; | |
</script> | |
<div id="rk_filter"></div> | |
<style> | |
#rk_filter { | |
justify-content: {{ block.settings.alignment }} !important; | |
} | |
#rk_filter button { | |
border: 1px solid {{ block.settings.button_colour | default: 'rgb(255, 130, 130)' }}; | |
background-color: {{ block.settings.button_colour | default: 'rgb(255, 130, 130)' }}; | |
} | |
</style> | |
{% schema %} | |
{ | |
"name": "Recipe Kit Filter", | |
"target": "section", | |
"javascript": "filter.js", | |
"stylesheet": "filter.css", | |
"enabled_on": { | |
"templates": ["blog"] | |
}, | |
"settings": [ | |
{ | |
"type": "text_alignment", | |
"id": "alignment", | |
"label": "Alignment" | |
}, | |
{ | |
"type": "checkbox", | |
"label": "Try placing filter near blog title", | |
"id": "h1_placement" | |
}, | |
{ | |
"type": "text", | |
"id": "filter_1_name", | |
"label": "Filter #1 Name (eg. Diet)" | |
}, | |
{ | |
"type": "text", | |
"id": "filter_1_tags", | |
"label": "Filter #1 Tags (eg. vegan, keto)" | |
}, | |
{ | |
"type": "text", | |
"id": "filter_2_name", | |
"label": "Filter #2 Name" | |
}, | |
{ | |
"type": "text", | |
"id": "filter_2_tags", | |
"label": "Filter #2 Tags" | |
}, | |
{ | |
"type": "text", | |
"id": "filter_3_name", | |
"label": "Filter #3 Name" | |
}, | |
{ | |
"type": "text", | |
"id": "filter_3_tags", | |
"label": "Filter #3 Tags" | |
}, | |
{ | |
"type": "color", | |
"id": "button_colour", | |
"label": "Cancel Button Colour" | |
}, | |
{ | |
"type": "header", | |
"content": "Translations", | |
"info": "Modify these fields if you need to change the various default English filter language to your store's language." | |
}, | |
{ | |
"type": "text", | |
"id": "all_translation", | |
"label": "All" | |
}, | |
{ | |
"type": "text", | |
"id": "cancel_translation", | |
"label": "Cancel Filter" | |
} | |
] | |
} | |
{% endschema %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment