How to get all column rows (even those which are not displayed)?

How to get all column rows (even those which are not displayed)?

julmotjulmot Posts: 7Questions: 3Answers: 0
edited January 2016 in Free community support

Modify a table row (DOM modification), then search for a keyword. If the row you just modified is not included in the search results it will disappear in the DOM. So you can only modify it back to its original state when clearing the search (because it is then back in the DOM).

So what is the preferred method to get all DOM rows, even those who were hidden from DataTables? I'm not talking about the data, I mean the DOM objects.

Let's take this fiddle as an example:
https://jsfiddle.net/julmot/c2am6zfr/
Here you have multiple search inputs. Type in "A" in the name input. You see that the "A" characters in the name "Airi Satou" will become highlighted. Now type in an age that does not fit the age of this employee, e.g. "47". You see that "Airi Satou" will disappear from DOM. At a last step remove "A" from name input and "47" from the age input (in that order). As you can see, the highlighting of "Airi Satou" wasn't removed because it was inacessable while it was hidden.

Answers

  • jr42.gordonjr42.gordon Posts: 305Questions: 2Answers: 49

    I hate to propose something as I like how effective and efficient your code is, but you might look at utilizing the "drawCallback" functionality in DataTables. Reason being is you need to wait for the search and draw to execute before removing/adding your class because, as you stated, the rows in question are not there.

    With that said, doing it this way will force you to have to execute the remove/add highlight functionality for each input. Now you can make like easier on yourself by adding a boolean/check to only fire this functionality if any of the inputs changed because this callback is fired a lot.

    The only other option I could suggest, I cannot think of anything specific, is looking into a more DataTables API solution.

    -- This pulls from the HTML currently visible
    var $col = $(".datatables-table tbody tr > td:nth-child(" + inputMapper[key] + ")");

    But the stuff you don't see exists in dtInstance.data() (you could also use dtInstance.columns().data() ). However, I am not a fan of going this route with what you are trying to do as i feel it adds an unnecessary level of complexity.

  • julmotjulmot Posts: 7Questions: 3Answers: 0

    Hi @jr42.gordon,

    thanks for your reply.

    I already know the workaround to highlight or remove highlight of keywords in each column on each input change. This would solve my problem, but as you said, would cause unnecessary performance. So I'm looking for a DataTables method, not a workaround in my code. DataTables offers so much options, it would be strange if it doesn't offer an option to get all rows as DOM element.

    Regarding your hint that I could also use dtInstance.columns().data(). Unfortunately I can't use it that way because the jmHighlight plugin requires to have DOM elements. This would just return an array with column text.

  • jr42.gordonjr42.gordon Posts: 305Questions: 2Answers: 49

    I think DataTables could argue that is what makes it so optimized, by removing those rows from the DOM. I have come across times where is has been a pain, but luckily I wasn't using a plugin like the one you are using.

    I still think that you are going to have to perform the add/remove highlight functionality for all inputs after the draw is performed. Not ideal but seems like a must, unless Allan replies and says otherwise.

  • julmotjulmot Posts: 7Questions: 3Answers: 0

    Ok for now I've implemented the workaround. I also updated the fiddle and set it as base. So if you want to reproduce the issue you have to enter the previous JS:

    $(function() {
    
      // Initialize DataTables
      var dtInstance = $(".datatables-table").DataTable({
            pageLength: 5, // set elements per page
            bLengthChange: false // disable entry selection
        });
        
        // Map inputs with columns (nth-child(X))
        var inputMapper = {
            "name": 1,
            "position": 2,
            "office": 3,
            "age": 4
        };
        
        // Act on search change
        $("input").on("keyup", function(){
            var $this = $(this);
            var val = $this.val();
            var key = $this.attr("name");
            
            // Search inside datatable column
            // subtract -1 because :nth-child starts with 1,
            // DataTables with 0
            dtInstance.columns(inputMapper[key] - 1).search(val).draw();
            
            // Determine the column related to the input
            // and highlight the keyword
            var $col = $(".datatables-table tbody tr > td:nth-child(" + inputMapper[key] + ")");
            $col.jmRemoveHighlight({
                "element": "span",
                "className": "highlightYellow"
            });
            $col.jmHighlight(val, {
                // Define jmHighlight options (see https://github.com/julmot/jmHighlight)
                "element": "span",
                "className": "highlightYellow",
                "separateWordSearch": true
            });
            
        });
    
    });
    

    If there is someone who knows a DataTables way to workaround that issue, please let me know.

  • julmotjulmot Posts: 7Questions: 3Answers: 0
    edited January 2016

    @jr42.gordon I agree with you. It may be performance-heavy if it would just set the non-related elements to display:none;.

    Which plugin you have used?

  • jr42.gordonjr42.gordon Posts: 305Questions: 2Answers: 49

    Luckily I have not had to use any additional plugins when using DataTables.

    The performance of your fix isn't terribly bad. What about setting a boolean value to true before calling "dtInstance.columns(inputMapper[key] - 1).search(val).draw();", within your drawCallback you check this value and perform searches if necessary. If you perform the searches, set the boolean to false.

    Again, drawCallback is fired often, so utilizing a check to only perform highlighting functionality after search input change will improve performance.

This discussion has been closed.