Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

145
Views
Js filter a multiple page list

I have a working filtered list using JS, but the amount of list elements is growing. So I need to divide the list in pages, but for the filter to keep working for the whole list, even if the list element is not showing because it is in another page.

I've seen how to make a "previous" and "next" buttons for list, but it breaks down the filter js, because it consists basically of placing the contents on different divs, but the filter will only filter the first one.

This is my HTML now:

<section>
  <input type="text" id="barraBusqueda" onkeyup="buscar()" placeholder="Buscar artículos">
  <ul id="articulos">
    <li><a href="/es/blog/1.html">Article 1</a></li>
    <li><a href="/es/blog/2.html">Article 2</a></li>
    <li><a href="/es/blog/3.html">Article 3</a></li>
    <li><a href="/es/blog/4.html">Article 4</a></li>
    <li><a href="/es/blog/5.html">Article 5</a></li>
    <li><a href="/es/blog/6.html">Article 6</a></li>
    <li><a href="/es/blog/7.html">Article 7</a></li>
    <li><a href="/es/blog/8.html">Article 8</a></li>
    <li><a href="/es/blog/9.html">Article 9</a></li>
    <li><a href="/es/blog/10.html">Article 10</a></li>
  </ul>
</section>
    

And my JS:

function buscar() {
  // Declare variables
  var input, filter, ul, li, a, i, txtValue;
  input = document.getElementById("barraBusqueda");
  filter = input.value.toUpperCase();
  ul = document.getElementById("articulos");
  li = ul.getElementsByTagName("li");

  // Loop through all list items, and hide those who don't match the search query
  for (i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName("a")[0];
    txtValue = a.textContent || a.innerText;
    if (txtValue.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
    } else {
      li[i].style.display = "none";
    }
  }
}

It works fine, but all the elements have to be showing, and I don't want an eternal scroll through dozens of list items.

Goal would be that the browser only displays 5 list items at a time, with a next and previous button to navigate through them, but that the filter considers all the list items, even those that are in other pages.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I would recommend to separate the data from the representation. This makes it easier to combine filtering and paging.

As a first step I would create an array of objects describing the list of entries. On this array you can perform filtering. Secondly, I would write a function which renders the list entries. This way you don't have to hide HTML elements, you only render those that match your filter and/or page.

Please take a look at this (incomplete) working example:

// The maximum size of a single page
const pageSize = 5;

// All list entries (unfiltered)
const data = [
   { name: 'Article 1', url: '/es/blog/1.html' },
   { name: 'Article 2', url: '/es/blog/2.html' },
   { name: 'Article 3', url: '/es/blog/3.html' },
   { name: 'Article 4', url: '/es/blog/4.html' },
   { name: 'Article 5', url: '/es/blog/5.html' },
   { name: 'Article 6', url: '/es/blog/6.html' },
   { name: 'Article 7', url: '/es/blog/7.html' },
   { name: 'Article 8', url: '/es/blog/8.html' },
   { name: 'Article 9', url: '/es/blog/9.html' },
   { name: 'Article 10', url: '/es/blog/10.html' },
   { name: 'Article 11', url: '/es/blog/11.html' },
   { name: 'Article 12', url: '/es/blog/12.html' },
   { name: 'Article 13', url: '/es/blog/13.html' },
   { name: 'Article 14', url: '/es/blog/14.html' },
];

// The filtered data; initially equal to `data`; 
// modified by function filter()
let filteredData = data;

// The current page index
let currentPage = 0;

// Adds/removes the `disabled` attribute from the element by
// specified ID according to the `disabled` flag
function updateButtonState(id, disabled) {
  const button = document.getElementById(id);
  if (disabled) {
    button.setAttribute('disabled', 'true');
  }
  else {
    button.removeAttribute('disabled');
  }
}

// Updates the states of the Previous/Next buttons
function updateButtonStates() {
  updateButtonState('btn-prev', currentPage === 0);
  updateButtonState('btn-next', (currentPage + 1) * pageSize >= filteredData.length);
}

// Filters the `data` array according to the given text
function filter(text) {
  filteredData = data.filter(entry => entry.name.includes(text));
  renderPage(currentPage);
}

// Renders a single page, using the `filteredData` array
function renderPage(pageNo) {
  currentPage = pageNo;

  const elList = document.getElementById('list');
  elList.innerHTML = '';

  const offset = pageNo * pageSize;
  for (let i = offset; i < offset + pageSize && i < filteredData.length; i++) {
    const entry = filteredData[i];
    const li = elList.appendChild(document.createElement('li'));
    const anchor = li.appendChild(document.createElement('a'));
    anchor.innerHTML = entry.name;
    anchor.href = entry.url;
  }
  
  updateButtonStates();
}


// Render first page initially
renderPage(0);
<input type="text" onkeyup="filter(this.value)">

<ul id="list">
</ul>

<button id="btn-prev" onclick="renderPage(currentPage - 1)">Previous</button>
<button id="btn-next" onclick="renderPage(currentPage + 1)">Next</button>

Test it by entering 1 into the search field.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!