Build Searchable Data Views from JSON Data with SenangWebs Index

Category: Javascript | November 7, 2025
Author:a-hakim
Views Total:35 views
Official Page:Go to website
Last Update:November 7, 2025
License:MIT

Preview:

Build Searchable Data Views from JSON Data with SenangWebs Index

Description:

SenangWebs Index is a lightweight, flexible JavaScript library that converts JSON data into interactive data views (e.g., lists and data tables) with search and pagination capabilities.

Features:

  • Dual initialization: Configure through HTML attributes or JavaScript API.
  • Multi-field search: Search across multiple data properties with 300ms debouncing.
  • Smart pagination: Automatic pagination handling for large datasets.
  • Loading states: Built-in loading, empty, and error state management.
  • Zero dependencies: Pure ES6+ JavaScript without external libraries.
  • Customizable styling: All CSS classes use swi- prefix for easy theming.
  • Mobile-friendly: Responsive design that works across device sizes.
  • Template Flexibility: Define item templates as HTML elements or JavaScript functions.

Use Cases:

  • Product Catalogs: Quickly render a filterable grid of products from a JSON file for an e-commerce site or portfolio. SWI handles the search and pagination, which are common pain points.
  • Data Tables: Display user lists, logs, or other tabular data in an admin dashboard. You can build a simple, searchable table without a complex table library.
  • Resource Directories: Create a searchable directory of articles, tools, or community links. This is perfect for documentation sites or knowledge bases.
  • Searchable FAQs: Implement a dynamic FAQ page where users can type keywords to filter questions.

How To Use It:

1. Download the package and load the following JS & CSS files in the document.

<link rel="stylesheet" href="path/to/dist/swi.css" />
<script src="path/to/dist/swi.js"></script>

2. Initialize SenangWebs Index via declarative HTML. This method requires no JavaScript and works entirely through the following data attributes:

AttributeRequiredDescription
data-swi-idYesUnique identifier for the SWI instance
data-swi-sourceYesURL to JSON data endpoint
data-swi-page-sizeNoNumber of items per page (default: 10)
data-swi-search-keyNoComma-separated list of searchable fields
data-swi-template="item"YesMarks the template element to clone
data-swi-value="item.property"YesBinds data property to element text content
data-swi-search-inputNoMarks the search input field
data-swi-paginationNoMarks the pagination container
<div class="demo-container" 
     data-swi-id="products" 
     data-swi-source="./data.json" 
     data-swi-page-size="5"
     data-swi-search-key="name">
  <!-- Search Controls -->
  <div style="margin-bottom: 20px;">
    <input type="text" 
           data-swi-search-input 
           placeholder="Search products by name..." 
           style="width: calc(100% - 120px);" />
    <button data-swi-search-action>Search</button>
  </div>
  <!-- Container for rendered items -->
  <div class="swi-item-container">
    <!-- 
      This template is hidden and cloned for each item in the JSON data.
    -->
    <div data-swi-template="item" style="display: none;">
      <h3 data-swi-value="item.name"></h3>
      <p data-swi-value="item.description"></p>
      <div class="price">$<span data-swi-value="item.price"></span></div>
      <span class="category" data-swi-value="item.category"></span>
    </div>
  </div>
  <!-- Pagination Controls will be rendered here -->
  <div data-swi-pagination></div>
</div>

3. For dynamic applications or when you need more control over the template rendering. The programmatic API accepts these configuration parameters:

OptionTypeRequiredDescription
containerString/ElementYesCSS selector or DOM element reference for the container
dataArray/StringYesArray of objects or URL to JSON endpoint
itemTemplateFunctionYesFunction that receives item object and returns HTML string
searchObjectNoSearch configuration with enabled, searchKey, and selector properties
paginationObjectNoPagination settings with enabled, itemsPerPage, and selector properties
<div id="search-container"></div>
<div id="data-container"></div>
<div id="pagination-container"></div>
// Define your data here
const products = [
  {
    id: 1,
    name: "Wireless Headphones",
    description: "Premium noise-cancelling wireless headphones with 30-hour battery life",
    price: 199.99,
    category: "Electronics",
    stock: 45
  },
  // ...
];
// Initialize SWI with JavaScript
const swi = new SenangWebsIndex({
  container: '#data-container',
  data: products,
  itemTemplate: (item) => {
    return `
      <div class="swi-item">
        <div class="swi-item-content">
          <h3>${item.name}</h3>
          <p>${item.description}</p>
          <span class="category-badge">${item.category}</span>
          <p class="stock-info">📦 ${item.stock} units in stock</p>
        </div>
        <div class="price-tag">$${item.price.toFixed(2)}</div>
      </div>
    `;
  },
  search: {
    enabled: true,
    selector: '#search-container',
    searchKey: 'name'
  },
  pagination: {
    enabled: true,
    selector: '#pagination-container',
    itemsPerPage: 5
  }
});
// Add custom search input to the search container
const searchContainer = document.getElementById('search-container');
searchContainer.innerHTML = `
  <div class="swi-search-container">
    <input type="text" 
           class="swi-search-input" 
           placeholder="Search products by name..." />
  </div>
`;
// Setup search functionality
const searchInput = searchContainer.querySelector('input');
searchInput.addEventListener('input', (e) => {
  swi.search(e.target.value);
});
console.log('SWI Instance:', swi);
console.log('Try using: swi.search("keyboard") or swi.goToPage(2)');

4. Once initialized, SWI instances expose these methods for runtime control:

API MethodDescription
search(query, searchKey)Filter data by query string. The searchKey parameter can override the initial configuration
goToPage(page)Navigate to a specific page number (1-indexed)
render()Force re-render of the current filtered and paginated data
destroy()Remove all event listeners and clear the DOM
showLoading()Display the loading spinner manually
hideLoading()Hide the loading spinner manually
showError(message, details)Display a custom error message with optional details

FAQs

Q: My list isn’t showing up, and I don’t see any errors. What should I check?
A: First, check your browser’s Network tab to ensure the JSON file specified in data-swi-source is loading correctly (no 404 errors). Second, verify that the keys you’re using in data-swi-value (e.g., item.name) exactly match the property names in your JSON objects. A common mistake is a simple typo in a key name.

Q: Can I add click events to buttons inside my itemTemplate?
A: Yes. Since SWI re-renders the list on search and pagination, the best approach is event delegation. Instead of adding a listener to each button, add a single click listener to the main container. Then, check if the clicked element (event.target) is a button you’re interested in. This ensures your events work reliably no matter how many times the list is redrawn.

Q: The search isn’t working on nested object properties. What’s wrong?
A: The searchKey parameter only supports top-level properties. If your data structure has nested objects like user.profile.name, you’ll need to flatten the data before passing it to SWI or modify the template to create searchable computed properties. This limitation comes from the simple item[key] lookup in the search filter function.

Q: Can I use SWI with dynamically loaded data?
A: Yes, either update the data source URL or use the JavaScript API with an array. Call render() after data changes.

You Might Be Interested In:


Leave a Reply