jQuery find/next/closest with ColVis

jQuery find/next/closest with ColVis

theflarenettheflarenet Posts: 26Questions: 5Answers: 0

I'm not sure whether a workaround could be done from the DataTables Buttons ColVis or the jQuery implementation itself; however, hiding columns creates new problems with my current implementation.

My table's last column is a clickable 'Update' button which grabs data from cells on the same row.
Example:
var appleCount = $(this).closest('tr').find('.appleCount').val();

The problem arises when I incorporate ColVis and decide to play devils-advocate by hiding the AppleCount column and clicking update--which fails to grab the data value of that row's cell since the column is hidden. I was curious about how to change the way ColVis hides a column so that my Update button can fetch the data as it is still retained.

Thanks!

Answers

  • kthorngrenkthorngren Posts: 21,143Questions: 26Answers: 4,918

    You might be able to use Datatables API's to get the data. See if something like this works:

          var row = table.row($(this).closest('tr'));
          var appleCount = row.data()['appleCount']
    

    Assumes table is a variable containing the Datatables API for your table and that you have a column named appleCount using columns.data. Or you could use something like this if you are using arrays: row.data()[0] for column 0.

    This should work since these access the Datatables data instead of the HTML. Let us know the results.

    Kevin

  • theflarenettheflarenet Posts: 26Questions: 5Answers: 0

    Kevin,

    This sounds amazing! I've started by adding an HTML5 data-name attribute to each of my column headers. Example:
    <th data-name='testID'>test</th>

    Then I followed by changing my jQuery to fetch through with:
    var row= table.row($(this).closest('tr'));
    var test = row.data()['testID'];
    console.log(row);
    console.log(test);

    It fails to fetch and the nothing displays on the console log. I've also tried row.data()[0] since it's the first column in the table and that failed as well. I'm so close I can feel it!

  • theflarenettheflarenet Posts: 26Questions: 5Answers: 0

    Update: I corrected a small error on my part and can now successfully fetch the data I need with row.data()[0] however fetching with the actual column name (which I have set as an HTML5 attribute on each <th>) does not work: row.data()['testID'].

    I wonder why?

  • kthorngrenkthorngren Posts: 21,143Questions: 26Answers: 4,918

    If you want to use a column name then you will need to define your columns using columns.data. Keep in mind the .data() API is looking at the Datatables data and data structure not anything in HTML.

    Kevin

  • theflarenettheflarenet Posts: 26Questions: 5Answers: 0

    Ahhh, I see! I've instead set my column names by including:

    "columns": [
    { "name": "id" },
    { "name": "testID" },
    { "name": "foo" }
    ],

    I can see that the column names have been set successfully as I called to fetch for a column name manually; however, row.data()[1] returns the actual data in that cell while row.data()['testID'] returns 'Undefined'.

    I'm not too sure why it's failing.

  • kthorngrenkthorngren Posts: 21,143Questions: 26Answers: 4,918
    edited May 2018

    Try this instead:

    "columns": [
    { "data": "id" },
    { "data": "testID" },
    { "data": "foo" }
    ],
    

    However for this to work you will need to change your data, if using ajax or Javascript data, to be object based instead of array based. But if your data is in HTML when Datatables initializes then columns.data should work as is.

    Kevin

  • theflarenettheflarenet Posts: 26Questions: 5Answers: 0

    Wow! It worked.. Excellent! Thank you.

    Looks like I'm set for grabbing plaintext from cells but, previously, I was using jQuery to dig in deeper and grab values from select dropdowns and input boxes:
    $(this).closest('tr').find('.dropdownBox1').val();

    Adding .find() or .closest() at the end of row.data()['testID'] doesn't work and I've found that .toArray() doesn't work either. I've been trying to figure this out before when I had column look up by column index but still can't figure out. Am I required to convert it to some other kind of format? I should be good after this!

  • kthorngrenkthorngren Posts: 21,143Questions: 26Answers: 4,918

    Maybe cell().node() will work for you. I haven't tried it with a hidden column though.

    Kevin

  • theflarenettheflarenet Posts: 26Questions: 5Answers: 0
    edited May 2018

    I just gave cell().node() a shot with a hidden column and, unfortunately, you are right. In order for me to use jQuery, the column/element has to be visible. I'll be on the lookout for alternatives and would highly appreciated if anyone could think of a simple workaround. I'm so close to achieving this goal with ColVis. :(

  • kthorngrenkthorngren Posts: 21,143Questions: 26Answers: 4,918
    edited May 2018

    See if this column selector helps:
    https://datatables.net/reference/type/column-selector#{integer}:visIdx

    Also look at the cell() docs to see the various options to choose the cell.

    Kevin

  • theflarenettheflarenet Posts: 26Questions: 5Answers: 0
    edited May 2018

    Kevin,

    I think I may have figured it out with a neat workaround:
    var id = $($.parseHTML( row.data()['id'] )).val();

    However, if I change any of the values within the dropdown/input boxes, DataTables does not capture that change in the row.data() call. I've tried running row.invalidate(); so that value can be updated but that does not work. I hope this thread helps others in the same situation!

    Any way to refresh and obtain new values?

  • kthorngrenkthorngren Posts: 21,143Questions: 26Answers: 4,918

    You will need to tell Datatables to re-draw the table. Try this:
    row.invalidate().draw();

    If that doesn't work can you put together a quick test case with what you are doing? It usually takes a bit of tweaking for me to get the invalidate() methods working.

    Kevin

  • theflarenettheflarenet Posts: 26Questions: 5Answers: 0

    I've attempted to tweak around it myself and lost all hope... so I've put together a test case as you suggested: live.datatables.net/johagehe/1/edit?html,js,console,output

    The first row's checkbox is unchecked and clicking the Update button will show you the data fetched within the console (0). Subsequently checking the box and clicking the update button again will yield the same result as it should be '1'.

    I really hope we figure this out! Thanks :smile:

  • kthorngrenkthorngren Posts: 21,143Questions: 26Answers: 4,918

    I made this example awhile back. Its a bit different as it doesn't use the update button to update the table. It updates the table when the checkbox is changed. The event handler directly updates the Datatables data and the rowCallback is used to display the checkbox state based on the Datatables data value for that column.

    http://live.datatables.net/legemixi/4/edit

    However I thought it would be a good learning experience to get your code running:
    http://live.datatables.net/navifiqa/1/edit

    I changed the pageLength to 1 to make sure the checkbox state stays when changing pages. Added a button to loop through each row and display the Datatabls checkbox state.

    Kevin

  • theflarenettheflarenet Posts: 26Questions: 5Answers: 0

    Interesting implementation. I tried it out but realized it goes against my workaround to maintain grabbing the element's values when it's within a hidden column and the Update button is clicked: $($.parseHTML( row.data()['id'] )).val();

    I suppose I could trigger to set each element's data.<column_name> respectively upon ever input/dropdown and checkbox change and maintain using the parseHTML workaround... but this seems like too much for a solution!

  • kthorngrenkthorngren Posts: 21,143Questions: 26Answers: 4,918
    edited May 2018

    I tried with parseHTML() but it wasn't reliable. The following steps would cause it to fail each time at the same spot:

    Click Update for Garret - got expected result:
    Parse HTML checkbox: false
    Name: Garrett Winters, DT checkbox: false
    
    Click Update for Tiger - got expected result:
    Parse HTML checkbox: true
    Name: Tiger Nixon, DT checkbox: true
    
    Click Update for Garret - got expected result:
    Parse HTML checkbox: false
    Name: Garrett Winters, DT checkbox: false
    
    Click Update for Tiger - expected "true" not "false" - failed:
    Parse HTML checkbox: false
    Name: Tiger Nixon, DT checkbox: false
    

    Then I change to using just this:
    $( row.data()['activateCheck'] )

    The same test steps work.

    You can try the updated code here:
    http://live.datatables.net/navifiqa/2/edit

    Still not sure that is what you want as I'm not using .val(). Feel free to update the example as you wish.

    Kevin

This discussion has been closed.