Files
bqkc/_includes/js/browse-simple-js.html
Nasir Anthony Montalvo 526096840e Initial commit
2025-11-13 14:48:58 -06:00

257 lines
9.0 KiB
HTML

<script>
/* add items */
var items = [
{% for item in items %}
{ {% for f in fields %}{% if item[f.field] %}{{ f.field | escape | jsonify }}:{{ item[f.field] | strip | jsonify }}, {%- endif -%}{%- endfor -%}
{% if item.image_thumb %}"img": {{ item.image_thumb | relative_url | jsonify }}, {%- endif -%}
{% if item.display_template %}"display_template": {{ item.display_template | jsonify }}, {%- endif -%}
{% if item.format %}"format": {{ item.format | jsonify }}, {%- endif -%}
{% if item.image_alt_text %}"alt": {{ item.image_alt_text | escape | jsonify }}, {%- endif -%}
"title":{{ item.title | strip | escape | jsonify }},
{% if item.parentid %}"parent": {{ item.parentid | jsonify }}, {%- endif -%}
"id":{{ item.objectid | jsonify }} }{% unless forloop.last %},{% endunless %}{%- endfor -%}
];
{% include helpers/get-icon.js %}
/* function to create cards for each item */
function makeCard(obj) {
// placeholder image for lazyload
var placeholder = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 2'%3E%3C/svg%3E";
// find item link
var itemHref = `{{ '/items/' | relative_url }}${ obj.parent ? obj.parent + ".html#" + obj.id : obj.id + ".html"}`;
// find image
var imgSrc, thumbIcon;
// if there is a thumb in the csv display it
if(obj.img) {
imgSrc = obj.img;
// else add an icon based on display_template or format
} else {
thumbIcon = getIcon(obj.template,obj.format,"thumb");
}
var imgAlt = obj.alt ? obj.alt : obj.title;
// start card
var card = '<div class="item col-lg-4 col-md-6 mb-2"><div class="card">';
// top image for items with image
if(imgSrc) {
card += '<a href="' + itemHref + '"> <img class="card-img-top lazyload" src="' + placeholder + '" data-src="' + imgSrc + '" alt="' + imgAlt + '"></a>';
}
// title
card += '<div class="card-body text-center"> <h3 class="card-title h4"><a href="' + itemHref + '" class="text-dark">' + obj.title + '</a></h3>';
// icon thumb for item without image
if(thumbIcon){
card += '<p><a href="' + itemHref + '">' + thumbIcon + '</a></p>';
}
// other fields
card += '<p class="card-text">';
{% for f in fields %}{% unless f.hidden == 'true' %}
if(obj[{{ f.field | jsonify }}]){
{% if f.display_name %}card += '<strong>{{ f.display_name }}:</strong> ';{% endif %}
{% if f.btn == 'true' %}
var btns = obj[{{ f.field | jsonify }}].split(";");
for (var i = 0, len = btns.length; i < len; i++) {
if(btns[i] != "") {
card += '<a class="btn btn-sm btn-secondary m-1 text-wrap" href="{{ page.url | relative_url }}#' + encodeURIComponent(btns[i].trim()) + '">' + btns[i].trim() + '</a>';
}
}
{% else %}
card += obj[{{ f.field | jsonify }}];
{% endif %}
{% unless forloop.last %}card += '<br>';{% endunless %}
}
{% endunless %}{% endfor %}
card += '</p>';
// media type
if(obj.template && obj.template != "") {
mediaIcon = getIcon(obj.template,obj.format,"hidden");
card += '<p class="card-text"><small><a class="btn btn-sm btn-outline-secondary" href="{{ page.url | relative_url }}#' + encodeURIComponent(obj.template) + '">' +
obj.template.toUpperCase().replace("_"," ") + ' ' + mediaIcon + '</a></small></p>';
}
// view button
card += '<hr><a href="' + itemHref + '" class="btn btn-sm btn-light" title="link to ' + obj.title + '">View Full Record</a>';
// close divs
card += '</div></div></div>';
// send back big string
return card;
}
/* filter items function */
function filterItems(arr,q,field) {
// show loading icon
loadingIcon.classList.remove("d-none");
// dont filter if no q
if (q=="") {
var filteredItems = arr;
} else {
q = q.trim().toUpperCase();
// js indexOf filter
var filteredItems = [];
for (var i = 0, len = arr.length; i < len; i++) {
var val = "";
// if field is specified, only search that field
if (field && field !== "all" && arr[i][field]) {
val = arr[i][field] + " ";
} else {
// search all fields
for (var k in arr[i]) {
if (k != "img") { val += arr[i][k] + " "; }
}
}
if(val.toUpperCase().indexOf(q) != -1){
filteredItems.push(arr[i]);
}
}
}
// add number
document.querySelector("#numberOf").innerHTML = filteredItems.length + " of {{ items | size }} items";
// add stuff, make cards first in giant var, then add all at once to speed things up
var cards = "";
for (var i = 0, len = filteredItems.length; i < len; i++) {
cards += makeCard(filteredItems[i]);
}
browseItemsDiv.innerHTML = cards;
// finish
if (q != "") {
filterTextBox.focus();
}
loadingIcon.classList.add("d-none");
};
/* Fisher-Yates shuffle https://bost.ocks.org/mike/shuffle/ */
function shuffle(array) {
var m = array.length, t, i;
while (m) {
i = Math.floor(Math.random() * m--);
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}
/* init browse page */
/* set default sort or randomize items once at page load */
{% if site.data.theme.default-sort-field %}
var defaultSort = "{{ site.data.theme.default-sort-field }}".toLowerCase();
// Apply default sort
sorting(items, defaultSort);
// Update UI to show default sort is active
var defaultSortButton = document.querySelector('[data-filter="' + defaultSort + '"]');
if (defaultSortButton) {
defaultSortButton.classList.add("active");
var sortFilter = document.querySelector("#sortFilter");
if (sortFilter) {
sortFilter.innerHTML = defaultSortButton.textContent;
}
}
{% else %}
/* randomize items once at page load */
shuffle(items);
{% endif %}
/* set some elements */
var loadingIcon = document.querySelector("#loadingIcon");
var filterTextBox = document.querySelector('#filterTextBox');
var filterButton = document.querySelector("#filterButton");
var browseItemsDiv = document.querySelector("#browseItems");
/* filter if hash in initial URL */
var query = "";
var searchField = "all";
if(window.location.hash) {
var hashValue = decodeURIComponent(location.hash.substr(1));
if (hashValue != 'maincontent') {
// check if hash contains field:query format
if (hashValue.includes(":")) {
var parts = hashValue.split(":");
searchField = parts[0];
query = parts.slice(1).join(":"); // rejoin in case value contains colons
} else {
query = hashValue;
}
} else {
query = "";
}
filterTextBox.value = query;
filterItems(items,query,searchField);
} else {
query = "";
filterItems(items,query,searchField);
}
/* filter form */
function submitFilter() {
query = filterTextBox.value;
window.location.hash = encodeURIComponent(query);
}
/* reset filters */
function resetFilter() {
query = "";
filterTextBox.value = query;
window.location.hash = encodeURIComponent(query);
}
/* filter if hash changes */
window.addEventListener("hashchange", function() {
// read hash
var hashValue = decodeURIComponent(location.hash.substr(1));
if (hashValue != 'maincontent') {
// check if hash contains field:query format
if (hashValue.includes(":")) {
var parts = hashValue.split(":");
searchField = parts[0];
query = parts.slice(1).join(":"); // rejoin in case value contains colons
} else {
searchField = "all";
query = hashValue;
}
filterTextBox.value = query;
// filter
filterItems(items,query,searchField);
}
});
/* item array sorting function */
function sorting(json_object, key_to_sort_by) {
function sortByKey(a, b) {
var x = a[key_to_sort_by];
var y = b[key_to_sort_by];
if (typeof x === 'string' ) { x = x.toUpperCase(); }
if (typeof y === 'string' ) { y = y.toUpperCase(); }
return ((x==null) ? 1: (y==null) ? -1: (x < y) ? -1 : ((x > y) ? 1 : 0));
}
json_object.sort(sortByKey);
};
/* add sort function on click of sort options */
var sortFilter = document.querySelector("#sortFilter");
var sortOptions = document.querySelectorAll(".browse-sort-item");
sortOptions.forEach((button) => {
button.addEventListener("click", (event) => {
// get the sort field
var field = button.dataset.filter;
var display_name = button.textContent;
// get current filter
var query = filterTextBox.value;
// switch active sort option
sortOptions.forEach((option) => { option.classList.remove("active"); } );
button.classList.add("active");
sortFilter.innerHTML = display_name;
// send to sort and filter
if (field != 'random') {
sorting(items, field);
filterItems(items, query);
}
else {
shuffle(items);
filterItems(items, query);
}
});
});
</script>