Pergunta no WordPress TablePress: Uma coluna inclui uma tabela/exibição da pesquisa via JS

Um usuário perguntou ?

Olá Tobias,

Preciso de uma tabela com colunas que possam ser parcialmente excluídas da pesquisa apenas em casos especiais (em tempo de execução). Caso contrário, todas as colunas visíveis serão usadas.

Existe uma solução para incluir/excluir uma coluna específica de uma pesquisa usando JS com a API DataTables? Por exemplo $(#table-id).dataTableSettings.***.bSearchable = false.

Saudações Sascha

(@tobiasbg)

3 anos, 3 meses atrás

Olá,

Obrigado pelo seu post e desculpe o transtorno.

Usar a API pode ser um caminho dinâmico (você precisa verificar o site DataTables), mas a maneira mais rápida que conheço é colocar “Custom Command” na tela “Edit” da tabela, como

"columnDefs": [ { "searchable": false, "targets": [ 0, 3 ] } ]

Abraços, Tobias

(@sesselschwitzer)

3 anos, 3 meses atrás

Olá Tobias,

Obrigado pela sua sugestão. Mas deve ser dinâmico.

Vou dar um jeito e te aviso :).

CU Sasha

(@tobiasbg)

3 anos, 3 meses atrás

Olá Sasha,

sim, então você precisaria de uma solução personalizada usando as funções da API, eu acho …

Abraços, Tobias

(@sesselschwitzer)

3 anos, 3 meses atrás

Olá Tobias,

“DataTable” e “CSS” têm vantagens e desvantagens.

Eu estava procurando uma solução usando a API DataTables de ontem, mas não consegui encontrá-la. O próximo problema é a necessidade de habilitar expressões regulares.
"search": { "regex": true })

que tem efeitos colaterais não intencionais (para mim) e acho que a maioria dos usuários não está ciente das expressões regulares.

