Magento – jQuery UI breaks when clicking on draggable element: “Cannot read property ‘defaultView’ of undefined”

jquerymagento2requirejstemplate

I'm using Ultimo theme and created a child theme. I created a custom module that uses jQuery UI draggable. When the page loads it's all fine but when I click on an element that should be able to be dragged, the console gives an error:

Uncaught TypeError: Cannot read property 'defaultView' of undefined ….. jquery.js:6702

Seems like it is conflicting with jQuery but I have no clue how to fix it, even after reading numerous posts about problems similar to this.

How can I fix this error?

requirejs-config.js @ app/code/Vendor/Module/view/frontend

var config = {
    map: {
        jqueryui: 'Vendor_Module/js/jquery-ui.min'
    }
};

drag.js file @ app/code/Vendor/Module/view/frontend/web/js

require(['jquery', 'jquery/ui'], function($){
    $(document).ready(function() {

        // Makes the pieces draggable & sets options
        $("#piecesArea > div > img").draggable({
            //Makes it so that the pieces' z-index can be reordered
            stack: { group: '#piecesArea > div > img', min: 500,scroll: false },
            distance: 0
        });

        // Sets what happens when you release a piece
        $("#roomArea").droppable({
            drop: function(event, ui){
                // This is so that the element "sticks" even when tab is changed.
                ui.draggable.addClass("draggedout");
            },
            // Changes current tab to the tab the piece belongs to when dragged out of body area
            out: function(event, ui){
                ui.draggable.removeClass("draggedout");
                var whichTab = ui.draggable.parent().attr("id");
                $("#piecesArea").tabs('select' , whichTab);
            }
        });

        // Tabs
        $("#piecesArea").tabs();

        // Changes the body when thumbnails are clicked
        $("#swatchesArea a").click( function() {
            var changeSrc = $(this).attr("href");
            $("#roomArea>img").attr("src", changeSrc);
            return false;
        });
    });
});

default.xml @ app/code/Vendor/Module/view/frontend/layout

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  <head>
    <link src="Vendor_Module::js/drag.js"/>
    <css src="Vendor_Module::css/mainstylesheet.css"/>
  </head>
  <body/>
</page>

Best Answer

There are a few potential issues with this:

  1. There is no need to add jQuery UI to your require JS config, it's already included with M2. Just use jquery/ui as a dependency.

  2. You should use domReady! as a dependency rather than $(document).ready. Like so: require(['jquery', 'jquery/ui', 'domReady!'], function($, ui, doc){

  3. You're loading your script via require and XML at the same time. You only need to add your script once via Require JS, once you have done this there is no need to include your JS via XML to. This is likely your issue.

To rule out any issues with your logic does the code work outside of Magento?

This is one method of calling a JS file from your template:

<script type="text/x-magento-init">
    {
        "*": {
            "Vendor_Module/js/drag": {}
        }
    }
</script>
Related Topic