list.js - Documentation

Introduction

What is list.js?

list.js is a lightweight JavaScript library that provides powerful client-side filtering and sorting capabilities for lists of data displayed in HTML tables or unordered lists. It allows you to easily add search, pagination, and advanced filtering functionalities to your web applications without needing a backend solution for these features. list.js operates directly on the DOM, making it efficient and fast, even with large datasets.

Key Features and Benefits

Installation and Setup

list.js can be easily integrated into your project using several methods:

<script src="path/to/list.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/list.js@2/dist/list.min.js"></script>
npm install list.js

Then import it into your JavaScript file:

import List from 'list.js';

Basic Usage Example

This example demonstrates creating a simple list with basic filtering:

<!DOCTYPE html>
<html>
<head>
<title>list.js Example</title>
<script src="https://cdn.jsdelivr.net/npm/list.js@2/dist/list.min.js"></script>
</head>
<body>

<input type="text" id="search" placeholder="Search...">
<ul id="myList"></ul>

<script>
  var values = [
    {name: "Item 1"},
    {name: "Item 2"},
    {name: "Item 3"}
  ];

  var options = {
    valueNames: ['name'] //Specifies which elements to search within
  };

  var list = new List('myList', options, values);
</script>

</body>
</html>

This code creates a searchable list. Typing into the search input will filter the ul element with the id “myList”, based on the ‘name’ property of the data objects. Remember to replace "https://cdn.jsdelivr.net/npm/list.js@2/dist/list.min.js" with the correct path if you downloaded the library locally.

Core Concepts

The List Object

The core of list.js is the List object. It’s created by instantiating the List class, passing it the ID of the list container (typically a <ul> or <table>), options, and optionally, an initial data array. The List object manages all aspects of the list, including rendering, searching, sorting, and pagination. It exposes methods for manipulating and interacting with the list’s items and data. A typical instantiation looks like this:

const list = new List('myList', {
  valueNames: ['name', 'age'], //fields to search
  page: 5, //number of items per page
  pagination: true // enable pagination
}, data); // optional initial data array

The List object then provides methods to interact with and manipulate the list data, such as add, remove, update, search, sort, etc.

Value and Item Objects

Working with Items

list.js provides methods to add, remove, and update items within the list:

Searching and Filtering

list.js allows for powerful searching and filtering using the search() method. The valueNames option specified during list initialization determines which fields are searchable. Searching is case-insensitive by default.

list.search('Alice'); // searches for 'Alice' in the specified fields
list.search('30');    // searches for '30' in the specified fields
list.search('');      // clears the search

You can use more advanced search techniques such as regular expressions. See the list.js documentation for more details on advanced filtering options.

Sorting

Sorting is performed using the sort() method. You specify the field to sort by and the direction (ascending or descending).

list.sort('name', { order: 'asc' }); // Sorts by name in ascending order.
list.sort('age', { order: 'desc' });  // Sorts by age in descending order.

You can chain multiple sort criteria; list.js will sort by each criteria sequentially. For instance:

list.sort('age', { order: 'desc' }, 'name', { order: 'asc' }); // Sort by age descending then by name ascending

List Manipulation

Adding Items

New items are added to the list using the add() method. This method accepts an array of value objects as an argument. Each value object represents a single item to be added. The structure of the value objects should match the valueNames defined during list initialization.

const newItem = { name: 'Bob', age: 25 };
list.add(newItem); //Adds a single item

const newItems = [
  { name: 'Charlie', age: 30 },
  { name: 'David', age: 28 }
];
list.add(newItems); // Adds multiple items

After adding items, the list is automatically re-rendered to reflect the changes.

Removing Items

Items can be removed using the remove() method. This method accepts different types of arguments:

const itemToRemove = { name: 'Bob', age: 25 };
list.remove(itemToRemove); //Removes one item


list.remove(function(item) {
  return item.age > 30; // Removes items where age is greater than 30
});

Updating Items

