0

I have been facing a problem when I try to implement SetDragImage on a 'LI' element, the 'LI' has been created dynamically searching inside of a folder and getting the name of the files inside and after being created I set the .draggable() properties

I am able to do drag and drop and the image shown while dragging is the text so I want to change it and show a custom image. The id of each 'LI' contains the source of the image (path + fileName)

I am trying to use SetDragImage but every time I get the error "Uncaught TypeError: Cannot read property 'SetDragImage' of undefined

I have also tried to do it without "originalEvent" and I get the same error

Could someone help me to find my mistake?

Please find below my code

Thank you in advance

Have a good day

HTML section:

<div class="toolGridContainer">
<div class="containerTitle">Container1</div>
<div class="containerSeparator">
    <hr>
</div>
<li id="./images/Image1.svg" class="toolItem ui-draggable ui-draggable-handle">Item 1</li>
<li id="./images/Image2.svg" class="toolItem ui-draggable ui-draggable-handle">Item 2</li>
<li id="./images/Image3.svg" class="toolItem ui-draggable ui-draggable-handle">Item 3</li>
<li id="./images/Image4.svg" class="toolItem ui-draggable ui-draggable-handle">Item 4</li></div>

Javascript:

$(document).on('dragstart', '.toolItem', function(evt){

    var imgObj = document.createElement('img');
    imgObj.src = $(this).prop('id');
    evt.originalEvent.dataTransfer.setDragImage(imgObj, 0, 0);
});

Edit 1: Here is the JSFiddle I made to reproduce my issue

Edit 2: I have made a test div, manually made it draggable and a test function to see if setDragImage is available in other events and this function works fine, why is it?

HTML:

<li id="testItem" draggable="true" class="toolItem">TestItem</li>

Javascript:

var testFunction = function(evt){
    console.log('testFunction running');
    var dataTransfer = evt.dataTransfer;
    var imgObj = document.createElement('img');
    imgObj.src = './image.svg';

    dataTransfer.setDragImage(imgObj, 0, 0);        
}

var testElement = document.getElementById('testItem');
testElement.ondragstart = testFunction;
HeytalePazguato
  • 290
  • 4
  • 13
  • Have you got some html to go along with that javascript. Also not too sure why but the examples I have seen have an offset of over 0.... supply your html and I can try and debug this one. I would check your id and make sure you are returning an image. – Richard Housham May 07 '20 at 15:45
  • @RichardHousham: I have added the html section where the lists items have been dynamically created. I have found code samples with items that are already created but I am not sure if I have to do something different for dynamic objects – HeytalePazguato May 07 '20 at 15:58
  • I remember something about this... For dynamically generated stuff, your jQuery has to be attached to a top-level object then filter down, because it can't attach to something that doesn't exist (yet). See if this helps: https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Kasey Chang May 07 '20 at 16:18
  • @KaseyChang, Thank you for the information, I have checked it but actually I am trying to access from "document" and I am inside the $(document).ready(function() so as far as I know, I am not trying to directly access the list objects. Am I missing something? Or is my understanding of my process incorrect? – HeytalePazguato May 07 '20 at 16:22
  • @RichardHousham, I have added a JSFiddle with a code I made to reproduce the issue, you just have to drag one item to the blue box and it will happen, if you comment the lines for the dragstar event it works properly. Hopefully you or someone might bring some light to this matter. Thank you in advance for your support – HeytalePazguato May 08 '20 at 10:23

1 Answers1

0

Can quite tell what you are going for you started with some pure javascript but then added in the draggable from jquery ui. The JSFiddle was a draggable so just modified that.

You basically just needed to modify the helper function.

<style>
.dropContainer{
  background-color: blue;
  height: 200px;
  width: 500px;
}
</style>

<div id="itemsList" class="toolContainer">
  <div class="toolGridContainer">
    <div class="containerTitle">Tool item container</div>
    <div class="containerSeparator">
      <hr>
    </div>
  </div>
</div>
<div id="dropContainer" class="dropContainer">

</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<script>
var getFileList = function (id){
    for (i = 0; i < 5; i++) {
    var newElement = document.createElement('li');
    var newElementText = document.createTextNode('Item' + i);

    newElement.className = 'toolItem';
    newElement.appendChild(newElementText);

    newElement.id = './image.svg';

    $(newElement).draggable({
        helper: function(e) { 
            image = $(this).attr('id');

            var imgObj = document.createElement('img');
            imgObj.src = image;
            return imgObj;
        },
        cursor: 'dragging'
    });

    $(id).append(newElement);
    }
}

//Drop area
$('#dropContainer').droppable({
        accept: '.toolItem',
        tolerance: 'pointer',

        drop: function(evt, ui){
            var canvasObj = document.createElement('canvas');
              canvasObj.className = 'droppedItem';

              var ctx = canvasObj.getContext('2d');
              ctx.beginPath();
                    ctx.rect(20, 20, 10, 10);
                    ctx.stroke();

        $(canvasObj).draggable().appendTo('#dropContainer');
    }
});


getFileList('#itemsList');
</script>
Richard Housham
  • 1,525
  • 2
  • 15
  • 31
  • Thank you, that helped me a lot To be honest this is my first application with javascript so I am not sure if I am mixing concepts or coding style, I just know what I want to have at the end and I research how to do it so while implementing maybe I mixed something – HeytalePazguato May 14 '20 at 03:34
  • What you find with javascript, is you have 'vanilla' javascript. So pure JS. Jquery which allows for more sleek javascript as well as cross browser support. Then most things like jquery-ui build upon that. Often the best thing to do is use a plugin like jquery-ui as that will give you the most support and is easier to implement. – Richard Housham May 15 '20 at 14:03