Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Real-World AJAX Examples

Example 1: Live Search / Autocomplete

A live search box that queries the server as the user types and displays suggestions in a dropdown — debounced to avoid flooding the server with requests.

Live Search — HTML Structure
<div class="search-wrapper" style="position:relative; max-width:400px;">
  <input type="text" id="live-search" placeholder="Search products..."
         autocomplete="off" class="form-control">
  <ul id="search-results" style="
    position:absolute; top:100%; left:0; right:0;
    background:#fff; border:1px solid #ddd; border-radius:4px;
    list-style:none; margin:0; padding:0; z-index:100; display:none;">
  </ul>
</div>
Live Search — JavaScript
const input = document.getElementById('live-search');
const resultsList = document.getElementById('search-results');
let debounceTimer;
let currentController = null;

input.addEventListener('input', function () {
  const query = this.value.trim();
  clearTimeout(debounceTimer);

  // Cancel any in-flight request
  if (currentController) currentController.abort();

  if (query.length < 2) {
    resultsList.style.display = 'none';
    resultsList.innerHTML = '';
    return;
  }

  debounceTimer = setTimeout(async () => {
    currentController = new AbortController();

    try {
      const res = await fetch(
        `/api/search?q=${encodeURIComponent(query)}`,
        { signal: currentController.signal }
      );
      const items = await res.json();

      if (items.length === 0) {
        resultsList.innerHTML = '<li style="padding:8px 12px;color:#999">No results</li>';
      } else {
        resultsList.innerHTML = items.map(item => `
          <li data-id="${item.id}" style="padding:8px 12px;cursor:pointer;border-bottom:1px solid #eee"
              onmouseover="this.style.background='#f5f5f5'"
              onmouseout="this.style.background=''">
            ${item.name}
          </li>
        `).join('');

        resultsList.querySelectorAll('li[data-id]').forEach(li => {
          li.addEventListener('click', () => {
            input.value = li.textContent.trim();
            resultsList.style.display = 'none';
            console.log('Selected ID:', li.dataset.id);
          });
        });
      }

      resultsList.style.display = 'block';
    } catch (err) {
      if (err.name !== 'AbortError') console.error('Search error:', err);
    }
  }, 300);
});

// Hide results when clicking outside
document.addEventListener('click', e => {
  if (!e.target.closest('.search-wrapper')) {
    resultsList.style.display = 'none';
  }
});

Example 2: Infinite Scroll / Load More

Load additional content when the user scrolls to the bottom of the page — a pattern used by social media feeds and product listings.

Infinite Scroll with IntersectionObserver
let currentPage = 1;
let isLoading = false;
let hasMore = true;

const feed = document.getElementById('post-feed');
const sentinel = document.getElementById('scroll-sentinel'); // empty div at bottom

// IntersectionObserver fires when sentinel enters the viewport
const observer = new IntersectionObserver(async (entries) => {
  if (entries[0].isIntersecting && !isLoading && hasMore) {
    await loadMorePosts();
  }
}, { threshold: 0.1 });

observer.observe(sentinel);

async function loadMorePosts() {
  isLoading = true;
  sentinel.innerHTML = '<div class="spinner">Loading...</div>';

  try {
    const res = await fetch(`/api/posts?page=${currentPage}&limit=10`);
    const { posts, totalPages } = await res.json();

    posts.forEach(post => {
      const article = document.createElement('article');
      article.className = 'post-card';
      article.innerHTML = `
        <h3>${post.title}</h3>
        <p>${post.excerpt}</p>
        <small>By ${post.author} — ${post.date}</small>
      `;
      feed.appendChild(article);
    });

    currentPage++;
    hasMore = currentPage <= totalPages;

    sentinel.innerHTML = hasMore
      ? '' // clear spinner, observer will trigger again
      : '<p style="text-align:center;color:#999">No more posts</p>';

  } catch (err) {
    sentinel.innerHTML = '<p class="text-danger">Failed to load posts</p>';
    console.error(err);
  } finally {
    isLoading = false;
  }
}

