mirror of https://github.com/kiwix/libkiwix.git
Add ability to filter by tags in kiwix serve
This change introduces filtering by tags. To filter, the user can click on the tag name and it will filter it. A label is added (clickable) to show the tag filter, it can be clicked to remove the filter
This commit is contained in:
parent
93f2686a94
commit
43ab6dfb6a
File diff suppressed because one or more lines are too long
|
@ -77,6 +77,13 @@
|
|||
return queryNode != null ? queryNode.innerHTML : "";
|
||||
}
|
||||
|
||||
function generateTagLink(tagValue) {
|
||||
tagValue = tagValue.toLowerCase();
|
||||
const humanFriendlyTagValue = humanFriendlyTitle(tagValue);
|
||||
const tagMessage = `Filter by tag "${humanFriendlyTagValue}"`;
|
||||
return `<span class='tag__link' aria-label='${tagMessage}' title='${tagMessage}' data-tag=${tagValue}>${humanFriendlyTagValue}</span>`
|
||||
}
|
||||
|
||||
function generateBookHtml(book, sort = false) {
|
||||
const link = book.querySelector('link[type="text/html"]').getAttribute('href');
|
||||
let iconUrl;
|
||||
|
@ -91,9 +98,9 @@
|
|||
const langCode = getInnerHtml(book, 'language');
|
||||
const language = languages[langCode];
|
||||
const tags = getInnerHtml(book, 'tags');
|
||||
let tagHtml = tags.split(';').filter(tag => {return !(tag.split(':')[0].startsWith('_'))})
|
||||
.map((tag) => {return tag.charAt(0).toUpperCase() + tag.slice(1)})
|
||||
.join(' | ').replace(/_/g, ' ');
|
||||
const tagList = tags.split(';').filter(tag => {return !(tag.startsWith('_'))});
|
||||
const tagFilterLinks = tagList.map((tagValue) => generateTagLink(tagValue));
|
||||
const tagHtml = tagFilterLinks.join(' | ');
|
||||
let downloadLink;
|
||||
let zimSize = 0;
|
||||
try {
|
||||
|
@ -113,17 +120,21 @@
|
|||
}
|
||||
const faviconAttr = iconUrl != undefined ? `style="background-image: url('${iconUrl}')"` : '';
|
||||
const languageAttr = langCode != '' ? `title="${language}" aria-label="${language}"` : 'style="background-color: transparent"';
|
||||
divTag.innerHTML = `<a class="book__link" href="${link}" data-hover="Preview">
|
||||
divTag.innerHTML = `
|
||||
<div class="book__wrapper">
|
||||
<a class="book__link" href="${link}" data-hover="Preview">
|
||||
<div class="book__link__wrapper">
|
||||
<div class="book__icon" ${faviconAttr}></div>
|
||||
<div class="book__header">
|
||||
<div id="book__title">${title}</div>
|
||||
${downloadLink ? `<div class="book__download"><span data-link="${downloadLink}">Download ${humanFriendlyZimSize ? ` - ${humanFriendlyZimSize}</span></div>`: ''}` : ''}
|
||||
</div>
|
||||
<div class="book__description" title="${description}">${description}</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="book__languageTag" ${languageAttr}>${getLanguageCodeToDisplay(langCode)}</div>
|
||||
<div class="book__tags"><div class="book__tags--wrapper">${tagHtml}</div></div>
|
||||
</div></div></a>`;
|
||||
</div></div>`;
|
||||
return divTag;
|
||||
}
|
||||
|
||||
|
@ -333,6 +344,7 @@
|
|||
insertModal(downloadButton);
|
||||
}
|
||||
});
|
||||
refreshTagLinks();
|
||||
}
|
||||
|
||||
async function resetAndFilter(filterType = '', filterValue = '') {
|
||||
|
@ -376,10 +388,45 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addTagElement(tagValue, resetFilter) {
|
||||
const tagElement = document.getElementsByClassName('tagFilterLabel')[0];
|
||||
tagElement.style.display = 'inline-block';
|
||||
const humanFriendlyTagValue = humanFriendlyTitle(tagValue);
|
||||
tagElement.innerHTML = `${humanFriendlyTagValue}`;
|
||||
const tagMessage = `Stop filtering by tag "${humanFriendlyTagValue}"`;
|
||||
tagElement.setAttribute('aria-label', tagMessage);
|
||||
tagElement.setAttribute('title', tagMessage);
|
||||
if (resetFilter)
|
||||
resetAndFilter('tag', tagValue);
|
||||
}
|
||||
|
||||
function refreshTagLinks() {
|
||||
const tagLinks = document.getElementsByClassName('tag__link');
|
||||
[...tagLinks].forEach(elem => {
|
||||
if (!elem.getAttribute('click-listener')) {
|
||||
elem.addEventListener('click', () => addTagElement(elem.dataset.tag, true));
|
||||
elem.setAttribute('click-listener', 'true');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeTagElement(resetFilter) {
|
||||
const tagElement = document.getElementsByClassName('tagFilterLabel')[0];
|
||||
tagElement.style.display = 'none';
|
||||
if (resetFilter)
|
||||
resetAndFilter('tag', '');
|
||||
}
|
||||
|
||||
function updateVisibleParams() {
|
||||
document.querySelectorAll('.filter').forEach(filter => {filter.value = params.get(filter.name) || ''});
|
||||
updateFilterColors();
|
||||
const tagKey = params.get('tag');
|
||||
if (tagKey !== null && tagKey.trim() !== '') {
|
||||
addTagElement(tagKey, false);
|
||||
} else {
|
||||
removeTagElement(false);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('resize', (event) => {
|
||||
|
@ -417,6 +464,8 @@
|
|||
document.querySelectorAll('.filter').forEach(filter => {
|
||||
filter.addEventListener('change', () => {resetAndFilter(filter.name, filter.value)});
|
||||
});
|
||||
const tagElement = document.getElementsByClassName('tagFilterLabel')[0];
|
||||
tagElement.addEventListener('click', () => removeTagElement(true));
|
||||
if (filters) {
|
||||
const currentLink = window.location.search;
|
||||
const newLink = `?${params.toString()}`;
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
</div>
|
||||
<form id='kiwixSearchForm' class='kiwixNav__SearchForm'>
|
||||
<input type="text" name="q" placeholder="Search" id="searchFilter" class='kiwixSearch filter'>
|
||||
<span class="kiwixButton tagFilterLabel"></span>
|
||||
<input type="submit" class="kiwixButton kiwixButtonHover" value="Search"/>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -179,12 +179,12 @@ R"EXPECTEDRESULT( src="/ROOT/skin/jquery-ui/external/jquery/jquery.js?cache
|
|||
src="/ROOT/skin/jquery-ui/jquery-ui.min.js?cacheid=d927c2ff"
|
||||
href="/ROOT/skin/jquery-ui/jquery-ui.min.css?cacheid=e1de77b3"
|
||||
href="/ROOT/skin/jquery-ui/jquery-ui.theme.min.css?cacheid=2a5841f9"
|
||||
href="/ROOT/skin/index.css?cacheid=1aca980a"
|
||||
href="/ROOT/skin/index.css?cacheid=a1acc52f"
|
||||
src: url("/ROOT/skin/fonts/Poppins.ttf?cacheid=af705837") format("truetype");
|
||||
src: url("/ROOT/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype");
|
||||
<script src="/ROOT/skin/isotope.pkgd.min.js?cacheid=2e48d392" defer></script>
|
||||
<script src="/ROOT/skin/iso6391To3.js?cacheid=ecde2bb3"></script>
|
||||
<script type="text/javascript" src="/ROOT/skin/index.js?cacheid=5f0f7683" defer></script>
|
||||
<script type="text/javascript" src="/ROOT/skin/index.js?cacheid=e99ed2dd" defer></script>
|
||||
)EXPECTEDRESULT"
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue