Shift table content

This post shows how to shift table content using JavaScript. REDIPS.shift library has four methods to shift table content in any direction (up, right, down and left). By default, content bunching is disabled. Please try to click on links and move content around table.

up up up up
left right
left
A
right
left right
left
B
right
left
C
right
down down down down

redips5.tar.gz package contains this demo (it’s free to download). Source code is written in script.js file (about 150 lines – well commented) and is verified with jslint. Table cells marked with class name “mark” are considered as boundary. Here is JS code snippet (shift content to the left):

// shift row content left
left = function (element) {
    var tr,          // current table row
        cellSource,  // source cell
        cellTarget,  // target cell
        i;           // local variables
    // find row where cell belongs
    tr = findParent('TR', element);
    // loop through cells
    for (i = 1; i < tr.cells.length; i++) {
        // define source and target cell
        cellSource = tr.cells[i];
        cellTarget = tr.cells[i - 1];
        // move cells
        relocate(cellSource, cellTarget);
    }
};

Hope this small JavaScript library will be useful for table content shifting.

8 thoughts on “Shift table content

  1. Source code is prepared in redips5.tar.gz package and can be downloaded from this page. Just click on the download link below post title.
    Cheers!

  2. if (window.XMLHttpRequest) {
      // code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp = new XMLHttpRequest();
    }
    else {
      // code for IE6, IE5
      xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
    }
    xmlhttp.open('GET', 'cd_catalog.xml', false);
    xmlhttp.send();
    xmlDoc = xmlhttp.responseXML; 
    
    document.write('');
    var x = xmlDoc.getElementsByTagName('CD');
    for (i=0; i < x.length; i++) { 
      document.write('');
      document.write(x[i].getElementsByTagName('ARTIST')[0].childNodes[0].nodeValue);
      document.write('');
      document.write(x[i].getElementsByTagName('TITLE')[0].childNodes[0].nodeValue);
      document.write('');
    }
    document.write('');
    

    This JavaScript code displays the data in a table with reference to an XML file below. My requirement s i have to show the data in 2pages with next and previous button, please help with this.

    XML File

    <DOCUMENT>
        <CD>
            <TITLE>Empire Burlesque</TITLE>
            <ARTIST>Bob Dylan</ARTIST>
            <COUNTRY>USA</COUNTRY>
            <PUBLISHER>Columbia</PUBLISHER>
            <PRICE>10.90</PRICE>
            <YEAR>1985</YEAR>
        </CD> 
        <CD>
            <TITLE>Hide your heart</TITLE>
            <ARTIST>Bonnie Tyler</ARTIST>
            <COUNTRY>UK</COUNTRY>
            <PUBLISHER>CBS Records</PUBLISHER>
            <PRICE>9.90</PRICE>
            <YEAR>1988</YEAR>
        </CD> 
        <CD>
            <TITLE>Greatest Hits</TITLE>
            <ARTIST>Dolly Parton</ARTIST>
            <COUNTRY>USA</COUNTRY>
            <PUBLISHER>RCA</PUBLISHER>
            <PRICE>9.90</PRICE>
            <YEAR>1982</YEAR>
        </CD>
    </DOCUMENT>
    
  3. @Gayathri – If you have static XML file then you can split XML to cd_catalog1.xml and cd_catalog2.xml – with this scenario, load first or second file to display on first or second page. On the other hand, if XML file is created dynamically then you will have to send pageno parameter as well. In MySQL is very easy to paginate record set using LIMIT clause. Here is simple SQL example:

    SELECT fields ... 
    FROM table 
    LIMIT $offset, $rows_per_page
    

    Database will return records for requested page. Offset parameter can be calculated on the following way:

    $offset = ($pageno - 1) * $rows_per_page;
    

    As you can see, pagination is mostly handled on server side. It wouldn’t be so efficient to load whole XML file and in “for loop” (on client side) display active page and discard unused rows. Anyway, I hope this few tips will give you some hints of how to approach and solve pagination problem.

  4. Hi
    is there a way of stopping it bunching up in 1 cell, so each element stays in a row.

    I have got a row of elements that I drag on to a seperate table underneath.
    I want the row to bunch up automatically filling the empty spaces and leaving all the spaces at the end.
    I was thinking of running this script when the element is dropped.

    Cheers
    Andrew

  5. @andy – REDIPS.shift (as well this post) is upgraded. Content bunching is now optional and is disabled by default. Please try this demo now. Cheers!

  6. Thanks for that, could you give me any pointers how to impliment this:-

    I currently use the drag and drop from 1 table to another,
    Table A’ has 1 row Table B is a 10 x 10

    I would like it so when I drag an element from ‘A’ and drop it in ‘B’, all the elements in ‘A’ shuffle up filling the empty space leaving the empty cell at the end.

    Cheers
    Andrew

  7. @andy – I have prepared new example in redips2.tar.gz package. Please see Example 21: Simple shift. Here is event.dropped() JS code:

    rd.event.dropped = function () {
        // get target and source position of dropped DIV element
        // pos[0] - target table index
        // pos[3] - source table index
        var pos = rd.getPosition(),
            td1, td2, // source and target cell
            ec,       // empty cell
            i;        // local variables
        // if DIV element is dropped from table 0 to table 1
        if (pos[3] === 0 && pos[0] === 1) {
            // loop through cells in myRow
            for (i = 0, ec = 0; i < tr.cells.length; i++) {
                // define source and target cells
                td1 = tr.cells[i];
                // if cell contains DIV element then shift DIV to the left
                if (td1.childNodes.length > 0) {
                    // define target cell and move DIV element 
                    td2 = tr.cells[i - ec];
                    rd.relocate(td1, td2, 'animation');
                }
                // increase number of current empty cells
                else {
                    ec++;
                }
            }
        }
    };
    

    Source code is located in example21/simple folder of redips2 package.

Leave a Comment