Help with filter an inner table

Help with filter an inner table

eddie909eddie909 Posts: 31Questions: 6Answers: 0
edited February 2011 in General
Here are the columns: (The Meeting day, time and room is coming from the inner table).
Index Meeting Day Meeting Time Room #
1 Mon 12:45pm - 03:00pm 1
Wed 01:00pm - 02:30pm 4
------------------------------------------------------------------------------------------
2 Tues 08:00am - 10:00am 123
Thur 09:00am - 11:30am 111
-----------------------------------------------------------------------------------------
I am trying to check the inner table for a certain condition, if that condition is met then do not display the outer row.If you unselect Mon Afternoon from the checkbox that do not display:
1 Mon 12:45pm - 03:00pm 1
Wed 01:00pm - 02:30pm 4
Here is my code:
[code]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">




DataTables example

@import "demo_page.css";
@import "demo_table.css";




$(document).ready(function() {
$('input[name="classTime"]', this).click( function () {
var checkboxs = document.getElementsByName('classTime');
var reg_exp = '';
for (var i = 0, inp; inp = checkboxs[i]; i++) {
if (inp.type.toLowerCase() == 'checkbox' && inp.checked) {
reg_exp = reg_exp + inp.value + '|';
}
}
var oTable = $('#example').dataTable();
$("tfoot th").each( function ( i ) {
if (reg_exp == '') {
reg_exp = 'X|'
} else {
oTable.fnFilter( reg_exp.slice(0, -1), 1, true, false, false );
}
} ); //tfoot th
} ); // classTime click
} ); // ready function




Live example




Index
Meeting Day
Meeting Times
Location




111




Mon


12:45pm - 2:30pm
4


Wed


12:45pm - 2:30pm
4






222




Tue


09:00am - 10:30am
3


Thur


10:00am - 11:30am
3





















Mon Morning

Thur Morning

Mon Afternoon

Wed Afternoon




[/code]
Thanks,
Ed

