filtrar contenido con jquery

Iniciado por gAb1, 16 Noviembre 2015, 06:11 AM

0 Miembros y 1 Visitante están viendo este tema.

gAb1

Tengo una función con JQuery Ajax que recibe contenido de PHP enviado variables, depende de las variables y el contenido de estas se recibiran unas cosas u otras.

Con la misma función (un on('click')) tengo que declarar y asignar valores a las variables que se envian, dandoles el valor del elemento que hizo click, mayormente checkboxes.

Lo único que se me ocurre es hacer un if para cada checkbox:

Código (javascript) [Seleccionar]
if ($(this).is(':checkbox') {
   //comprobar la clase del checkbox para saber que datos enviar
   if ($(this).attr('class') == 'filter1') {
       var filtro1 = $(this).val();
   }
   if ($(this).attr('class') == 'filter2') {
       var filtro2 = $(this).val();
   }
   if ($(this).attr('class') == 'filter3') {
       var filtro3 = $(this).val();
   }
}

Y asi sucesivamente... ¿Hay alguna manera más eficiente de hacer esto? Tambien tengo que comprobar que si se han checkeado dos checkboxes o mas de la misma clase se envien los valores como array o algo. Agradeceria cualquier ejemplo.

PHP se encarga del resto, de crear los condicionales "AND" y agregarlos al "SELECT" de la consulta mysqli.

Gracias!

MinusFour

No es necesario que guardes los valores en variables, al final la información tiene que ser serializada y jQuery tiene un metodo para eso.

gAb1

#2
Pues entonces lo he estado haciendo mal, aunque funcionando:

Código (javascript) [Seleccionar]
    $('body').on('click', '.click, :checkbox, .pag_link', function() { // search, filters and change page buttons

        var self = this;

        if ($('#res_prop').is(':checked')) {
            var use = $('#res_prop').val();
        }
        else if ($('#com_prop').is(':checked')) {
            var use = $('#com_prop').val();
        }
        else {
            $('p.error').show();
            die();
        }

        if ($(self).is(':checkbox')) {
            $(self).on('change', function() {
                if ($(self).attr('class') == 'filter1' || $('.filter1').is(':checked')) {
                    if ($('.filter1').is(':checked'))
                        var type = $(self).val(); // maybe should be an array
                    else var type = null;
                } else var type = null;
                if ($(self).attr('class') == 'filter2' || $('.filter2').is(':checked')) {
                    if ($('.filter2').is(':checked'))
                        var status = $(self).val(); // maybe should be an array
                    else var status = null;
                } else var status = null;
                if ($(self).attr('class') == 'filter3' || $('.filter3').is(':checked')) {
                    if ($('.filter3').is(':checked'))
                        var bhk = $(self).val(); // maybe should be an array
                    else var bhk = null;
                } else var bhk = null;
            });
        }
        else {
            var type = status = bhk = null;
        }

        if ($(self).is('.pag_link')) {
            if ($(self).text() == '«')
                var page = (parseInt($('.active').text()) - 1);
            else if ($(self).text() == '»')
                var page = (parseInt($('.active').text()) + 1);
            else
                var page = parseInt($(self).text());
        }
        else {
            var page = 1;
        }

        $.ajax({
            method: 'POST',
            url: '/search',
            data: {
                'do': getUrlParameter('do'),
                'use': use,
                'type': type,
                'status': status,
                'bhk': bhk,
                'city': $('select[name="city"]').val(),
                'zone': $('select[name="zone"]').val(),
                'page': page
            }
        }).done(function(data) {
            if ($( '#search' ).is(':visible'))
                $( '#search' ).hide();

            if ($(self).is(':checkbox')) {
                var new_content = $(data).find( '#scroll-to-list' );
                $( '#scroll-to-list' ).replaceWith( new_content );
            }
            else {
                var new_content = $(data).find( '#search-filters, #scroll-to-list' );
                $( '#results' ).html( new_content );
                $( 'html, body' ).animate({
                    scrollTop: $( '#scroll-to-list' ).offset().top
                }, 1000);
            }

        });
    });


No entiendo bien para que es necesario codificar estos datos, ¿es necesario hacerlo?

Realmente necesito aprender a reducir el código...

MinusFour

Código (javascript) [Seleccionar]

var data = $('input[class^="filter"]')
.add('select[name="city"]')
.add('select[name="zone"]').serializeArray();

//para agregar nuevos pares:
//data.push({ name : 'nombre', value : 'valor'});
$.ajax({
    method: 'POST',
    url: '/search',
    data: $.param(data)
}).done(function (data) {
    if ($('#search').is(':visible')) $('#search').hide();
    if ($(self).is(':checkbox')) {
        var new_content = $(data).find('#scroll-to-list');
        $('#scroll-to-list').replaceWith(new_content);
    } else {
        var new_content = $(data).find('#search-filters, #scroll-to-list');
        $('#results').html(new_content);
        $('html, body').animate({
            scrollTop: $('#scroll-to-list').offset().top
        }, 1000);
    }
});


Si "use" puede ser "#res_prop" o "#com_prop" entonces el control debería ser un radio button.

Código (html5) [Seleccionar]

<input type="radio" name="use">
<input type="radio" name="use">


Los filtros tambien deberían tener los nombres(el atributo name) de tus variables (bhk, type, status). Es muy probable que necesites agregar page y do manualmente. (Lee el comentario que puse).

gAb1

Si, estoy usando radio button para esos dos id.

¿Te refieres a cada checkbox ponerle el atributo name?

$('input[class^="filter"]') Esto añade solo los checkboxes que estén marcados no?

Entonces los ifs que tengo creados no sirven? Como sé que número de página pasar o que valor de los radio button pasar? Para todo en general, como hago eso??

Y luego en php como cojo los datos del post? Actualmente lo estaba haciendo asi:

Código (php) [Seleccionar]
$use            = isset( $_POST['use'] ) ? (int) $_POST['use'] : '';        // int AJAX
$filter_type    = isset( $_POST['type'] ) ? (int) $_POST['type'] : '';      // int AJAX
$filter_status  = isset( $_POST['status'] ) ? (int) $_POST['status'] : '';  // int AJAX
$filter_bhk     = isset( $_POST['bhk'] ) ? (int) $_POST['bhk'] : '';        // int AJAX
$filter_city    = isset( $_POST['city'] ) ? (int) $_POST['city'] : 0;       // int AJAX
$filter_zone    = isset( $_POST['zone'] ) ? (int) $_POST['zone'] : 0;       // int AJAX
$page_number    = isset( $_POST['page'] ) ? (int) $_POST['page'] : '';      // int AJAX


Lo siento, no me entero.

MinusFour


'input[class^="filter"]'


Selecciona todos los inputs con clase que empieze como 'filter' (filter1, filter2, filter3). No te tienes que preocupar si están vacios o no. "serializeArray" debería seleccionar solo los que no esten marcados. De igual forma, necesitas agregar los radios (se serializa el que esta marcado):

Código (javascript) [Seleccionar]

var data = $('input[class^="filter"]')
                        .add('input[name="use"]')
.add('select[name="city"]')
.add('select[name="zone"]').serializeArray();


Mira como trabaja ".serializeArray" con "$.param":

https://jsfiddle.net/19avm4rb/

Para "do" y page puedes hacer lo que ya haces...

gAb1

#6
Ah vale ya lo entiendo mejor. Pero si tengo más de un checkbox con el mismo nombre luego en php como hago? Por ejemplo name type, un checkbox tiene el valor 1 y otro 2, ¿como manejo eso en php? Luego con IFs compruebo si se ha recibido el filtro y incluyo una condición AND al prepare, pero si son dos como hago?

Código (php) [Seleccionar]
$filter_type    = isset( $_POST['type'] ) ? (int) $_POST['type'] : NULL;
if ($filter_type != NULL) {
   $filter_type = 'AND t2.type = ' . $filter_type;
   // si se marcaron dos checkboxes de nombre type, como hago la otra condición OR?
}
if ($stmt = $mysqli->prepare(' SELECT t1.id, t2.*
                              FROM ' . $table . ' t1
                              INNER JOIN property t2 ON t2.id = t1.id
                              WHERE t2.use = ?
                              ' . $filter_type
                                . $filter_status
                                . $filter_bhk
                                . $filter_city
                                . $filter_zone . '
                              LIMIT ?, ?'))


Para do y page usaré lo que me dijiste, el data.push.

Muchas gracias!

EDITO: Ya casi lo tengo:

Código (javascript) [Seleccionar]
$('body').on('click', '.click, :checkbox, .pag_link', function() {

   var self = this;

   if (!$(':radio').is(':checked')) {
       $('p.error').show();
       die();
   }

   var data = $('input, select').serializeArray(),
       mode = getUrlParameter('do'),
       page = 1;

   if ($(self).is('.pag_link')) {
       if ($(self).text() == '«')
           page = (parseInt($('.active').text()) - 1);
       else if ($(self).text() == '»')
           page = (parseInt($('.active').text()) + 1);
       else
           page = parseInt($(self).text());
   }

   data.push({ name : 'do',   value : mode});
   data.push({ name : 'page', value : page});

   $.ajax({
       method: 'POST',
       url: '/search',
       data: $.param(data)
   }).done(function (data) {
       if ($( '#search' ).is(':visible'))
           $( '#search' ).hide();

       if ($(self).is(':checkbox')) {
           var new_content = $(data).find( '#scroll-to-list' );
           $( '#scroll-to-list' ).replaceWith( new_content );
       }
       else {
           var new_content = $(data).find( '#search-filters, #scroll-to-list' );
           $( '#results' ).html( new_content );
           $( 'html, body' ).animate({
               scrollTop: $( '#scroll-to-list' ).offset().top
           }, 1000);
       }

   });
});


¿Se podrá optimizar todavía más? : :)

MinusFour

#7
Cita de: gAb1 en 16 Noviembre 2015, 22:11 PM
Ah vale ya lo entiendo mejor. Pero si tengo más de un checkbox con el mismo nombre luego en php como hago? Por ejemplo name type, un checkbox tiene el valor 1 y otro 2, ¿como manejo eso en php? Luego con IFs compruebo si se ha recibido el filtro y incluyo una condición AND al prepare, pero si son dos como hago?

Suena a que debería ser otro filtro o si es una opción entre 1 y 2 entonces un radio. También puedes tratar los filtros como si fuera un arreglo:

Código (html5) [Seleccionar]

<input type="checkbox" name="filtros[]">
<input type="checkbox" name="filtros[]">


Y desde PHP:

Código (php) [Seleccionar]

$filtros = $_POST['filtros'];
list($filtro1, $filtro2) = $filtros;
//$filtro1 == $filtros[0];
//$filtro2 == $filtros[1];


Aunque $.param transforma los "[]" en el query string, no se si PHP trabaje ese caso.

gAb1

#8
Pues podría ponerlos como radio, pero me gustaría dar la opción de que elijan más de un tipo a la vez.

EDITO: Si que funciona lo de meter arrays en el serializeArray() con el $.param: https://jsfiddle.net/19avm4rb/1/ En PHP se cogen como si fuera un post normal, pero tengo un problema para crear las condiciones OR. La primera (AND) funciona bien, pero ya las demás da error:

Código (php) [Seleccionar]
if ($filter_type != NULL) {
    foreach ($filter_type as $type=>$value) {
        if ($type === 0) {
            $type_cond = 'AND t2.type = ' . $value;
        } else {
            $type_cond .= $type_cond . "\n OR t2.type = " . $value;
        }
    }
}


CitarMySQLi failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't2.type = 2
OR t2.type = 3

                                           LIMIT ?,' at line 5<br><br />

Debe ser un error al crear las variables o al imprimirlas dentro del prepare(), ya que están bien:

Código (sql) [Seleccionar]
SELECT t1.id, t2.*
FROM for_sale t1
INNER JOIN property t2 ON t2.id = t1.id
WHERE t2.use = 1
AND t2.type = 2
OR t2.type = 1
OR t2.type = 3
AND t2.status = 0
OR t2.status = 1
OR t2.status = 2
AND t2.bhk = 3
OR t2.bhk = 1
OR t2.bhk = 2

Algo así es lo que quiero que haga. Lo he ejecutado y funciona perfectamente.

¿Abro mejor una pregunta en el subforo PHP?

eLank0

Buenas,

Una consulta sobre tu código, porqué pones \n dentro de una consulta SQL? No será por ahí que te tira un error?

S2