Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 3 of 3
  1. #1
    New to the CF scene
    Join Date
    Jun 2006
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Dynamically adding a DIV to document.body

    Hi,

    I am working with a table sorting script which can be found here
    http://www.workingwith.me.uk/article..._table_sorting
    This script works very nicely, but when there is a large amount of data
    to sort e.g > 200 then there is a slight delay in the table sort. To
    cater for this I want to provide some feedback to the user to inform
    them that the sort function is processing. My idea is to add a
    "sorting...." message to the top right of the page, much the same as
    the 'loading' message in gmail.
    To do this I am dynamically creating a div element and adding it to the
    document.body
    I do this as part of the onclick event that triggers the table sort.

    My problem is, eventhough I create and append the 'sorting...' element
    at the start of the onclick event (before the sorting is done), the
    element only gets added after the sorting is complete?

    I cant seem to get the 'sorting..' element to be added to the page
    while the sorting is in progress. Does javascript execute things in a
    sequence that prevents me adding my element to the page?
    Interestingly, I can execute a javascript alert and this gets displayed
    before the sorting begins.....why would
    document.body.appendChild(myDiv) not?

    Hopefully someone has come across this before and can help. I've added
    my HTML and javascript below.

    Thank you,

    Chris

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html>
    <head>
    <title>Table Sorter Proof of Concept</title>

    <link rel="stylesheet" href="style.css" type="text/css" />

    <script type='text/javascript' src='common.js'></script>
    <script type='text/javascript' src='css.js'></script>
    <script type='text/javascript'
    src='standardista-table-sorting.js'></script>
    </head>
    <body>


    <table class='sortable autostripe'>
    <thead>
    <tr>
    <th>Heading</th>
    <th>Heading</th>
    <th>Heading</th>
    <th>Heading</th>
    <th>Heading</th>
    <th>Heading</th>
    <th>Heading</th>
    <th>Heading</th>
    </tr>
    </thead>
    <tbody>
    <script>
    for (var i=0; i < 500; i++) {

    var number = Math.round(Math.random()*1000);

    var day = (1 + Math.round(Math.random()*30));
    if (day < 10) {
    day = '0' + day;
    }
    var month = (1 + Math.round(Math.random()*11));
    if (month < 10) {
    month = '0' + month;
    }
    var year = (1990 + Math.round(Math.random()*16));

    var pennies = (1 + Math.round(Math.random()*99));
    if (pennies < 10) {
    pennies = '0' + pennies;
    }

    var pounds = (1 + Math.round(Math.random()*1500));

    var date = day + '/' + month + '/' + year;

    document.write("<tr>");
    document.write("<td>"+number+"</td>");
    document.write("<td>"+date+"</td>");
    document.write("<td>$"+pounds+'.'+pennies+"</td>");
    document.write("<td>"+number+"</td>");
    document.write("<td>"+date+"</td>");
    document.write("<td>$"+pounds+'.'+pennies+"</td>");
    document.write("<td>"+number+"</td>");
    document.write("<td>"+date+"</td>");
    document.write("</tr>");
    }
    </script>
    </tbody>
    </table>

    </body>
    </html>


    var standardistaTableSorting = {

    that: false,
    isOdd: false,

    sortColumnIndex : -1,
    lastAssignedId : 0,
    newRows: -1,
    lastSortedTable: -1,

    /**
    * Initialises the Standardista Table Sorting module
    **/
    init : function() {
    // first, check whether this web browser is capable of running this
    script
    if (!document.getElementsByTagName) {
    return;
    }

    this.that = this;

    this.run();

    },

    /**
    * Runs over each table in the document, making it sortable if it has
    a class
    * assigned named "sortable" and an id assigned.
    **/
    run : function() {
    var tables = document.getElementsByTagName("table");

    for (var i=0; i < tables.length; i++) {
    var thisTable = tables[i];

    if (css.elementHasClass(thisTable, 'sortable')) {
    this.makeSortable(thisTable);
    }
    }
    },

    /**
    * Makes the given table sortable.
    **/
    makeSortable : function(table) {

    // first, check if the table has an id. if it doesn't, give it one
    if (!table.id) {
    table.id = 'sortableTable'+this.lastAssignedId++;
    }

    // if this table does not have a thead, we don't want to know about
    it
    if (!table.tHead || !table.tHead.rows || 0 ==
    table.tHead.rows.length) {
    return;
    }

    // we'll assume that the last row of headings in the thead is the row
    that
    // wants to become clickable
    var row = table.tHead.rows[table.tHead.rows.length - 1];

    for (var i=0; i < row.cells.length; i++) {

    // create a link with an onClick event which will
    // control the sorting of the table
    var linkEl = createElement('a');
    linkEl.href = '#';
    linkEl.onclick = this.headingClicked;
    linkEl.setAttribute('columnId', i);
    linkEl.title = 'Click to sort';

    // move the current contents of the cell that we're
    // hyperlinking into the hyperlink
    var innerEls = row.cells[i].childNodes;
    for (var j = 0; j < innerEls.length; j++) {
    linkEl.appendChild(innerEls[j]);
    }

    // and finally add the new link back into the cell
    row.cells[i].appendChild(linkEl);

    var spanEl = createElement('span');
    spanEl.className = 'tableSortArrow';
    spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
    row.cells[i].appendChild(spanEl);

    }

    if (css.elementHasClass(table, 'autostripe')) {
    this.isOdd = false;
    var rows = table.tBodies[0].rows;

    // We appendChild rows that already exist to the tbody, so it moves
    them rather than creating new ones
    for (var i=0;i<rows.length;i++) {
    this.doStripe(rows[i]);
    }
    }
    },

    headingClicked: function(e) {
    //This is where I am adding the Div. This is the start of the sort function but it does not get added until the sorting is complete
    showDialog();


    var that = standardistaTableSorting.that;

    // linkEl is the hyperlink that was clicked on which caused
    // this method to be called
    var linkEl = getEventTarget(e);

    // directly outside it is a td, tr, thead and table
    var td = linkEl.parentNode;
    var tr = td.parentNode;
    var thead = tr.parentNode;
    var table = thead.parentNode;

    // if the table we're looking at doesn't have any rows
    // (or only has one) then there's no point trying to sort it
    if (!table.tBodies || table.tBodies[0].rows.length <= 1) {
    return false;
    }

    // the column we want is indicated by td.cellIndex
    var column = linkEl.getAttribute('columnId') || td.cellIndex;
    //var column = td.cellIndex;

    // find out what the current sort order of this column is
    var arrows = css.getElementsByClass(td, 'tableSortArrow', 'span');
    var previousSortOrder = '';
    if (arrows.length > 0) {
    previousSortOrder = arrows[0].getAttribute('sortOrder');
    }

    // work out how we want to sort this column using the data in the
    first cell
    // but just getting the first cell is no good if it contains no data
    // so if the first cell just contains white space then we need to
    track
    // down until we find a cell which does contain some actual data
    var itm = ''
    var rowNum = 0;
    while ('' == itm && rowNum < table.tBodies[0].rows.length) {
    itm =
    that.getInnerText(table.tBodies[0].rows[rowNum].cells[column]);
    rowNum++;
    }
    var sortfn = that.determineSortFunction(itm);

    // if the last column that was sorted was this one, then all we need
    to
    // do is reverse the sorting on this column
    if (table.id == that.lastSortedTable && column ==
    that.sortColumnIndex) {
    newRows = that.newRows;
    newRows.reverse();
    // otherwise, we have to do the full sort
    } else {
    that.sortColumnIndex = column;
    var newRows = new Array();

    for (var j = 0; j < table.tBodies[0].rows.length; j++) {
    newRows[j] = table.tBodies[0].rows[j];
    }

    newRows.sort(sortfn);
    }

    that.moveRows(table, newRows);
    that.newRows = newRows;
    that.lastSortedTable = table.id;

    // now, give the user some feedback about which way the column is
    sorted

    // first, get rid of any arrows in any heading cells
    var arrows = css.getElementsByClass(tr, 'tableSortArrow', 'span');
    for (var j = 0; j < arrows.length; j++) {
    var arrowParent = arrows[j].parentNode;
    arrowParent.removeChild(arrows[j]);

    if (arrowParent != td) {
    spanEl = createElement('span');
    spanEl.className = 'tableSortArrow';
    spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
    arrowParent.appendChild(spanEl);
    }
    }

    // now, add back in some feedback
    var spanEl = createElement('span');
    spanEl.className = 'tableSortArrow';
    if (null == previousSortOrder || '' == previousSortOrder || 'DESC' ==
    previousSortOrder) {
    spanEl.appendChild(document.createTextNode(' \u2191'));
    spanEl.setAttribute('sortOrder', 'ASC');
    } else {
    spanEl.appendChild(document.createTextNode(' \u2193'));
    spanEl.setAttribute('sortOrder', 'DESC');
    }

    td.appendChild(spanEl);

    return false;
    },

    getInnerText : function(el) {

    if ('string' == typeof el || 'undefined' == typeof el) {
    return el;
    }

    if (el.innerText) {
    return el.innerText; // Not needed but it is faster
    }

    var str = el.getAttribute('standardistaTableSortingInnerText');
    if (null != str && '' != str) {
    return str;
    }
    str = '';

    var cs = el.childNodes;
    var l = cs.length;
    for (var i = 0; i < l; i++) {
    // 'if' is considerably quicker than a 'switch' statement,
    // in Internet Explorer which translates up to a good time
    // reduction since this is a very often called recursive function
    if (1 == cs[i].nodeType) { // ELEMENT NODE
    str += this.getInnerText(cs[i]);
    break;
    } else if (3 == cs[i].nodeType) { //TEXT_NODE
    str += cs[i].nodeValue;
    break;
    }
    }

    // set the innertext for this element directly on the element
    // so that it can be retrieved early next time the innertext
    // is requested
    el.setAttribute('standardistaTableSortingInnerText', str);

    return str;
    },
    function showDialog(){

    var shortcutsDiv = document.createElement('DIV');
    shortcutsDiv.id = 'shortcutsDivId';
    //Esc will lose focus and close it. Need an input field to focus on.
    with (shortcutsDiv.style) {
    display = "block";
    position = "fixed";
    visibility = "visible";
    top = "8%";
    left = "41%";
    margin = "0 10% 0 10%";
    width = "30%";
    textAlign = "center";
    MozBorderRadius = "10px";
    padding = "10px";
    color = "#000";
    background = "#EE8800";

    zIndex = 1000;
    }
    shortcutsDiv.innerHTML = 'sorting';
    document.body.appendChild(shortcutsDiv);

    }

  • #2
    Senior Coder
    Join Date
    Mar 2005
    Location
    Portsmouth UK
    Posts
    4,518
    Thanks
    3
    Thanked 506 Times in 493 Posts
    namically creating a div element and adding it to t
    why such a difficult life you make???????


    code the elemnt in the HTML Code and make visible and hidden as required
    Vic

    God Loves You and will never love you less.

    http://www.vicsjavascripts.org/Home.htm

    If my post has been useful please donate to http://www.operationsmile.org.uk/

  • #3
    New to the CF scene
    Join Date
    Jun 2006
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Thanks for the reply. But this does not solve the issue.
    From what I have read around the web, there is a known issue with JS that with intensive calculations the UI doesnt get updated straight away. Apparently, createing a timeout might help solve th issue?
    Any thoughts on this?

    Thanks,

    Chris


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •