Reader Stacks

How to Update Page Data Without a Reload Using jQuery

The core pattern is always the same three steps: intercept the action, fetch or send data with AJAX, then update the specific DOM elements that changed — no full page reload needed.

Updating part of a page's content without a full reload — after a form submission, a filter change, a "load more" click — follows the same three-step pattern regardless of the specific use case: intercept the default action, fetch or send data via AJAX, then update just the relevant DOM elements.

Updating content after a form submission, without a page reload

$('#filter-form').submit(function (event) {
    event.preventDefault(); // stop the normal full-page form submission

    $.ajax({
        url: '/products',
        method: 'GET',
        data: $(this).serialize(),
        success: function (response) {
            $('#product-list').html(response.html);
        }
    });
});

event.preventDefault() is the essential first step — without it, the browser performs its normal full-page form submission and navigation regardless of what the AJAX call below it does.

Updating content on a dropdown or filter change

$('#category-filter').change(function () {
    const categoryId = $(this).val();

    $.get('/products', { category: categoryId }, function (response) {
        $('#product-list').html(response.html);
    });
});

A "load more" pattern that appends rather than replaces

let currentPage = 1;

$('#load-more').click(function () {
    currentPage++;

    $.get('/products', { page: currentPage }, function (response) {
        $('#product-list').append(response.html); // append, not replace
        if (!response.hasMore) {
            $('#load-more').hide();
        }
    });
});

Using .append() instead of .html() is what makes this a "load more" pattern rather than a page-replacement one — the existing content stays in place, and new content is added onto the end of it.

Updating a specific field's displayed value after an action, without touching the rest of the page

$('.add-to-cart').click(function () {
    const productId = $(this).data('product-id');

    $.post('/cart/add', { product_id: productId }, function (response) {
        $('#cart-count').text(response.cartCount);
    });
});

Updating just the one specific element that actually changed (#cart-count here), rather than replacing a larger section of the page, is more efficient and avoids any visual flicker in unrelated parts of the page that didn't need to change at all.

Handling the request while it's in flight, and errors

$('#filter-form').submit(function (event) {
    event.preventDefault();
    $('#product-list').addClass('loading');

    $.ajax({
        url: '/products',
        data: $(this).serialize(),
        success: function (response) {
            $('#product-list').html(response.html);
        },
        error: function () {
            $('#product-list').html('

Something went wrong. Please try again.

'); }, complete: function () { $('#product-list').removeClass('loading'); } }); });

Adding a loading state and handling the error case explicitly (rather than only the success case) gives a considerably more complete, production-appropriate experience than the bare-minimum happy-path examples above.