JavaScript Drag and Drop example 3

School timetable is example of how to use REDIPS.drag library. Page layout contains two tables – left table with school subjects and timetable on the right. After subject is placed to timetable, button in the same color will be displayed next to the subject (clone object).

REDIPS.drag example03

Please note two checkboxes in upper left timetable corner. First checkbox is turned on by default to enable cloning subjects across a week. You can turn it off for placing single subject to timetable. If second checkbox is checked, then “subject report” will pop up if report button (button next to subjects in left table) is clicked. At the same time, all other subjects will be hidden. Clicking on any element in left or right table will show up all elements.

The following code shows event.dropped() event handler (with logic for cloning DIV elements across a week).

rd.event.dropped = function () {
    var objOld = rd.objOld,                // original object
        targetCell = rd.td.target,         // target cell
        targetRow = targetCell.parentNode, // target row
        i, objNew;                         // local variables
    // if checkbox is checked and original element is of clone type
    // then clone spread subjects to the week
    if (document.getElementById('week').checked === true &&
        objOld.className.indexOf('clone') > -1) {
        // loop through table cells
        for (i = 0; i < targetRow.cells.length; i++) {
            // skip cell if cell has some content
            // (first column is not empty because it contains label)
            if (targetRow.cells[i].childNodes.length > 0) {
                continue;
            }
            // clone DIV element
            objNew = rd.cloneObject(objOld);
            // append to the table cell
            targetRow.cells[i].appendChild(objNew);
        }
    }
    // print message only if target and source table cell differ
    if (rd.td.target !== rd.td.source) { 
        printMessage('Content has been changed!');
    }
    // show / hide report buttons
    reportButton();
};

Source code (including school timetable with save/recall table using PHP and MySQL) and detailed description of library can be found on Drag and drop table content with JavaScript.

