From 9117f65f7248582aa3f7b3ccf4a6b8767dbb3717 Mon Sep 17 00:00:00 2001 From: Alexis Rodriguez Reyes Date: Fri, 24 Jan 2025 12:47:59 -0500 Subject: [PATCH] Added theme related styles, highlighted and order search --- js/modules/es4/search.js | 220 -------------------- js/modules/es4/site-search.js | 93 +++++++-- js/modules/site-search.js | 93 +++++++-- templates/data/meta-info.json | 2 +- templates/data/site-search.json | 8 +- templates/includes/documentation-header.php | 2 +- 6 files changed, 157 insertions(+), 261 deletions(-) delete mode 100644 js/modules/es4/search.js diff --git a/js/modules/es4/search.js b/js/modules/es4/search.js deleted file mode 100644 index 41dd566f..00000000 --- a/js/modules/es4/search.js +++ /dev/null @@ -1,220 +0,0 @@ -//import accessibility from "../../enable-node-libs/accessibility-js-routines/dist/accessibility.module"; -//import FlexSearch from '../../node_modules/flexsearch/dist/flexsearch.bundle.module.min'; - -//const FlexSearch = require("flexsearch"); - -//import data from "./search.json"; -const search = new (function() { - //const FlexSearch = require('flexsearch'); - - let curSearch; - let inputTarget = null; - - this.init = () => { - - // Step 1: Example data this needs to be extracted from website in this form final result is shown here - const documents = [ - { id: '1', title: 'Sample Title 1', description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' }, - { id: '2', title: 'Sample Title 2', description: 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.' }, - // Add more documents as needed - ]; - - // Step 2: Adding index/document to the library - var index = new FlexSearch.Document({ - tokenize: "forward", - cache: 100, - document: { - id: 'id', - store: [ - "title", "description" - ], - index: ["title", "description"] - } - }); - - documents.forEach(item => { - index.add({ - id: item.id, - title: item.title, - description: item.description - }); - }); - - - // Step 3: Searching - const query = 'sample'; // Example search query - const results = index.search(query); - - console.log('Results here!!!!') - - // Step 4: Display search results - console.log(results); - - - - - - } - - this.init3 = () => { - console.log("initialization 3"); - //const comboboxElement = document.querySelector('.enable-combobox'); - //const combobox = new enableComboboxes(); - enableComboboxes.init(); - console.log("initlaize 3") - - - //Add minisearch - const miniSearch = new MiniSearch({ - fields: ['title', 'keywords'], // fields to index for full-text search - storeFields: ['title', 'link'] // fields to return with search results - }); - - // - - //miniSearch.addAll(documents) - fetch('/json/search.json') - .then(response => response.json()) - .then(data => { - console.log(data) - - // Index all documents - - return miniSearch.addAll(data) - - }) - .catch(error => { - console.error('Error fetching the JSON file:', error); - }); - - //Add custom event listener for input and populating the output - document.getElementById('aria-fruit').addEventListener('input', function(e) { - - - console.log("aria-fruit") - }); - - - - } - - - this.init2 = () => { - const documents = [ - { id: 1, title: 'Moby Dick', author: { name: 'Herman Melville' }, pubDate: new Date(1851, 9, 18) }, - { id: 2, title: 'Zen and the Art of Motorcycle Maintenance', author: { name: 'Robert Pirsig' }, pubDate: new Date(1974, 3, 1) }, - { id: 3, title: 'Neuromancer', author: { name: 'William Gibson' }, pubDate: new Date(1984, 6, 1) }, - { id: 4, title: 'Zen in the Art of Archery', author: { name: 'Eugen Herrigel' }, pubDate: new Date(1948, 0, 1), link: "" }, - // ...and more - ] - - - const miniSearch = new MiniSearch({ - fields: ['title', 'keywords'], // fields to index for full-text search - storeFields: ['title', 'link'] // fields to return with search results - }) - //miniSearch.addAll(documents) - fetch('/json/search.json') - .then(response => response.json()) - .then(data => { - console.log(data) - - // Index all documents - - return miniSearch.addAll(data) - - }) - .catch(error => { - console.error('Error fetching the JSON file:', error); - }); - - - - - - - - // Search with default options - - // console.log('search results', results) - - ///Add event listener - // Handling the input event for the search bar - document.getElementById('search-input').addEventListener('input', function(e) { - - inputTarget = e.target; - // console.log(e.target) - closeAllLists(); - const searchTerm = this.value; - const list = document.getElementById('search-results'); - list.style.display = 'block'; - // list.innerHTML = ''; - let filteredItems = miniSearch.search(searchTerm, { prefix: false, fuzzy: 1 }) - let auto = miniSearch.autoSuggest(searchTerm); - console.log('auto', auto) - - const a = document.getElementById('autocomplete-items'); - - if (searchTerm && searchTerm !== curSearch) { - - - // const filteredItems = results[0].result; - filteredItems.forEach(item => { - const listItem = document.createElement('li'); - //console.log('map', item) - listItem.textContent = item.title; - listItem.classList.add('search-result-item'); - //list.appendChild(listItem); - - var link = document.createElement('a'); - link.href = item.link; - - - // const listItem = document.createElement('DIV'); - // listItem.textContent = `

