Sorting secondary table by values on a column in first table.

Sorting secondary table by values on a column in first table.

rpittrpitt Posts: 2Questions: 0Answers: 0
edited July 2013 in DataTables 1.9
Hey everyone.

I am currently building a system for my company that allows users to see a list of contracts within a table, there is also a secondary table below listing items within the contracts in the first table.

What I am trying to do is:

- Allow the user to search the first table
- With the filtered results collect the values from the "Contract ID" column
- Then with those values filter the second table to only show items related to the filtered contracts in table1.

Here is what I currently have:

[code]
/**
* Performs post initialization for tables processed by the dataTable library
* @param {Object} table
*/
Controller.prototype.onTableInitializeComplete = function(table) {
/**
* Change the placeholder for the filter element
*/
$("#" + table.sTableId+"_filter input").attr("placeholder", "Filter...");

/**
* Get the input for the contracts table
*/
var input = $("#" + table.sTableId+"_filter input");

/**
* Fetch the table id from the data-* api
*/
var id = $(table.nTable).data('tableid');

/**
* Id this table is the contracts table then
*/
if(id == 'contracts')
{
/**
* Listen for the keyup event
*/
input.keyup(function(e){
/**
* We need to collect the contract numbers from the filtered results.
*/
var serials = [];
var rows = $('tbody tr td:nth-child(6)', table.nTable).each(function(pos, context){
serials.push(context.innerText.toString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"));
});

/**
* Fetch the contracts line table.
*/
var lineTable = $('table[data-tableid="contractsline"]').DataTable();

/**
* Update the contracts line with the filter from the contracts table.
*/
lineTable.fnFilter(serials.join("|"), 8, true);
});
}
};
[/code]

It does not work as expected, I know that the [code]serials[/code] array contains a list of serials and the join looks like so:

[code]
856|947|1482/01|1482/02|1482/03|1482/04|1482/05|1482/06|1482/07|1482/09
[/code]

When I start to filter the first table I get the following error within the console

[code]
Uncaught TypeError: Cannot call method 'fnGetData' of undefined datatables.js:28
v datatables.js:28
Ha datatables.js:53
K datatables.js:52
(anonymous function) datatables.js:51
jQuery.event.dispatch jquery.js:3058
elemData.handle.eventHandle
[/code]

Also to note is that when I filter, the second table becomes empty, and as I continue to type into the first tables filter, once the table is empty the second table shows all results.

Something weird is going on here and I need some help trying to figure it out.

P.S, Great plugin.. amazing in fact. good job.

Replies

  • rpittrpitt Posts: 2Questions: 0Answers: 0
    Ok so I think I have solved it, ill explain what I did as this seems to be unexpected.

    From what I could gather about how the UI was reactivating to the events it seemed like the second table was referencing the first table.

    What I was doing originally was the following:

    [code]
    $('table[data-datatable="1"]').DataTable(this.options.dataTable);
    [/code]

    I suspected that this could be an issues so I changed it to:

    [code]
    var opts = this.options.dataTable;
    $('table[data-table="1"]').each(function(idx, table){
    $(this).dataTable(opts);
    });
    [/code]

    This would allow me to create a single instance of DataTable per table. This actually stopped causing a lot of issues and also removed that error above regarding fnGetData.

    I also had to restructure the the handle to pass over a list of serials to the second table is it was always defaulting to the the first pages results and not all pages.

    [code]
    if(id == 'contracts')
    {
    console.log("Setting up table filter for contracts");
    /**
    * Listen for the keyup event
    */
    input.keyup(function(e){
    /**
    * We need to collect the contract numbers from the filtered results.
    */
    var nodes = $('table[data-tableid="contracts"]').dataTable()._('tr', {"filter": "applied"} );

    /**
    * Loop the nodes and retrieve the ID's
    */
    var serials = [];
    for(var i = 0; i < nodes.length; i++)
    {
    /**
    * Requires testing on smaller devices as columns may change with responsive design.
    */
    serials.push(nodes[i][5]);
    }

    /**
    * Fetch the contracts line table.
    */
    var lineTable = $('table[data-tableid="contractsline"]').dataTable();

    /**
    * Update the contracts line with the filter from the contracts table.
    */
    lineTable.fnFilter(serials.join("|"), 7, true, false);
    });
    }
    [/code]

    If any developers or admins require further information feel free to ping me on my email address I registered with.

    Thanks.
This discussion has been closed.