Non-specific search filter

Asked

Viewed 74 times

0

I have a page with a search filter with the options "service", "state" and "city" and a Ubmit button that redirects to the page where a table will appear with already filtered entries.

But currently the filter works only if the three options are filled limiting the user to search for a service only if looking together the state and the city, and the goal is that he is not obliged to fill the three options of the filter, being able to see all the services of the city, for example.

This is the page with the filter:

<?php require_once("_topo.php"); ?>

<?php
    $link = mysqli_connect("localhost", "root", "", "db_qualquer");
    //Verificar se está sendo passado na URL a página atual, senao é atribuido a pagina 
    $pagina = (isset($_GET['pagina']))? $_GET['pagina'] : 1;

    $result_serv = "SELECT * FROM teste WHERE permicao = 'sim' ORDER BY servico";
    $resultado_serv = mysqli_query($link, $result_serv);
    $result_servN = "SELECT * FROM teste WHERE permicao = 'sim' ORDER BY id DESC";
    $resultado_servN = mysqli_query($link, $result_servN);
    //Contar o total de serv
    $total_serv = mysqli_num_rows($resultado_serv);

    //Seta a quantidade de cursos por pagina
    $quantidade_pg = 10;

    //calcular o número de pagina necessárias para apresentar os cursos
    $num_pagina = ceil($total_serv/$quantidade_pg);

    //Calcular o inicio da visualizacao
    $incio = ($quantidade_pg*$pagina)-$quantidade_pg;

    //Selecionar os cursos a serem apresentado na página
    $result_serv = "SELECT * FROM teste limit $incio, $quantidade_pg";
    $resultado_serv = mysqli_query($link, $result_serv);
    $total_serv = mysqli_num_rows($resultado_serv);

?>

<?php 
    require 'conexao.php';
    $queryServicos = mysqli_query ($link, "SELECT DISTINCT servico FROM teste ORDER BY servico"); 
    $id           = $_POST["id"];
    $serv       = $_POST["servico"];

?>
        <div class="container">
            <table class="table table-bordered">
                <form action="teste-busca.php" method="POST">
                    <div class="form-group col-md-3">
                        <div class="input-group">
                          <span class="input-group-addon">Serviço:</i></span>
                          <select name="servico" id="servico" class="form-control">
                            <option>Selecione...</option>
                            <!-- PEGA OS SERVIÇOS DO BANCO DE DADOS E COLOCA NO OPTION -->
                                <?php while($serv = mysqli_fetch_array($queryServicos)) { ?> 
                                <option value="<?php echo $serv['servico']; ?>"><?php echo $serv['servico']; ?></option>
                                <?php } ?>
                             -->
                          </select>
                        </div>
                    </div>
                    <div class="form-group col-md-3">
                    <div class="input-group">
                      <span class="input-group-addon">Estado:</i></span>
                      <select name="estado" id="estados" class="form-control">
                      </select>
                    </div>
                </div>
                    <div class="form-group col-md-3">
                    <div class="input-group">
                      <span class="input-group-addon">Cidade:</i></span>
                      <select name="cidade" id="cidades" class="form-control">
                        <option value="none">Selecione um estado</option>
                      </select>
                    </div>
                </div>
                <div>
                    <button class="btn btn-primary col-md-1">Buscar</button>
                </div>
                </form>

            <!-- Aqui a tabela é criada -->
        </div>
    </header>
</body>
</html>

This is the page redirected by the search filter:

<?php
    $link = mysqli_connect("localhost", "root", "", "db_qualquer");
    //Verificar se está sendo passado na URL a página atual, senao é atribuido a pagina 
    $pagina = (isset($_GET['pagina']))? $_GET['pagina'] : 1;

    $result_serv = "SELECT * FROM teste";
    $resultado_serv = mysqli_query($link, $result_serv);
    //Contar o total de serv
    $total_serv = mysqli_num_rows($resultado_serv);

    //Seta a quantidade de cursos por pagina
    $quantidade_pg = 10;

    //calcular o número de pagina necessárias para apresentar os cursos
    $num_pagina = ceil($total_serv/$quantidade_pg);

    //Calcular o inicio da visualizacao
    $incio = ($quantidade_pg*$pagina)-$quantidade_pg;

    //Selecionar os cursos a serem apresentado na página
    $result_serv = "SELECT * FROM teste limit $incio, $quantidade_pg";
    $resultado_serv = mysqli_query($link, $result_serv);
    $total_serv = mysqli_num_rows($resultado_serv);

