Search pane button with custom pane

Search pane button with custom pane

antokiosantokios Posts: 14Questions: 1Answers: 0

Hello, I am trying to implement a button to this example: https://datatables.net/extensions/searchpanes/examples/customFiltering/onlyCustom.html when I add the following code and change dom to bfrtip button is shown but on press it says no search pane found.

buttons:[
            'searchPanes'
        ],

This question has an accepted answers - jump to answer

Answers

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    full code :

    $(document).ready(function() {
        $('#example').DataTable( {
            searchPanes:{
                controls: false,
                panes: [
                    {
                        header:'Contact Filter',
                        options:[
                            {
                                label:'Following (1,3)',
                                value: function(rowData, rowIdx){
                                    return rowData[4] === '1' || rowData[4] === '3';
                                },
                            },
                            {
                                label:'Followers (2,3)',
                                value: function(rowData, rowIdx){
                                    return rowData[4] === '2' || rowData[4] === '3';
                                },
                            },
                            {
                                label:'Common (3)',
                                value: function(rowData, rowIdx){
                                    return rowData[4] === '3';
                                },
                            },
                            {
                                label:'Only Following (1)',
                                value: function(rowData, rowIdx){
                                    return rowData[4] === '1';
                                },
                            },
                            {
                                label:'Only Followers (2)',
                                value: function(rowData, rowIdx){
                                    return rowData[4] === '2';
                                },
                            },
                        ],
                        dtOpts:{
                            searching: false,
                            order: [[1, 'desc']]
                        }
                    }
                ],
                layout: 'columns-1'
            },
            columnDefs:[{
                searchPanes:{
                    show: false
                },
                targets: ['_all']
            }],
            dom: 'Bfrtip',
            buttons:[
                'searchPanes'
            ],
        });
    });
    
  • sandysandy Posts: 913Questions: 0Answers: 236

    Hi @antokios ,

    You need to set your SearchPanes config within the config for the SearchPanes button. Take a look at this example.,

    Thanks,
    Sandy

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    Hi @sandy ,

    I might be a dum dum but still I can't figure it out. I tried as follows yet I only get one pane to show. I also tried to simply running the example code and only the same pane appears (column friendship_status).

    $(document).ready(function() {
        $('#example').DataTable( {
            buttons:[
                {
                    extend: 'searchPanes',
                    config: {
                        cascadePanes: true,
                        searchPanes:{
                            panes: [
                                {
                                    header:'Custom',
                                    options:[
                                        {
                                            label:'Following (1,3)',
                                            value: function(rowData, rowIdx){
                                                return rowData[4] === '1' || rowData[4] === '3';
                                            },
                                        },
                                        {
                                            label:'Followers (2,3)',
                                            value: function(rowData, rowIdx){
                                                return rowData[4] === '2' || rowData[4] === '3';
                                            },
                                        },
                                        {
                                            label:'Common (3)',
                                            value: function(rowData, rowIdx){
                                                return rowData[4] === '3';
                                            },
                                        },
                                        {
                                            label:'Only Following (1)',
                                            value: function(rowData, rowIdx){
                                                return rowData[4] === '1';
                                            },
                                        },
                                        {
                                            label:'Only Followers (2)',
                                            value: function(rowData, rowIdx){
                                                return rowData[4] === '2';
                                            },
                                        },
                                    ],
                                    dtOpts:{
                                        searching: false,
                                        order: [[1, 'desc']]
                                    }
                                }
                            ],
                            layout: 'columns-1'
                        },
                        columnDefs:[{
                            searchPanes:{
                                show: false
                            },
                            targets: ['_all']
                        }],
                        dom: 'Pfrtip'
                    }
                }
            ],
            dom: 'Bfrtip',
        });
    });
    
  • sandysandy Posts: 913Questions: 0Answers: 236

    Hi @antokios,

    There are a few things here.

    Firstly, the searchPanes.cascadePanes option is not inside the SearchPanes config, it won't take any effect unless it is. I'd actually recommend that you remove that completely if you only want to show one pane.

    Secondly, the columnDefs config doesn't need to be within the buttons config, it should just be in the DataTable config. The same goes for the second dom property within the buttons config, just get rid of that.

    Lastly you need to remove the searchPanes level from the button object, as you can see in the example that I linked the buttons.config option takes it's place.

    I've put all of this together into an example for you.

    Hope this helps,
    Sandy

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    Hi @sandy,

    sorry for the late response. I did use your snippet and it worked just fine. Million thanks for that mate. Although I was thinking that if there is a property to hide the pane I could just have a regular button that on click hide/show the pane. Anyhow it works and I am grateful !

  • sandysandy Posts: 913Questions: 0Answers: 236

    Hi @antokios ,

    If you take a look at this discussion it might help you out. The examples in there are using a collapsible div to show/hide the SearchPanes. Is that more along the lines that you are looking for?

    Thanks,
    Sandy

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    Hello again @sandy ,

    sorry for the late response. I just tried that code. First thing that bothers me is that it starts collapsed and then once again due to my lack of knowledge I can't compine it with my previous code which you provided in your example.

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    I tried to do so but it's kinda hard to provide a test case. My table is getting populated by django template tags and I am not quite sure of how to express what I want. I could do a screen share though and explain in detail though I don't if that's possible from your end.

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    Understood, we only need to see the code running that will be on the page, so don't need all the Django templates. Otherwise, we could be talking cross purposes,

    Colin

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    @colin I'll try my best to explain then. Current code is as follows:

    $(document).ready(function() {
        var table = $('#example').DataTable({
            "language": {
                searchPanes: {
                    collapse: 'Contact Filter',
                }
            },
            scrollY:        '65vh',
            scrollCollapse: true,
            buttons:[
                {
                    extend: 'searchPanes',
                    config: {
                        panes: [
                            {
                                header:'CONTACT FILTERS',
                                options:[
                                    {
                                        label:'Following',
                                        value: function(rowData, rowIdx){
                                            return rowData[5] === '1' || rowData[4] === '3';
                                        },
                                    },
                                    {
                                        label:'Followers',
                                        value: function(rowData, rowIdx){
                                            return rowData[5] === '2' || rowData[4] === '3';
                                        },
                                    },
                                    {
                                        label:'Common',
                                        value: function(rowData, rowIdx){
                                            return rowData[5] === '3';
                                        },
                                    },
                                    {
                                        label:'Only Following',
                                        value: function(rowData, rowIdx){
                                            return rowData[5] === '1';
                                        },
                                    },
                                    {
                                        label:'Only Followers',
                                        value: function(rowData, rowIdx){
                                            return rowData[5] === '2';
                                        },
                                    },
                                ],
                                dtOpts:{
                                    searching: false,
                                    order: [[1, 'desc']]
                                }
                            }
                        ],
                        layout: 'columns-1'
                    }
                },
                {
                    text: 'Mass UnFollow',
                    action: function ( e, dt, node, config ) {
    
                    }
                },
                {
                    text: 'Mass Follow',
                    action: function ( e, dt, node, config ) {
    
                    }
                }
            ],
            'columnDefs': [
                {
                    searchPanes:{
                        show: false
                    },
                    targets: ['_all']
                },
                {
                    'targets': 0,
                    'checkboxes': {
                        'selectRow': true
                    }
                },
                {
                    "targets": [ 5 ],
                    "visible": false
                },
                {
                    "targets": [ 1 ],
                    "orderable": false,
                    "bSortable": false
                },
            ],
            'select': {
                'style': 'multi'
            },
            'order': [[2, 'asc']],
            dom: 'Bfrtip',
        });
    
        // Handle form submission event
        $('#frm-example').on('submit', function(e){
            var form = this;
    
            var rows_selected = table.column(0).checkboxes.selected();
    
            // Iterate over all selected checkboxes
            $.each(rows_selected, function(index, rowId){
                // Create a hidden element
                $(form).append(
                    $('<input>')
                        .attr('type', 'hidden')
                        .attr('name', 'id[]')
                        .val(rowId)
                );
            });
    
            // Mass Unfollow
            // HTTP Requests jQuery API
            for (let i = 0; i < rows_selected.length; i++) {
                if (i === rows_selected.length - 1) {
                    unFollow(rows_selected[i], true);
                } else {
                    unFollow(rows_selected[i], false);
                }
            }
    
            // Remove added elements
            $('input[name="id\[\]"]', form).remove();
    
            // Prevent actual form submission
            e.preventDefault();
    
    
        });
    });
    
    // Unfollow function
    function unFollow(name, willReloadInline) {
        $.get("/unfollow/" + name + "/")
            .fail(function () {
                console.log('Deleted user  : ' + name)
                if (willReloadInline) {
                    location.reload();
                }
            })
    }
    
    // Follow function
    function Follow(name, willReloadInline) {
        $.get("/follow/" + name + "/")
            .fail(function () {
                console.log('Followed user  : ' + name)
                if (willReloadInline) {
                    location.reload();
                }
            })
    }
    

    and output is : this

    now what I want to achieve is something similar to this example demonstrated by @sandy but with a button like this one. To be more specific optimal output would be something like this.

    Finally I would like to ask if its possible for Mass UnFollow Button to run this code mentioned above:

     // Handle form submission event
        $('#frm-example').on('submit', function(e){
            var form = this;
    
            var rows_selected = table.column(0).checkboxes.selected();
    
            // Iterate over all selected checkboxes
            $.each(rows_selected, function(index, rowId){
                // Create a hidden element
                $(form).append(
                    $('<input>')
                        .attr('type', 'hidden')
                        .attr('name', 'id[]')
                        .val(rowId)
                );
            });
    
            // Mass Unfollow
            // HTTP Requests jQuery API
            for (let i = 0; i < rows_selected.length; i++) {
                if (i === rows_selected.length - 1) {
                    unFollow(rows_selected[i], true);
                } else {
                    unFollow(rows_selected[i], false);
                }
            }
    
            // Remove added elements
            $('input[name="id\[\]"]', form).remove();
    
            // Prevent actual form submission
            e.preventDefault();
    
    
        });
    
  • antokiosantokios Posts: 14Questions: 1Answers: 0

    Also when I tried to simply change button text like so

    buttons:[
                {
                    extend: 'searchPanes',
                    text: '<i class="fas fa-filter"></i>',
                    title: 'Contact Filters',
                    config: {
                        panes: [
    

    it didn't work. Hence the language part on the cove mentioned on previous answer. Sorry if I sound too newbie it's cause I am. This is just polishing for an academic project due on Friday. Thanks in advance.

  • sandysandy Posts: 913Questions: 0Answers: 236

    Hi @antokios ,

    Going back a bit, I'm going to combine my original example with the sliding div example that I provided for you. The difference here is that the SearchPanes Button is not being used, so all of your SearchPanes config is declared normally. A custom button is then created to achieve the sliding effect. See here.

    In this example I've copied in all of the relevant code that you have provided and added comments to say what we are doing. Hopefully that will clear up the structure a bit.

    Thanks,
    Sandy

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    Hello @sandy,

    first of all thanks for all the great support. It already nearly looks the part. I tried implementing your example to my project. Output is like this. In your above mentioned example button and clear all option are all inside that borderlike place holder and search is outside. in my output buttons are outside and above where search and clear all are outside and below. I would like to have it as shown in your example and if possible the search to be contained inside the collapsing panel. Also is there an option to prevent it from starting collapsed by default?

    current code:

    $(document).ready( function () {
        var table = $('#example').DataTable({
            dom: 'BPfrtip',
            buttons: [
                {
                    text: '<i class="fas fa-filter"></i>', // Custom Button text
                    className: 'spToggle showPanes',
                    action: function (e, dt, node, config) {
                        dt.searchPanes.container().find('.dtsp-searchPanes').slideToggle(200, function () {
                            $('.spToggle').toggleClass('showPanes', $(this).is(':visible'));
                        });
                    },
                },
                { // Your other custom buttons
                    text: 'Mass UnFollow',
                    action: function ( e, dt, node, config ) {
    
                    }
                },
                {
                    text: 'Mass Follow',
                    action: function ( e, dt, node, config ) {
    
                    }
                }
            ],
            searchPanes:{ // Normal SearchPanes configuartion - we aren't using the SearchPanes Button new
                filterChanged: function (count) {
                    // This function changes the button text as you select filters, so it is important to set the correct values here for your custom text
                    $('.spToggle').text(this.i18n('searchPanes.collapse', {0: 'Contact Filter', _: 'Contact Filter (%d)'}, count));
                },
                panes: [ // Custom SearchPanes go in here
                    {
                        header:'CONTACT FILTERS', // Custom Pane Header
                        options:[ // Custom option go in here
                            {
                                label:'Following',
                                value: function(rowData, rowIdx){
                                    return rowData[5] === '1' || rowData[4] === '3';
                                },
                            },
                            {
                                label:'Followers',
                                value: function(rowData, rowIdx){
                                    return rowData[5] === '2' || rowData[4] === '3';
                                },
                            },
                            {
                                label:'Common',
                                value: function(rowData, rowIdx){
                                    return rowData[5] === '3';
                                },
                            },
                            {
                                label:'Only Following',
                                value: function(rowData, rowIdx){
                                    return rowData[5] === '1';
                                },
                            },
                            {
                                label:'Only Followers',
                                value: function(rowData, rowIdx){
                                    return rowData[5] === '2';
                                },
                            },
                        ],
                        dtOpts:{ // Custom DT options for the SearchPanes
                            searching: false,
                            order: [[1, 'desc']]
                        }
                    }
                ],
                layout: 'columns-1' // Layout 1 pane wide in the SearchPanes container
            },
            columnDefs:[
                {
                    searchPanes:{
                        show: false
                    },
                    targets: ['_all']
                },
                { // Show checkboxes on first column
                    'targets': 0,
                    'checkboxes': {
                        'selectRow': true
                    }
                },
                { // Hide friendship column
                    "targets": [ 5 ],
                    "visible": false
                },
                { // Hide sorting arrows and disable ordering on profile image column
                    "targets": [ 1 ],
                    "orderable": false,
                    "bSortable": false
                },
            ],
            'select': { // Enable multiple selection
                'style': 'multi'
            },
            'order': [[2, 'asc']],  // Set default sorting
        });
    
    });
    
    
  • antokiosantokios Posts: 14Questions: 1Answers: 0

    Also @sandy sadly this approach broke my previously working code. ERROR CODE

  • sandysandy Posts: 913Questions: 0Answers: 236

    Sorry @antokios ,

    I should have mentioned that there are a few extra css properties that you will need to add. Take a look under the css tab in the previous example.

    Hopefully then it should work as desired.

    Thanks,
    Sandy

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    @sandy

    My bad for not noticing it. Thanks for all the great help but apparently I am going to have to stick with my previous code. This approach breaks my code for some reason that I don't understand. Also even if my code worked it still starts collapsed which bothers me and I don't know how to get my mass unfollow code to work inside the custom button.

    Thanks once again for being here,
    Antonios Kiosses

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    @sandy

    Hello again. So I tried working on with the documentation and with the example you provided. I managed to get my code working again. I have only three worries now that probably missing an easy fix.
    1. Using bootstrap 4 the "clear all" button gets off alignment.
    2. The searchpanes start collapsed while I want the panes to show only on button click
    3. I want to get the paginator numbers, clear all button, and button(searchpanes + custom buttons) to share one color

    here is my JS fiddle: http://live.datatables.net/yawemaci/1/edit

  • sandysandy Posts: 913Questions: 0Answers: 236

    Hi @antokios ,

    1. The title row which is made up of the Clear All button and the Title for SearchPanes is a flex container. When you set the title row to have a display value of none, it no longers stretches to fill the space so the Clear All button sits to the left. You'll need to add some more custom css to push it to the right (or wherever you want it!)

    2. If you want the panes to start collapsed then just add the following line after your SearchPanes initialisation

    table.searchPanes.container().find('.dtsp-searchPanes').css("display", "none");
    

    This will hide the SearchPanes element on startup.

    1. Again, you'll either need to implement your own css to match Bootstraps, or alternatively you could change the classes on the clearAll button using
    table.searchPanes.container().find('.dtsp-clearAll').removeClass("btn-primary btn-light").addClass("btn-secondary");
    

    Hope this helps,
    Sandy

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    @sandy

    when I add the line provided to prevent search pane to start collapsed it removes everything above table header. This picture is demonstrating what I want to achieve. Also I tried to force the container to flex using:

    .dtsp-title {
      flex:1
      display: none;
      
    }
    

    but then filter title is displaying behind buttons.

  • sandysandy Posts: 913Questions: 0Answers: 236
    Answer ✓

    Hi @antokios ,

    I've added the line to your example that you provided above and it works fine - see here.

    I've added the changes to the button classes as well in this example.

    And then I've added some css to make the button go to the right here.

    Hope this helps,
    Sandy

  • antokiosantokios Posts: 14Questions: 1Answers: 0

    Million thanks to you sir ! I was placing the line on the wrong spot. Everything works as intended except scroller but tbh I don't really care. Thanks for spoonfeeding the parts. Seems I have a lot to learn.

This discussion has been closed.