Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag and drop positioning problems+ updating the id

Hello my stackoverflow friends. I have some problems today and need your help to solve them. If you can help with anything it would be much appreciated! Because I really need to finish this project.

JSFiddle: https://jsfiddle.net/rdxmmobe/1/

This is the script:

<script type="text/javascript">
$(function(){
$(".DraggedItem").draggable({
        helper:'clone', 
        cursor:'move',
        opacity: 0.7
});

$('#rang1').droppable({
    drop: function(ev, ui) {
        $('#rang1input').val($(ui.draggable).attr('id'));
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

$('#rang2').droppable({
    drop: function(ev, ui) {
        $('#rang2input').val($(ui.draggable).attr('id'));
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

$('#rang3').droppable({
    drop: function(ev, ui) {
        $('#rang3input').val($(ui.draggable).attr('id'));
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

$('#rang4').droppable({
    drop: function(ev, ui) {
        $('#rang4input').val($(ui.draggable).attr('id'));
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

$('#rang5').droppable({
    drop: function(ev, ui) {
        $('#rang5input').val($(ui.draggable).attr('id'));
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

$('#rang6').droppable({
    drop: function(ev, ui) {
        $('#rang6input').val($(ui.draggable).attr('id'));
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

$('#rang7').droppable({
    drop: function(ev, ui) {
        $('#rang7input').val($(ui.draggable).attr('id'));
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});
}); 
</script>


These are the 7 droppable divs (where you can drop images):

<form action="<?php echo $_SERVER["PHP_SELF"] ?>" method="POST">
<input type="hidden" value="<?php echo $row["IDBewoner"] ?>" name="bewoner">
<td> 
    <div id="rang1"></div> 
    <input type="hidden" value="" id="rang1input" name="rang1value">
</td>
<td> 
    <div id="rang2"></div> 
    <input type="hidden" value="" id="rang2input" name="rang2value">
</td>
<td> 
    <div id="rang3"></div> 
    <input type="hidden" value="" id="rang3input" name="rang3value">
</td>
<td> 
    <div id="rang4"></div> 
    <input type="hidden" value="" id="rang4input" name="rang4value">
</td>
<td> 
    <div id="rang5"></div>
    <input type="hidden" value="" id="rang5input" name="rang5value">
</td>
<td> 
    <div id="rang6"></div> 
    <input type="hidden" value="" id="rang6input" name="rang6value">
</td>
<td> 
    <div id="rang7"></div> 
    <input type="hidden" value="" id="rang7input" name="rang7value">
</td>
<input type="submit" value="Save">
</form>


And these are the draggable images (images you can drag) they come from a database and have different id's:

<td> <?php echo "<img class='DraggedItem' id='".$row["IDPictogram"]."' src='data:image/jpeg;base64,".base64_encode($row['Pictogram'])."' width='90' height='90' draggable='true'>"; ?> </td>


This is the php code:

if($_SERVER["REQUEST_METHOD"] == "POST") {
$rang1 = $_POST["rang1value"];
$rang2 = $_POST["rang2value"];
$rang3 = $_POST["rang3value"];
$rang4 = $_POST["rang4value"];
$rang5 = $_POST["rang5value"];
$rang6 = $_POST["rang6value"];
$rang7 = $_POST["rang7value"];
$bewonerID = $_POST["bewoner"];

echo "<script>alert('Rang1: $rang1')</script>";
echo "<script>alert('Rang2: $rang2')</script>";
echo "<script>alert('Rang3: $rang3')</script>";
echo "<script>alert('Rang4: $rang4')</script>";
echo "<script>alert('Rang5: $rang5')</script>";
echo "<script>alert('Rang6: $rang6')</script>";
echo "<script>alert('Rang7: $rang7')</script>";
}


First problem: As you can see in my script above I used "helper: 'clone'" but the images
with the class".DraggedItem" are being moved and this is not the point. The images are supposed to be moved and replaced between the 7 divs. But they are supposed to be cloned from the original list (so i can use the same icon twice e.g)

Second problem: I have a hidden input for each div and they must contain the id of the
dropped image so i can insert them into a database. Let's just say I dropped an image on Div1 (#rang1), and then moved the image to Div4 (#rang4), the id of the image remains in the hidden input of the Div1 and not get deleted/updated. How can I make sure that the id also gets updated when I drop a new image on the div?

Third problem: how can I do a check when I drop an image from the main list, that if there is already an image, the old image gets deleted and replaced by the new one?
enter image description here

Fourth problem: what is the best way to switch between 2 images?
enter image description here


If you can help me with any of these problems it would be much appreciated!! I can't go further without solving these problems and I really need help from experts.

like image 285
Elomar Adam Avatar asked Oct 20 '22 14:10

Elomar Adam


2 Answers

I would start with some refactoring of the code to get rid of all copy-paste code. Droppables can be initialised with a single call, referencing each input within the callback as $(this).next('input').

Next, I would not clone the images directly into the dropped fields to avoid ID duplication. I'd create new image elements with a different class inside the slots, as they have to behave differently when moved between slots, in my example without a translucent helper.

So in my example, you have your DraggedItem images without changes. I added the DropZone class to each droppable slot to allow initialisation with a single call.

When an image is dropped, I check where it came from. If it came from the library, create a new image element, set its src to match the original and set the data-id data attribute to the original item's ID for keeping track if needed. As a final step, I add a DroppedItem class and make it another kind of draggable without a helper.

If the item dropped is a DroppedItem, i.e. came from a different slot, simply swap the contents of the containers and the corresponding input box values.

HTML

<table>
    <tr>
        <td> 
            <div id="rang1" class="DropZone"></div> 
            <input type="text" value="" id="rang1input" name="rang1value" />
        </td>
        <td> 
            <div id="rang2" class="DropZone"></div> 
            <input type="text" value="" id="rang2input" name="rang2value" />
        </td>
        <td> 
            <div id="rang3" class="DropZone"></div> 
            <input type="text" value="" id="rang3input" name="rang3value" />
        </td>
        <td> 
            <div id="rang4" class="DropZone"></div> 
            <input type="text" value="" id="rang4input" name="rang4value" />
        </td>
        <td> 
            <div id="rang5" class="DropZone"></div>
            <input type="text" value="" id="rang5input" name="rang5value" />
        </td>
        <td> 
            <div id="rang6" class="DropZone"></div> 
            <input type="text" value="" id="rang6input" name="rang6value" />
        </td>
        <td> 
            <div id="rang7" class="DropZone"></div> 
            <input type="text" value="" id="rang7input" name="rang7value" />
        </td>
    </tr>
</table>
<img id="img1" class="DraggedItem" src="http://dummyimage.com/50x50/000/fff&text=1" />
<img id="img2" class="DraggedItem" src="http://dummyimage.com/50x50/000/fff&text=2" />
<img id="img3" class="DraggedItem" src="http://dummyimage.com/50x50/000/fff&text=3" />
<img id="img4" class="DraggedItem" src="http://dummyimage.com/50x50/000/fff&text=4" />
<img id="img5" class="DraggedItem" src="http://dummyimage.com/50x50/000/fff&text=5" />
<img id="img6" class="DraggedItem" src="http://dummyimage.com/50x50/000/fff&text=6" />
<img id="img7" class="DraggedItem" src="http://dummyimage.com/50x50/000/fff&text=7" />

CSS

table { margin-bottom: 50px; }
td div { width: 50px; height: 50px; border:1px solid silver; margin-bottom: 10px;}
td input { width: 50px; }

JavaScript

$('.DraggedItem').draggable({
    helper: 'clone',
    cursor:'move',
    opacity: 0.7
});

var droppedOptions = {
    revert: 'invalid',
    cursor: 'move'
};

$('.DropZone').droppable({
    drop: function(ev, ui) {
        var dropped = ui.draggable;
        var droppedOn = $(this);

        if(ui.draggable.is('.DroppedItem')) {
            // Item is dragged from another slot, swap images

            var draggedFrom = ui.draggable.parent();
            droppedOn.find('img').appendTo(draggedFrom);
            dropped.css({ top:0, left:0 }).appendTo(droppedOn);

            var temp = '' + droppedOn.next('input').val();
            draggedFrom.next('input').val(temp);
            droppedOn.next('input').val(dropped.data('id'));
        } else {
            // Item is dragged from library

            droppedOn
                .empty() // Delete already dropped items
                .next('input')
                    .val(dropped.attr('id'));

            $('<img class="DroppedItem">')
                .attr('src', dropped.attr('src'))
                .data('id', dropped.attr('id'))
                .draggable(droppedOptions)
                .appendTo(droppedOn);
        }
    }
});

JS Fiddle example

Note that in my example I changed the input type to text for display, just change it back to hidden an you're all set.

like image 157
DarthJDG Avatar answered Oct 27 '22 09:10

DarthJDG


Here is what I did: https://jsfiddle.net/Twisty/rdxmmobe/3/

$(function () {
    $(".DraggedItem").draggable({
        helper: 'clone',
        cursor: 'move',
        opacity: 0.7,
        revert: true
    });

    $("div[id^='rang']").droppable({
        drop: function (ev, ui) {
            var target = $("#" + $(this).attr("id") + "input");
            target.val($(ui.draggable).attr('id'));
            var dropCopy = $("<img>");
            console.log("Setting DropCopy Source: " + $(ui.draggable).attr('src'));
            $(dropCopy).attr('src', $(ui.draggable).attr('src'));
            var droppedOn = $(this);
            droppedOn.append(dropCopy).css({
                top: 0,
                left: 0
            });
        }
    });
});
like image 44
Twisty Avatar answered Oct 27 '22 10:10

Twisty