Categories: CSSScriptWeb Design

Mobile-First Drag and Drop Alternative for List Reordering – picknplace.js

picknplace.js is a JavaScript library that replaces traditional drag-and-drop with a two-step pick-and-place interaction pattern.

Standard HTML5 drag and drop APIs are notoriously difficult to control on mobile devices. You might often accidentally scroll the page when you intend to move an item.

Picknplace.js addresses this by changing the interaction model. The user first “picks” an item (locks it), scrolls or moves to the desired location, and then “places” it. This ensures intentionality and prevents accidental UI shifts.

Features:

    Sponsored
  • Two-Step Interaction Model: Separates selection from placement.
  • Visual Feedback: Creates a ghost element during picking mode. Users see exactly where their item will be placed.
  • Scroll-Aware Positioning: Automatically adjusts ghost element position during scrolling.
  • Customizable Selectors: Configurable class names and DOM selectors.
  • Keyboard Support: Includes Enter and Escape key handlers for accessibility.
  • State Management Pattern: Uses a reducer-based approach for predictable state transitions.

See It In Action:

Use Cases:

  • Mobile Task Management Apps: Reorder priority lists on smartphones.
  • E-Commerce Product Ordering: Arrange items in wishlists or shopping cart priorities.
  • Dashboard Widget Arrangement: Customize dashboard layouts on tablets.
  • Content Management Systems: Reorder articles, images, or menu items in admin panels.

How It Works:

  • Click on Pick Button: Enters picking mode. Creates a ghost element and cloned list overlay.
  • Click on Place Button: Confirms the new position. Reorders the DOM to match the visual layout.
  • Click on Cancel Button: Exits picking mode. Discards all position changes and removes visual overlays.
  • Enter Key Press: Confirms placement when in picking mode. Functions identically to clicking the Place button.
  • Escape Key Press: Cancels the operation when in picking mode. Functions identically to clicking the Cancel button.
  • Scroll Event: Updates ghost element position during picking mode. Maintains proper visual alignment with list items.

How to use it:

1. Download the picknplace.js library and import the createPickPlace function into your project:

import { createPickPlace } from "./picknplace.js";

2. Initialize the library and attach it to your list elements:

// Create a new instance with default settings
const pnp = createPickPlace();

// Initialize the pick-and-place functionality
pnp.init();

3. Create the list structure. You need a container (list), items (list elements), and trigger buttons inside the items.

<ul class="pnp-list">
  <li class="pnp-item">
    <div class="item-content">
      <div class="avatar">👨‍💻</div>
      <div class="info">
        <span class="name">Alex Chen</span>
        <span class="role">Frontend Lead</span>
      </div>
    </div>
    <div class="pnp-buttons">
      <button class="pnp-pick btn-pick">Move</button>
    </div>
  </li>
  <li class="pnp-item">
    <div class="item-content">
      <div class="avatar">👩‍🎨</div>
      <div class="info">
        <span class="name">Sarah Jones</span>
        <span class="role">Product Designer</span>
      </div>
    </div>
    <div class="pnp-buttons">
      <button class="pnp-pick btn-pick">Move</button>
    </div>
  </li>
  <li class="pnp-item">
    <div class="item-content">
      <div class="avatar">🚀</div>
      <div class="info">
        <span class="name">Mike Ross</span>
        <span class="role">DevOps Engineer</span>
      </div>
    </div>
    <div class="pnp-buttons">
      <button class="pnp-pick btn-pick">Move</button>
    </div>
  </li>
  <li class="pnp-item">
    <div class="item-content">
      <div class="avatar">💼</div>
      <div class="info">
        <span class="name">Jessica Wu</span>
        <span class="role">Product Owner</span>
      </div>
    </div>
    <div class="pnp-buttons">
      <button class="pnp-pick btn-pick">Move</button>
    </div>
  </li>
  <li class="pnp-item">
    <div class="item-content">
      <div class="avatar">🛡️</div>
      <div class="info">
        <span class="name">David Miller</span>
        <span class="role">Security Specialist</span>
      </div>
    </div>
    <div class="pnp-buttons">
      <button class="pnp-pick btn-pick">Move</button>
    </div>
  </li>
  <li class="pnp-item">
    <div class="item-content">
      <div class="avatar">📊</div>
      <div class="info">
        <span class="name">Emily Davis</span>
        <span class="role">Data Scientist</span>
      </div>
    </div>
    <div class="pnp-buttons">
      <button class="pnp-pick btn-pick">Move</button>
    </div>
  </li>