?>
<?php 
    require 'conexao.php';
?>

<!-- - - - - - Isso aqui é o filtro - - - - - - - - - -->
<?php
    error_reporting(E_ERROR | E_PARSE);
    $lnk = mysqli_connect('localhost','root','') or die(mysqli_error()) or die ('Nao foi possível conectar ao MySql: ' . mysqli_error($lnk));
    mysqli_select_db($lnk,'db_qualquer') or die ('Nao foi possível ao banco de dados selecionado no MySql: ' . mysqli_error($lnk));
    //require("conexao.php")

    $sql = 'SELECT * FROM teste ORDER BY servico, estado, cidade ASC';
    $servico = $_POST['servico'];
    $estado = $_POST['estado'];
    $cidade = $_POST['cidade'];

    if(!is_null($servico) && !empty($servico)) 
        $sqli = "SELECT * FROM teste WHERE servico LIKE '%".$servico."%' AND estado LIKE '%".$estado."%' AND cidade LIKE '%".$cidade."%'";

    $qry = mysqli_query($lnk, $sqli) or die(mysqli_error($lnk));
    $count = mysqli_num_rows($qry);
    $num_fields = mysqli_num_fields($qry);//Obtém o número de campos do resultado
    //$fields[] = array();
    if($num_fields > 0) {
        for($i = 0;$i<$num_fields; $i++){//Pega o nome dos campos
            $fields[] = mysqli_fetch_field_direct($qry,$i)->name;
        }
    } 
?> 

<!-- - - - - - Tabela com as buscas- - - - - - -->
<table class="table table-bordered"> <tr>
<tr>
    <th>Nome</th>
    <th>Serviço</th>
    <th class="no-responsive">Cidade</th>
    <th>Visualizar</th>
</tr>
<?php
    for($i = 0;$i < $num_fields; $i++){
        $table .= '<th>'.$fields[$i].'</th>';
    }
    while($row = mysqli_fetch_array($qry)){
    $table .= '<tr>';
    for($i = 0;$i < $num_fields; $i++){
        $table .= '<td>'.$r[$fields[$i]].'</td>';
    }
    ?>
<tr>
        <td><?=$row['nome'];?></td>
        <td><?=$row['servico'];?></td>
        <td class="no-responsive"><?=$row['cidade'];?></td>
        <td><a href="visualiza.php?id=<?=$row['id'];?>" class="btn btn-primary">Visualizar</a></td>
</tr>
        <?php    }?>
</table>

<?php

$table .= '<tbody>';
while($r = mysqli_fetch_array($qry)){
    $table .= '<tr>';
    for($i = 0;$i < $num_fields; $i++){
        $table .= '<td>'.$r[$fields[$i]].'</td>';
    }
}
?>
</nav>
</body>
</html>

NOTE: In case the user could choose or see all the records with that service or view all records with that record and state and city, once once filled my state, it automatically already fills the city based on a json that I use. :/

I’ve tried to exchange AND for OR but it doesn’t work if you choose only two of the three filters for example. You can make sure you don’t have to fill in all the options using the filter I already have?

Here I tried to use the filter of one of the answers, but gave that the page was not working:

