JavaScript Drag and Drop example 3

More...

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 the timetable, button in the same color will be displayed next to the subject (clone object).

Arts
Biology
Chemistry
English
Ethics
History
IT
Mathematics
Physics
Trash
Drag school subjects to the timetable (clone subjects with SHIFT key)

Please note two checkboxes in the upper left corner of timetable. First checkbox is turned on by default to enable cloning subjects across a week. You can turn it off for placing single subject to the 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 myhandler_dropped() event handler (with logic for cloning DIV elements across a week).

rd.myhandler_dropped = function () {
    var obj_old = rd.obj_old,                   // original object
        target_cell = rd.target_cell,           // Target cell
        target_row = rd.target_cell.parentNode, // Target row
        marked_cell = rd.marked_cell,           // marked cells
        mark_cname = rd.mark_cname,             // name of marked cells
        i, obj_new, mark_found;                 // local variables
    // 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 through table cells
        for (i = 0; i < target_row.cells.length; i++) {
            // skip if table cell is not empty (true for cell where
            // element is currently dropped)
            if (target_row.cells[i].childNodes.length > 0) {
                continue;
            }
            // search for "mark" class name
            mark_found = target_row.cells[i].className.indexOf(mark_cname) > -1 ? true : false;
            // if current cell is marked and access type is 'deny' or current cell
            // is not marked and access type is "allow" then skip this table cell
            if ((mark_found === true && marked_cell === 'deny') ||
                (mark_found === false && marked_cell === 'allow')) {
                continue;
            }
            // clone DIV element
            obj_new = rd.clone_div(obj_old);
            // append to the table cell
            target_row.cells[i].appendChild(obj_new);
        }
    }
    // print message only if target and source table cell differ
    if (rd.target_cell !== rd.source_cell) {
        print_message('Content has been changed!');
    }
    // show / hide report buttons
    report_button();
};

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.

This entry was posted on February 22, 2010 and is filed under Drag and Drop, JavaScript

Related posts

