JavaScript Drag and Drop example 6

Example shows dragging functionality across scrollable DIV containers. If DIV container is bigger than displayed size, moving element near edge will start to auto-scroll. Other dragging examples are placed in Drag and Drop section.

REDIPS.drag example06

The whole magic lies in changing style position declaration. If position declaration isn’t defined then element has default static style position. So, when DIV elements is clicked with left mouse button nothing will happen until element is moved. In that moment, script will change style position from static to fixed. This change will take out DIV element from normal DOM flow and position it at defined coordinates (relative to browser window). Element will stay at that position regardless of scrolling – and that’s exactly what we want.

Position style has four values: static, relative, absolute, and fixed. Their explanation can be read on very good site http://www.quirksmode.org/css/position.html – it’s definitely recommended to visit.

For the first visitors
Example 6 (scrollable and fixed DIV containers) is based on REDIPS.drag library. Please visit Drag and drop table content with JavaScript where you will find more details, comments and source package to download.

33 thoughts on “JavaScript Drag and Drop example 6”

  1. When DIV element is dragged across table(s), REDIPS.drag will highlight TDs which can accept DIV element. So, when DIV element is dragged out of a table then last TD will stay highlighted. This is needed to enable dropping DIV element to the last possible TD if user releases button out of table boundaries (otherwise dropped DIV element will be lost).

    If I understood your question well, currently is not possible to delete DIV element by dropping DIV element out of a table.

  2. Hello,
    when drag div to occupied cell, I would like to ask the user what he would like to do.
    Is it possible ?

  3. @Adam – When dropMode is set to “single” then is not possible to drop DIV element to the occupied TD. Instead, you can define dropMode to “multiple” and inside event.droppedBefore(targetCell) event handler write custom JS code. This code will be executed in moment when user releases left mouse button but before dropping DIV element to the target cell. If you return “false” from droppedBefore, then DIV element will be returned to the initial position.

    Input parameter of droppedBefore is target cell reference, so you can test whether cell is empty or not.

  4. @dbunic – First thank you very much!! I made what you said, I test whether cell is empty or not, if is not empty, I open a jquery-ui menu and return false. More than that I store the target cell reference in another page (because when droppedBefore return false, and I store the reference in the same page it makes it undefined). How should I make the changes of the DIV in the chosen dropMode?

    thanks
    Adam

  5. I’ve tried to call from the click event on the select mode to the

    rd.event.dropped = function (targetCell)
    

    but it’s not working.

    Adam

  6. @Adam – REDIPS.drag is updated to version 5.0.3 (emptyCell method now has option to test target cell and to delete cell content) – this is needed for your case. Here is complete JS code in droppedBefore event handler:

    // event handler invoked before DIV element is dropped to the cell
    rd.event.droppedBefore = function (targetCell) {
        // test if target cell is occupied and set reference to the dragged DIV element
        var empty = rd.emptyCell(targetCell, 'test'),
            obj = rd.obj;
        // if target cell is not empty
        if (!empty) {
            // confirm question should be wrapped in setTimeout because of
            // removeChild and return false below
            setTimeout(function () {
                // ask user if he wants to overwrite TD (cell is already occupied)
                if (confirm('Overwrite content?')) {
                    rd.emptyCell(targetCell);
                }
                // append previously removed DIV to the target cell
                targetCell.appendChild(obj);
            }, 50);
            // remove dragged DIV from from DOM (node still exists in memory)
            obj.parentNode.removeChild(obj);
            // return false (deleted DIV will not be returned to source cell)
            return false;
        }
    };
    

    I also created jsfiddle where you can see demo in live.

    http://jsfiddle.net/dbunic/v4qhdmzL/

    If target cell is not empty, application will ask to confirm whether to overwrite or to append dropped DIV element. This should help you with jQuery popup dialog and possible actions in case of dropping content to non empty cell.

  7. @dbunic – Thank you very very much!!!
    the last thing i would like to know is if can I ask the user i what drop position he want to chose – shift, switch or overwrite ?

    I mean I want to do this: If the cell is not empty i will show to the user a menu with 3 drop mode – shift, switch and overwrite and he will have to chose, when he will chose the drop will be fired in the mode the user was chose.

    please let me know if is it possible.

    Thanks!

  8. @Adam – dropMode in general can be set before dragging begins or in the early stage of drag process like event.clicked and event.moved hooks. If you want to set dropMode depending on cell content, then it’s needed to use trick like is shown in jsfiddle demo:
    1) dropped DIV element should be temporary removed
    2) content in target cell should be deleted, switched or shifted in event.droppedBefore
    3) and place DIV element from the first step to the TD

    Nevertheless I have prepared example26: jQuery dialog with shift, switch and overwrite actions. So, answer to your question is yes, it’s possible ;)

    I also had to make small modifications within enableDrag and relocate methods so please download latest redips2.tar.gz package (version 5.0.4).

  9. Oh please help.. why would I lose the horizontal scrolling?

    I am working on an iPhone app. The footer needs to be inside the drag area. The content area contains the table that needs to scroll.

    Drag and drop is working well and the footer is fixed but I have lost the horizontal scroll.

    Please advise.. Thanks

  10. @Michelle – Maybe the problem is related to DIV sections inside drag area. Anyway, make sure that with an overflow set to “auto” (anything else then “visible”), also has a position style set to something other than the default “static” (needed for correct offset calculation). CSS may look like:

    overflow: auto;
    position: relative;
    

    I’m only guessing because I didn’t see the source code.

  11. I have used this example (6) to create a big table on the left which I can use to populate a small table on the right. I already had most the page built before I found your tool but I still started with this example page and gradually added my code and css checking at each step to make sure the drag feature was still working.

    Everything worked fine until I added my features to sort or filter the big table (this essentially refreshes the page). As soon as the page refreshes, the ability to drag has gone. I am fairly new to PHP so the problem could be something fairly simple I’ve missed… I just don’t know where to begin to look other than the fact that when I go back to my controller/model to re-filter the data and then refresh the view the cursor’s back to selecting text rather than dragging.

    I also found that if I go into this page via my simple login page it just doesn’t work right off the bat.

    Do you have any ideas where I should look to fix this?

    Thanks.

  12. @MikeF – If drag&drop doesn’t work after page is refreshed then the problem might be related to the drag container initialization. Just call REDIPS.drag.init() method after your page is reloaded.

    Every page should have at least one drag container and it should be initialized after page loading is finished.

Leave a Comment