This function is searching from a Json data the field "title". Please, how can I modify this to include multiple fields, like: "tags", "author" etc.? Thanks!
document.addEventListener('DOMContentLoaded', function(event) {
const search = document.getElementById('search');
const results = document.getElementById('results');
let data = [];
let search_term = '';
fetch('/search.json')
.then(response => response.json())
.then(data_server => {
data = data_server;
});
search.addEventListener('input', event => {
search_term = event.target.value.toLowerCase();
showList();
});
const showList = () => {
results.innerHTML = '';
if (search_term.length <= 0) return;
const match = new RegExp(`${search_term}`, 'gi');
let result = data.filter(name => match.test(name.title));
if (result.length == 0) {
const li = document.createElement('li');
li.innerHTML = `No results found 😢`;
results.appendChild(li);
}
result.forEach(e => {
const li = document.createElement('li');
li.innerHTML = `<a href="${e.url}">${e.title}</a>`;
results.appendChild(li);
});
};
});
change
let result = data.filter(name => match.test(name.title));
to
let result = data.filter(name => match.test(name.title) || match.test(name.tags) || match.test(name.auther));
It may be an idea to filter on all entries of the objects within the Array retrieved from the json.
Here's a minimal reproducable example, using Event Delegation.
document.addEventListener(`click`, handle);
const data = getJSONFakeData();
function handle(evt) {
if (evt.target.id === `search`) {
return searchJSON();
}
}
function searchJSON() {
const resultsDiv = document.querySelector(`#results`);
resultsDiv.textContent = ``;
const nothingFound = isEmpty =>
resultsDiv.insertAdjacentHTML(
`beforeend`,
`<h3>${isEmpty
? `😢 No input`
: `No results found 😢`}</h3>` );
const term = document.querySelector(`#term`).value.trim();
if (term.length < 1) {
return nothingFound(true);
}
const re = new RegExp(term, `gi`);
// filter here
const results = data
.filter( entry => Object.entries(entry)
.find( ([, value]) => re.test(value) )
);
if (results.length) {
let elems = [];
results.forEach( result => {
const res = Object.entries(result)
.reduce( (acc, [key, value]) =>
acc.concat(`<i>${key}</i>: ${value};<br>`), ``);
elems.push(`<li>${res}</li>`);
});
return resultsDiv.insertAdjacentHTML(
`beforeend`,
`<ul>${elems.join(``)}</ul>`);
}
return nothingFound();
}
function getJSONFakeData() {
return [{
title: `title1`,
author: `author1`,
tags: `science, medicine`,
editor: `Springer Verlag`
},
{
title: `title2`,
author: `author2`,
tags: `automotive, engine`,
editor: `Elsevier`
},
{
title: `title3`,
author: `author3`,
tags: `programming, functional, loops`,
editor: `Elsevier`
},
];
}
body {
font: normal 12px/15px verdana, arial;
margin: 2em;
}
<input type="text" id="term" value="Elsevier">
<button id="search">Find</button>
<div id="results"></div>