Replies

  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Hi Ed,

    The way regular filtering works in DataTables is by simple string matching - which might not be what you want here (it might be good enough in fairness, if you have a regex which specifically can pull out the information you need - and that is certainly possible however, it might be a little more difficult). There is also another type of filtering which works on the live DOM:

    Documentation: http://datatables.net/development/filtering#row_filters
    Example: http://datatables.net/examples/plug-ins/range_filtering.html

    So what I think you need to do here is have a custom live DOM filter which will pull out the date / time in inner table and perform some logic matching on that. For example you might have something along these lines:

    [code]
    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {
    var innerDates = $('input', oSettings.aoData[iDataIndex].nTr);
    var monday_afternoon = $('input[name=monday_afternoon]').attr('checked');

    for ( var i=0, iLen=innerDates.length ; i
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Allan,

    Thank you so much for getting back to me, I added the code as you suggested and also changed my checkbox but what table id (the outer table id or the inner table id's) do I use for the following:

    When I use the outer table id - i get sData is undefined - if I use inner table id I get oColumn is undefined.
    [code]
    $(document).ready(function() {
    /* Initialise datatables */
    var oTable = $('#data1').dataTable();
    $('#monday_afternoon').click( function() { oTable.fnDraw(); } );

    } );
    [/code]

    Thanks,

    - Ed
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Allan,

    I got the sData undefined resolved (I add two more columns to the outer table after the inner table) but having problem extracting the data from the inner table. When I display column 2 i get the following:
    plus my innerDates.length is 0

    meetingData ===


    MON_AFTERNOON
    12:45pm - 2:30pm
    4


    Wed
    12:45pm - 2:30pm
    4



    [code]
    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {
    var meetingData = aData[1];
    alert(" meetingData === " + meetingData);

    var innerDates = $('input', oSettings.aoData[iDataIndex].nTr);
    var monday_afternoon = $('input[name=monday_afternoon]').attr('checked');

    for ( var i=0, iLen=innerDates.length ; i
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    You've got multiple elements with the same ID (example1), which the browser certainly won't like since IDs must be unique in the document. I'd suggest removing them, or modifying them to each be unique, and see what happens then :-)

    Allan
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Allan,

    I tried that and still get the same results. My innerDates.length is 0 and the meetingData is the same as above.
    Here is my last code. Note: for the inner tables I tried with & within id's on the table
    [code]
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">




    DataTables example

    @import "demo_page.css";
    @import "demo_table.css";





    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {

    var meetingData = aData[1];
    alert(" meetingData === " + meetingData);

    var innerDates = $('input', oSettings.aoData[iDataIndex].nTr);
    var monday_afternoon = $('input[name=monday_afternoon]').attr('checked');
    for ( var i=0, iLen=innerDates.length ; i
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Thanks for the code paste - there is a difference between your original inner HTML table and the new one. The first one has:

    [code]

    [/code]

    While the old one has:

    [code]
    MON_MORNING
    [/code]
    If you want to just use the string method (although that means that the string is visible unless you hide it), then a simple indexOf match will do - rather than using the jQuery search for 'input' elements. So the question is - how do you want to proceed...? :-)

    Allan
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Allan,

    Thanks for getting back to me. Yeah I was displaying a hidden tag that was showing MON_AFTERNOON
    The web app will have Meeting day in one column and the meeting time in the other column along with the meeting location.

    My goal is to have everything initially displayed and if a user un-selects a checkbox then it will not display the outer row based on the inner table data.

    Looking at the example below If the un-selects Mon afternoon then the Mon and the Wed row will not be displayed.

    Ex
    1 Mon 12:45pm - 03:00pm 1
    Wed 01:00pm - 02:30pm 4
    ------------------------------------------------------------------------------------------
    2 Tues 08:00am - 10:00am 123
    Thur 09:00am - 11:30am 111

    As you said there is two ways to do this:
    1) Using a hidden tag and filter it based on it's value
    2) Or translate the day (Mon) and time (12:45pm) to determine the day and if it meets in the morning, afternoon or evening. (Ex. Mon Afternoon)

    I am leading towards the first way using a hidden. Do you think that way is an hack?

    Thanks,
    - Ed
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    > Do you think that way is an hack?

    No I think that sounds quite sensible. Having a computer readable string as well as a human readable one it not an unreasonable thing to do, and will save a good amount of work in decoding the human readable string, when that isn't needed.

    So option thing you could do, is use the TITLE attribute. For example Monday Morning. With this method you aren't creating the input elements (simply because it isn't semantically correct, as they aren't in a form) and then parse that. Then you could so something like $('span.dateTime', ...).attr('title'); to get the information you need. Then the format of the text in 'title' can be whatever makes life easy for you!

    Regards,
    Allan
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Alan,

    I still can't get it to work. Do I put the tag on the outside table or inner table?
    Here is what I have so far: (I get the value from the title from the span tag and the checkbox but it either displaying everything or nothing.)

    [code]


    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {

    var title = $("span.dateTime").attr("title");
    var innerDates = $('input', oSettings.aoData[iDataIndex].nTr);
    var monday_afternoon_cbox = $('input[name=monday_afternoon]').attr('checked');

    if (monday_afternoon_cbox == true) {
    if (title == "MON_AFTERNOON") {
    return false;
    } else {
    return true;
    }
    } else {
    return true;
    }
    });

    $(document).ready(function() {
    /* Initialise datatables */
    var oTable = $('#example').dataTable();
    $('#monday_afternoon').click( function() { oTable.fnDraw(); } );
    } );





    Live example




    Index




    Meeting Day
    Meeting Times
    Location




    Section
    Exam code




    111




    Mon
    12:45pm - 2:30pm
    4


    Wed
    12:45pm - 2:30pm
    4








    222




    MON
    09:00am - 10:30am
    4


    THU
    10:am - 11:30am
    48





















    Monday Afternoon




    [/code]

    Thanks,
    Ed
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Change these two lines:

    [code]
    var title = $("span.dateTime").attr("title");
    var innerDates = $('input', oSettings.aoData[iDataIndex].nTr);
    [/code]
    to:

    [code]
    var innerDates = $('span.dateTime', oSettings.aoData[iDataIndex].nTr);
    [/code]
    It will probably also need a loop in there:

    [code]
    innerDates.each( function () { .... } );
    [/code]
    in order to loop over each of the found SPANs and see if it matches.

    Also your HTML is invalid - on line 057. you've got a tbody tag which isn't in a table, which will probably confuse things a bit.

    Allan
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Allan,

    thank you so much for all your help, I just have a quick question, how do you extract the value from innerDates?
    [code]
    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {

    var monday_afternoon_cbox = $('input[name=monday_afternoon]').attr('checked');

    var innerDates = $('span.dateTime', oSettings.aoData[iDataIndex].nTr);

    innerDates.each( function (i) {
    alert(" *** inner dates value === " + innerDates[i]???? );
    });
    /* if (monday_afternoon_cbox == true) {
    if (title == "MON_AFTERNOON") {
    return false;
    } else {
    return true;
    }
    } else {
    return true;
    } */
    });

    $(document).ready(function() {
    /* Initialise datatables */
    var oTable = $('#example').dataTable();
    $('#monday_afternoon').click( function() { oTable.fnDraw(); } );
    } );
    [/code]
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Allan,
    I was able to extract the value from innerDates. I check to see if that value is equal to the checkbox value (MON_AFTERNOON) - I then return a false or true.

    It seems like I return true or false I always get: "No matching records found"
    [code]


    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {
    var monday_afternoon_cbox = $('input[name=monday_afternoon]').attr('checked');
    var innerDates = $('span.dateTime', oSettings.aoData[iDataIndex].nTr);

    innerDates.each( function () {
    var title = $(this).attr("title");

    if (monday_afternoon_cbox == true) {
    if (title == "MON_AFTERNOON") {
    return false;
    } else {
    return true;
    }
    } else {
    return true;
    }
    });
    });
    $(document).ready(function() {
    /* Initialise datatables */
    var oTable = $('#example').dataTable();
    $('#monday_afternoon').click( function() { oTable.fnDraw(); } );
    } );




    Live example




    Index




    Meeting Day
    Meeting Times
    Location




    Section
    Exam code




    111




    Mon

    12:45pm - 2:30pm
    4


    Wed

    12:45pm - 2:30pm
    4








    222




    MON

    09:00am - 10:30am
    4


    THU

    10:am - 11:30am
    48





















    Monday Afternoon




    [/code]
    Thanks again,
    - Ed
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    I've simplified your Javascript a little bit, and altered the logic to what I think should be correct:

    [code]
    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {
    var monday_afternoon_cbox = $('input[name=monday_afternoon]').attr('checked');
    console.log( 'Monday afternoon cbox:', monday_afternoon_cbox );

    $('span.dateTime', oSettings.aoData[iDataIndex].nTr).each( function () {
    var title = $(this).attr("title");
    console.log( title );

    if (monday_afternoon_cbox == true && title == "MON_AFTERNOON") {
    return true;
    }
    } );

    return false;
    });

    $(document).ready(function() {
    /* Initialise datatables */
    var oTable = $('#example').dataTable();
    $('#monday_afternoon').click( function() { oTable.fnDraw(); } );
    } );
    [/code]
    I've also added two debug console.log lines - if this doesn't work, can you post back with what the output is. If it does work, you can just remove them.

    Allan
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Allan,

    I replace my code with your code and it still not working. When the page loads nothing is displayed and when I select the checkbox still no data.

    Monday afternoon cbox: false
    MON_AFTERNOON
    WED_AFTERNOON
    Monday afternoon cbox: false
    MON_MORNING
    THU_MORNING

    Monday afternoon cbox: true
    MON_AFTERNOON
    WED_AFTERNOON
    Monday afternoon cbox: true
    MON_MORNING
    THU_MORNING
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Okay so the reason that no data is shown when there is no data, is because of the inverted filter. There needs to be a "if ( !monday_afternoon_cbox ) return true;" line near the top of the function to say "there is no filter - lets show everything". I'm surprised it doesn't work when the checkbox is checked though - can you link us to your example please? It might be worth adding a console.log line just before the return true to make sure it is falling into that.

    Allan
  • eddie909eddie909 Posts: 31Questions: 6Answers: 0
    Allan,
    I got it to work correctly :)
    Thank you so much for all your help in steering me in the right direction. I was working on this prototype to determine if we should use jquery or dojo. Hands down I love using your jquery plugin (DataTables) it will save me a lot of coding that I would have to do if I use dojo. I also need to learn jquery which would help me understand things better.Once I get my production release I will send you the link.

    Here are the changes that I made:
    The problem that I was having was inside the $('span.dateTime', oSettings.aoData[iDataIndex].nTr).each( function () . When I select the check box. No data was displaying. So I added a new var checkIfMatch to the program, if I have a match then I want to display both rows. Since they are tie together to the same index (111).
    Mon 12:45pm - 2:30pm4
    Wed 12:45pm - 2:30pm4
    [code]
    $.fn.dataTableExt.afnFiltering.push(
    function( oSettings, aData, iDataIndex ) {
    var monday_afternoon_cbox = $('input[name=monday_afternoon]').attr('checked');
    console.log( 'Monday afternoon cbox:', monday_afternoon_cbox );
    var checkIfMatch = false;
    if (monday_afternoon_cbox == false) {
    console.log(" cbox is FALSE so return true" );
    checkIfMatch = true;
    return true;
    }
    $('span.dateTime', oSettings.aoData[iDataIndex].nTr).each( function () {
    var title = $(this).attr("title");
    console.log( title );
    if (monday_afternoon_cbox == true && title == "MON_AFTERNOON") {
    console.log("cbox and title match - so return true");
    checkIfMatch = true;
    //return true;
    } //else {
    // console.log(" *** else return false ***");
    //return false;
    //}
    } );
    if (checkIfMatch == true) {
    return true;
    } else {
    return false;
    }
    console.log("checkIfMatch == " + checkIfMatch);
    checkIfMatch = false; //reset flag
    });
    $(document).ready(function() {
    /* Initialise datatables */
    var oTable = $('#example').dataTable();
    $('#monday_afternoon').click( function() { oTable.fnDraw(); } );
    } );




    Live example




    Index




    Meeting Day
    Meeting Times
    Location




    Section
    Exam code




    111




    Mon

    12:45pm - 2:30pm
    4


    Wed

    12:45pm - 2:30pm
    4








    222




    MON

    09:00am - 10:30am
    4


    THU

    10:am - 11:30am
    48





















    Monday Afternoon




    [/code]
    Thanks again for all your help,
    - Ed
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Ah very nice! Good fix - great to hear you got it going :-)

    > Once I get my production release I will send you the link.

    Yes please!

    Regards,
    Allan
This discussion has been closed.