94 Responses to JavaScript Drag and Drop example 3

  1. Prabu says:

    Hi dbunic,

    I need one more thing..

    When i picking the left table subject , that can be drop only to the particular period. It must satisfied some constrains like below:

    For example " Art " subject can only place in Friday not to other days .. also the mathematics period cannot be placed at the last period of a day (it must place any period expect the last period).. like that..

    Can it possible ?

    Pls help me

  2. dbunic says:

    @Prabu - Table can be dynamically added to the "drag" container. After table is added, just call REDIPS.drag.init() method. Example 0: AJAX / jQuery modification shows scenario where table is loaded on button click using jQuery.

    REDIPS.drag has options to define dropping rules. Please see:
    Example 7: A B C D
    Example 7: E F
    I also wrote REDIPS.drag documentation - Appendix A where you can find explanation with examples for mark and only class name keywords.
    Cheers!

  3. Prabu says:

    dbunic,

    None of them work in the example 03.

    http://www.redips.net/javascript/drag-and-drop-example-3/

    In example three ajax load not work
    and constrains not checking..

    I dont know why because its working in the link you have mentioned in the last message but not in drag-and-drop-example-3.

  4. David Roa says:

    Thank you very much dbunic!! You´re rock!!!

  5. rosie says:

    Hi Dbunic! You've been really helpful but I still got one problem: I add some information along with the subjects like name of the professor and room number, but I don't know how to pass this additional information to db_save and store it to timetable table. How can I do that? Thanks.

  6. dbunic says:

    @Prabu - If you can prepare standalone example or send me URL of your online example I will gladly help you. In case of standalone example, prepare your code so I can unzip it and test with local Apache/PHP.

    I suppose that problems are related to REDIPS.drag initialization but can't be sure without peek to the code.

    @David Roa - You're welcome and thanks! ;)

    @rosie - One way can be to append professor id and room number to the DIV id. In this case, DIV id can look (please note it's used dash, not underscore):

    <div id="1234-2-22">Mr. Brown, room 22<div>
    

    On the server side, DIV id should be decomposed:

    foreach ($arr as $p) {
        // detach values from combined parameters
        // $tbl parameter is ignored because saving goes only from table 1
        list($sub_id, $row, $col) = explode('_', $p);
        // $sub_id contains professor id and room number
        list($sub_id, $prof_id, $room) = explode('-', $sub_id);
        // discard clone id part from the sub_id
        $sub_id = substr($sub_id, 0, 2);
        // insert to the database
        ...
        ...
    }
    

    This is only an idea, but it should be feasible ... If you will have further questions, don't hesitate to ask. Cheers!

  7. rosie says:

    dbunic it's not working. I tried to echo it, it always says undefined offset. I did it like this:

    config.php

    <div id="$id-$prof-$room">
    

    db_save.php

    list($sub_id, $prof, $room) = explode('-', $sub_id);
    echo $prof;
    

    Where am I doing it wrong?

  8. dbunic says:

    @rosie - My guess is that you have somewhere glitch in code and it's not easy to fix it without having access to all parts. Anyway, I have prepared example with $prof and $room so you can try to use this modification.

  9. rosie says:

    Hi dbunic!
    I was able to save into timetable (database table) the additional information I wanted to add, so that when printing the subjects to timetable (grid) I don't have to refer to other table but the timetable alone and also so I could delete the list of subjects in the left. (I hope you understand what I mean). But when I clone the elements the information is deleted leaving it (DIV) blank. What I'm just trying to achieve here is to be able to delete the subjects in the left side without the subjects in the timetable being affected.

    Thanks.

  10. dbunic says:

    @rosie - I'm glad you succeeded to save additional data to the database. Maybe the problem is related to the SQL select. If subject is deleted from database, then SQL to retrieve grid table could not join redips_timetable with redips_subject data. Here is original SQL from example03:

    select
    concat(t.tbl_row,'_',t.tbl_col) as pos,
    t.tbl_id,
    t.sub_id,
    s.sub_name
    
    from
    redips_timetable t,
    redips_subject s
    
    where
    t.sub_id = s.sub_id
    

    Instead of inner join, you can try with left join:

    select
    concat(t.tbl_row,'_',t.tbl_col) as pos,
    t.tbl_id,
    t.sub_id,
    ifnull(s.sub_name, t.sub_id)
    
    from
    redips_timetable t left join redips_subject s on (t.sub_id = s.sub_id)
    

    This should retrieve data from redips_timetable regardless of state in redips_subject db table.

    Hope this was your question.
    Cheers!

  11. rosie says:

    Hi dbunic. It's still not working.

    subjects:

    $subjects = sqlQuery("select SubjectID, Subject, Instructor, CollegeID, Course, Year, Section
    from subjects
    where CollegeID='$_SESSION[college]'
    order by SubjectID");
    

    timetable:

    $rs = sqlQuery("select concat(t.tbl_row,'_',t.tbl_col) as pos, t.tbl_id, t.sub_id, t.subject, t.instructor, t.college, t.course, t.year, t.section
    from timetable t left join subjects s on (t.sub_id = s.SubjectID)
    where t.room='$idid'");
    

    I can drag the subjects just fine but when I clone it using shift key the data saved in timetable columns are deleted except the data in sub_id, tbl_id and pos columns. Is there another way to delete the subjects without affecting the timetable?

    I'm sorry to bother you this much. Thanks.

  12. dbunic says:

    @rosie - It will be much easier if you can send/show me the live example. Please try to make database dump with mysqldump utility and zip it together with Web scripts (PHP and JS files). I will prepare your example locally on my LAMP computer and try to fix the problem. Hope this will not be a problem for you. Here is how you can save database content on Linux host:

    # subject table
    mysqldump -p -u<username> <database> subjects > /tmp/subjects.sql
    
    # subject table
    mysqldump -p -u<username> <database> timetable > /tmp/timetable.sql
    
  13. rosie says:

    It's very kind of you but I don't think it's a good idea. My codes are messy plus I already altered a lot. I just want to have an option to delete the list of subjects on the left but I think that's impossible right now. I'll just stick to your old code. Thank you so much. :)

  14. dbunic says:

    @rosie - OK, but I have one more idea that may help you. Instead of deletion subject from the left table, you can hide them. Here is how:

    1) Expand db table subjects with column display char(1):

    ALTER TABLE subjects ADD COLUMN display char(1) NOT NULL DEFAULT 'Y' AFTER sub_name
    

    All existing subject should have Y value in display column.

    2) Modify subjects() function in config.php to retrieve only visible subjects:

    // returned array is compound of nested arrays
    $subjects = sqlQuery("select sub_id, sub_name from subjects where display = 'Y' order by sub_name");
    

    3) Try to update subjects as hidden:

    update subjects set display = 'N' where sub_id = 'hi'
    

    Timetable (on the right) should stay intact while subject from the left table is not shown.

    Hope this will do the trick ;)
    Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

In case of posting HTML tags or JavaScript code please convert special characters to HTML entities.
Especially pay attention to convert "<" to "&lt;" character!