Pregunta sobre TablePress de Wordpress:

Una columna incluye una tabla / pantalla de la búsqueda a través de JS

Un usuario preguntó 👇

Hola Tobias,

Necesito una tabla con columnas que puedan excluirse parcialmente de la búsqueda solo en casos especiales (en tiempo de ejecución). De lo contrario, se utilizarán todas las columnas visibles.

¿Existe una solución para incluir / excluir una columna específica de una búsqueda usando JS con la API de DataTables? P.ej $(#table-id).dataTableSettings.***.bSearchable = false.

Saludos Sascha

(@tobiasbg)

Hace 3 años, 3 meses

Hola,

gracias por tu publicación y perdón por las molestias.

El uso de la API puede ser una ruta dinámica (debe consultar el sitio web de DataTables), pero la forma más rápida que conozco es poner «Comando personalizado» en la pantalla «Editar» de la tabla, como

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

Saludos, Tobias

(@sesselschwitzer)

Hace 3 años, 3 meses

Hola Tobias,

gracias por tu sugerencia. Pero debería ser dinámico.

Buscaré la manera y te lo haré saber :).

CU Sascha

(@tobiasbg)

Hace 3 años, 3 meses

Hola Sascha,

sí, entonces necesitaría una solución personalizada usando las funciones de la API, supongo …

Saludos, Tobias

(@sesselschwitzer)

Hace 3 años, 3 meses

Hola Tobias,

«DataTable» y «CSS» tienen ventajas y desventajas.

Estaba buscando una solución usando la API de DataTables de ayer pero no pude encontrarla. El siguiente problema es la necesidad de habilitar expresiones regulares.
"search": { "regex": true })
que tiene efectos secundarios no deseados (para mí) y creo que la mayoría de los usuarios no conocen las expresiones regulares.

Finalmente, debido a evitar el uso excesivo, decidí agregar una nueva columna visible (!) Y ocultarla a través de CSS. (ver: https://wordpress.org/support/topic/filtering-and-searching-from-a-hidden-column/). Esta columna contiene términos que las otras columnas no contienen. Estos términos son proporcionados por un control DropDown adicional (ubicado debajo del campo de entrada de búsqueda) y se incluyen en el campo de búsqueda de TablePress.

Véalo en acción: – http://www.regionalmuseum-alsfeld.de/dokumente/lexika/bauwerke/ (actualmente no se requieren columnas ocultas) – http://www.regionalmuseum-alsfeld.de/dokumente/lexika/personen/#Buergermeister (con columna oculta)

Y aquí está el 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 puedas usarlo también :).

Saludos Sascha

(@tobiasbg)

Hace 3 años, 3 meses

Hola Sascha,

¡muy genial! Revisé tu solución brevemente, ¡pero se ve muy bien! ¡Gracias por compartirlo!

Todo lo mejor, Tobias

(@sesselschwitzer)

Hace 3 años, 3 meses

Hola Tobias,

fue un placer. «¡Kost ‘nix!» como sugiere el Hessian superior;).

Saludos Sascha

(@tobiasbg)

Hace 3 años, 3 meses

Hola,

ja, der ist gut 🙂

Viele Grüße, Tobias

(@sesselschwitzer)

Hace 3 años, 3 meses

Hola Tobias,

Este simple enlace respondió a mi pregunta sobre cómo seleccionar las columnas de la tabla para incluir al buscar con expresiones regulares:
https://datatables.net/examples/api/regex.html

Las líneas mágicas:

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

Bueno, parece restringido a buscar una o todas las columnas y nada en el medio pero, en mi caso, está bien.

Genial: – ¡La entrada de búsqueda aún funciona sin regex! – No se requiere columna visible adicional (oculta por CSS)

El 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: https://datatables.net/examples/api/regex.html
     */
    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();
});

Si encuentra una solución para filtrar las columnas 2 a n-1: avíseme.

Sobre eso y que tengas un buen fin de semana 🙂 Sascha

(@tobiasbg)

Hace 3 años, 3 meses

Hola Sascha,

¡bonito! No es asi https://datatables.net/reference/api/columns ().search () ¿haces una búsqueda de varias columnas? El código de muestra está ahí table.column( [0, 1] ).search( 'Fred' ).draw(); mencionado en el mismo.

Saludos, Tobias

(@sesselschwitzer)

Hace 3 años, 3 meses

Hola Tobias,

¡eso es todo! Muchas gracias.

Observación: Otra ventaja de usar la API de DataTable es que las expresiones regulares están completamente ocultas para el usuario: el campo de entrada de búsqueda no se completará de acuerdo con los términos de búsqueda seleccionados.

De nuevo el código. Ahora con una breve descripción de la estructura de datos. Elimina un error.

/*
    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))|(17\d\d)|(180[0-6])).*)' },
//            { name: '— Sonstiges —' },
//            { name: 'bis 1574',         value: '(.*((13\d\d|14\d\d)|(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: https://datatables.net/examples/api/regex.html
     *      https://datatables.net/reference/api/columns().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();
});

Todo lo que Sascha quiere

(@tobiasbg)

Hace 3 años, 3 meses

Hola,

¡bonito! ¡Es bueno saber que esto ayudó!

Todo lo mejor, Tobias

¿Solucionó tu problema??

0 / 0

Deja una respuesta 0

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *