olifolkerd / tabulator

Interactive Tables and Data Grids for JavaScript
http://tabulator.info
MIT License
6.71k stars 818 forks source link

external link from HTML table to Tabulator #90

Closed agrazziotin closed 7 years ago

agrazziotin commented 7 years ago

Hello,

I have an html table in which some cells have a link directing the user to an external page. I would like to have an interactive, searchable table using Tabulator.js. I am following the example Filter Data (#example-table-filters). However, when converting my HTML table to javascript, the link is lost. Is this a supported feature in Tabulator? How could I implement that? <td><a href="http://viralzone.expasy.org/" target="_blank">virus</a></td> Thank you very much.

olifolkerd commented 7 years ago

Do you have an exaple of the table structure you are trying to import including the table tags and the header tag structure

agrazziotin commented 7 years ago

Sending you an example. In some columns, an external link is indicated and they are distinct for each cell in a same column.

<table id="table" class="display" cellspacing="0" width="100%"> <thead> <tr><th>Organism Name</th><th>Genome Accession</th><th>Genome Size (bp)</th><th>Proteins</th><th>VOGs</th><th>Host</th><th>Host Domain</th><th>Genetic Material</th><th>Order</th><th>Family</th><th>Genus</th></tr> </thead> <tbody>

<tr><td><a href="http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?id=645116" target="_blank">Acaryochloris phage A-HIS1&#10138</a></td><td><a href="http://www.ncbi.nlm.nih.gov/nuccore/FN436268" target="_blank">FN436268&#10138</a></td><td>55653</td><td>97</td><td><a href="genomes/FN436268.html">See 13&#8635</a></td><td>Acaryochloris marina strain MBIC11017</td><td>Bacteria</td><td>dsDNA viruses, no RNA stage</td><td>Caudovirales</td><td>Siphoviridae</td><td>NA</td></tr>

<tr><td><a href="http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?id=645117" target="_blank">Acaryochloris phage A-HIS2&#10138</a></td><td><a href="http://www.ncbi.nlm.nih.gov/nuccore/FN436269" target="_blank">FN436269&#10138</a></td><td>57391</td><td>106</td><td><a href="genomes/FN436269.html">See 11&#8635</a></td><td>Acaryochloris marina strain MBIC11017</td><td>Bacteria</td><td>dsDNA viruses, no RNA stage</td><td>Caudovirales</td><td>Siphoviridae</td><td>NA</td></tr>

<tr><td><a href="http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?id=46014" target="_blank">Acholeplasma phage L2&#10138</a></td><td><a href="http://www.ncbi.nlm.nih.gov/nuccore/NC_001447" target="_blank">NC_001447&#10138</a></td><td>11965</td><td>18</td><td><a href="genomes/NC_001447.html">See 3&#8635</a></td><td>Acholeplasma laidlawii</td><td>Bacteria</td><td>dsDNA viruses, no RNA stage</td><td>NA</td><td>Plasmaviridae</td><td>Plasmavirus</td></tr> </tbody> </table>

olifolkerd commented 7 years ago

I am putting in some updates this weekend that should make this very simple for you, i will post on here when the never version is released tomorrow afternoon.

olifolkerd commented 7 years ago

I have just released an update to the HTML table parser that should pull in the HTML for you.

There have also been a number of improvements to the HTML parser in this release.

Checkout the documentation for more information

agrazziotin commented 7 years ago

Thank you very much! This parser for cells with an external link is working perfectly with my HTML table (very happy about it).

I've tried to see the conversion using my HTML table with your #example-table-filters code. It has been what I was expecting to, except by the filters.

Filters: Everything is working fine using the filters with your HTML table [http://olifolkerd.github.io/tabulator/examples/#filter] but the exact same script is not working properly with my HTML content. I was wondering if the filters are not correctly identifying the cell value because the content holds a link... I also noted that >, < and != are not displaying the correct result when the column has numerical values (Proteins column in my html table).

I am sending you the code I used in case you would like to check the issue: testfiltertablegenomes.txt

Thank you again!

olifolkerd commented 7 years ago

Thanks for sending over the code, i will have a look at it and get back to you with a solution

agrazziotin commented 7 years ago

Thank you for your time to check this issue for me! I'll be looking forward to hearing back from you.

olifolkerd commented 7 years ago

Sorry for the delay, had a busy few days at work. i have had a look at your code you sent over, thanks for that it was very helpful.

When Tabulator is parsing in the data from the table it is pulling it all in as strings and therefor the filter is not applying properly to the string of the numeric value. The best way round this would be to apply a mutator to the proteins column that forces the value to a number. The mutator you want to use is:

var numericMutator = function(value){
    return parseInt(value);
}

Which should give the adjusted code of:

var numericMutator = function(value){
    return parseInt(value);
}

$("#example-table-filters").tabulator({
    height:"311px",
    fitColumns:true,
    columns:[
    {title:"Organism Name", field:"Organism", width:280},
    {title:"Genome Accession", field:"Accession",sorter:"string", width:180},
    {title:"Genome Size (bp)", field:"Size", sorter:"number", width:170, mutator:numericMutator},
    {title:"Proteins", field:"Proteins", sorter:"number", width:100, mutator:numericMutator},
    {title:"VOGs", field:"VOGs", sorter:"string", width:130},
    {title:"Host", field:"Host", sorter:"string", width:300},
    {title:"Host Domain", field:"Domain", sorter:"string"},
    {title:"Genetic Material", field:"Material", sorter:"string", width:180},
    {title:"Order", field:"Order", sorter:"string"},
    {title:"Family", field:"Family", sorter:"string"},
    {title:"Genus", field:"Genus", sorter:"string"},
    ],
});

Mutators are use to alter data as it is loaded into the Tabulator, they are only called when data is loaded or edited. For more information check out the Mutator Documentation

agrazziotin commented 7 years ago

Thank you again for your help with this. I am not a js programmer, that is why I looked for a module with built-in/easy-to-use features for having fancy tables for my website.

Your solution is working as I was expecting. Yet, one part of my issue was not solved and I think it is because it is a new update to the module related to the external links to the HTML table. I noted that the code for the links are being considered as part of the cell content. This became very clear when I added the tooltips function to see the content (the link code is shown as well, which is weird).

Having the links considered as cell content is impairing the filtering parameters, which I really need working fine as much as I need the links for my public.

If possible, could check this issue for me? testfiltertablegenomes2b.txt

Thank you very much!

olifolkerd commented 7 years ago

Looking at the code, it is because it is parsing the entire link as the value of the cell.

To get around this you want to use a mutator that splits the value in the cell into its link url and its text value and stores them in two different fields. in this case the link text value is stored in the original field and its url is stored in the fieldname_link:

var linkMutator = function(value, type, data, field){
    if(value.indexOf("<a") == 0){
        var a = $(value);
        data[field + "_link"] = a.attr("href");
        return a.text();
    }
    return value;
}

You can then use a formatter on the field to recombine these into a link to be displayed to the user:

var linkFormatter = function(value, data, field){
    if(data[field + "_link"]){
        var a = $("<a target='_blank'></a>");
        a.text(value);
        a.attr("href", data[field + "_link"])
        return a;
    }
    return value;
}

This way only the link text is stored in the original field and so only that is processed by any filters or sorters.

Your finalised code should look something like this:

//Make sure numeric strings are filtered as numbers
var numericMutator = function(value){
    return parseInt(value);
}

//Break links into their text and url components
var linkMutator = function(value, type, data, field){
    if(value.indexOf("<a") == 0){
        var a = $(value);
        data[field + "_link"] = a.attr("href");
        return a.text();
    }
    return value;
}

//Recombine links into their a tags
var linkFormatter = function(value, data, field){
    if(data[field + "_link"]){
        var a = $("<a target='_blank'></a>");
        a.text(value);
        a.attr("href", data[field + "_link"])
        return a;
    }
    return value;
}

//Build Tabulator
$("#example-table-filters").tabulator({
    height:"600px",
    fitColumns:true,
    colResizable:false,
    pagination:true, //option2, enable pagination but removes x and y scroll bars
    tooltips:true, //enable tooltips in every row/column
    tooltipsHeader:true, //enable tooltips in header
    columns:[
        {title:"Organism Name", field:"Organism", width:280, mutator:function(value, type, data){return linkMutator(value, type, data, "Organism")}, formatter: function(value, data){return linkFormatter(value, data, "Organism")}},
        {title:"Genome Accession", field:"Accession",sorter:"string", width:180, mutator:function(value, type, data){return linkMutator(value, type, data, "Accession")}, formatter: function(value, data){return linkFormatter(value, data, "Accession")}},
        {title:"Genome Size (bp)", field:"Size", sorter:"number", width:170, mutator:numericMutator},
        {title:"Proteins", field:"Proteins", sorter:"number", width:100, mutator:numericMutator},
        {title:"VOGs", field:"VOGs", sorter:"string", width:130, mutator:function(value, type, data){return linkMutator(value, type, data, "VOGs")}, formatter: function(value, data){return linkFormatter(value, data, "VOGs")}},
        {title:"Host", field:"Host", sorter:"string", width:300},
        {title:"Host Domain", field:"Domain", sorter:"string"},
        {title:"Genetic Material", field:"Material", sorter:"string", width:180},
        {title:"Order", field:"Order", sorter:"string"},
        {title:"Family", field:"Family", sorter:"string"},
        {title:"Genus", field:"Genus", sorter:"string"},
    ],
});
olifolkerd commented 7 years ago

Has this resolved the issue for you?