Searching for value in table and making whole row or only cell change background

Searching for value in table and making whole row or only cell change background

MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

I'm trying to connect diagrams with DataTables. Basically on the click it takes diagram value and shows in the table. The value is stored in 'params'.

Below code seems to work fine when searching for that value via Search, however what I wanted is to actually highlight rows or cells (depending on user choice) via custom CSS. I tried different code from examples but can't seem to get it right.

Keep in mind I'm a total noob when it comes to JS/JQuery.

                params.event = "[original event]";
                var tableId = '#DT-VgpAcPqa'
                var tableSearch = $(tableId).DataTable();
                //var rowCount = tableSearch.rows().count()
                //console.log(rowCount);
                tableSearch.search('').draw();
                tableSearch.search(params.nodes).draw();

                var data = tableSearch.rows().data();
                data.each(function (value, index) {
                    //console.log(`For index ${index}, data value is ${value}`);


                });

                tableSearch
                    .column(1)
                    .data()
                    .each(function (value, index, row) {
                        if (value == params.nodes) {
                            console.log('Data in index: ' + index + ' is: ' + value);
                            console.log(row)
                            //console.log(index)
                            var cell = tableSearch.row(index);

                            $(cell).css({
                                "background-color": "#ffff00"
                            });
                        }
                    });

This question has an accepted answers - jump to answer