<?
    error_reporting(E_ERROR | E_PARSE);
    $lnk = mysqli_connect('localhost','root','') or die(mysqli_error()) or die ('Nao foi possível conectar ao MySql: ' . mysqli_error($lnk));
    mysqli_select_db($lnk,'db_qualquer') or die ('Nao foi possível ao banco de dados selecionado no MySql: ' . mysqli_error($lnk));



    $sql = 'SELECT * FROM teste ORDER BY servico, estado, cidade ASC';
    $servico = isset($_POST['servico']) ? $_POST['servico'] : null;
    $estado = isset($_POST['estado']) ? $_POST['estado'] : null;
    $cidade = isset($_POST['cidade']) ? $_POST['cidade'] : null;
    $arrParams = [];

    $sqli = "SELECT * FROM teste WHERE ";
    if(!is_null($servico) && !empty($servico)){
        $arrParams[] = [
            'filter' => 'servico',
            'value' => $servico
        ];
    }
    if (!is_null($estado) && !empty($estado)) {
        $arrParams[] = [
            'filter' => 'estado',
            'value' => $estado
        ];
    }
    if (!is_null($cidade) && !empty($cidade)) {
        $arrParams[] = [
            'filter' => 'cidade',
            'value' => $cidade
        ];
    }
    $cont = 1;
    $total = count($arrParams);
    foreach($arrParams as $param){

        $sqli .= $param['filter'] . " LIKE '%".$param['value']."%'";
        if ($total > 1 && $cont != $total) {
            $sqli.= "AND ";
        }
        $cont ++;
    }
    $qry = mysqli_query($lnk, $sqli) or die(mysqli_error($lnk));
    $count = mysqli_num_rows($qry);
    $num_fields = mysqli_num_fields($qry);//Obtém o número de campos do resultado
    //$fields[] = array();
    if($num_fields > 0) {
        for($i = 0;$i<$num_fields; $i++){//Pega o nome dos campos
            $fields[] = mysqli_fetch_field_direct($qry,$i)->name;
        }
    } 
?>

2 answers

1

You can solve this way by breaking the sql into parts:

$servico = isset($_POST['servico']) ? $_POST['servico'] : null;
$estado = isset($_POST['estado']) ? $_POST['estado'] : null;
$cidade = isset($_POST['cidade']) ? $_POST['cidade'] : null;
$arrParams = [];

$sqli = "SELECT * FROM teste WHERE ";
if(!is_null($servico) && !empty($servico)){
    $arrParams[] = [
        'filter' => 'servico',
        'value' => $servico
    ];
}
if (!is_null($estado) && !empty($estado)) {
    $arrParams[] = [
        'filter' => 'estado',
        'value' => $estado
    ];
}
if (!is_null($cidade) && !empty($cidade)) {
    $arrParams[] = [
        'filter' => 'cidade',
        'value' => $cidade
    ];
}
$cont = 1;
$total = count($arrParams);
foreach($arrParams as $param){

    $sqli .= $param['filter'] . " LIKE '%".$param['value']."%'";
    if ($total > 1 && $cont != $total) {
        $sqli.= "AND ";
    }
    $cont ++;
}
$qry = mysqli_query($lnk, $sqli) or die(mysqli_error($lnk));
$count = mysqli_num_rows($qry);
$num_fields = mysqli_num_fields($qry);//Obtém o número de campos do resultado
//$fields[] = array();
if($num_fields > 0) {
    for($i = 0;$i<$num_fields; $i++){//Pega o nome dos campos
        $fields[] = mysqli_fetch_field_direct($qry,$i)->name;
    }
}
  • 1

    It is a good suggestion, but ends up working in the same way, only with all filters filled. :/

  • Do you want to search only by city and state too? service is not mandatory?

  • 1

    I edited for everyone to be independent

  • I tried to use this filter (which is very well structured by the way) and gave that the page is not working. I’ll edit my question to show you how I put it.

  • Mariana, try printing the final result of the variable before it is executed and see if it is being mounted correctly. and if possible report the error, here worked

1

Mariana see if this helps you:

$where = '';
$whereFiltro = array();
$filtroConsulta = '';

if(!is_null($servico) && !empty($servico))
{
   $whereFiltro[] = "servico LIKE '%{$servico}%'";
}

if(!is_null($estado) && !empty($estado))
{
   $whereFiltro[] = "estado LIKE '%{$estado}%'";
}

if(!is_null($cidade) && !empty($cidade))
{
  $whereFiltro[] = "cidade LIKE '%{$cidade}%'";
}

//quebra o array para string e coloca o AND
if (count($whereFiltro) > 0)
{
   $where = implode("\n AND ", $whereFiltro);
}

if(strlen($where) > 0)
{
   $filtroConsulta = "WHERE " . $where;
} 

$sqli = "SELECT * FROM teste {$filtroConsulta}";

implode

strlen

Browser other questions tagged

You are not signed in. Login or sign up in order to post.