</ul>

4. Create global controls to confirm or cancel the action.

<div class="pnp-controls">
  <button class="pnp-cancel ctrl-btn ctrl-cancel">Cancel (Esc)</button>
  <button class="pnp-place ctrl-btn ctrl-place">Confirm (Enter)</button>
</div>

5. picknplace.js accepts an options object during initialization. All selectors and class names can be customized:

Sponsored
  • root: The root element for event listeners. Default: document.
  • listSelector: Selector for the container element. Default: .pnp-list.
  • itemSelector: Selector for individual list items. Default: .pnp-item.
  • controlsSelector: Selector for the global control container. Default: .pnp-controls.
  • buttonsSelector: Selector for the button container within an item. Default: .pnp-buttons.
  • pickSelector: Selector for the button that starts the pick action. Default: .pnp-pick.
  • placeSelector: Selector for the button that confirms the new position. Default: .pnp-place.
  • cancelSelector: Selector for the button that cancels the action. Default: .pnp-cancel.
  • pickedClass: Class added to the item currently selected. Default: pnp-picked.
  • realClass: Class applied to the original DOM elements. Default: pnp-real.
  • ghostClass: Class applied to the floating duplicate element. Default: pnp-ghost.
  • cloneClass: Class applied to the placeholder clones during sorting. Default: pnp-clone.
createPickPlace({
  // options here
})

Alternatives:

  • Sortable: A lightweight and simple JavaScript library that makes a list of items sortable by using the native HTML5 drag and drop API.
  • dragula: A simple, dependency-free, touch-enabled JavaScript library that provides drag and drop functionality on DOM elements.
  • 10 Best Drag And Drop JavaScript Libraries

FAQs

Q: Can I use this library with dynamically added list items?
A: Yes. The library attaches event listeners to the root element using event delegation. New items added to the list automatically gain pick-and-place functionality.

Q: Does the library work with nested lists?
A: No. The current implementation assumes a flat list structure. Each createPickPlace instance targets a single list level. For nested hierarchies, you would need to create separate instances for each nesting level and handle the interaction boundaries manually.

Q: How do I persist the new order after placement?
A: The library reorders DOM elements but does not handle persistence. After a successful place event, read the new order from the DOM and send it to your backend. You can query all items with document.querySelectorAll('.pnp-item.pnp-real') and extract their data attributes or IDs in sequence.

Q: Can I customize the animation timing for item transitions?
A: Yes. The cloned items use CSS transforms for positioning. Add transition properties to the .pnp-clone class in your stylesheet. For example: .pnp-clone { transition: transform 0.3s ease-out; } will smooth the repositioning animations.

Q: Why does the ghost element sometimes appear offset during fast scrolling?
A: The library adjusts ghost position using CSS custom properties and requestAnimationFrame. On very fast scroll events, there may be a brief visual lag. This happens because the browser processes scroll events faster than animation frames. The offset corrects itself within one frame cycle.

The post Mobile-First Drag and Drop Alternative for List Reordering – picknplace.js appeared first on CSS Script.

rssfeeds-admin

Share
Published by
rssfeeds-admin

Recent Posts

IGN Community Awards

As IGN Fan Fest 2026 comes to a close, and we celebrate our favorite franchises…

5 minutes ago

Trump orders federal agencies to drop Anthropic’s AI

On Friday afternoon, Donald Trump posted on Truth Social, accusing Anthropic, the AI company behind…

40 minutes ago

Researchers Uncover Aeternum C2 Infrastructure with Advanced Persistence and Network Evasion Features

For years, taking down a botnet meant finding its command-and-control (C2) server, seizing the domain,…

54 minutes ago

Vshell Gains Traction Among Threat Actors as an Alternative to Cobalt Strike

A Go-based command-and-control (C2) framework originally marketed within Chinese-speaking offensive security communities has been quietly…

54 minutes ago

New Dohdoor Malware Attacking Schools and Health Care Sectors in U.S. via Multi-Stage Attack Chain

A newly discovered malware campaign has been quietly targeting educational institutions and healthcare organizations across…

55 minutes ago

This website uses cookies.