REDIPS.drag documentation – Appendix A

Here is list of keywords (mostly class names) used in REDIPS.drag library. Id of drag container(s) or table cell class names should be named properly to achieve needed functionality like cloning DIV elements, adding trash cell, mark cells, adding row handler or mark table as “nolayout”. This post is appendix to the REDIPS.drag documentation post.

Keywords
  1. redips-drag
  2. redips-clone
  3. redips-mark
  4. redips-only
  5. redips-single
  6. redips-trash
  7. redips-rowhandler / row
  8. redips-nolayout
  9. redips-noautoscroll
  10. redips-nodrag

Before going to keywords details, make sure that HTML file has DOCTYPE definition at the top. This will switch browser to the strict mode needed for drag and drop functionality – otherwise REDIPS.drag library will not work properly.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

1. redips-drag
drag is one of the most important keywords. It is used as default name for drag container and for marking DIV elements as drag-n-drop elements. During initialization, REDIPS.drag searches inside the drag container for every DIV element with redips-drag class name and assigns onmousedown event handler. First, here is example of how to create drag container:

<div id="redips-drag">
    <!-- table1 -->
    <table>
     ...
    </table>
    <!-- table2 -->
    <table>
     ...
    </table>
</div>

Any table within drag container will become drag-n-drop layout. The most common problems and questions I received in using REDIPS.drag library are related to drag container size. If width and height CSS properties of drag container are not properly set and inner table comes out of drag container borders then dragged DIV element will not “see” exceeded cells. Good rule is to make drag container visible in customization process of REDIPS.drag library to avoid mentioned problem:

#redips-drag {
    border: 1px solid lime;
}

Next main role of redips-drag keyword is to mark DIV elements as drag elements. Every DIV element inside drag container will be able to drag and drop if drag is in class names list.

<!-- simple DIV drag element -->
<div class="redips-drag">Drag1</div>

<!-- DIV element contains two class names -->
<div class="redips-drag green">Drag2</div>

And finally, it’s possible to have more drag containers. Elements from first drag container can’t be dropped to second drag container and vice versa.

<!-- first drag container -->
<div id="my-drag1">
    <table>
     ...
    </table>
</div>

<!-- second drag container -->
<div id="my-drag2">
    <table>
     ...
    </table>
</div>

Initialization of separated drag containers is slightly different because REDIPS.drag should know names of drag containers. Here is code snippet from example08:

// reference to the REDIPS.drag library
var rd = REDIPS.drag;
// DIV container initialization
rd.init('my-drag1');
rd.init('my-drag2');

2. redips-clone
If DIV element contains redips-clone class name then in a moment of dragging a new DIV element will be cloned. Original DIV element will stay in table cell. Here is how to define clone type of DIV element.

<!-- clone DIV element -->
<div class="redips-drag redips-clone">One of Many</div>

Cloning can be further customized with climit1_X and climit2_X class names (X is integer). If needed, number of cloned DIV elements can be limited with adding climit class name. climit1 means that last DIV element will be moveable while in case of climit2 last object will stay in cell as immovable object.

<!-- allow 4 cloned elements -->
<div class="redips-drag redips-clone climit1_4">Clone type1</div>

<!-- allow 3 cloned elements and left original element as immovable in cell -->
<div class="redips-drag redips-clone climit2_3">Clone type1</div>

3. redips-mark
By default, if table cell is marked with redips-mark class name then this table cell will be closed (forbidden) for any DIV element. Simply said, DIV element will not be able to drop to this cell. Here is example of how to mark table cells as closed:

<tr>
    <td class="redips-mark">You</td>
    <td class="redips-mark">can</td>
    <td class="redips-mark">not</td>
    <td class="redips-mark">drop</td>
    <td class="redips-mark">here</td>
</tr>

It is possible to define exceptions for closed cells. For example, table cell can be forbidden for every DIV element except DIV elements with defined “id”.

// allow DIV element with id="g1" to enter to the marked cell with class="green"
rd.mark.exception.g1 = 'green';

Or it’s possible to define exception for all DIV elements with class name “green” to enter to TD defined with class name “green_cell”.