Updating items modifies the values of existing items in the list. The update() method takes an array of value objects as an argument. Each object must contain at least one unique identifier property (e.g., an id field) that allows list.js to match it with an existing item. Only the properties present in the update object will be changed; other properties remain untouched.

const updatedItem = { id: 1, name: 'Bob Updated', age: 26 };
list.update([updatedItem]); //Updates a single item

If an id property is not explicitly defined in valueNames option, list.js will attempt to match by comparing the whole objects. Ensure that all properties of the object are included in the update if you are not using an id property.

Reordering Items

list.js doesn’t directly provide a method for reordering items in the DOM. However, you can achieve this by manipulating the underlying data array and then calling the update() method. The update method will re-render the list based on the new order of the items in the array. If your values have unique identifiers (e.g., an ‘id’ property), this will be the most efficient approach.

// Example assuming your data is in a variable called 'data'
// and data items have an 'id' property for identification

data.sort((a, b) => a.name.localeCompare(b.name)); // Sort by name
list.update(data); // Update the list to reflect the reordering

Pagination

Pagination divides the list into multiple pages, displaying only a subset of items at a time. Pagination is enabled by setting the page and pagination options during list initialization. page specifies the number of items per page.

const options = {
  valueNames: ['name', 'age'],
  page: 10, // 10 items per page
  pagination: true
};

const list = new List('myList', options, data);

list.js automatically generates pagination controls (previous and next buttons). You can customize the appearance and behavior of pagination by using callbacks (see list.js documentation for details on customizing pagination).

Advanced Features

Custom Templates

list.js allows for highly customized rendering using custom templates. Instead of relying on the default rendering of list items, you can define your own HTML structure using a template function. This function receives an item object as input (an internal list.js object representing a single item) and should return the HTML string for that item. This template is then used to render each item in the list.

const options = {
  valueNames: ['name', 'age'],
  item: function(value, index) {
    return `<li>
              <span class="name">${value.name}</span> - 
              <span class="age">${value.age}</span>
            </li>`;
  }
};

const list = new List('myList', options, data);

This replaces the default list item rendering with a custom structure.

Working with External Data Sources

list.js is not limited to working with data provided directly during initialization. You can load data from external sources (e.g., JSON APIs, CSV files) and then use the add() or update() methods to populate or refresh the list.

fetch('data.json')
  .then(response => response.json())
  .then(data => {
    list.add(data);
  });

This example fetches JSON data and adds it to the list once the data is loaded. Remember to handle potential errors during the fetching process.

Integration with Other Libraries

list.js can be easily integrated with other JavaScript libraries and frameworks. Since it operates directly on the DOM, it’s generally compatible with most other libraries. For instance, you could use it alongside a framework like React, Vue, or Angular by placing the list within your component and managing the data flow between the library and your application’s state.

Event Handling

list.js provides events that you can listen to in order to react to changes in the list. Common events include:

list.on('updated', function(list) {
  console.log('List updated:', list.items);
});

list.on('searched', function(list) {
  console.log('Search complete:', list.matchingItems);
});

These event handlers receive the List object as an argument.

Plugins and Extensions

While list.js doesn’t have a formal plugin system, its modular design allows you to extend its functionality. You can create custom functions to enhance search, sorting, or filtering capabilities. You might create a function that performs a fuzzy search, adds a custom sorting algorithm, or integrates with a specific data source. These custom functions can be integrated directly into your application code, working alongside the core list.js functionality. See the list.js documentation for examples and best practices on extending functionality.

Performance Optimization

Improving Search Speed

For optimal search performance with list.js, consider these strategies:

Handling Large Datasets

Working with large datasets requires careful consideration of performance. Here are some strategies:

Minimizing DOM Manipulation

Excessive DOM manipulation is a common cause of performance issues. These are key areas to focus on:

Troubleshooting

Common Issues and Solutions

Debugging Techniques

Error Handling

