Dynamic creation

Dynamic creation

SellesSelles Posts: 32Questions: 0Answers: 0
edited May 2009 in General
Hi Allan,

I have a question about dataTables and especially the dynamic creation part. You say that i can improve the loadtime, so I think I need to rewrite my code for my on-line explorer to handle with dynamic creation.

On this site:

http://datatables.net/examples/example_dynamic_creation.html

you use an array, but how can I use that, can you give me an example to get the data and put it in the table.

The way I do it know is like this (please keep in mind that I'm a newbie to JQUERY and PHP ;-)):

When a user clicks on a folder the following is done:
[code]
$.post('include/files.php',{folder: folder}, function onSelect(data){
// Reload data on page without pagerefresh
$("#files").html(data);
});
[/code]

Then the var folder is posted to the file "files.php"

[code]
<?php
$dir = $_POST['folder'];

// Define dir that is used in the A HREF
$dir_href = str_replace("../","",$dir);

// Define path for the input bar in the top
$path = substr($dir, 0, -1);
$str = str_replace("/", "", $path, $count);
$path = explode('/', $path, $count+1);
$sizep = count($path);
?>





Filename :
Type :
Size :
Altered on :



<?php
$allow_ext = array("gif", "GIF",
"jpg", "JPG",
"jpeg", "JPEG",
"png", "PNG",
"bmp", "BMP",
"tif", "TIF",
"doc", "DOC",
"docx", "DOCX",
"xls", "XLS",
"xlsx", "XLSX",
"ppt", "PPT",
"pptx", "PPTX",
"txt", "TXT",
"rtf", "RTF",
"pdf", "PDF"
);
$ext_image = array("gif", "GIF", "jpg", "JPG","jpeg", "JPEG","png", "PNG","bmp", "BMP","tif", "TIF");
$ext_doc = array("doc", "DOC","docx", "DOCX","txt", "TXT","rtf", "RTF");
$ext_xls = array("xls", "XLS","xlsx", "XLSX");
$ext_ppt = array("ppt", "PPT","pptx", "pptx");
$ext_pdf = array("pdf", "PDF");
// end of part 1, see next comment
[/code]

Replies

  • SellesSelles Posts: 32Questions: 0Answers: 0
    [code]
    // part 2
    if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
    //while (($file = readdir($dh)) !== false) {
    //sort($file);
    while (($file = readdir($dh)) !== false) {
    $files[] = trim($file);
    }
    sort($files);
    foreach($files as $file){
    if ($file != "." && $file != ".."){
    $ext = substr(strrchr($file, '.'), 1);
    //echo ="ext = ".$ext."\n";
    ?>

    <?php
    if(strlen($ext) == 0){
    echo " ";
    }elseif (strlen($ext)>3 || !in_array($ext, $allow_ext)){
    echo " ";
    }
    elseif (in_array($ext, $allow_ext)){
    echo " ";
    }
    elseif (in_array($ext, $ext_doc)){
    echo"doc.png\" rel=\"".$dir.$file."\"> ";
    }
    elseif (in_array($ext, $ext_xls)){
    echo"xls.png\" rel=\"".$dir.$file."\"> ";
    }
    elseif (in_array($ext, $ext_ppt)){
    echo"ppt.png\" rel=\"".$dir.$file."\"> ";
    }
    elseif (in_array($ext, $ext_pdf)){
    echo"pdf.png\" rel=\"".$dir.$file."\"> ";
    }
    }
    echo "".$file."\n";
    //echo $ext; // to check what extension is
    ?>


    <?php
    if (strlen($ext)>0){
    if (in_array($ext, $allow_ext) || !in_array($ext, $allow_ext)){
    echo "File";
    }else {
    echo "Folder";
    }
    }
    else {
    echo "Folder";
    }
    ?>


    <?php
    if (strlen($ext)>0){
    if (in_array($ext, $allow_ext) || !in_array($ext, $allow_ext)){
    $filesize=round(filesize($dir.$file)/1024,1);
    echo $filesize."kB\n";
    }
    }
    ?>


    <?php
    if (strlen($ext)>0){
    if (in_array($ext, $allow_ext)|| !in_array($ext, $allow_ext)){
    $filetime=date("d-m-Y H:i", filemtime($dir.$file));
    echo $filetime."\n";
    }
    }
    ?>


    <?php
    }
    }
    closedir($dh);
    }
    }
    ?>




    [/code]

    Then the "data" is put on the HTML page:

    [code]

    <!-- Here the sortable table will be put -->

    [/code]

    and with this in my HEAD, I create the sortable table:

    [code]
    $(document).ready( function() {
    // Making sortable table in right div
    $("#folder_file").livequery(function(){
    $("#folder_file").dataTable({
    "iDefaultSortIndex": 0,
    "fnInitComplete": function() { $('#processing_right').hide();},
    "sDefaultSortDirection": "asc",
    "aoData": [
    /* Filename */ null,
    /* Extension */ null,
    /* Type */ null,
    /* Date */ null
    ]});
    });
    });
    [/code]

    I know I ask a lot of you with all this code above, but I hope you have time for it.

    Greetings,

    Wim
  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    Phew - loads of code :-)

    Am I correct in saying that the only thing that is happening here is that the table's data is being refreshed? At the moment that is done by replacing the old table completely and then initialising a new one right?

    Perhaps a better way of doing this is using DataTables' sAjaxSource option to load data from a Javascript array produced by the server ( http://datatables.net/examples/example_ajax_source.html ). Then whenever you need to reload the data for the table you can refresh the table by using the fnReloadAjax() ( http://datatables.net/plug-ins#fnReloadAjax ) plug-in. Using a GET variable on the sAjaxSource (which you can change by passing in the new address to the plug-in) you can tell the server what it is you are looking for.

    In this way you don't need to re-initialise a different table on each change.

    How does that sound?

    Allan
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    I told you that I'm a newbie ;-), and yes you are right. I complete load a new table each time.

    I'm going to try to use your solution, may take me a while, but I hope I succeed. tnx

    Greetings


    Wim
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    It's such a beautiful weather that I took the day of and sat in the garden with my laptop.
    I got my php file working so that it produces an export like this:

    [code]
    { "aaData": [
    [ "Trident", "Internet Explorer 4.0", "Win 95+", 4, "X" ],
    [ "Trident", "Internet Explorer 5.0", "Win 95+", 5, "C" ],
    [ "Trident", "Internet Explorer 5.5", "Win 95+", 5.5, "A" ],
    [ "Trident", "Internet Explorer 6.0", "Win 98+", 6, "A" ],
    [ "Trident", "Internet Explorer 7.0", "Win XP SP2+", 7, "A" ],
    [ "Gecko", "Firefox 1.5", "Win 98+ / OSX.2+", 1.8, "A" ],
    [ "Gecko", "Firefox 2", "Win 98+ / OSX.2+", 1.8, "A" ],
    [ "Gecko", "Firefox 3", "Win 2k+ / OSX.3+", 1.9, "A" ],
    [ "Webkit", "Safari 1.2", "OSX.3", 125.5, "A" ],
    [ "Webkit", "Safari 1.3", "OSX.3", 312.8, "A" ],
    [ "Webkit", "Safari 2.0", "OSX.4+", 419.3, "A" ],
    [ "Webkit", "Safari 3.0", "OSX.4+", 522.1, "A" ]
    ] }
    [/code]

    On http://wwmci.familieselles.nl/v1.11/ you can see the latest version. Here the right part is made through the DataTables' sAjaxSource option.

    Normally when a user clicked on the image in the left part or the folder in the right part the "rel" value was passed to this function (located in jqueryFileTree.js):
    [code]
    var folder = $(this).attr('rel');
    clickOnFolder(folder);

    // this is the old function to completle refresh my right part
    function clickOnFolder(folder){
    $.post('include/files.php',{folder: folder}, function onSelect(data){
    // Reload data on page without pagerefresh
    $("#files").html(data);
    })
    });
    [/code]

    So that's the first part =).

    Now for the second part, passing the data. I checked the link you gave me, but I can't figure out how to implement that in my code (see above).
    Clicking on for example a folder in the right part needs to pass a value to the dataTable sAjaxSource option, but also to the jqueryFileTree.js file to update the left part (expand of collaps the tree).

    Got an idea, because I don't (burned my face in the sun from thinking ;-))

    Greetings

    Wim
  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    Okay, in this case, it's probably best to take some hints from the fnReloadAjax() function, but not use it directly (since you already have an Ajax call being done!). What you could do is to delete all the data currently in the table ( fnClearTable() ) and then add your new data ( fnAddData() ). With fnAddData you can pass it data.aaData (i.e. your array of array of strings :-) ) and that will then be drawn on the page.

    Nearly there? :-)
    Allan
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    Tnx for the answer. I'll try to do that, but I don't know when, I first have a holiday for a few days. When I succeed I'll let you know.
    Have a nice day an till soon.

    Greetings,

    Wim
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    I'm back in town after a few days of vacation.
    I tried your suggestion and it works, but now I want to add the new data when a user clicks on a folder.
    I got this:

    [code]
    /*////////////////////////////////////////////////////
    * function for taking action after clicking on folder
    */
    function clickOnFolder(folder){
    // Clear excisting data from the table
    oTable.fnClearTable( 0 );
    // Post data to the table
    $.post('include/files_ajax.php',{folder: folder}, function addRows(rows){
    oTable.fnAddData(rows);
    });
    }
    [/code]

    The problem is that when I use Firebug I can see that the data is retrieved through the POST method, but it isn't shown on my page

    When I do this, not dynamically, the data is shown on the page.

    [code]
    /*////////////////////////////////////////////////////
    * function for taking action after clicking on folder
    */
    function clickOnFolder(folder){
    // Clear excisting data from the table
    oTable.fnClearTable( 0 );
    oTable.fnAddData([[ " 1Demo2.jpg", "File", "26.7 kB", "26-04-2009 10:56" ],
    [ " 2006", "Folder", " ", " " ],
    [ " 2007", "Folder", " ", " " ],
    [ " 2008", "Folder", " ", " " ]
    ]);
    }
    [/code]

    Is my POST-method wrong? You can see a working version on http://wwmci.familieselles.nl and select version 1.11

    Tnx in advance

    Greetings Wim
  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    Odd one - the return you are getting from the server certainly looks correct. What is the return value from the oTable.fnAddData call? That should return the indexes of the rows that have been added to aoData. If it returns nothing (or an array of -1s) then something has gone wrong - most like an incorrect number of data columns compared to the number of columns DataTables is using.

    It's looking good though!

    Allan
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    First of all I didn't receive a mail that you replied, strange....

    But tnx for your reply. What do you mean with this:

    [quote]
    What is the return value from the oTable.fnAddData call?
    [/quote]

    Is there an other way do solve this with a workaround?

    Tnx

    Greetings,

    Wim
  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    What I mean is if you do:

    var tmp = oTable.fnAddData( [ whatever ] );

    what is the value of tmp? I would expect it to be an array of integers. If you are using Firefox with Firebug or Safari/Chrome you can do "console.dir(tmp)" just after that line to find out what it's value is.

    Did you get an e-mail this time? I don't think I've changed anything that would effect that...

    Allan
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Alan,

    I think I see the problem. When I do this:

    [code]
    $.post('include/files_ajax.php',{folder: folder}, function addRows(rows){
    var tmp = oTable.fnAddData(rows);
    alert(tmp);
    });
    [/code]

    Nothing is in the alert box, it's empty. But the post gives back data, I've updated the site for you to see it.

    I think it is strange. Can it be that the function won't work?

    By the way, I still didn't got and email, but that's not such a problem. I try to look every day on you forum to see if something is new, how people use Datatables and look if I can help ;-)
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    Here I'm again. I tried the following without the postfunction:

    [code]
    tmp = '[[ "1","2","3","4" ]]';
    oTable.fnAddData(tmp);
    [/code]
    Resulted in showing nothing
    [code]
    oTable.fnAddData([[ "1","2","3","4" ]]);
    [/code]
    resulted in showing 1 2 3 4 in the dataTable. May I then conclude that the function can't handle a variable so that can be called a bug? (By the way, I use jquery-1.3.2.min.js)

    Greetings Wim
  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    Hi Wim,

    That's very odd - every code path in fnAddData() returns the array aiReturn, so your alert(tmp) should have given you "object [Object]" or something like that. The only thing I can think of would be that the internal add row function is returning -1 and therefore the return array is length 0. What you could do is:

    alert( tmp.length +" "+ rows[0].length +" "+ oTable.fnSettings().aoColumns.length );

    The first part is the number of rows which have benn added, and then the second two should be equal - the number of columns in each row.

    Allan
  • SellesSelles Posts: 32Questions: 0Answers: 0
    edited May 2009
    Hi Allan,

    tnx for your quick reaction. Do you have a day of or so?

    The alert returned 0 1 4

    I've updated the server, do you have skype? Then maybe we can chat through skype?

    Wim

    ps: I got a mail now :D
  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    If the alert return 0 1 4 then the problem is that no rows were added, and the reason for that is that that you are giving it an array of only 1 item (1 column) but it is expecting four. Remember that is is expecting an array of rows, and each row is an array of four elements. Looking at your Ajax return, you do indeed only have one element for each inner row.

    re day off: Nope - just answering questions over breakfast (and now lunch)
    re mail: Good stuff - glad to hear that is working again.
    re skype: I tend only to use that for work related issues and contract work

    Regards,
    Allan
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    Again tnx for your quick reaction, but why does this doesn't work (see few comments before this one)

    [code]
    tmp = '[[ "1","2","3","4" ]]';
    oTable.fnAddData(tmp);
    [/code]

    and this does work:

    [code]
    oTable.fnAddData([[ "1","2","3","4" ]]);
    [/code]
  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    Hi Wim,

    Try running the following an perhaps it will help your understanding of why it doesn't work:

    [code]
    tmp = '[[ "1","2","3","4" ]]';
    alert( typeof tmp )
    oTable.fnAddData(tmp);
    [/code]

    and

    [code]
    tmp = [[ "1","2","3","4" ]];
    alert( typeof tmp )
    oTable.fnAddData(tmp);
    [/code]

    Allan
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    Ok, I think the problem is that the post that is returned is a string. When I do this:

    [code]
    /*////////////////////////////////////////////////////
    * function for taking action after clicking on folder
    */
    function clickOnFolder(folder){
    // Clear excisting data from the table
    oTable.fnClearTable( 0 );
    // Post data to the table
    $.post('include/files_ajax.php',{folder: folder}, function addRows(rows){
    alert(typeof rows);
    oTable.fnAddData(rows);
    });
    }
    [/code]

    I get the alert => "String".

    But now comes the newbie question, ;-), how can I transform my post to an object? Have you got an idea?

    Greetings

    Wim
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    Don't laugh about the solution, but I think I found a solution to turn the post into a object. I found this plugin http://code.google.com/p/jquery-json/

    I changed my function to this:
    [code]
    /*////////////////////////////////////////////////////
    * function for taking action after clicking on folder
    */
    function clickOnFolder(folder){
    // Clear excisting data from the table
    oTable.fnClearTable( 0 );
    // Post data to the table
    $.post('include/files_ajax.php',{folder: folder}, function addRows(rows){
    // Change rows into JSON object
    var rows = $.evalJSON(rows);
    oTable.fnAddData(rows);
    });
    }
    [/code]

    And this works, see my site http://wwmci.familieselles.nl Version 1.11

    But now constantly, when updating the right part, the "sZeroRecords" is shown because the table is first being emptied. Can I make this better by not first showing the deleted table, or isn't there a solution for?

    Greetings Wim
  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    Hi Wim,

    Yup - eval() is the way to convert a text string into a javascript object. It is perhaps worth noting that eval() is evil ( http://blogs.msdn.com/ericlippert/archive/2003/11/01/53329.aspx and others ) so it's generally best to use JSON2.js ( http://www.JSON.org/js.html ) or something like that. A further note is that jQuery uses eval() itself, so you certainly can do it - I'm just noting it here to promote best practice :-)

    As with the sZeroRecords issue, I see two options:

    1. Change the text of sZeroRecords to "Loading..." or something like that

    2. Move the fnClearTable() call inside your $.post() callback function, so the old table remains until the new one is created - the user will never see sZeroRecords (it will render too fast).

    Hope this helps,
    Allan
  • SellesSelles Posts: 32Questions: 0Answers: 0
    Hi Allan,

    Tnx for your replies. I got it working now as it should be. It's faster and better to maintain. tnx

    To see a working version please visit http://wwmci.familieselles.nl

    version 1.12 is the last release and it pretty stable.

    Again, tnx for all your help and good luck with your project, and you know, if I can help then let me know

    Grtz

    Wim
This discussion has been closed.