{"id":17133588,"url":"https://github.com/toddkummer/drag_and_drop","last_synced_at":"2026-05-19T07:02:37.242Z","repository":{"id":235020906,"uuid":"609674719","full_name":"toddkummer/drag_and_drop","owner":"toddkummer","description":"Drag and Drop with Stimulus","archived":false,"fork":false,"pushed_at":"2023-06-04T19:32:03.000Z","size":263,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-29T11:32:49.744Z","etag":null,"topics":["html-drag-and-drop","rails","stimulus"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/toddkummer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-03-04T22:16:55.000Z","updated_at":"2024-05-07T22:38:04.000Z","dependencies_parsed_at":"2024-04-22T02:49:48.922Z","dependency_job_id":null,"html_url":"https://github.com/toddkummer/drag_and_drop","commit_stats":null,"previous_names":["toddkummer/drag_and_drop"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toddkummer%2Fdrag_and_drop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toddkummer%2Fdrag_and_drop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toddkummer%2Fdrag_and_drop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toddkummer%2Fdrag_and_drop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/toddkummer","download_url":"https://codeload.github.com/toddkummer/drag_and_drop/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245217791,"owners_count":20579297,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html-drag-and-drop","rails","stimulus"],"created_at":"2024-10-14T19:42:31.534Z","updated_at":"2025-10-24T13:18:50.551Z","avatar_url":"https://github.com/toddkummer.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Drag and Drop\n\nThis provides an example of using [the HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) to sort a list in a Rails application. The solution uses two [Stimulus](https://stimulus.hotwired.dev/) controllers to invoke the API and update the sort order.\n\n## Usage\n\nThis solution is not packaged. Implementation requires the copy-and-paste skills of the developer.\n\nThe two controllers are in `app/javascript/controllers` and namespaced as `dnd`:\n- [Container Controller](app/javascript/controllers/dnd/container_controller.js)\n- [Item Controller](app/javascript/controllers/dnd/item_controller.js)\n\nIn this implementation, the two controllers are added to [the TODO List form view](app/views/todo_lists/_form.html.erb) and [the Task Fields partial](app/views/todo_lists/_task_fields.html.erb).\n\n### Container Controller\n\nThe main container element specifies (1) the container controller, (2) the outlet for the item controller, and (3) the mouseup listener:\n\n```html\n  \u003cdiv id=\"container\"\n    data-controller=\"dnd--container\"\n    data-dnd--container-dnd--item-outlet=\".nested-fields\" \n    data-action=\"mouseup-\u003ednd--container#disableDrag\" \u003e\n```\n\n### Item Controller\n\nThe main item element specifies (1) the item controller, (2) listeners (dragstart, dragend, dragenter, dragover, dragleave, and drop), and (3) the outlet for the container controller:\n\n```html\n\u003cdiv\n    data-controller=\"dnd--item\"\n    data-dnd--item-dnd--container-outlet=\"#container\"\n    data-action=\"dragstart-\u003ednd--item#dragStart\n                 dragend-\u003ednd--item#dragEnd\n                 dragenter-\u003ednd--item#addDropIndicator\n                 dragover-\u003ednd--item#allowDrop\n                 dragleave-\u003ednd--item#removeDropIndicator\n                 drop-\u003ednd--item#drop\" \u003e\n```\n\nThe handle for the item includes the handle target as well as a mousedown listener:\n\n```html\n\u003ca href=\"#\" class=\"btn btn-primary\" \n    data-dnd--item-target=\"handle\"\n    data-action=\"mousedown-\u003ednd--item#enableDrag\" \u003e\n  \u003ci class=\"fa fa-bars\"\u003e\u003c/i\u003e\n\u003c/a\u003e\n```\n\nThere are three additional targets for the item controller:\n- id: the form element with the unique item Id\n- order: the form element with the order; this value gets updated\n- description: only used by the debugger to help identify the row in the logs\n\n### Styling\n\nThe [following styles](app/assets/stylesheets/dnd.css) support the feature. The can be customized as needed, though the `pointer-events: none` is required.\n\n| Selector | Notes |\n|  --- | --- |\n| .dragged | Reduces opacity to highlight which item is being dragged |\n| .drop-above | When items are dragged upwards, this draws a line where the item would be dropped |\n| .drop-below | When items are dragged dwonwards, this draws a line where the item would be dropped |\n| .dropzone .nested-fields * | Prevents events from firing while the drag is occurring (required) |\n\n## Trying It Out\n\nThe versions in the repo are a bit dated. I found I had to use node 13 to get yarn to install.\n\nThere is a seed file with a sample TODO list.\n\n\n## License\n\nThe code is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n### Credits\n\nThe [underlying TODO app](https://github.com/driftingruby/186-nested-forms-from-scratch-with-stimulusjs) comes from the talented folks at [Drifting Ruby](https://www.driftingruby.com/), from [an episode about nested forms and Stimulus](https://www.driftingruby.com/episodes/nested-forms-from-scratch-with-stimulusjs).\n\nThanks to [Doug Pace](https://github.com/dmpace) for his help in testing the feature.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoddkummer%2Fdrag_and_drop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoddkummer%2Fdrag_and_drop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoddkummer%2Fdrag_and_drop/lists"}