riktar / jkanban

Vanilla Javascript plugin for manage kanban boards
https://www.riccardotartaglia.it/jkanban/
Apache License 2.0
1.07k stars 299 forks source link

Item callback "drop" firing event ignoring the "dragTo" board values #22

Closed jhonatanjunio closed 5 years ago

jhonatanjunio commented 5 years ago

When I set the dragTo value to a board, the item callbackdrop is ignoring dragTo possible limitations. In my project, I'm allowing the items to move through the boards one at once. It's working fine, but when this is done, I have to change the status_id of this item I dragged to the next board. To accomplish this, I created an $.ajax to post the new id to that Item. The problem is: the drop callback is firing this $.ajax dispite of the board limitations (which is visually showing that the dropping are not allowed in certain boards), changing the item ID, which is not the expected behaviour. Can you help me with this? What can I be doing wrong on here? Sorry if this is not an Issue. Tell me if it's not. Thanks for this amazing work!

Regards, Jhon

riktar commented 5 years ago

Hi @jhonatanjunio can you post an example of your code?

jhonatanjunio commented 5 years ago

Of course! Here you go!

kanban.addElement("_primaryboard", {
    "title": item.name,
    "id": item.id,
    "drop": function(el){

        $.ajax( {
            "url"  :"/changeItemStatus",
            "type" :"POST",
            "data": {"_token": _token, "id": el.dataset.eid},
            "dataType": "json",
        });
    },
    "click": function (el) {
        location.replace("kanban?item-id="+el.dataset.eid);
        $('.box1, .box2').toggle(600);
    }
})

This is running under an Ajax call that collect items from database to fill the boards, based on their statuses. I simplified the names I used (which it was in portuguese) to a close approach, focusing on the drop callback I mentioned. Then, here you have the PHP Laravel function which changes the item status:

public function changeItemStatus(Request $request)
{
    //get the ajax var item_id
    $item_id = $request['id'];

    $item= Item::find($item_id); //get the item based on the id from the Ajax call
    if($item->status_id < ItemStatus::FINAL_CHANGEABLE_STATUS) //check if the status is not the last
    {
        $item->status_id = $item->status_id + 1; //changes the status to +1 until it is the last status
    }

    try{
        //Save the item new status
        $item->save();
    }catch (\PDOException $e)
    {
        //Error message.
    }

    //Call the success message and the redirect to the kanban page.

}

Thanks in advance, @riktar !

riktar commented 5 years ago

Hi @jhonatanjunio. This is a bug to fix in the library, because also when you drop an item on an invalid board jKanban trigger anyway thte drop event. I'm working on it :smile:

jhonatanjunio commented 5 years ago

Nice, @riktar ! I really appreciate that. Let me know if I can help you somehow or even if you have news about this please?

Again, thanks and congrats for the amazing work!

marcosrocha85 commented 5 years ago

I had that issue either. Unlikely dragula fires the drop event even when we had set dragTo attribute. @riktar I guess expose board dragTo property can help developer to handle that. I saying just because at my application I handle item sorting, drag and drop, user permissions and so on.

marcosrocha85 commented 5 years ago

@jhonatanjunio My example of code:

jkanban = new jKanban({
    element: '#my_kanban',
    click: function(el) {
        showDialogModal(
            $(el).data("eid"), // item id
            $(el.parentElement.parentElement).data("id") // board id
        );
    },
    dropEl: function(el, target, source, sibling) {
        var allowedBoards = [];
        jkanban.options.boards.map(function (board) {
            if (board.id === $(source.parentElement).data("id")) {
                board.dragTo.map(function (_board) {
                    if (allowedBoards.indexOf(_board) === -1) {
                        allowedBoards.push(_board);
                    }
                });

                return allowedBoards[0];
            }

            return allowedBoards[0];
        });

        if (allowedBoards.length > 0 && allowedBoards.indexOf($(target.parentElement).data("id")) === -1) {
            kanban.drake.cancel(true);
            return;
        }

        var item_id = $(el).data("eid");
        var new_board = target.children("header").data('id');
        $.ajax({
            type: 'POST',
            url: 'localhost/move',
            data: {
                'item_id': item_id,
                'new_board': new_board,
            },
            cache: false,
            success: function (result) {
                console.log("It's done.");
            },
            error: function() {
                console.log("Uh oh! There's an error!");
            }
        });
    }
});
jhonatanjunio commented 5 years ago

Thanks, @marcosrocha85 ! This solved my problem. I had to remove the var new_board = target.children("header").data('board_id'); line, which was throwing the error target.children its not a function. Anyways, I sorted this out and everything is working as expected. Thanks a lot!

Regards, Jhon