// allow DIV containing class name "green" to enter to the
// marked cell with class="redips-mark green_cell"
rd.mark.exception.green = 'green_cell';

To avoid class name collisions on existing page, redips-mark class name can be renamed with the following property:

// rename "mark" class name to "my_mark"
REDIPS.drag.mark.cname = 'my_mark';

If REDIPS.drag.mark.action is set to “allow”, then dropping will be possible only to the marked table cell. This means that default behaviour is inverted.

// reference to the REDIPS.drag library
var rd = REDIPS.drag;
// allow dropping only to the marked table cells
rd.mark.action = 'allow';

4. redips-only
Table cells marked with redips-only class name can accept only defined DIV elements. Here is example of how to define table cells marked with redips-only class name.

<th class="redips-only last"></th>

Without any additional rule, redips-only table cells will be closed for any DIV element. With the following JS lines, table cells will accept only DIV elements with id=”a” and id=”b”.

// reference to the REDIPS.drag
var rd = REDIPS.drag;
// define table cells with class="redips-only last" to accept only
// DIV elements with id="a" and id="b"
rd.only.div.a = 'last';
rd.only.div.b = 'last';

It’s also possible to set rule for DIV elements with defined class name to enter to “redips-only” table cell. Here is example how:

// only DIV elements with class="redips-drag orange" can be dropped
// to TD with class="redips-only last"
rd.only.divClass.orange = 'last';

Above rules also mean that DIV elements with id=”a” and id=”b” or with class=”redips-drag orange” will not be able to drop to any other table cell. That behaviour defines REDIPS.drag.only.other property with default value set to “deny”. If defined DIV elements are allowed to enter to other table cells then set the following property:

// allow DIV element tied with "only" rule to enter to other table cells
rd.only.other = 'allow';

5. redips-single
Table cell marked with class name redips-single will accept only one DIV element.

<!-- accept only one DIV element to the dark table cell -->
<td class="redips-single dark" title="Single content cell"></td>

6. redips-trash
Table cell marked with class name redips-trash will behave as trash can.

<td class="redips-trash" title="Trash">Trash</td>

It is possible to rename default class name (to avoid class name collisions):

REDIPS.drag.trash_cname = 'redips-bin';

Now trash cell will be defined as follows:

<td class="redips-bin" title="Trash">Trash</td>

7. redips-rowhandler / redips-row
To define row handler it is needed to add redips-row class name to the DIV element and set redips-rowhandler class name to table cell.

<tr>
    <td class="redips-rowhandler"><div class="redips-drag redips-row"></div></td>
    <td></td>
    <td></td>
    <td></td>
</tr>

Table cells marked with class name redips-rowhandler will be closed (or forbidden) for other DIV elements. In other words, DIV elements won’t have access to the “row handler” table cell.

8. redips-nolayout
If table contains redips-nolayout in class name list then it will be treated as ordinary table and other DIV elements will not be able to enter to such table. This option can be handy if you want to put table inside DIV element and drag as any other content.

<table class="redips-nolayout">
 ...
</table>

9. redips-noautoscroll
If class name of scrollable DIV container contains redips-noautoscroll class name then autoscroll option will be disabled.

<!-- drag container -->
<div id="redips-drag">
    <!-- scrollable div container -->
    <div id="sdc" class="redips-noautoscroll">
        <table>
         ...
        </table>
    </div>
</div>

To make DIV container scrollable, it is needed to set overflow to “auto” and position property to something else then default “static”:

/* make sdc DIV container scrollable */
#sdc {
    overflow: auto;
    position: relative;
}

Here is snippet from www.howtocreate.co.uk: Element position with scrolling offsets with explanation why is needed to set CSS position property (to something else then default “static”). If CSS position of scrollable DIV container is not set, then dragged DIV element will not have correct position below mouse pointer.

… make sure that every element with an overflow of anything other than “visible” also has a position style set to something other than the default “static”. This way, they will all appear in the offsetParent chain, and can be easily subtracted in the same loop that adds the offsetLeft and offsetTop.

10. redips-nodrag
If HTML element has “redips-nodrag” class, then dragging will not be able. It can be useful when DIV element contains inner HTML like in example11.