176 thoughts on “JavaScript Drag and Drop example 3”

  1. Thanks for the answer, its work on it. Now I want to create another function that can show me each subject has been drop to the table2 for how many times.

    // search for div elements in first table cell
    var content = document.getElementById('first_cell').getElementsByTagName('div');
    // if content exists
    if (content.length > 0) {
        ...
        ...
    

    By using the example that you gave me, it just allow to show whether there is any subject in the table,how can I know English class is in which column or Mathematics in which column. Hope you can help me, thank you.

  2. @arzozeus – I prepared JavaScript function to report how many times and where subjects are appearing in the timetable. Just call function with ID of subject like report(‘en’) or report(‘ph’). Hope this code will give you a direction …

    // function reports how many times subjecs occures in timetable
    function report(subject) {
            // define day and time labels
        var day = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
            time = ['08:00', '09:00', '10:00', '11:00', '12:00',
                    '13:00', '14:00', '15:00', '16:00'],
            // define node list oft DIV elements from table2
            div_nl = document.getElementById('table2').getElementsByTagName('div'),
            div = [],    // define array
            cellIndex,   // cell index
            rowIndex,    // row index
            id,          // element id
            i,           // loop variable
            num = 0,     // number of found subject
            str = '';    // result string
        // create array from node list
        for (i = 0; i < div_nl.length; i++) {
            div[i] = div_nl[i];
        }
        // sort div elements by the cellIndex
        div.sort(function (a, b) {
            return a.parentNode.cellIndex - b.parentNode.cellIndex;
        });
        // loop goes through all collected elements
        for (i = 0; i < div.length; i++) {
            // define only first two letters of ID
            // (cloned elements have appended c1, c2, c3 ...)
            id = div[i].id.substr(0, 2);
            // if id is equal to the passed subject then we have a match
            if (id === subject) {
                // define cell index
                cellIndex = div[i].parentNode.cellIndex;
                // table row is parent element of table cell 
                rowIndex = div[i].parentNode.parentNode.rowIndex;
                // add line with found element
                str += day[cellIndex - 1] + '\t\t' + time[rowIndex - 1] + '\n';
                // increase counter
                num++;
            }
        }
        alert('Number of found subjects: ' + num + '\n' + str);
    }
    
  3. I need help. I need to do something like timetable example, when I set a subject of 2 hours at 8:00, I need to create an object that covers the line 8:00 and 9:00 am, how I can do that? sorry for my English, I need to cover automatically 2 o more lines in a day :s how i can do that?, Thnx

  4. @David Santiago – Table content (in this case DIV elements) can be placed only to one table cell. DIV element can’t cover two cells. Actually you can clone element like in this demo and place each element to their table cell. I know this is not exactly what you looking for but it’s the closest possible solution.

    REDIPS.drag library is based on table cells and table cell content.

  5. Hi dbunic! thanks for your time, in this case how can i create a function that clone automatically any droped subject and set it to the next cell, i mean without using SHIFT key, :) sorry for my english again

  6. @David Santiago – Your English is good enough – nothing to worry about ;) Here is modification of myhandler_dropped code:

    rd.myhandler_dropped = function () {
        var obj = rd.obj,                           // dragged OBJect
            obj_old = rd.obj_old,                   // original object
            target_cell =  rd.target_cell,          // target cell
            target_row = rd.target_cell.parentNode, // target row
            obj_new, id,                            // local variables
            rowIndex = target_row.rowIndex,         // rowIndex of row below target row
            cellIndex = target_cell.cellIndex,      // cellIndex of cell below target cell
            tbl = target_row,                       // reference to the target table
            target_cell1;                           // table cell below target cell
        // if checkbox is checked and original element is clone type then clone school subject to the week
        if (document.getElementById('week').checked === true && obj_old.className.indexOf('clone') > -1) {
            // loop up until table found
            while (tbl && tbl.nodeName !== 'TABLE') {
                tbl = tbl.parentNode;
            }
            // if bottom row exists
            if (tbl.rows[rowIndex + 1]) {
                // define table cell below target cell
                target_cell1 = tbl.rows[rowIndex + 1].cells[cellIndex];
                // if target_cell is empty
                if (target_cell1.childNodes.length === 0) {
                    // clone DIV element
                    obj_new = obj.cloneNode(true);
                    // set id (first two characters are id of original element)
                    id = obj.id.substring(0, 2);
                    // set id for cloned element
                    obj_new.id = id + 'c' + rd.cloned_id[id];
                    // set reference to the DIV container 
                    obj_new.redips_container = obj.redips_container;
                    // increment cloned_id for cloned element
                    rd.cloned_id[id] += 1;
                    // set onmousedown/ondblclick event on cloned object
                    obj_new.onmousedown = rd.handler_onmousedown;
                    obj_new.ondblclick = rd.handler_ondblclick;
                    // append to the table cell if target cell exists
                    if (target_cell1) {
                        target_cell1.appendChild(obj_new);
                    }
                }
            }
        }
    };
    

    Replace original myhandler_dropped function in example03 with this function. In a moment of dropping element from the left table to the timetable, element below dropped element will be automatically cloned. Hope this functionality is what you looking for.
    Cheers!

  7. Hi dbunic

    how can i do the save on drag and drop for more columns on server sides..???

    meaning i need some more data to be saved in the timetable table……

    not able to figure exactly..

    thanx…

  8. @Sayan – I’m not sure if I understand your question but save_content() method scans all content in selected table and prepares query string. This way content from all columns will be saved to the database.

  9. hmmm… I understood that, but what if i just want to save the data which i dragged from the left??

    meaning, what is the need of delete the table everytime the save.php is called?

    Can u help me in that context??

    I dont want that the table be cleared out evertime and the data be freshly inserted..

    I just want to save the data which is dragged.

    Am in big soup right now.

  10. @Sayan – I prepared AJAX variant of School timetable example. Please download latest redips2.tar.gz package and peek to the example03/ajax directory. Hope this improvement will help you to solve your problems.
    Cheers!

  11. Hi,

    I found that when we are dragging the picked item, we can autoscroll the to the limits of whole webpage.

    Can someone please guide me, if I want to implement the same thing in my page (auto-scroll), what I need to do?

    Could you please paste the JS code covering this?

    Regards,
    Saurabh

  12. Hi Darko,

    Please help me with auto-scroll page source code with drag and drop functionality. It’s working perfect in your above application, Could you please suggest me what code do I need to implement to do this?

    Regards,
    Saurabh

  13. Thanx for such a prompt response…Yup it helped a lot.

    Instead of dragging just one cell…. in the right table that is………can i drag a bunch of cells as per my selection……meaning….select a start cell and select an end cell and drag the first cell to an empty place,……….so that every cell from the start cell to the end cell gets dragged and then gets dropped in the adjacent places of the start cells????

    What say?????

  14. @Saurabh Agrawal – Autoscroll is activated in a moment when dragged element crosses page bound defind with REDIPS.drag.bound public property (default value is 25px). When this happen, autoscrollY() private method is called and recursive calls are continued until the end of page. In a moment when dragged element leaves page bound, autoscroll will stop. Pause of recursive calls is function of proximity to the page bounds (if the element is closer to page end then autoscroll will go faster). So, I will suggest you to open REDIPS.drag source (redips-drag.js) and to search for autoscrollY() method. This method will do page autosrcoll as well as DIV container autosrcoll (and that’s why input parameter is needed). It’s about of 70 lines of well comented JavaScript code, so I’m sure it will be easy to understand.

    @Sayan – I’m glad AJAX version gave you some directions of how to make save/delete on element drop event. REDIPS.drag library can drag only one element at a time. After element is dropped, JS code in event handler can move other elements to the any table cell (not only to the dropped cell). If you take a peek to the example12 you will see how to select and move more elements to the target cell. This example can be a good start point to move selected elements to the adjacent table cells. You will need to implement some logic to set more target cells.

  15. Hi Darko,

    Thanks for this information, I’ll give it a try…..

    Regards,
    Saurabh

  16. Hello, How can I realize such an effect:
    After I put the clone object to the right-hand-side table, I want to double click one of them and perform some actions. So how can I perform the double click action, learn which object are clicked and do other action( such as alert(“you click the IT clone object”);)

    Thanks

    beta (a newer in JS)

  17. @beta – Here is example of how to display a message on DIV element dblclick:

    // dblclick event handler
    rd.myhandler_dblclicked = function () {
        // define text of clicked element
        // (rd.obj is reference of clicked DIV element)
        var text = rd.obj.innerText;
        // display a message
        alert('You click the ' + text + ' clone object');
    };
    
  18. Congratulations, great piece of work!

    I ran into a bug because I wanted to clone/move contents that had
    nested DIVs while using the ‘overwrite’ option. There is a loop around
    line 1037 that doesn’t work correctly in handling content with nested DIVs.
    Easy enough to fix one way or another.

    Also, for my purposes I wanted cloned cells that themselves could be recloned.
    Your code allows only for “sterile” offspring so-to-speak, but it would be easy
    enough to allow users to choose whether they want the offspring to be sterile or fertile.

Leave a Comment