0

I'm currently working on a mobile app/game. I am having a difficult time getting an inventory system working properly on a phone. the drag and drop work perfectly fine with a mouse on the pc, but will not work on phone.

JavaScript code:

document.addEventListener("DOMContentLoaded", function(event) {
  $(document).ready(function(){
    var videoPath = "videos/lg/";
    var draggedItem = null; 
    $('.segmentListItem').each(function(index){
      $(this).on("dragstart", handleDragStart);
      $(this).on("drop", handleDrop);
      $(this).on("dragover", handleDragOver);                        
    });
    function handleDragStart(e){
      //console.log('start');
      draggedItem=this;
      e.originalEvent.dataTransfer.effectAllowed = 'move';
      //e.dataTransfer.dropEffect = 'move'; //MH - do we need both of these?
      e.originalEvent.dataTransfer.setData('text/html', this.innerHTML);
    }

    function handleDragOver(e) {
      if (e.preventDefault) {
        e.preventDefault(); // Necessary. Allows us to drop.
      }
      e.originalEvent.dataTransfer.dropEffect = 'move';  // See the section on the DataTransfer object.
      return false;
    }

    function handleDrop(e){
      if (e.stopPropagation) {
        e.stopPropagation(); // Stops some browsers from redirecting.
      }

      if (draggedItem != this) { //MH - swap if we're not dragging the item onto itself
        var copy=$(this).clone(true,true);
        var slot1 = $(this).attr("id");
        var slot1Temp = slot1 + "temp";
        var slot2 = $(draggedItem).attr("id");
        $(this).replaceWith($(draggedItem).clone(true,true));
        $(draggedItem).replaceWith($(copy).clone(true,true));
        slotID = "slotID-" + slot1;
        document.getElementById(slot1).id = slot1Temp;
        document.getElementById(slot2).id = slot1;
        document.getElementById(slot1Temp).id = slot2;
                
        $.ajax({
          type: "GET",
          url: '/inventorySwap.php',
          data: {'slot1': slot1,'slot2': slot2},
          success: function(data) {
            alert(data);
          }
        });                
      } 
      return false;
    }              
  });
});

HTML/PHP code:

<div class='inventorySlot". $obj->slot_id ."'>
  <img class='segmentListItem' draggable='true' id=slotID-". $obj->slot_id ." src='{$itemImage}' />
</div>

Sorry if this question is set up a bit weird, I generally research and learn on my own. I don't like asking questions, I'm just completely stumped on this one.

What I need (and works perfect with mouse/on pc) Drag element from 1 div to another. In code posted, it also changed the id of swapped elements to match their div inventory slot number. this is to prevent errors when updating database to swap within slot record.

thank you for any and all help given.

Shiladitya
  • 12,003
  • 15
  • 25
  • 38
Donnie
  • 11
  • 2
  • It seems that drop event doesn't fire on some mobile device. – Timothy Lee Oct 02 '17 at 06:59
  • I know drag events work. as shown here https://jsfiddle.net/ktxygdvq/. – Donnie Oct 02 '17 at 07:44
  • https://stackoverflow.com/questions/20927759/html5-drag-and-drop-for-mobile – Timothy Lee Oct 02 '17 at 07:48
  • Have to long press item (which i am fine with), i'm by no means good at javascript. and have played with the code posted in jsfiddle, but can not get it to switch slots. the origional for that script is from w3schools, just easier to edit and play with in jsfiddle. – Donnie Oct 02 '17 at 07:48
  • ill look more into that answer, so far i'm not able to swap the images between div's still though. seems a few people were having issues with the answers over there. while playing with their demo and looking at how its working, i'm not sure this will do what i need. closest thing would be the list reordering. I need to swap everything within the 2 div's the inventory is 5x9, and wanting it to be able to be rearranged. thank you for your time. I'll keep playing with what they have and what i have and maybe be able to find a solution, ill check back often in hopes of other ideas as well. – Donnie Oct 02 '17 at 08:23
  • after playing a bit, i made a possible solution tweaking the previous jsfiddle i posted, https://jsfiddle.net/ktxygdvq/2/ still needs some tweaking to get it the way i want. but it will work for now until i can find a better solution. I'll check back here when i wake up. Ideally i would like it to work exactly like the original i use, but i fear that may not happen. hopefully i can at least get it close. – Donnie Oct 02 '17 at 09:49