<td class="redips-nodrag">
 ...
</td>

62 thoughts on “REDIPS.drag documentation – Appendix A”

  1. When using rd.myhandler_dropped – how do i get the ID of the dropped element. I need this to make an instant save using ajax.

    Or is there a smarter way to make an instant save?

    thanks for great script.

  2. @jesper giortz – Instant save in myhandler_dropped is fine. Here is code snippet from example03/ajax/script.js (save dropped DIV element – id and position). Id of dropped DIV is set in rd.obj.id property:

    // save - after element is dropped
    rd.myhandler_dropped = function () {
        // get element position (method returns array with current and source positions)
        var pos = rd.get_position();
        // save table content
        send_request('ajax/db_save.php?p=' + rd.obj.id + '_' + pos.join('_'));
    };
    

    send_request() is custom JavaScript function which starts AJAX call …

  3. Hi, I am having a problem aligning a set of drag and drop elements to the bottom of the page – like a static footer. As soon as i use fixed or absolute positioning the drop function stops working. Please can you offer some advice. Thanks.

  4. @Michelle – DIV elements can be placed only to table cells – dropping grid is based on HTML table (colspan and rowspan cells are supported). If REDIPS.drag works in single mode then table cell can accept only one DIV element. By default REDIPS.drag has multiple drop option and that allows more DIV elements in one TD. In that case, DIV elements will be aligned vertically. In example21 is shown how to place DIV elements horizontally (just set vertical2 shift mode and drag elements to the first two columns – overflowed DIV elements will be shifted to the wide cell at the bottom).

    If you will have any further questions, don’t hesitate to ask.
    Cheers!

  5. Hi, I’ve a problem using variables with your script.

    I want to place drag DIV in a table and I want to clone them and especial DIV only could enter special rows. I got all data from a MySQL table so I need to do it dynamically.

    function semesterHandling() {
        var rd = REDIPS.drag;
        $.each(list_modul_ID, function(i, v) {
            var fachid = list_modul_ID[i],
                modulid = "modul" + fachid,
                modulidc = "modul" + fachid + "c1";
            
            console.log(modulidc);
            rd.only.div.modulid = 'last1';
            rd.only.div.modulidc = 'last1';
        });    
    }
    

    That’s my function and I want to make it work with variables could you help?

    Or could I use of DIV id a class instead that would also help THX

  6. @Jan – In example 7 – “A B C D” only A and B elements can go to the last row. Cells in last row are defined with class=”only last”. In the moment when DIV elements are cloned the following code is executed:

    rd.event.cloned = function () {
        // define variables
        var clonedId = rd.obj.id; // cloned id
        // if cloned begins with 'a' or 'b' define dropping rule 'only' for last row
        if (clonedId.substr(0, 1) === 'a' || clonedId.substr(0, 1) === 'b') {   
            rd.only.div[clonedId] = 'last';
        }
    };
    

    As you can see, if ID of cloned element begins with “a or “b” then dropping rule will be automatically created. Anyway, REDIPS.drag.only.div is initialized as empty array, here is code snippet from REDIPS.drag source:

    only = {div: [],       // (array) DIVid -> className, defined DIV elements can be placed only to the marked table cell
            cname: 'only', // (string) class name for marked cells (default is "only")
            other: 'deny'} // (string) allow / deny dropping marked objects with "only" to other cells
    

    So, definition of dropping rules must be with square braces and that is maybe the problem in your case:

    rd.only.div[modulid] = 'last1';
    rd.only.div[modulidc] = 'last1';
    
  7. Hi, i’m writting from Argentina. Sorry by my terrible english. I’m trying your code in a website and it seems very useful and practice to me. Congratulation for your excelent work! But I need your help, I would like to save de ubication of divs in a mysql database or something like that. Could you give some idea of how can I do it? Thanks!

  8. Hi Marcelo!
    If you ask how to save table content (DIV id + position on table) please see example03. In redips2.tar.gz you will find all needed scripts to prepare example locally. On the other hand, if your question is how to save DIV content (text in DIV element) then REDIPS.drag doesn’t have such option. But, you can copy saveContent() method to your script.js and make needed modification. e.g. instead of line:

    // prepare query string
    query += pname + '[]=' + cn.id + '_' + r + '_' + c + '&';
    

    you can write:

    // prepare query string
    text = cn.innerText || cn.textContent;
    query += pname + '[]=' + text + '_' + r + '_' + c + '&';
    

    You will need to change server side script too. This is just code snippet and should give you an idea how to save content from DIV elements.

  9. Hi, this is a brilliant tutorial, well done on the work.

    Just a simple question – after saving the Query string to the db, what would be the best method of loading this back into the tables?

    Thanks

  10. @Dave – Actually you have two approaches. First is classic – create HTML table on the server with some of server side scripts (PHP, ASPX, JSP …). This is actually how example3 (School time table) works. A bit harder to implement is a pure AJAX table content load. If you have some JS & AJAX skills, you can call your own method after page is ready to load DIV elements and place it on table.

    In my case, I would take combination of JS and server side scripting. First page load with already prepared DIV elements and user actions (dragging/deleting/cloning) saved via AJAX. Hope this tips will be helpful for you.

  11. Hi!

    Very impressive script but as a rookie, I’m a bit lost with all theses options ;)

    Here is what I tried to do and problem I get

    On table1, several activities: let say Act1, Act2, Act3
    On table2 a sort of organizer/calendar with boxes. Let say Block1, Block2, Block3 and Block4

    Users drag activities from table1 to table 2 to kinda book activities.

    Block1 and Block2 is 1st choice
    Block3 and Block4 is 2nd choice

    Now, I need to get these choices to be in a form so that I can see what has been chosen!

    In table2, each Block has its box (td ==> /td) and I wanted to put a hidden field inside so that I can get what has been dropped.

    Something like:

    <input type="hidden" name="Block1" id="Block1" value=" ">
    

    Problem is: how do I get the value of what has been dropped!?? I mean I can set an unique ID for each activiy but I cannot figure out how to tell the input field that I need to get it as value!

    I know it has to deal with myhandler_dropped but cannot figure out how to use it!

    What should I put in value field (value=””) in my hidden input?

    Thanks a lot for this script which is very complete ;)

    Lost

  12. I have prepared example 27 where id of dropped DIV elements is displayed below tables. After DIV element is dropped or deleted, result string will be updated. This solution is without “input type=hidden” form element (you can simply reuse prepared string to any form element if needed). JS code scans TD in right table and prepares DIV id separated with “underline” character. You will see that cloned DIV elements have cX sufix (because each element in DOM should have unique ID) and that can be discarded on the server side. Hope this example will give you a hint and point to the right direction. And here is a link:

    Example 27: TD content

  13. Thanks a lot for such a fast reply! I will definitively check this as soon as I can and give you feedback! Probably one of the most complete script and with such support, what to ask more ;)

  14. Ok, I’ve checked the code and still cannot find a way to send it to a form :(

    Here is what I understand how the script is built:

    Part 1 : initialize the whole thing, declare limitation/option for cells (accept single/multiple dropped boxes, and so on)
    1. Then initialize showContent
    2. Tell showContent to refresh when detect a box has been dropped to a td
    3. Same thing if a box has been deleted from td

    Part 2 : tell showContent what to display and how
    1. Declare all td (in the script td1 to td4)
    2. getContent from each td (here it displays the ID of dropped box from left table1)
    2.a. First display box ID (a to c) + c suffix if cloned item is allowed (if not I guess that this « c » won’t appear like if “single” is chosen) + number that indicates the occurrence. Separates entries with underscore.
    2.b. For ex : cc2 means the dropped box ID is « b », the script allows several occurrence of « b » as dropped boxes , and 2 means it’s the third « b » box dropped (first dropped will be 0).

    Part3 : check if there are several entries in one td
    • If true, increment number

    Part 4: in html file: show the message variable (message = document.getElementById(‘message’);) in a div

    You say to reuse string but where is it in the script?

    I’m very dumb with javascript : I can understand the logic, tweak a bit, but not too much!

    I just need to transform
    « message.innerHTML = ‘td1 = ‘ + td1 + ‘ »
    Into a variable (php or html) that I can put in a hidden input to be sent and stored in a db.

    Basically, it’s like creating a variable message for each td and declare it in my hidden input to use it as an entry.

    Like:
    Messagetd1.innerHTML = ‘ + td1+’;
    Messagetd2.innerHTML = ‘ + td2+’;
    And so on ‘til I get all TDs

    Then, in my hidden input, I would get
    Input id=”td1entry” value=”$Messagetd1”
    Input id=”td2entry” value=”$Messagetd2”

    I don’t’ know how to pass a javascript variable to php one. I guess this is why you said to reuse the string as it’s probably not possible to create a $var from “message” javascript var.

    This is frustrating because I think i’m almost done but cannot find this small key that permits me to achieve what I need :(

    Anyway, thank for your time and help!

    Lost

  15. @Lost – Here is how to prepare URL with query string concatenated from tdx variables:

    // send TD content to PHP script
    send = function () {
        // get content of TD cells
        var td1 = getContent('td1'),
            td2 = getContent('td2'),
            td3 = getContent('td3'),
            td4 = getContent('td4'),
            // prepare URL
            url = 'td1=' + td1 + '&td2=' + td2 + '&td3=' + td3 + '&td4=' + td4;
        // show content in popup window
        window.open('db-save.php?' + url, 'MyPopup', 'width=350,height=260');
    };
    

    PHP side (db-save.php script):

    <html>
    <head>
        <title>Read parameters from URL</title>
    </head>
    <body>
        <b>Query string</b>
        <br/>
        <?php print($_SERVER['QUERY_STRING']) ?>
        <br/>
        <br/>
        <b>Accepted parameters:</b>
        <br/>
        <?php
            // accept tdx parameters
            $td1 = $_REQUEST['td1'];
            $td2 = $_REQUEST['td2'];
            $td3 = $_REQUEST['td3'];
            $td4 = $_REQUEST['td4'];
            // print accepted parameters
            print "td1=$td1<br>";
            print "td2=$td2<br>";
            print "td3=$td3<br>";
            print "td4=$td4<br>";
        ?>
    </body>
    </html>
    

    Anyway, I have prepared complete demo from example27 and sent zip to you.
    Hope my email will not be caught by spam filter.
    ;)

  16. Thanks so much for this help! It’s really appreciated! I feel so ridiculous to see how simple it was (didn’t thought about passing through url…)

    This works like a charm ;)

    Not Lost anymore ;)

  17. hi there.
    I would like to execute a php file when I take a dragable cell in order to show me where I can drop this cell.
    I’m thinking about using AJAX/javascipt, but I would like at least a way to call a php file at the moment when I take a cell.
    Thank you for your time and your help

  18. Hi,

    I have been using redips to allow a bunch of elements to be draggable. It was taking a few seconds to load all the elements. When I try profiling in Chrome, it says it spends most of its time in Style Recalculation events (and shows a bunch of redips-min.js calls)

    Frequent Layout activity : @3.53s - Event triggered 190 layouts taking 103ms.
    Long Duration Events : @3.53s - Event lasted: 10135ms. Exceeded threshold: 2000ms
    

    I know the above data might be insufficient, but can you let me know how I can improve the load speed? I am testing this locally, so data is already local. Network should not be an issue.

    Thanks

  19. @Quakee – If you want to make an AJAX call in the moment when REDIPS.drag highlights TD please use event.changed() event handler. Here is part from documentation:

    changed(currentCell)
    Event handler invoked on every change of current (highlighted) table cell
    

    You can see list of all event handlers in docs.

    @Mentalic – If you have large HTML tables with a lot of DIV elements then performance can be the issue. Inspecting with Chrome (or any other Web inspecting tool) is a good direction to solve the problem. With all info in your comment, I can only suggest to replace redips-drag-min.js with redips-drag-source.js and to continue inspecting. Source file is nicely formatted and well commented so you will be able to see which method is the most called and where REDIPS.drag should be optimized for your case. Hope this tip will be helpful for you.

Leave a Comment