${item.title}

`; - - link.append(listItem) - list.append(link) - - - - // a.appendChild(link); - - - }); - } - - curSearch = searchTerm; - }); - - function closeAllLists() { - - /*close all autocomplete lists in the document, - except the one passed as an argument:*/ - var list = document.getElementById("search-results"); - while (list.firstChild){ - list.firstChild.remove(); - } - //list.style.display = 'none' - } - - - - document.addEventListener("click", function (e) { - - if (e.target != inputTarget){ - closeAllLists(e.target); - } - - }); - - //console.log("results2", results) - - } - function execute() { - - } - - - -}); \ No newline at end of file diff --git a/js/modules/es4/site-search.js b/js/modules/es4/site-search.js index b64491c1..de87e557 100644 --- a/js/modules/es4/site-search.js +++ b/js/modules/es4/site-search.js @@ -5,38 +5,93 @@ const search = new (function() { function removeListItems(listId) { - if (!list.firstChild) return; + if (!list || !list.firstChild) return; var list = document.getElementById(listId); while (list.firstChild){ list.firstChild.remove(); } } - function fetchSearchData(){ - + function fetchSearchData() { fetch('/templates/data/site-search.json') .then(response => response.json()) .then(data => { - - //Add all options to the list - const list = document.getElementById('home-search__list'); - - for (let i = 0; i < data.length; i++){ - const listItem = document.createElement('li'); - const link = document.createElement('a'); - link.textContent = data[i].title; - listItem.setAttribute('role', 'option'); - listItem.setAttribute('tabindex', '-1'); - link.setAttribute('href', data[i].link); - listItem.appendChild(link) - list.append(listItem); - } - + const inputField = document.querySelector('[role="combobox"]'); + const list = document.getElementById('home-search__list'); + + inputField.addEventListener('input', () => { + const searchTerm = inputField.value.trim().toLowerCase(); + + removeListItems('home-search__list'); + clearComboboxState(); + + // Separate title and descriptions to order accordingly + const titleMatches = []; + const descMatches = []; + + data.forEach(item => { + const originalTitle = item.title; + const originalDesc = item.desc; + + if (originalTitle.toLowerCase().includes(searchTerm)) { + titleMatches.push(item); + } else if (originalDesc.toLowerCase().includes(searchTerm)) { + descMatches.push(item); + } + }); + + // Helper function to populate list + const populateList = (items) => { + items.forEach(item => { + const listItem = document.createElement('li'); + listItem.setAttribute('role', 'option'); + listItem.setAttribute('tabindex', '-1'); + + const link = document.createElement('a'); + link.setAttribute('href', item.link); + link.style.display = 'block'; + link.style.textDecoration = 'none'; + + // Highlight title and description + const title = document.createElement('strong'); + title.innerHTML = highlightText(item.title, searchTerm); + + const desc = document.createElement('p'); + desc.innerHTML = highlightText(item.desc, searchTerm); + desc.style.margin = '4px 0'; + + link.appendChild(title); + link.appendChild(document.createElement('br')); + link.appendChild(desc); + + listItem.appendChild(link); + list.appendChild(listItem); + }); + }; + + populateList(titleMatches); + populateList(descMatches); + enableComboboxes.init(); + }); }) .catch(error => { console.error('Error fetching the JSON file:', error); - }); + }); + } + + function highlightText(text, searchTerm) { + if (!searchTerm) return text; + const regex = new RegExp(`(${searchTerm})`, "gi"); + return text.replace(regex, '$1'); + } + + function clearComboboxState() { + const listbox = document.querySelector('[role="listbox"]'); + if (listbox) { + listbox.innerHTML = ''; + } + enableComboboxes.list = []; } this.init = () => { diff --git a/js/modules/site-search.js b/js/modules/site-search.js index cbd890a8..c7fff73c 100644 --- a/js/modules/site-search.js +++ b/js/modules/site-search.js @@ -7,38 +7,93 @@ const search = new function () { function removeListItems(listId) { - if (!list.firstChild) return; + if (!list || !list.firstChild) return; var list = document.getElementById(listId); while (list.firstChild){ list.firstChild.remove(); } } - function fetchSearchData(){ - + function fetchSearchData() { fetch('/templates/data/site-search.json') .then(response => response.json()) .then(data => { - - //Add all options to the list - const list = document.getElementById('home-search__list'); - - for (let i = 0; i < data.length; i++){ - const listItem = document.createElement('li'); - const link = document.createElement('a'); - link.textContent = data[i].title; - listItem.setAttribute('role', 'option'); - listItem.setAttribute('tabindex', '-1'); - link.setAttribute('href', data[i].link); - listItem.appendChild(link) - list.append(listItem); - } - + const inputField = document.querySelector('[role="combobox"]'); + const list = document.getElementById('home-search__list'); + + inputField.addEventListener('input', () => { + const searchTerm = inputField.value.trim().toLowerCase(); + + removeListItems('home-search__list'); + clearComboboxState(); + + // Separate title and descriptions to order accordingly + const titleMatches = []; + const descMatches = []; + + data.forEach(item => { + const originalTitle = item.title; + const originalDesc = item.desc; + + if (originalTitle.toLowerCase().includes(searchTerm)) { + titleMatches.push(item); + } else if (originalDesc.toLowerCase().includes(searchTerm)) { + descMatches.push(item); + } + }); + + // Helper function to populate list + const populateList = (items) => { + items.forEach(item => { + const listItem = document.createElement('li'); + listItem.setAttribute('role', 'option'); + listItem.setAttribute('tabindex', '-1'); + + const link = document.createElement('a'); + link.setAttribute('href', item.link); + link.style.display = 'block'; + link.style.textDecoration = 'none'; + + // Highlight title and description + const title = document.createElement('strong'); + title.innerHTML = highlightText(item.title, searchTerm); + + const desc = document.createElement('p'); + desc.innerHTML = highlightText(item.desc, searchTerm); + desc.style.margin = '4px 0'; + + link.appendChild(title); + link.appendChild(document.createElement('br')); + link.appendChild(desc); + + listItem.appendChild(link); + list.appendChild(listItem); + }); + }; + + populateList(titleMatches); + populateList(descMatches); + enableComboboxes.init(); + }); }) .catch(error => { console.error('Error fetching the JSON file:', error); - }); + }); + } + + function highlightText(text, searchTerm) { + if (!searchTerm) return text; + const regex = new RegExp(`(${searchTerm})`, "gi"); + return text.replace(regex, '$1'); + } + + function clearComboboxState() { + const listbox = document.querySelector('[role="listbox"]'); + if (listbox) { + listbox.innerHTML = ''; + } + enableComboboxes.list = []; } this.init = () => { diff --git a/templates/data/meta-info.json b/templates/data/meta-info.json index b55aa366..1e780919 100644 --- a/templates/data/meta-info.json +++ b/templates/data/meta-info.json @@ -357,7 +357,7 @@ "img.php": { "sectionPages": [ { "content": "Static Content" }], "title": "Images", - "desc": "How to code both >img< tags and background images so they are understandable by screen reader users.", + "desc": "How to code both <img> tags and background images so they are understandable by screen reader users.", "searchable": true }, "infographic.php": { diff --git a/templates/data/site-search.json b/templates/data/site-search.json index 48025604..055f965c 100644 --- a/templates/data/site-search.json +++ b/templates/data/site-search.json @@ -134,7 +134,7 @@ { "id": 28, "title": "Images", - "desc": "How to code both >img< tags and background images so they are understandable by screen reader users.", + "desc": "How to code both <img> tags and background images so they are understandable by screen reader users.", "link": "/img.php" }, { @@ -328,5 +328,11 @@ "title": "Bookmarklets to Test Accessibility Features On A Page", "desc": "The bookmarklets on this page are designed to help developers check if certain features are coded correctly on a webpage.", "link": "/bookmarklets.php" + }, + { + "id": 72, + "title": "Generating Accessible PDFs", + "desc": "Step-by-step guide to generate accessible PDFs with Open HTML to PDF and SpringBoot.", + "link": "/accessible-pdf-generation.php" } ] \ No newline at end of file diff --git a/templates/includes/documentation-header.php b/templates/includes/documentation-header.php index 23dfe475..54e9b0ce 100755 --- a/templates/includes/documentation-header.php +++ b/templates/includes/documentation-header.php @@ -51,7 +51,7 @@ class="site-search__icon" >