Finalmente, para evitar o uso excessivo, decidi adicionar uma nova coluna visible(!) e escondê-la via CSS. (consulte: Esta coluna contém termos que as outras colunas não contêm. Esses termos são fornecidos por um controle DropDown adicional (localizado abaixo do campo de entrada de pesquisa) e estão incluídos no campo de pesquisa do TablePress.

Veja-o em ação: – (atualmente não são necessárias colunas ocultas) – (com coluna oculta)

E aqui está o código:

jQuery(document).ready(function($) {

    const FILTER_INFO = [];

    FILTER_INFO['Dokumente_Lexika_Bauwerke'] = {
        filterTitle: 'Vordefinierte Filter:<br/>',
        data: [
            [ '[Leer]',         '' ],
            [ '— Orte —',       null ],
            [ 'Alsfeld',        'Alsfeld,' ],
            [ 'Altenburg',      'Altenburg,' ],
            [ 'Angenrod',       'Angenrod,' ],
            [ 'Berfa',          'Berfa,' ],
            [ 'Billertshausen', 'Billertshausen,' ],
            [ 'Eifa',           'Eifa,' ],
            [ 'Elbenrod',       'Elbenrod,' ],
            [ 'Eudorf',         'Eudorf,' ],
            [ 'Fischbach',      'Fischbach,' ],
            [ 'Hattendorf',     'Hattendorf,' ],
            [ 'Heidelbach',     'Heidelbach,' ],
            [ 'Leusel',         'Leusel,' ],
            [ 'Liederbach',     'Liederbach,' ],
            [ 'Lingelbach',     'Lingelbach,' ],
            [ 'Münch-Leusel',   'Münch-Leusel,' ],
            [ 'Reibertenrod',   'Reibertenrod,' ],
            [ 'Schwabenrod',    'Schwabenrod,' ],
            [ '— Bauwerke —',   null ],
            [ 'Regionalmuseum', 'Regionalmuseum' ],
            [ '— Sonstiges —',  null ],
            [ 'Routen',         'Route' ],
        ]
    };
    FILTER_INFO['Dokumente_Lexika_Personen_Buergermeister'] = {
        filterTitle: '<abbr title="Verwendet interne Filter">Vordefinierte Filter</abbr>:<br/>',
        data: [
            [ '[Leer]',   '' ],
            [ '— Jahrhunderte —',  null ],
            [ '2001 – 2001',      '{2001–2100}' ],
            [ '1901 – 2000',      '{1901–2000}' ],
            [ '1801 – 1900',      '{1801–1900}' ],
            [ '1701 – 1800',      '{1701–1800}' ],
            [ '1601 – 1700',      '{1601–1700}' ],
            [ '1501 – 1600',      '{1501–1600}' ],
            [ '1401 – 1500',      '{1401–1500}' ],
            [ '1301 – 1400',      '{1301–1400}' ],
            [ '— Epochen —',      null ],   // additional visible (!) table column needed
            [ 'bis 1574',         '{–1574}' ],
            [ '1567 – 1604',      '{1567–1604}' ],
        ]
    };

    /**
     * Create and add a select tag with options to under the search input field.
     */
    function addFilterSelectTagToDOM( jWrapper, tableID ){

        let filterSelectTag = '';

        // build <option> tags
        for (let i = 0; i < FILTER_INFO[tableID].data.length; i++) {

            var optionValue = FILTER_INFO[tableID].data[i][0];
            var optionAttributes = (FILTER_INFO[tableID].data[i][1] !== null)
                ? ' value="' + FILTER_INFO[tableID].data[i][1] + '"'
                : ' disabled="disabled"'
                ;

            filterSelectTag += '<option' + optionAttributes + '>' + optionValue + '</option>';
        }

        filterSelectTag = '<select>' + filterSelectTag + '</select>';

        // append HTML
        jWrapper.find('.dataTables_filter').after(
            '<div' +
                ' class="predefined-filter"' +
                ' style="clear: both; display: block; text-align: right;"' +
            '>' +
                FILTER_INFO[tableID].filterTitle + filterSelectTag +
            '</div>'
        );

        let jSelect = jWrapper.find('.predefined-filter select');
        return jSelect;
    }

    /**
     * Put selected search term into search input field.
     */
    function setInputTextCallback( jInput, jSelect ){
        jSelect.change( function(){
            return function(){
                let filterValue = $(this).children(":selected").val();
                jInput
                    .val( filterValue )
                    .keyup()
                    ;
            };
        }());
    }

    /**
     * Set input option selectedIndex to 0.
     */
    function setOptionSelectedIndexTo0Callback( jInput, jSelect ){
        jInput.keyup( function(){
            return function(){
    			if (!jInput.val()) {
    			    jSelect.prop('selectedIndex', 0);
    			}
    		};
        }());
    }

    /**
     * 
     */
    function run() {
        for (let tableID in FILTER_INFO){
            if (FILTER_INFO.hasOwnProperty(tableID)) {
    
                let jWrapper = $('#tablepress-' + tableID + '_wrapper');
                if (jWrapper.length) {

                    let jInput = jWrapper.find('.dataTables_filter > label > input[type="search"]');
                    let jSelect = addFilterSelectTagToDOM( jWrapper, tableID );

                    setInputTextCallback( jInput, jSelect );
                    setOptionSelectedIndexTo0Callback( jInput, jSelect );
                }
            }
        }
    }

    run();
});

Espero que você possa usá-lo também :).

Saudações Sascha

(@tobiasbg)

3 anos, 3 meses atrás

Olá Sasha,

muito genial! Eu verifiquei sua solução brevemente, mas parece ótimo! Obrigado por compartilhar!

Tudo de bom, Tobias

(@sesselschwitzer)

3 anos, 3 meses atrás

Olá Tobias,

foi um prazer. “Kost’nix!” como sugere o Hessian superior ;).

Saudações Sascha

(@tobiasbg)

3 anos, 3 meses atrás

Olá,

ha, der ist intestino ?

Viele Gruße, Tobias