1 Answers1

1

After a few hours of playing around with everything I managed to get what I needed.

outer div is for drop events, middle div is for drag events, has to have width/height to fill outer div inner div HAS to have position as absolute and z index less than the middle div.

this way no matter what, you click on middle div, and not it's inner contents.

the JS code saves both slot ids as a variable then stores the id's innerhtml as another variable.

then it changes innerhtml of stored variable id1 with html of id2

contents as a var, then replaces each one to

function dragStart(event) {
    event.dataTransfer.setData("Text", event.target.id);
    id1 = event.target.id;
    id1Html = document.getElementById(id1).innerHTML;
}

function dragging(event) {

}

function allowDrop(event) {
    event.preventDefault();
}

function drop(event) {
    event.preventDefault();
    var data = event.dataTransfer.getData("Text");
    id2 = event.target.id;
    id2Html = document.getElementById(id2).innerHTML;
    document.getElementById(id1).innerHTML = id2Html;
    document.getElementById(id2).innerHTML = id1Html;
    alert(id1);
    alert(id2);
}
.inventorySlot1{position: absolute;top: 22%;left: 45%;width: 9%;height: 1px;height: 7%;overflow:hidden;background-color:green;opacity:0.5;}
.inventorySlot2{position: absolute;top: 22%;left: 54.5%;width: 9%;min-height: 1px;height: 7%;overflow:hidden;background-color:red;opacity:0.5;}
.inventorySlot6{position: absolute;top: 29.5%;left: 45%;width: 9%;height: 1px;height: 7%;overflow:hidden;background-color:green;opacity:0.5;}
.inventorySlot7{position: absolute;top: 29.5%;left: 54.5%;width: 9%;min-height: 1px;height: 7%;overflow:hidden;background-color:red;opacity:0.5;}
    <div class='inventorySlot1' ondrop='drop(event)' ondragover='allowDrop(event)'>
        <div ondragstart='dragStart(event)' ondrag='dragging(event)' draggable='true' id='slotID-1' style='width:100%;height:100%;'>
            <div style='position:absolute;z-index:-1;'>
            <img src='http://siteprice.co/images/failed.png'>
            </div>
        </div>
    </div>
    
        <div class='inventorySlot2' ondrop='drop(event)' ondragover='allowDrop(event)'>
        <div ondragstart='dragStart(event)' ondrag='dragging(event)' draggable='true' id='slotID-2' style='width:100%;height:100%;'>
            <div style='position:absolute;z-index:-1;'>
            <img src='http://siteprice.co/images/safe.png'>
            </div>
        </div>
    </div>
    
    <div class='inventorySlot6' ondrop='drop(event)' ondragover='allowDrop(event)'>
        <div ondragstart='dragStart(event)' ondrag='dragging(event)' draggable='true' id='slotID-6' style='width:100%;height:100%;'>
            <div style='position:absolute;z-index:-1;'>
            <img src='http://siteprice.co/images/alexa.png'>
            </div>
        </div>
    </div>
    
        <div class='inventorySlot7' ondrop='drop(event)' ondragover='allowDrop(event)'>
        <div ondragstart='dragStart(event)' ondrag='dragging(event)' draggable='true' id='slotID-7' style='width:100%;height:100%;'>
            <div style='position:absolute;z-index:-1;'>
            <img src='http://siteprice.co/images/whois.png'>
            </div>
        </div>
    </div>
Donnie
  • 11
  • 2
  • You still have to long click before dragging, but it works perfectly for what i need. and styles look horrible here, but website is run through android webview will app set to portrait only. Each device i tested inventory page on looks great. The colors and opacity are only for debugging location of slot in app. they are not needed. Was just carried over when sending working code here. – Donnie Oct 02 '17 at 21:48