Custom search bar with AJAX

Loading

Creating a custom search bar with AJAX in Power Pages enhances the user experience by enabling real-time, dynamic search results without requiring full page reloads. This approach is especially useful when dealing with large datasets such as knowledge base articles, FAQs, product catalogs, or user directories.


Overview

AJAX (Asynchronous JavaScript and XML) allows your search bar to fetch data from a server (e.g., Dataverse or SharePoint) asynchronously and update part of the webpage without refreshing the entire page.


Step-by-Step Guide

Step 1: Prepare Your Data Source

Use a secure and well-structured table in Dataverse (or another backend like SharePoint or an external REST API). Ensure the columns you’re searching (like Title, Description, or Tags) are indexed for performance.


Step 2: Enable OData or Web API for Data Retrieval

For Power Pages + Dataverse:

  • Enable Web API permissions on your Dataverse table.
  • Use Web Roles to secure data access.
  • You’ll call the Web API endpoint with a GET request, using $filter for your search logic.

Example OData URL:

/_api/data/v9.2/custom_entity?$filter=contains(name,'searchTerm')

Step 3: Create the Search Bar in HTML

<input type="text" id="searchInput" placeholder="Search..." />
<div id="searchResults"></div>

Step 4: Add AJAX Script

Use JavaScript with fetch() or XMLHttpRequest. Here’s an example with fetch():

<script>
document.getElementById('searchInput').addEventListener('keyup', function () {
let query = this.value;
if (query.length < 3) return; // wait for minimum characters

fetch(`/_api/data/v9.2/custom_entity?$filter=contains(name,'${encodeURIComponent(query)}')`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'OData-MaxVersion': '4.0',
'OData-Version': '4.0'
}
})
.then(response => response.json())
.then(data => {
let resultsDiv = document.getElementById('searchResults');
resultsDiv.innerHTML = '';
if (data.value.length === 0) {
resultsDiv.innerHTML = '<p>No results found.</p>';
} else {
data.value.forEach(item => {
resultsDiv.innerHTML += `<div class="search-result">${item.name}</div>`;
});
}
})
.catch(error => console.error('Search Error:', error));
});
</script>

Step 5: Style the Results

<style>
#searchResults {
border: 1px solid #ddd;
padding: 10px;
max-height: 300px;
overflow-y: auto;
background-color: #fff;
}
.search-result {
padding: 5px;
border-bottom: 1px solid #eee;
cursor: pointer;
}
.search-result:hover {
background-color: #f0f0f0;
}
</style>

Step 6: Add Click Event for Results (Optional)

document.getElementById('searchResults').addEventListener('click', function (e) {
if (e.target && e.target.classList.contains('search-result')) {
alert(`You clicked on: ${e.target.textContent}`);
// Or redirect to detail page
}
});

Step 7: Secure the API Access

  • Restrict access using Web Roles.
  • Ensure the user is authenticated if sensitive data is being shown.
  • Avoid exposing internal field names directly in JS.

Step 8: Use Liquid for Initial Loading (Optional)

For static data or cached entries, you can use Liquid to render initial values and reduce API calls.


Step 9: Optimize Performance

  • Add debounce logic (e.g., 300ms) to avoid firing too many requests.
  • Use pagination or limit results ($top=10).
  • Index frequently searched columns in Dataverse.

Use Cases

  • Live product or article search
  • FAQ lookup
  • Employee directory search
  • Autocomplete dropdown for forms

Advanced Enhancements

  • Use Power Automate to enrich results before displaying.
  • Display search suggestions using a pre-configured keyword list.
  • Highlight matching terms using JS regex.

Leave a Reply

Your email address will not be published. Required fields are marked *