4

I have a search function on my site that takes a text input and searches "documents" for a matching string of text, then displays the matching items in a list. This works perfectly. I just need a way to limit the number of list items that can be appended to the list. For example, if there are 4 matching results, then I only want 2 to be displayed.

const documents = [
    { id: 1, innerHTML: "<a data-name='Princess' href='/The_Princess'>The Princess</a>" },
    { id: 2, innerHTML: "<a data-name='Player' href='/The_Player'>The Player</a>" },
    { id: 3, innerHTML: "<a data-name='Narrator' href='/The_Narrator'>The Narrator</a>" },
    { id: 4, innerHTML: "<a data-name='Vessel Adversary' href='/Vessel/Adversary'>Vessel: Adversary</a>" },
];

function performSearch() {
    const query = document.getElementById('searchBox').value.toLowerCase();
    const results = search(query);
    displayResults(results);
}

function search(query) {
    return documents.filter(doc => doc.innerHTML.toLowerCase().includes(query));
}

function displayResults(results) {
    const resultsElement = document.getElementById('results');
    resultsElement.innerHTML = '';
    results.forEach(result => {
        const listItem = document.createElement('li');
        listItem.innerHTML = result.innerHTML;
        resultsElement.appendChild(listItem);
    });
}
<input type="text" id="searchBox" placeholder="Search...">
<button onclick="performSearch()">Search</button>
<ul id="results"></ul>

I've tried using listItem.slice(0, 2), innerHTML.slice(0, 2), listItem.innerHTML.slice(0, 2), and resultsElement.slice(0, 2), but those either didn't do anything or limited the list to only one item, regardless of end value. Is there a way to limit appended children?

2 Answers 2

3

You can use slice like this

function displayResults(results) {
    const resultsElement = document.getElementById('results');
    resultsElement.innerHTML = '';

    // Limit to 2 results
    const limited = results.slice(0, 2);

    limited.forEach(result => {
        const li = document.createElement('li');
        li.innerHTML = result.innerHTML;
        resultsElement.appendChild(li);
    });
}
Sign up to request clarification or add additional context in comments.

1 Comment

this worked!! thank you!
0

You can use the filter function of arrays for this purpose. The first parameter of .filter() is a callback function which gets the current element, the index and the array. In this case the index is of interest. You can implement a function for paging, pass the array, the offset and the page size and then use .filter() to get an array representing a subset of the initial array within the bounds you specify:

const documents = [
    { id: 1, innerHTML: "1" },
    { id: 2, innerHTML: "2" },
    { id: 3, innerHTML: "3" },
    { id: 4, innerHTML: "4" },
    { id: 5, innerHTML: "5" },
    { id: 6, innerHTML: "6" },
    { id: 7, innerHTML: "7" },
    { id: 8, innerHTML: "8" },
    { id: 9, innerHTML: "9" },
    { id: 10, innerHTML: "10" },
    { id: 11, innerHTML: "11" },
    { id: 12, innerHTML: "12" },
    { id: 13, innerHTML: "13" },
    { id: 14, innerHTML: "14" },
    { id: 15, innerHTML: "15" },
    { id: 16, innerHTML: "16" },
    { id: 17, innerHTML: "17" },
    { id: 18, innerHTML: "18" },
    { id: 19, innerHTML: "19" },
    { id: 20, innerHTML: "20" },
    { id: 21, innerHTML: "21" },
    { id: 22, innerHTML: "22" },
    { id: 23, innerHTML: "23" },
    { id: 24, innerHTML: "24" },
];

function getPage(array, offset, pageSize) {
    return array.filter((element, index, array) => ((index >= offset) && (index < offset + pageSize)));
}

function change() {
    let offset = parseInt(document.getElementById("offset").value);
    let size = parseInt(document.getElementById("size").value);
    document.getElementById("output").innerHTML = JSON.stringify(getPage(documents, offset, size));
}
<input type="number" placeholder="offset" id="offset" oninput="change();">
<input type="number" placeholder="page size" id="size" oninput="change();">
<div id="output"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.