(@sesselschwitzer)

3 anos, 3 meses atrás

Olá Tobias,

Este link simples respondeu à minha pergunta sobre como selecionar colunas de tabela para incluir ao pesquisar com expressões regulares:

As linhas mágicas:

$(table-id)
	.DataTable()
	.column( columnIndex )// searches within this column only
	.search( filterValue, useRegexSearch, useSmartSearch )
	.draw()
	;

Bem, parece restrito a pesquisar uma ou todas as colunas e nada no meio, mas, no meu caso, tudo bem.

Ótimo: – A entrada de pesquisa ainda funciona sem regex! – Nenhuma coluna visível adicional necessária (oculta por CSS)

O código:

jQuery(document).ready(function($) {

    const FILTER_INFO = [];

    FILTER_INFO['Dokumente_Lexika_Bauwerke'] = {
        filterTitle: 'Vordefinierte Suche:<br/>',
        filterColIdx: 0,// -1 := filter all columns
        searchRegex: false,
        searchSmart: true,
        options: [
            [ '[Leer]',         '' ],
            [ '— Orte —',       null ],
            [ 'Alsfeld',        'Alsfeld,' ],
            [ 'Altenburg',      'Altenburg,' ],
            [ 'Angenrod',       'Angenrod,' ],
            [ 'Berfa',          'Berfa,' ],
            [ 'Billertshausen', 'Billertshausen,' ],
            [ 'Eifa',           'Eifa,' ],
            [ 'Elbenrod',       'Elbenrod,' ],
            [ 'Eudorf',         'Eudorf,' ],
            [ 'Fischbach',      'Fischbach,' ],
            [ 'Hattendorf',     'Hattendorf,' ],
            [ 'Heidelbach',     'Heidelbach,' ],
            [ 'Leusel',         'Leusel,' ],
            [ 'Liederbach',     'Liederbach,' ],
            [ 'Lingelbach',     'Lingelbach,' ],
            [ 'Münch-Leusel',   'Münch-Leusel,' ],
            [ 'Reibertenrod',   'Reibertenrod,' ],
            [ 'Schwabenrod',    'Schwabenrod,' ],
            [ '— Bauwerke —',   null ],
            [ 'Regionalmuseum', 'Regionalmuseum' ],
            [ '— Sonstiges —',  null ],
            [ 'Routen',         'Route' ],
        ]
    };
    FILTER_INFO['Dokumente_Lexika_Personen_Buergermeister'] = {
        filterTitle: 'Vordefinierte Suche:<br/>',
        filterColIdx: 1,//-1 := filter all columns
        searchRegex: true,
        searchSmart: true,
        options: [
            [ '[Leer]',   '' ],
            [ '— Jahrhunderte —',  null ],
            [ '2001 – 2100',      '(.*(20(0[1-9]|[1-9]d)|2100).*)' ],
            [ '1901 – 2000',      '(.*(19(0[1-9]|[1-9]d)|2000).*)' ],
            [ '1801 – 1900',      '(.*(18(0[1-9]|[1-9]d)|1900).*)' ],
            [ '1701 – 1800',      '(.*(17(0[1-9]|[1-9]d)|1800).*)' ],
            [ '1601 – 1700',      '(.*(16(0[1-9]|[1-9]d)|1700).*)' ],
            [ '1501 – 1600',      '(.*(15(0[1-9]|[1-9]d)|1600).*)' ],
            [ '1401 – 1500',      '(.*(14(0[1-9]|[1-9]d)|1500).*)' ],
            [ '1301 – 1400',      '(.*(13(0[1-9]|[1-9]d)|1400).*)' ],
            [ '— Territorien —',  null ],
            [ '1567 – 1604',      '((15(6[7-9]|[7-9]d))|(160(0-4)))' ],
            [ '1604 – 1806',      '((16(0[4-9]|[1-9]d))|(180(0-6)))' ],
            [ '— Sonstiges —',    null ],
            [ 'bis 1574',         '(15([0-6]d|7[0-4]))' ],
        ]
    };

    /**
     * Creates and adds a <select> tag with <option> tags under the search input field.
     */
    function addFilterSelectTagToDOM( jWrapper, tableID ){

        let filterSelectTag = '';

        // build <option> tags
        let options = FILTER_INFO[tableID].options;
        for (let i = 0; i < options.length; i++) {

            var optionValue = options[i][0];
            var optionAttributes = (options[i][1] !== null)
                ? ' value="' + options[i][1] + '"'
                : ' disabled="disabled"'
                ;

            filterSelectTag += '<option' + optionAttributes + '>' + optionValue + '</option>';
        }

        filterSelectTag = '<select>' + filterSelectTag + '</select>';

        // append HTML
        jWrapper.find('.dataTables_filter').after(
            '<div' +
                ' class="predefined-filter"' +
                ' style="clear: both; display: block; text-align: right;"' +
            '>' +
                FILTER_INFO[tableID].filterTitle + filterSelectTag +
            '</div>'
        );

        let jSelect = jWrapper.find('.predefined-filter select');
        return jSelect;
    }

    /**
     * See: 
     */
    function setSearchTableCallbacks( tableID, jInput, jSelect ){

        // Search Input field key down => set select option 0
        jInput.keydown( function(){
            jSelect.prop('selectedIndex', 0).change();
        });

        // Search Input field key down => run search (will be triggered ALREADY)
        //jInput.keyup( function(){ ... });

        // Option click => empty input field
        jSelect.find('option').click( function(){
            jInput.val('').keyup();
        });

        // Option change => run search
        jSelect.change( function(){
            return function(){
                let info = FILTER_INFO[tableID];
                let jTable =  $('#tablepress-' + tableID);
                let filterValue = $(this).children(":selected").val();

                if (info.filterColIdx < 0)// search all columns
                    jTable
                        .DataTable()
                        .search( filterValue, info.searchRegex, info.searchSmart )
                        .draw()
                        ;
                else
                   jTable
                        .DataTable()
                        .column( info.filterColIdx )// searches within this column only
                        .search( filterValue, info.searchRegex, info.searchSmart )
                        .draw()
                        ;
            };
        }());
    }

    /**
     * 
     */
    function main() {
        for (let tableID in FILTER_INFO){
            if (FILTER_INFO.hasOwnProperty(tableID)) {
    
                let jWrapper = $('#tablepress-' + tableID + '_wrapper');
                if (jWrapper.length) {

                    let jInput = jWrapper.find('.dataTables_filter > label > input[type="search"]');
                    let jSelect = addFilterSelectTagToDOM( jWrapper, tableID );

                    setSearchTableCallbacks( tableID, jInput, jSelect );
                }
            }
        }
    }

    main();
});