Answers

  • colincolin Posts: 15,144Questions: 1Answers: 2,586

    Hi @MadBoyEvo ,

    Do you mean something like this blog post?

    Cheers,

    Colin

  • MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

    SearchFade is cool and something I will use in the future. However what I need is actually both. I want to retain standard search so that user can use search as he wants.

    You can see it here: https://codepen.io/MadBoyEvo/pen/qBBOgaX

    Basically, when you click on a Tab you get 2x tables and diagram, when you click on objects on a diagram (user ones work) right now it influences search. But this is a bit too much.

    Your solution would make sense if it could be enabled only for queries done by user when clicking on diagram... is it possible?

    Otherwise I was simply thinking that I wouldn't use a search feature at all and simply make the row red.

    network.on("click", function (params) {
        params.event = "[original event]";
    
        var table = document.getElementById("DT-VgpAcPqa");
        //var row = "";
        for (var i = 0; i < table.rows.length; i++) {
    
    
            for (var j = 0; j < table.rows[i].cells.length; j++) {
                if (table.rows[i].cells[j].innerHTML == params.nodes) {
                    //row = table.rows[i].cells[j].innerHTML
                    table.rows[i].style.backgroundColor = "red";
                    return
                } else {
                    table.rows[i].style.backgroundColor = ''
                }
    
                //row += table.rows[i].cells[j].innerHTML;
                //row += " | ";
            }
        }
        // $(document).ready(function () {
        var table = $('#DT-KcPSJsnN').DataTable();
        //$('#btnSearch').click(function () {
        table.search(params.nodes).draw();
        //});
        //  });
    
        console.log(
            "click event, getNodeAt returns: " +
            this.getNodeAt(params.pointer.DOM)
        );
    });
    

    Normally above would work but the thing is, DataTables actually hide rows when paging so it wasn't working correctly. In perfect world I would take your solution enabled on demand or my solution above that works with DataTables.

  • colincolin Posts: 15,144Questions: 1Answers: 2,586

    Your solution would make sense if it could be enabled only for queries done by user when clicking on diagram... is it possible?

    That's possible. The SearchFade plugins main code is here:

        table.rows(':visible').every(function(rowIdx, tableLoop, rowLoop) {
            var present = true;
            if ($('.searchFadeInput' + table.settings()[0].sTableId).val().length) {
                present = table
                    .row(rowIdx)
                    .data()
                    .some(function(v) {
                        return v.match(new RegExp($('.searchFadeInput' + table.settings()[0].sTableId).val(), 'i')) != null;
                    });
            }
            $(table.row(rowIdx).node()).toggleClass('notMatched', !present);
        });
    

    You could just need to change $('.searchFadeInput' + table.settings()[0].sTableId).val() to be your string from the chart.

    Cheers,

    Colin

  • MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

    It seems to work: https://codepen.io/MadBoyEvo/pen/RwwrWbd

    However:
    - Is there a way for the search to be an exact match only?
    - Is there a way for me to specify which column I want to search for only?
    - Is there a way to search to work on different pages? Right now if the element is on next page nodes on other pages sometimes are blanked out, but sometimes not really
    - Is there a way to highlight the page the "element" is on?

    Additionally, for standard search would there be a way to exact search only?

                network.on("click", function (params) {
                    params.event = "[original event]";
    
                    var table = $('#SpecialID123').DataTable();
                    //table.search(params.nodes).draw();
    
    
                    table.rows(':visible').every(function (rowIdx, tableLoop, rowLoop) {
                        var present = true;
                        if (params.nodes) {
                            present = table
                                .row(rowIdx)
                                .data()
                                .some(function (v) {
                                    return v.match(new RegExp(params.nodes, 'i')) != null;
                                });
                        }
                        $(table.row(rowIdx).node()).toggleClass('notMatched', !present);
                    });
                });
    
  • MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

    I've also created another diagram with 2 tables and 1 diagram: https://codepen.io/MadBoyEvo/pen/MWWKaLG

    I've created:

                network.on("click", function (params) {
                    params.event = "[original event]";
                    var table = $('#SpecialID123').DataTable();
                    if (params.nodes != '') {
                        table.columns(1).search("^" + params.nodes + "$", true, false, true).draw();
                    } else {
                        table.columns(1).search('').draw();
                        //table.search('').draw();
                    }
                });
                network.on("click", function (params) {
                    params.event = "[original event]";
                    var table = $('#OtherTable').DataTable();
                    if (params.nodes != '') {
                        table.columns(1).search("^" + params.nodes + "$", true, false, true).draw();
                    } else {
                        table.columns(1).search('').draw();
                        //table.search('').draw();
                    }
                });
    

    This means that if you click a node it checks one table and then another table. Is it possible to detect whether the search did give any results and if no skip the search? And simply redraw table?

  • colincolin Posts: 15,144Questions: 1Answers: 2,586

    Hi @MadBoyEvo ,

    It looks good!

    • Is there a way for the search to be an exact match only?

    Yep, you can use regexes with search(), so something like table.search('^' + searchTerm + '$', true, false).draw()

    • Is there a way for me to specify which column I want to search for only?

    Yep, column().search().

    • Is there a way to search to work on different pages? Right now if the element is on next page nodes on other pages sometimes are blanked out, but sometimes not really

    No, the search is across the table as a whole. SearchFade scans the current page to do its magic, but that's more of a scan of the existing results rather than a search.

    • Is there a way to highlight the page the "element" is on?

    Not out of the box. You could scan the current order, table.rows({order: 'applied'}).data(), see where it lies, determine the current page length, then apply some styling to the page's button. Definitely possible, but a bit of a fiddle.

    Is it possible to detect whether the search did give any results and if no skip the search? And simply redraw table?

    You can use table.rows({search: 'applied'}).count() and if it's '0', you'll know nothing was matched.

    Cheers,

    Colin

  • MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

    Btw I keep getting errors: for the min.js on line with this code

                    b(".searchFadeInput" + d.settings()[0].sTableId).val().length && (c = d.row(a).data().some(function(a) {
    

    It happens even if I don't use it (searchFade: false) and no code related to searchFade. I guess it's because I've not defined searchFadeInput.

    Should I fix it on my side, or should it be fixed on your end?

  • colincolin Posts: 15,144Questions: 1Answers: 2,586
    Answer ✓

    Hi @MadBoyEvo ,

    That would be a fix on your part - we'd expect the input element to be present.

    Cheers,

    Colin

This discussion has been closed.