vakata / jstree

jquery tree plugin
http://jstree.com
MIT License
5.15k stars 1.38k forks source link

How to cancel the node move, depending on conditions? #843

Closed acelot closed 10 years ago

acelot commented 10 years ago
.on("move_node.jstree", function (e, data) {
  // moving node via ajax request...
  // if not success cancel moving
  // else move
})

How to implement this behavior?

vakata commented 10 years ago

Use check_callback - there are a lot of examples in the discussion group - for example this one: https://groups.google.com/d/msg/jstree/bwZyny3eos4/V4e4q3fUQwAJ

Best regards, Ivan

acelot commented 10 years ago

Thanks for examples, but I still have problem with browser UI hanging while ajaxing:

$pagesTree
  .jstree({
    core: {
      data: data,
      check_callback: function (op, node, parent, position, more) {
        if (op === "move_node" && more && more.core) {
          var result = false;

          $pagesTree.parent().addClass("dimmed");

          $.ajax({
            type: 'post',
            url: "pages/movenode",
            async: false,
            data: {
              id: node.id,
              parentId: parent.id != "#" ? parent.id : null,
              position: position
            },
            success: function () {
              result = true;
            },
            error: function () {
            },
            complete: function () {
              $pagesTree.parent().removeClass("dimmed");
            }
          });

          return result;
        }
      }
    },
    plugins: [
      "dnd"
    ],
    dnd: {
      inside_pos: "last"
    }
  });

As you can see I'm trying to dim tree div while ajaxing, but it doesn't work, because ajax function blocks js thread.

Can you provide some workaround to prevent this behavior?

vakata commented 10 years ago

Well, you are using async: false, which has nothing to do with jstree, your approach is wrong - doing a check with the server while the user drags a node is not a good idea. But that is an architectural decision - I do not know how to solve this for you, it is up to you to figure out a way. Just a quick idea (without grapsing the big picture) - you can just let the move_node happen (since you do not know if you should prevent it on the client), and if it should not happen - return an error code (when moving) and when you get the error code on the client - refresh the tree.

Best regards, Ivan

acelot commented 10 years ago

I thought about this idea. Probably have to realize that.

Thanks for support!

redtopia commented 6 years ago

@acelot - did you ever figure out how to undo a drag and drop action? From what I can see in your example (and I assume from what you already figured out by now), your ajax call to move the node on the server would happen in the move_node event listener as follows (shorthand code):

$('#tree').jstree(options).on('move_node.jstree', function(e, data) {
    // the check_callback returned true and the user moved the node
    // make ajax call to move the node in the back end
    // if the ajax call fails, undo the move action and restore the tree to the previous state
});

I'm trying to figure out how I can cancel the move action (or undo the move action) if the ajax call failed for some reason, like if the server rejected the move?

acelot commented 6 years ago

@redtopia I've been waiting for you 4 years! :D (joke) As far as I remember, it was a long time ago (in far far galaxy), I decided to do so, as recommended by @vakata.

ekr3peeK commented 4 years ago

@redtopia @acelot this is an old thread, but assuming that you have all the information in the move_node event listener, you can revert the action manually, in case the ajax request failed somehow.

I would advise putting the tree in a loading state, while the ajax request runs, and if the ajax request fails, using the same data variable to perform the inverse move action.