Se você encontrar uma solução para filtrar as colunas 2 a n-1: me avise.

Sobre isso e bom fim de semana ? Sascha

(@tobiasbg)

3 anos, 3 meses atrás

Olá Sasha,

legais! Não é assim ().search() você faz uma pesquisa em várias colunas? O código de exemplo está lá table.column( [0, 1] ).search( 'Fred' ).draw(); mencionado nele.

Abraços, Tobias

(@sesselschwitzer)

3 anos, 3 meses atrás

Olá Tobias,

isso é tudo! Muito obrigado.

Observação: Outra vantagem de usar a API DataTable é que as expressões regulares ficam completamente ocultas do usuário: o campo de entrada de pesquisa não será preenchido de acordo com os termos de pesquisa selecionados.

Novamente o código. Agora com uma breve descrição da estrutura de dados. Elimine um bug.

/*
    FILTER_INFO['table-id-example'] = {
        filterTitle: 'Predef. Search:<br/>', // String (required):  Title. May be empty.
        searchColumns: [ ]                   // Int    (required):  Default col filter index array.
                                             //                     [ ] := filter all columns
        searchRegex: false,                  // Bool   (required):  Default search regex
        searchSmart: true,                   // Bool   (required):  Default search smart
        options: [                           // Array  (required)
            {
                name: 'name',                // String (required):  Option name
                value: 'value',              // String (optional):  Option value. If not set this option will be disabled => "delimiter".
                searchColumns: '-1',         // Int    (optional):  Overwrites default searchColumns
                searchRegex: false,          // Bool   (optional):  Overwrites default searchRegex
                SearchSmart: true            // Bool   (optional):  Overwrites default searchSmartt
            },
// more options
//          { ... }
//          { ... }
        ]
    };
*/