list.js itself doesn’t throw many explicit errors. Errors usually arise from incorrect usage or from problems with your data or surrounding application code. The browser’s JavaScript console will be your primary tool for identifying errors. Pay close attention to error messages – they often provide clues about the source of the problem.

Consider adding your own error handling within your application code, particularly when dealing with asynchronous operations such as fetching data from external sources. Use try...catch blocks to gracefully handle potential errors, such as network failures or invalid JSON data, and to prevent unexpected crashes. Provide informative error messages to users if necessary.

API Reference

This section provides a concise reference for the list.js API. For detailed explanations and examples, refer to the comprehensive documentation available on the official list.js website.

List Object Methods

The List object exposes several methods for manipulating and interacting with the list. Here are some key methods:

Item Object Methods

The Item object, returned by list.getItems() or list.matchingItems(), provides access to individual list items. Key methods include:

Events

list.js triggers several events that you can listen for using the on() method. Some key events are:

Configuration Options

The List object is initialized with options that define its behavior. Key options include:

Note that many additional options and callbacks exist; consult the official list.js documentation for the complete and up-to-date list of available options and their detailed functionalities.

Examples and Use Cases

This section provides examples demonstrating various functionalities of list.js. These examples assume basic familiarity with the API and concepts covered in previous sections. Refer to the official documentation for more comprehensive examples and detailed code explanations.

Simple Search and Filtering

This example demonstrates basic search and filtering on a list of products:

<input type="text" id="search" placeholder="Search products...">
<ul id="products"></ul>

<script>
  const products = [
    { name: "Product A", category: "Electronics", price: 100 },
    { name: "Product B", category: "Clothing", price: 50 },
    { name: "Product C", category: "Electronics", price: 150 }
  ];

  const list = new List('products', {
    valueNames: ['name', 'category', 'price']
  }, products);

  document.getElementById('search').addEventListener('input', function() {
    list.search(this.value);
  });
</script>

Typing into the search input filters the products list based on name, category, and price.

Advanced Filtering with Multiple Criteria

Advanced filtering allows combining multiple criteria. This example filters products by category and price range:

// ... (previous code) ...

const categoryFilter = 'Electronics';
const minPrice = 100;
const maxPrice = 200;

list.filter(function(item) {
  return item.values().category === categoryFilter &&
         item.values().price >= minPrice &&
         item.values().price <= maxPrice;
});

This filters the list to show only electronics products within the specified price range. You could dynamically update categoryFilter, minPrice, and maxPrice based on user input.

Custom Sorting and Ordering

This example demonstrates custom sorting based on price, then by name:

// ... (previous code) ...

list.sort('price', {order: 'asc'}, 'name', {order: 'asc'});

This sorts the products first by price (ascending) and then by name (ascending) for products with the same price.

Pagination and Infinite Scrolling

Pagination can be easily implemented:

const list = new List('products', {
  valueNames: ['name', 'category', 'price'],
  page: 5, // 5 items per page
  pagination: true
}, products);

For infinite scrolling, you would need to add custom logic to fetch and append additional data to the list as the user scrolls near the bottom. This would involve listening to the scroll event and making AJAX requests to load more data when appropriate. This is not directly handled by list.js but is achievable with additional code.

Integrating with Forms and User Input

list.js integrates seamlessly with forms and user input. You can trigger filtering or sorting based on form submissions or changes in input fields:

// ... (Assuming you have a form with inputs for category and price) ...

document.getElementById('filterForm').addEventListener('submit', function(e) {
  e.preventDefault();
  const category = document.getElementById('category').value;
  const minPrice = document.getElementById('minPrice').value;
  const maxPrice = document.getElementById('maxPrice').value;

  list.filter(function(item) {
    return (category === '' || item.values().category === category) &&
           (minPrice === '' || item.values().price >= minPrice) &&
           (maxPrice === '' || item.values().price <= maxPrice);
  });
});

This example filters the list dynamically based on the user’s selections in the form. Empty input fields are treated as “no filter” conditions. Remember to replace the IDs with those present in your actual form.