Implementing a Swipe-to-Reveal Options Panel with jQuery

Swipe-to-reveal options are a common UI pattern in mobile applications. They allow users to access additional options for a list item by swiping it to the side. This blog post will walk you through a jQuery code snippet that implements this feature. The code uses touch events to detect swipes and reveals an options panel when a long swipe is detected.

Skip to Implementation Details with Oxygen.

jQuery(document).ready(function($) {
    let startX, endX, touchTimer, touchDuration;
    let lastActivePanel = null;
    const threshold = 100;
    const holdDuration = 200; // time in milliseconds to consider as a hold
    const maxDrag = 0; // maximum distance the panel can be dragged

    function resetLastActivePanel(event) {
        if (event && $(event.target).closest('.options').length) {
            // If the clicked element is inside the .options div, do not reset
            return;
        }
        if (lastActivePanel) {
            lastActivePanel.css('transform', 'translateX(0)');
            lastActivePanel.siblings('.options').css('right', '-300px');
        }
    }

    $('body').on('touchstart', '.activity-panel-item', function(event) {
        if (lastActivePanel && lastActivePanel[0] !== this) {
            resetLastActivePanel();
        }
        lastActivePanel = $(this);

        startX = event.originalEvent.changedTouches[0].pageX;
        touchDuration = null;

        touchTimer = setTimeout(function() {
            touchDuration = 'long';
        }, holdDuration);

    }).on('touchmove', '.activity-panel-item', function(event) {
        if (touchDuration === 'long') {
            event.preventDefault();
            event.stopPropagation();
            window.isOptionSwipe = true;

            let currentX = event.originalEvent.changedTouches[0].pageX;
            let movedX = Math.max(maxDrag, currentX - startX); // limit the drag

            $(this).css('transform', `translateX(${movedX}px)`);
            $(this).siblings('.options').css('right', `${-movedX}px`);
        }
    }).on('touchend', '.activity-panel-item', function(event) {
        clearTimeout(touchTimer);

        if (touchDuration === 'long') {
            endX = event.originalEvent.changedTouches[0].pageX;

            if (startX - endX > threshold) {
                $(this).siblings('.options').css('right', '0');
                $(this).css('transform', `translateX(-300px)`);
            } else {
                resetLastActivePanel();
            }
        } else {
            resetLastActivePanel();
        }
        touchDuration = null;
    });

    $('body').on('touchstart', function(event) {
        if (!$(event.target).closest('.activity-panel-item').length && !$(event.target).closest('.options').length) {
            resetLastActivePanel(event); // Pass the event to the function
        }
    });
});

Variables

  • startX, endX: Store the starting and ending X-coordinates of the touch event.
  • touchTimer: A timer to detect the duration of the touch.
  • touchDuration: Stores whether the touch is a long touch.
  • lastActivePanel: Keeps track of the last panel that was swiped.
  • threshold: The minimum distance to consider as a swipe.
  • holdDuration: The time in milliseconds to consider as a long touch.

Functions

  • resetLastActivePanel(): This function resets the last active panel to its original position.
function resetLastActivePanel() {
  if (lastActivePanel) {
    lastActivePanel.css('transform', 'translateX(0)');
    lastActivePanel.siblings('.options').css('right', '-300px');
  }
}

Event Handlers

  • touchstart: Initializes variables and sets a timer to detect a long touch.
  • touchmove: Checks if it's a long touch and then allows swipe actions.
  • touchend: Clears the timer and performs the swipe action if conditions are met.

Implementation Details with Oxygen Builder

To implement this feature using Oxygen Builder, follow these steps:

Step 1: Create Your Oxygen Repeater

Navigate to your Oxygen Builder editor and create a repeater element where you want the swipe-to-reveal functionality.

Step 2: Add Class to Default Div

Select the default div within the repeater and give it a class of "activity-panel-wrapper".

Step 3: Add Sibling Divs

Inside the "activity-panel-wrapper" div, add two sibling divs. Assign a class of "activity-panel-item" to one div and "options" to the other.

Step 4: Style the "activity-panel-item" Div

Apply the following CSS styling to the "activity-panel-item" div:

.activity-panel-wrapper{
     flex-wrap: nowrap;
     flex-direction: column;
     position: relative;
     align-items: center;
     overflow: hidden;
     display: inline-flex;
     align-self: stretch;
     justify-content: flex-start;
     align-content: flex-start;
     gap: 8px;
     border-bottom-color: var(--grey-200,#ECECEC);
     border-bottom-width: 1px;
     border-bottom-style: solid;
}
Step 5: Style the "options" Div

Apply the following CSS styling to the "activity-panel-item" div:

.activity-panel-item{
     flex-wrap: nowrap;
     flex-direction: column;
     align-items: flex-start;
     overflow: hidden;
     position: relative;
     transition: transform 0.3s ease;
     display: inline-flex;
     align-self: stretch;
     justify-content: flex-start;
     align-content: flex-start;
     margin-top: 8px;
     margin-bottom: 8px;
     padding-top: 15px;
     padding-right: 15px;
     padding-bottom: 15px;
     padding-left: 15px;
     gap: 8px;
}
Step 6: Style the contents

Next, you can style the contents of each of the divs according to your design requirements.

Step 7: Add to a code block

Lastly, paste the Java/jQuery into a code block.

This jQuery code snippet, when combined with Oxygen Builder, provides a robust way to implement the swipe-to-reveal options panel commonly used in mobile UIs. It uses touch events and timers to detect long swipes and reveal additional options for a list item.

For a seamless user experience, consider integrating this with your existing tab navigation. Both scripts work in harmony to enhance your site's interactivity.

Jump to Tab Navigation Implementation

Share this post