How to change SearchPanes title dynamically?

How to change SearchPanes title dynamically?

RaidekRaidek Posts: 69Questions: 7Answers: 0

Description of problem:
I know this exists:
https://datatables.net/reference/option/columns.searchPanes.header
but I want that every time I choose a filter option the 'header' changes to that filter value.

Answers

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    We don't have an API for that at this time I'm afraid.

    Allan

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    And is there any way to collect what value has been punctured in a filter?

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Answer ✓

    I hate to say it, but no, we don't have an API method for that either. I can see it being potentially useful though, so if we get other requests for this feature I'll look at adding it in.

    Allan

  • colincolin Posts: 15,240Questions: 1Answers: 2,599
    Answer ✓

    I poked around and you can use the API to do what you're after - see here. This is updating that columns.searchPanes.header whenever the pane's selection changes.

    Colin

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    Thanks Allan and thanks Collin.
    Thanks for your solution Collin, the truth is that it would not have occurred to me... My knowledge of JavaScript does not go that far, but it would be nice to implement it in the API.

    Also, this can help me to create a single filter for different tables. I'll have to find out how.

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    Colin,
    I have seen your example but in my page I have more than one table.

    So this line of code:

     $('table').DataTable().on('select deselect', function(e, dt) {
        let selected = dt.rows({selected: true}).data().toArray();
        let text = selected.length? selected.map(function(r) {return r.display;}) : nothing;
        $(dt.table().node()).closest('.dtsp-searchPane').find('input').attr('placeholder', text);
      });
    

    $('table') it only calls the <table> tag, but of course, I have more than one table and it gives an error. I have tried to put the id of each table. But it breaks the functionality.

    Example code: http://live.datatables.net/kiyahozi/3/edit

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Yes, Colin's example would need to be modified to use the SearchPane tables in a specific container only. If you right click and inspect the elements, you'll be able to build a suitable selector.

    Allan

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    I think I don't quite understand what you mean by putting the Search panes in a single container.

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951
    edited June 2022 Answer ✓

    You have this same code three times:

      $('table').DataTable().on('select deselect', function(e, dt) {
        let selected = dt.rows({selected: true}).data().toArray();
        let text = selected.length? selected.map(function(r) {return r.display;}) : nothing;
        $(dt.table().node()).closest('.dtsp-searchPane').find('input').attr('placeholder', text);
      });
    

    One after each Datatable initialization. The reason for the Cannot reinitialise DataTable error is that your first Datatable is initialized then the above will initialize the other tables it finds on the page. Then your other Datatable init blocks will cause the reinitialization error. You can create the three event but use more specific selectors, like the table id, or create one event at the end including all the tables. Like this:
    http://live.datatables.net/kiyahozi/4/edit

    I think the tet case is doing what you want but not totally sure :smile:

    Kevin

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    Wow, what a stupid mistake. Thank you very much, that's exactly what I wanted.

  • RaidekRaidek Posts: 69Questions: 7Answers: 0
    edited June 2022

    I found a weird bug. If I use the language option, the code:

          let nothing = "Nada seleccionado";
          $('table').DataTable().on('select deselect', function(e, dt) {
          let selected = dt.rows({selected: true}).data().toArray();
          let text = selected.length? selected.map(function(r) {return r.display;}) : nothing;
          $(dt.table().node()).closest('.dtsp-searchPane').find('input').attr('placeholder', text);
        });
    

    stops working.

    I have modified @kthorngren's example where I have added the code:

    language: {
      url: "url cdn of some language",
    },
    

    So that:

    1. table in Spanish, //cdn.datatables.net/plug-ins/1.12.1/i18n/es-ES.json (does not work)
    2. table in italian, //cdn.datatables.net/plug-ins/1.12.1/i18n/it-IT.json (doesn't work)
    3. table in english, //cdn.datatables.net/plug-ins/1.12.1/i18n/en-GB.json, (doesn't work)

    http://live.datatables.net/kiyahozi/7/edit

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    See the paragraph that starts "Note that when this parameter is set" in the language.url documentation.

    Allan

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    hi @allan
    I read it, but I couldn't integrate it with the code:

      let nothing = "Nada seleccionado";
      $('table').DataTable().on('select deselect', function(e, dt) {
      let selected = dt.rows({selected: true}).data().toArray();
      let text = selected.length? selected.map(function(r) {return r.display;}) : nothing;
      $(dt.table().node()).closest('.dtsp-searchPane').find('input').attr('placeholder', text);
    });
    

    So initComplete must be used inside the table initialization code block.
    So I created a function from the code:

    function my_function(){
       let nothing = "Nothing selected";
       $('table').DataTable().on('select deselect', function(e, dt) {
       let selected = dt.rows({selected: true}).data().toArray();
       let text = selected.length? selected.map(function(r) {return r.display;}) : nothing;
       $(dt.table().node()).closest('.dtsp-searchPane').find('input').attr('placeholder', text);
    });
    }
    

    Y luego en cada creación de tabla poner:

      "initComplete": function( settings, json ) {
        my_function();
      }
    

    But it does not work.
    http://live.datatables.net/kiyahozi/9/edit

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    Someone please?
    Thanks

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951
    Answer ✓

    Look in the browser's console and you will see these errors:

    GET http://live.datatables.net/cdn.datatables.net/plug-ins/1.12.1/i18n/es-ES.json net::ERR_ABORTED 404 (Not Found)

    You have a script tag in the HTML section trying to fetch this file.

    Uncaught ReferenceError: nothing is not defined

    The nothing variable is not defined when trying to use it to initialize the search panes.

    I fixed both here:
    http://live.datatables.net/kiyahozi/10/edit

    There is still a problem. You are calling my_function() in initComplete in all the Datatables. Each time you select an option in the search panes the event will fire 3 times. See the console output.

    Instead of using table is the selector for the select event $('table').DataTable().on('select deselect' use the searchPanes.container() to find the SearchPanes container for the specific table. Using table will apply the select event to all the tables in the page, including the main tables if you had select enabled on them.

    See the updated test case using searchPanes.container() and jQuery find() to find the SP table. Also note the use of this.api() in initComplete to pass the Datatable API instance to my_function().

    Kevin

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    Okay thank you very much @kthorngren .
    And if now I want the name of the original filter that I have put with the 'header' clause to appear instead of anything selected.

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951

    Sorry, I don't understand what you are looking for. Please provide more details.

    Kevin

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    @kthorngren http://live.datatables.net/kiyahozi/13/edit
    In this example you can see that the filters have the header with the word 'POSITION' (which is the name of the column to which the filter refers) because we have put this:

      columnDefs: [{
           targets: 1,
           searchPanes: {
             header: 'POSITION',
           }
         }],
    

    Logically, if you select something from the filter, it will change 'POSITION' to the chosen one. But if you deselect what you have selected it says "Nothing selected". However, I want it to put 'POSITION'.
    If there is only one filter it is easy because it is to change:

    let nothing = "Nothing selected";
    

    by:

    let nothing = 'POSITION';
    

    But if we have more than one filter how can we do this.

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Sorry, I'm not clear what you mean by "more than one filter". Could you update that example to demonstrate this, with steps on how to reproduce the issue.

    Colin

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    Hello @colin .
    I am attaching two screenshots.
    I have changed with the header the name of each filter.

    But when deselecting:

    But when deselecting it takes the "Nothing selected". This is logical, but I would like the deselect to take the header of the filter.

    If there was only one filter activated, for example the "POSITION FILTER" one, it would be as easy as changing the "Nothing selected" to "POSITION FILTER" and thus when deselecting it would come out "POSITION FILTER" and not "Nothing selected". But with more than one filter this cannot be done.

    CODE: http://live.datatables.net/kiyahozi/18/edit

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    Hi @colin , was my explanation helpful?
    I always wait 10 days if I don't get a response.

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951
    Answer ✓

    I mentioned before that you should pass the Datatable API from initComplete into my_function() but I guess I didn't save the updated example. You will notice that each time you select or deselect a search option that the event runs three times - one for each table. We need to have it run only once.

    This allows us to grab the default placeholder and save it to the input using HTML5 data attributes. We can then use this data attribute to set the placeholder if no rows are selected. See this example:
    http://live.datatables.net/kiyahozi/19/edit

    Kevin

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    Thanks @kthorngren. It's works

  • karandolyphkarandolyph Posts: 3Questions: 1Answers: 0

    i want replace searchpanes title with selected value basically i want to show selected value as title in searchpane is there any option or solution

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    @karandolyph No, there's not. It may work on the selection of a single item, but would get messy quick if multiple filter options were selected,

    Colin

  • RaidekRaidek Posts: 69Questions: 7Answers: 0

    @karandolyph

    $(document).ready(function () {
      function filtros(table) {
    
            table.searchPanes
                .container()
                .find("table.dataTable")
                .each(function (index) {
                    let input = $(this).closest(".dtsp-searchPane").find("input");
                    $(input).data("default_placeholder", $(input).prop("placeholder"));
                });
    
            table.searchPanes
                .container()
                .find("table")
                .on("select.dt deselect.dt", function (e, dt) {
                    let selected = dt.rows({ selected: true }).data().toArray();
    
                    // Get the default placeholder
                    let default_placeholder = $(dt.table().node())
                        .closest(".dtsp-searchPane")
                        .find("input")
                        .data("default_placeholder");
                    let text = selected.length
                        ? selected.map(function (r) {
                            return r.display;
                        })
                        : default_placeholder;
                    $(dt.table().node())
                        .closest(".dtsp-searchPane")
                        .find("input")
                        .attr("placeholder", text);
                });
      }
    
      let table = $("#tableID").DataTable({
            initComplete: function (settings, json) {
                filtros(this.api());
            },
      });
    }
    
Sign In or Register to comment.