MdMasud

WordPress, Laravel, Flutter

Category: JS

  • DataTables in WordPress: Use Callback Data to Calculate Totals and Update the Page (Frontend‑Only)

    DataTables in WordPress: Use Callback Data to Calculate Totals and Update the Page (Frontend‑Only)

    When you’re building dashboards in WordPress, you often need to use the data currently loaded into your DataTable—not just display it. This post shows how to sum values from all rows (across pages), split totals by Payment Method (Cash vs Card), and push those numbers into elements elsewhere on the page using a reusable callback function.

    What you’ll achieve

    • Fetch table data via AJAX (already set up in your site).
    • Initialise DataTables in WordPress.
    • Use a separate, reusable function to:
      • Iterate all rows, ignoring pagination.
      • Parse currency like £45.00.
      • Update three on‑page counters: #log_cash, #log_card, #log_total.

    HTML markup

    <div class="table-container">
      <table id="todaysLogs" class="table display" style="width:100%">
        <thead>
          <tr>
            <th>Time</th>
            <th>Driver</th>
            <th>Sold By</th>
            <th>Amount</th>
            <th>Discount</th>
            <th>Payment Method</th>
            <th>Action</th>
          </tr>
        </thead>
      </table>
    </div>
    
    <!-- Totals display anywhere on the page -->
    <div class="totals">
      <div>Cash: <strong id="log_cash">£0.00</strong></div>
      <div>Card: <strong id="log_card">£0.00</strong></div>
      <div>Total: <strong id="log_total">£0.00</strong></div>
    </div>
    

    Reusable totals function + DataTable initialisation

    function updateLogTotals(tableApi) {
        var parseValue = function (val) {
    	if (typeof val === 'string') {
    		return parseFloat(val.replace(/[£,]/g, '')) || 0;
    	}
    	return typeof val === 'number' ? val : 0;
       };
       var totalCash = 0;
       var totalCard = 0;
       tableApi.rows().every(function () {
            var row = this.data();
    	var value  = row[3];
    	var type   = row[5];
    	if (type === 'Cash') {
    		totalCash += parseValue(value);
    	} else {
    		totalCard += parseValue(value);
    	}
       });
    
       $('#log_cash').text('£' + totalCash.toFixed(2));
       $('#log_card').text('£' + totalCard.toFixed(2));
       $('#log_total').text('£' + (totalCash + totalCard).toFixed(2));
    }
    
    var todaysLogsTable = $('#todaysLogs').DataTable({
    	dom: 'Bfrtip',
    	pageLength: 9,
    	buttons: [
    		'copyHtml5',
    		'excelHtml5',
    		'csvHtml5',
    		'pdfHtml5'
    	],
    	columns: [
    		null,
    		null,
    		null,
    		null,
    		null,
    		null,
    		{ orderable: false }
    	],
    	ajax: {
    		url: ajaxurl + '?action=pos&post_action=get_todays_log'
    		},
    		responsive: true,
    		drawCallback: function (settings) {
    			updateLogTotals(this.api());
    		}
    });

    Make it truly reusable

    You can call updateLogTotals(todaysLogsTable) from anywhere—buttons, tabs, or additional DataTables events:

    $('#todaysLogs').on('search.dt order.dt page.dt', function () {
        updateLogTotals(todaysLogsTable);
    });
    

    Only count visible (filtered) rows? Swap:

    tableApi.rows().every(…)

    for:

    tableApi.rows({ filter: 'applied' }).every(…)
    

    Currency parsing

    parseFloat(val.replace(/[£,]/g, ''))
    • If your data can include other currencies or locale formats, either:
      • Normalise in your renderer (e.g. store a hidden numeric value and display £ in the cell), or
      • Expand the regex/logic to handle your formats.

    Troubleshooting

    • Totals don’t change: Ensure your callback runs on drawCallback or bind to search.dt/order.dt/page.dt.
    • NaN totals: Check the column indexes and the currency format in your cells.
    • Wrong values: Confirm your table’s JSON returns the columns in the order you expect.

    Takeaway

    With a small reusable function and DataTables’ API, you can read current table data on the client and push real‑time totals into any element on your WordPress page—no page refreshes, no backend edits required here.

  • Custom Cursor Navigation in SwiperJS – What I Built and How I Fixed It

    Today, I was working on a custom slider using SwiperJS, and I wanted to do something a bit more interactive than the usual arrows or dots.

    Instead of showing fixed navigation arrows, I thought it would be more fun to show floating “Next” and “Previous” text that follow the cursor, depending on which side of the slider you’re hovering. Kind of like a tail that hints where the slider will move if you click.

    It turned out to be a really nice effect – but getting it right wasn’t completely straightforward. Here’s how I made it work, and what issues came up along the way.

    What I Was Trying to Do

    • Show “Next” on the right side of the slider
    • Show “Previous” on the left
    • Make the text follow the cursor with a smooth animation (like a trailing effect)
    • Hide the floating text when hovering buttons inside each slide (so it doesn’t get in the way)

    The First Hurdle: Cursor Trail Jumping or Sticking

    At first, I tried updating the cursor-following text using transform: translate(...) inside mousemove, and it seemed okay. But it felt jumpy, and sometimes the text would just snap to the corner or get stuck.

    After a bit of testing, I realised the issue was that I was mixing transform with left/top positioning. That doesn’t play well when you’re trying to animate smoothly using requestAnimationFrame.

    The Fix: Left & Top + Easing Transition

    To get that smooth “trailing” or “wave” motion, I switched to updating left and top with easing. That way, the text glides behind the mouse rather than sticking to it like glue.

    This made a big difference. Now the text follows the cursor in a fluid way – not jerky, not laggy, just smooth.

    floatX += (mouseX - floatX) * 0.1;
    floatY += (mouseY - floatY) * 0.1;

    Next Issue: Hovering Over Buttons

    Each slide had a button in the bottom-right corner (like “Book Now”). But when you hovered over that button, the floating “Next”/”Previous” text would still be there — not ideal for usability or design.

    So I added a simple fix: detect when the user is hovering the button (or the caption area), and hide the floating text during that time.

    $(document).on('mouseenter', '.v-pageHead__caption', function () {
    	hoveringButton = true;
    	$('.floating-nav').css('opacity', 0);
    });
    
    $(document).on('mouseleave', '.v-pageHead__caption', function () {
    	hoveringButton = false;
    });

    Now, when you’re over the button, the cursor tail disappears. Clean and and tidy.

    Keeping It Clean: Only Run If Slider Is Active

    One more thing I wanted to avoid was unnecessary code running on pages where there was only one slide — or no slider at all.

    So I wrapped everything inside a conditional check like this:

    if ($('.v-pageHead__slide', '.v-pageHead__slider').length > 1) {
    	// Only run this whole block if more than 1 slide
    }

    That way, no Swiper is initialised unless needed, and no extra listeners or animations are running in the background.

    Finally, This was a fun little UX tweak — a bit fiddly at times, but the end result feels smooth and adds a nice touch. It’s the kind of detail that makes a site feel that bit more alive.

    If you’re using Swiper and fancy something a bit cooler than the usual arrows, give it a try! And if you want a peek at the code, just give me a shout here.