// Load first page on startup
loadMorePosts();

Example 3: Real-Time Form Validation

Validate form fields against the server in real time — checking for duplicate emails, weak passwords, or invalid coupon codes as the user fills in the form.

Real-Time Email and Coupon Validation
// Reusable debounced validator
function createValidator(inputEl, feedbackEl, endpoint, paramName, minLength = 3) {
  let timer;

  inputEl.addEventListener('blur', () => validate()); // also validate on blur
  inputEl.addEventListener('input', () => {
    clearTimeout(timer);
    const value = inputEl.value.trim();

    if (value.length < minLength) {
      setFeedback(feedbackEl, '', 'neutral');
      return;
    }

    setFeedback(feedbackEl, 'Checking...', 'neutral');
    timer = setTimeout(() => validate(), 400);
  });

  async function validate() {
    const value = inputEl.value.trim();
    if (value.length < minLength) return;

    try {
      const res = await fetch(`${endpoint}?${paramName}=${encodeURIComponent(value)}`);
      const { valid, message } = await res.json();
      setFeedback(feedbackEl, message, valid ? 'success' : 'error');
      inputEl.dataset.valid = valid;
    } catch {
      setFeedback(feedbackEl, 'Could not validate', 'neutral');
    }
  }
}

function setFeedback(el, message, type) {
  el.textContent = message;
  el.className = `feedback feedback-${type}`;
}

// Initialize validators
createValidator(
  document.getElementById('email'),
  document.getElementById('email-feedback'),
  '/api/validate/email', 'email', 5
);

createValidator(
  document.getElementById('coupon'),
  document.getElementById('coupon-feedback'),
  '/api/validate/coupon', 'code', 4
);

// Prevent form submission if any field is invalid
document.getElementById('register-form').addEventListener('submit', function (e) {
  const fields = this.querySelectorAll('[data-valid]');
  const allValid = Array.from(fields).every(f => f.dataset.valid === 'true');

  if (!allValid) {
    e.preventDefault();
    document.getElementById('form-error').textContent = 'Please fix the errors above.';
  }
});

Example 4: Dynamic Content Loading (Tabs without Page Reload)

Load tab content on demand via AJAX — only fetching data when the user clicks a tab, and caching it so subsequent clicks don't re-fetch.

AJAX Tabs with Caching
// HTML structure expected:
// <div class="tab-nav">
//   <button class="tab-btn active" data-tab="overview" data-url="/api/tabs/overview">Overview</button>
//   <button class="tab-btn" data-tab="reviews" data-url="/api/tabs/reviews">Reviews</button>
//   <button class="tab-btn" data-tab="specs" data-url="/api/tabs/specs">Specs</button>
// </div>
// <div id="tab-content"></div>

const tabCache = {};
const tabContent = document.getElementById('tab-content');

document.querySelectorAll('.tab-btn').forEach(btn => {
  btn.addEventListener('click', async function () {
    const tabId = this.dataset.tab;
    const url = this.dataset.url;

    // Update active state
    document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
    this.classList.add('active');

    // Serve from cache if available
    if (tabCache[tabId]) {
      tabContent.innerHTML = tabCache[tabId];
      return;
    }

    // Show loading state
    tabContent.innerHTML = '<div class="tab-loading"><span class="spinner"></span> Loading...</div>';

    try {
      const res = await fetch(url);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);

      const html = await res.text(); // tabs return HTML fragments
      tabCache[tabId] = html;        // cache for future clicks
      tabContent.innerHTML = html;

    } catch (err) {
      tabContent.innerHTML = `<p class="text-danger">Failed to load tab: ${err.message}</p>`;
    }
  });
});

// Load the default active tab on page load
const defaultTab = document.querySelector('.tab-btn.active');
if (defaultTab) defaultTab.click();

Previous Next

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.