jQuery(document).ready(function($) {

    const FILTER_INFO = [];

    FILTER_INFO['Dokumente_Lexika_Bauwerke'] = {
        filterTitle: 'Vordefinierte Suche:<br/>',
        searchColumns: [ 0 ],// -1 := filter all columns
        searchRegex: false,
        searchSmart: true,
        options: [
            { name: '[Keine]',          value: '' },
            { name: '— Orte —' },
            { name: 'Alsfeld',          value: 'Alsfeld,' },
            { name: 'Altenburg',        value: 'Altenburg,' },
            { name: 'Angenrod',         value: 'Angenrod,' },
            { name: 'Berfa',            value: 'Berfa,' },
            { name: 'Billertshausen',   value: 'Billertshausen,' },
            { name: 'Eifa',             value: 'Eifa,' },
            { name: 'Elbenrod',         value: 'Elbenrod,' },
            { name: 'Eudorf',           value: 'Eudorf,' },
            { name: 'Fischbach',        value: 'Fischbach,' },
            { name: 'Hattendorf',       value: 'Hattendorf,' },
            { name: 'Heidelbach',       value: 'Heidelbach,' },
            { name: 'Leusel',           value: 'Leusel,' },
            { name: 'Liederbach',       value: 'Liederbach,' },
            { name: 'Lingelbach',       value: 'Lingelbach,' },
            { name: 'Münch-Leusel',     value: 'Münch-Leusel,' },
            { name: 'Reibertenrod',     value: 'Reibertenrod,' },
            { name: 'Schwabenrod',      value: 'Schwabenrod,' },
            { name: '— Bauwerke —' },
            { name: 'Regionalmuseum',   value: 'Regionalmuseum', searchColumns: [ 1 ] },
            { name: '— Sonstiges —' },
            { name: 'Routen',           value: 'Route',          searchColumns: [ 1 ] },
        ]
    };
    FILTER_INFO['Dokumente_Lexika_Personen_Buergermeister'] = {
        filterTitle: 'Vordefinierte Suche:<br/>',
        searchColumns: [ 1 ],//-1 := filter all columns
        searchRegex: true,
        searchSmart: true,
        options: [
            { name: '[Keine]',          value: '' },
            { name: '— Jahrhunderte —' },
            { name: '2001 – 2100',      value: '(.*(20(0[1-9]|[1-9]d)|2100).*)' },
            { name: '1901 – 2000',      value: '(.*(19(0[1-9]|[1-9]d)|2000).*)' },
            { name: '1801 – 1900',      value: '(.*(18(0[1-9]|[1-9]d)|1900).*)' },
            { name: '1701 – 1800',      value: '(.*(17(0[1-9]|[1-9]d)|1800).*)' },
            { name: '1601 – 1700',      value: '(.*(16(0[1-9]|[1-9]d)|1700).*)' },
            { name: '1501 – 1600',      value: '(.*(15(0[1-9]|[1-9]d)|1600).*)' },
            { name: '1401 – 1500',      value: '(.*(14(0[1-9]|[1-9]d)|1500).*)' },
            { name: '1301 – 1400',      value: '(.*(13(0[1-9]|[1-9]d)|1400).*)' },
//            { name: '— Territorien —' },
//            { name: '1567 – 1604',      value: '(.*((15(6[7-9]|[7-9]d))|(160(0-4))).*)' },
//            { name: '1604 – 1806',      value: '(.*((16(0[4-9]|[1-9]d))|(17dd)|(180[0-6])).*)' },
//            { name: '— Sonstiges —' },
//            { name: 'bis 1574',         value: '(.*((13dd|14dd)|(15([0-6]d|7[0-4])).*))' },
        ]
    };

    /**
     * Creates and adds a <select> tag with <option> tags under the search input field.
     */
    function addFilterSelectTagToDOM( jWrapper, tableID ){

        let filterSelectTag = '';

        // build <option> tags
        let options = FILTER_INFO[tableID].options;
        for (let i = 0; i < options.length; i++) {

            let optionValue = options[i].name;
            let optionAttributes = (options[i].hasOwnProperty('value'))
                ? ' value="' + options[i].value + '"'
                : ' disabled="disabled"'
                ;

            filterSelectTag += '<option' + optionAttributes + '>' + optionValue + '</option>';
        }

        filterSelectTag = '<select>' + filterSelectTag + '</select>';

        // append HTML
        jWrapper.find('.dataTables_filter').after(
            '<div' +
                ' class="predefined-filter"' +
                ' style="clear: both; display: block; text-align: right;"' +
            '>' +
                FILTER_INFO[tableID].filterTitle + filterSelectTag +
            '</div>'
        );

        let jSelect = jWrapper.find('.predefined-filter select');
        return jSelect;
    }

    /**
     * See: 
     *      ().search()
     */
    function setSearchTableCallbacks( tableID, jInput, jSelect ){

        // Search Input field key down => set select option 0
        jInput.keydown( function(){
            if (jSelect.prop('selectedIndex') != '0')
                jSelect.prop('selectedIndex', '0').change();
        });

        // Search Input field key down => run search (will be triggered ALREADY)
        //jInput.keyup( function(){ ... });

        // Option change => run search
        jSelect.change( function(){
            return function(){
                let info = FILTER_INFO[tableID];
                let option = info.options[ jSelect.prop('selectedIndex') ];
                
                // use specifix option property or default options property
                let searchColIdx = option.hasOwnProperty('searchColumns') ? option.searchColumns : info.searchColumns;
                let searchRegex  = option.hasOwnProperty('searchRegex')     ? option.searchRegex     : info.searchRegex;
                let searchSmart  = option.hasOwnProperty('searchSmart')     ? option.searchSmart     : info.searchSmart;

                let jTable = $('#tablepress-' + tableID);
                let filterValue = $(this).children(":selected").val();

                if (searchColIdx.length > 0)// search single columns
                    jTable
                        .DataTable()
                        .search( '' )// remove global columns filter (empties search input field, too)
                        .columns( searchColIdx )// search within single column only
                        .search( filterValue, searchRegex, searchSmart )
                        .draw()
                        .search( '' )// remove single columns filter (but do NOT redraw table)
                        ;
                else// search all columns
                    jTable
                        .DataTable()
                        .search( filterValue, searchRegex, searchSmart )
                        .draw()
                        .search( '' )// remove global columns filter (but do NOT redraw table)
                        ;
            };
        }());
    }

    /**
     * 
     */
    function main() {
        for (let tableID in FILTER_INFO){
            if (FILTER_INFO.hasOwnProperty(tableID)) {
    
                let jWrapper = $('#tablepress-' + tableID + '_wrapper');
                if (jWrapper.length) {

                    let jInput = jWrapper.find('.dataTables_filter > label > input[type="search"]');
                    let jSelect = addFilterSelectTagToDOM( jWrapper, tableID );

                    setSearchTableCallbacks( tableID, jInput, jSelect );
                }
            }
        }
    }

    main();
});

Tudo o que Sascha quer

(@tobiasbg)

3 anos, 3 meses atrás

Olá,

legais! Bom saber que isso ajudou!

Tudo de bom, Tobias

Isto foi útil?

0 / 0

Deixe uma resposta 0

O seu endereço de email não será publicado. Campos obrigatórios são marcados *