πŸš€ Making Cards Draggable in Oracle APEX (Save Order Dynamically)

πŸš€ Making Cards Draggable in Oracle APEX (Save Order Dynamically)

Modern applications are all about better user experience. One powerful UX feature is allowing users to reorder cards using drag & dropβ€”just like Trello or Jira.

In this blog, I’ll show you how to implement a Draggable Card Region in Oracle APEX and persist the order in the database.


🎯 What We Are Building

  • A Card Region (Card View) based on EMP table
  • Users can drag & reorder cards
  • Order is saved automatically in database
  • Displays a success message after saving

🧱 Step 1: Create Card Region Query

Use the following SQL query for your Card Region:

select 
    EMPNO,
    ENAME as CARD_TITLE,
    JOB as CARD_SUBTITLE,
    'Hired on ' || to_char(HIREDATE, 'DD-MON-YYYY') as CARD_BODY,
    case 
        when DEPTNO = 10 then 'Accounting'
        when DEPTNO = 20 then 'Research'
        when DEPTNO = 30 then 'Sales'
        else 'Operations'
    end as CARD_BADGE,
    MGR,
    SAL,
    substr(ENAME, 1, 1) as CARD_INITIALS,
    DISPLAY_ORDER
from EMP
order by nvl(DISPLAY_ORDER, 999), ENAME

πŸ’‘ Key Points:

  • DISPLAY_ORDER β†’ Used to maintain card position
  • order by nvl(DISPLAY_ORDER, 999) β†’ Ensures proper sorting
  • CARD_* columns β†’ Required by APEX Card UI

βš™οΈ Step 2: Include SortableJS Library

Add this in Page β†’ JavaScript β†’ File URLs:

https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js

πŸ‘‰ This library enables drag-and-drop functionality.


🧠 Step 3: Enable Drag & Drop (JavaScript)

Add this code in Execute when Page Loads:

var el = document.querySelector('#my_draggable_cards .a-CardView-items');

var sortable = Sortable.create(el, {
    animation: 150,
    ghostClass: 'u-colors-gray-1',
    onEnd: function (evt) {
        var orders = [];
        document.querySelectorAll('#my_draggable_cards .a-CardView-item').forEach(function(card) {
            var id = card.getAttribute('data-id');
            if (id) { orders.push(id); }
        });

        var lWait = apex.util.showSpinner(el);

        apex.server.process('SAVE_CARD_ORDER', {
            f01: orders 
        }, {
            success: function(pData) {
                lWait.remove();
                                apex.message.showPageSuccess("Card order saved successfully!");
                setTimeout(function() {
                    apex.message.hidePageSuccess();
                }, 2000);
            },
            error: function(request, status, error) {
                lWait.remove();
                apex.message.showErrors([{
                    type:       "error",
                    location:   "page",
                    message:    "Error saving Card order: " + error,
                    unsafe:     false
                }]);
            }
        });
    }
});

πŸ”‘ Important Configuration

Make sure your Card Region Static ID is:

my_draggable_cards

πŸ‘‰ This is required for JavaScript to target the correct region.


πŸ”„ Step 4: Create AJAX Callback Process

Create a Process β†’ AJAX Callback named:

SAVE_CARD_ORDER

PL/SQL Code:

begin
    for i in 1 .. apex_application.g_f01.count loop
        update EMP
           set DISPLAY_ORDER = i  -- The loop index is the new position
         where EMPNO = apex_application.g_f01(i);
    end loop;
    apex_json.open_object;
    apex_json.write('status', 'success');
    apex_json.close_object;
exception
    when others then
        apex_json.open_object;
        apex_json.write('status', 'error');
        apex_json.close_object;
end;

πŸ” How It Works

  1. User drags cards
  2. JavaScript captures new order (data-id)
  3. Sends array to APEX (f01)
  4. PL/SQL updates DISPLAY_ORDER
  5. Cards reload in saved order

✨ Final Result

βœ” Drag-and-drop cards

βœ” Instant save without page refresh

βœ” Clean UX with success message

βœ” Fully database-driven ordering


πŸš€ Benefits

  • Improves user experience
  • Works with any dataset
  • Easy to reuse in multiple apps
  • Minimal backend logic

πŸ”₯ Pro Tips

  • Add Refresh Region after save if needed
  • Use Row Locking for multi-user environments
  • Add drag handle icon for better UI
  • Store order per user (if required)

🎯 Conclusion

With just a small JavaScript library and an AJAX process, you can transform a static Card Region into a fully interactive, draggable UI component.

πŸ‘‰ This is a great way to bring modern UX patterns into Oracle APEX applications.

Love coding? Me too! Let’s keep in touch – subscribe to my website for regular chats on Oracle APEX, PL/SQL,SQL JavaScript, and CSS.

Comments

No comments yet. Why don’t you start the discussion?

    Leave a Reply

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