1

Currently I have a page where there are 3 panels I can drag and drop. On these panels I have 3 glyphs one for zooming, one for deleting and one for edit. Take for example the deletion glyph, when I click this it should remove the whole section within the page. This works if I do not drag and drop the panel that I want to delete. However once I drag it over to a new position, my javascript does not seem to recognize the glyph/click event anymore.

Here is my javascript code for deleting.

$(document).ready(function(){
    $(".glyphicon.glyphicon-trash").click(function (event) {
        event.preventDefault();
        $(this).closest(".col-md-4").remove();
    });
});

and here is the HTML for the panels I am attempting to delete after I drag and drop.

<div class="row" id="columns">
<div class="col-md-4 column">
    <div class="panel panel-default" draggable="true">
        <div class="panel-heading">
            <h3 class="panel-title">Panel title
                <span class="glyphicon glyphicon-pencil panel-icons"></span>
                <span class="glyphicon glyphicon-zoom-in panel-icons"></span>
                <span class="glyphicon glyphicon-trash panel-icons"></span>
            </h3>
        </div>
        <div class="panel-body" id="testchart">
            <!--CHART GOES HERE-->
        </div>
    </div>
</div>
<div class="col-md-4 column">
    <div class="panel panel-default" draggable="true">
        <div class="panel-heading panel-backcolour">
            <h3 class="panel-title">
                Panel title
                <span class="glyphicon glyphicon-pencil panel-icons"></span>
                <span class="glyphicon glyphicon-zoom-in panel-icons" data-toggle="modal" data-target="#myModal"></span>
                <span class="glyphicon glyphicon-trash panel-icons"></span>
            </h3>
        </div>
        <div class="panel-body">
            Panel content
        </div>
    </div>
</div>
<div class="col-md-4 column">
    <div class="panel panel-default" draggable="true">
        <div class="panel-heading">
            <h3 class="panel-title">Panel title
                <span class="glyphicon glyphicon-pencil panel-icons"></span>
                <span class="glyphicon glyphicon-zoom-in panel-icons"></span>
                <span class="glyphicon glyphicon-trash panel-icons"></span>
            </h3>
        </div>
        <div class="panel-body">
            Panel content
        </div>
    </div>
</div>

Also here is my js code for drag and dropping

    //For reference tutorial can be found here http://www.html5rocks.com/en/tutorials/dnd/basics/

var dragSrcEl = null;

function handleDragStart(e) {
    // Target (this) element is the source node.
    this.style.opacity = "1.0";

    dragSrcEl = this;

    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.setData("text/html", this.innerHTML);
}

function handleDragOver(e) {
    if (e.preventDefault) {
        e.preventDefault(); // Necessary. Allows us to drop.
    }

    e.dataTransfer.dropEffect = "move";  // See the section on the DataTransfer object.

    return false;
}

function handleDragEnter(e) {
    // this / e.target is the current hover target.
    e.target.classList.add("over");
}

function handleDragLeave(e) {
    e.target.classList.remove("over");  // this / e.target is previous target element.
}

function handleDrop(e) {
    // this/e.target is current target element.

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

    // Don't do anything if dropping the same column we're dragging.
    if (dragSrcEl != this) {
        // Set the source column's HTML to the HTML of the column we dropped on.
        dragSrcEl.innerHTML = this.innerHTML;
        this.innerHTML = e.dataTransfer.getData("text/html");
    }

    return false;
}

function handleDragEnd(e) {
    // this/e.target is the source node.

    [].forEach.call(columns, function (column) {
        column.classList.remove("over");
    });
}

var columns = document.querySelectorAll(".panel");

[].forEach.call(columns, function (column) {
    column.addEventListener("dragstart", handleDragStart, false);
    column.addEventListener("dragenter", handleDragEnter, false)
    column.addEventListener("dragover", handleDragOver, false);
    column.addEventListener("dragleave", handleDragLeave, false);
    column.addEventListener("drop", handleDrop, false);
    column.addEventListener("dragend", handleDragEnd, false);
});
1
  • 1
    Would be nice if you show the same in a fiddle. Commented May 13, 2015 at 12:58

2 Answers 2

2

You need to use event delegation by providing selector as a second argument in on() call, see example below:

$(document).ready(function(){
    $('#columns').on('click', '.glyphicon.glyphicon-trash', function (event) {
        event.preventDefault();
        $(this).closest(".col-md-4").remove();
    });
});

From jQuery on() method documentation:

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.

See "Direct and delegated events" in jQuery on() method documentation and jQuery DataTables – Why click event handler does not work for more information.

On a side note, see suggestion from ImreNage about removing .col-md-4 instead of .panel.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi Gyrocode that worked perfectly, can you explain a little on how it differs from my code?
Also would this work, if I was to let the user add panels during runtime?
@Johnathon64, click events would be delegated as long as your new panels stay inside element with id columns. Otherwise define a new container that would hold all your panels and use its selector instead.
1

As far as I can see it, you seem to drag this element:

<div class="panel panel-default" draggable="true">

out of it's parent:

<div class="col-md-4 column">

and then look for the parent to delete it:

$(this).closest(".col-md-4").remove();

Which is not there anymore. Try to move the whole container as one instead or delete one level below:

$(this).closest(".panel").remove();

3 Comments

This has just made me realise a flaw in my logic, thanks for pointing that out.
Hi @ImreNagy, I have done as you said, which worked however, if I delete the middle panel and try to move another panel in that empty space it does not let me. Any suggestions?
Cos that I already have code in place I thought maybe it would only be a small tweak. I've only just started html and javascript.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.