JQuery Ajax实时搜索两个字段 - 输入并选择

时间:2017-03-20 09:50:07

标签: javascript php jquery mysql ajax

我能够在输入字段上进行jQuery AJAX实时搜索,并返回我想要的结果。现在我想在两个字段上进行复合搜索。

这就是我所拥有的,但它没有工作或返回任何错误:

表格

<div class="form-group">
   <div class="input-group">
      <span class="input-group-addon">Name</span>
      <input class="form-control" type="text" name="searchName" id="searchName" placeholder="Search by name">

      <span class="input-group-addon">Class</span>
      <select name="current_class" id="current_class" class="form-control">

       ## I populate my list from the database using php
       <?php 
            $sql = "SELECT * from classes";

               if ($result = mysqli_query($connection, $sql)){
                   if(mysqli_num_rows($result) > 0){
                       while ($row = mysqli_fetch_array($result)){
                       echo "<option value=\"{$row['class_id']}\"
                            {$row['class_name']} </option>";
                       }
                    }
               }
         ?>
      </select>
    </div>

   ##results are displayed
   <div id="result"></div>
   <div>

脚本

<script>
     $(document).ready(function(){
         $('#searchName').keyup(function(){
            var name = $('#searchName').val();
            var current_class = $('#current_class').val();
          if (name != '' || current_class != '') {
             $.ajax({
                url:"fetch2.php",
                method:"post",
                data:{searchName:name, current_class:current_class},
                dataType:"text",
                success:function(data){
                    $("#result").html(data);
                }
            });
         } else {
            $("#result").html('');
         }   
      });

      $('#current_class').keyup(function(){
            var name = $('#searchName').val();
            var current_class = $('#current_class').val();
          if (name != '' || current_class != '') {
             $.ajax({
                url:"fetch2.php",
                method:"post",
                data:{searchName:name, current_class:current_class},
                dataType:"text",
                success:function(data){
                    $("#result").html(data);
                }
            });
         } else {
            $("#result").html('');
         }   
      });
    });
</script>

在fetch2.php中查询

$search_name = $_POST['searchName'];
$search_class = $_POST['current_class'];

$select__args = array();
$from__args = array();
$where__args = array("1=1");

$select__args[] = "student_id";
$from__args[] = "students";
$where__args[] = "(CONCAT(first_name,' ',surname) LIKE '%{$search_name}%')";

if($search_class != ''){
    $where__args[] = "current_class_id like '%{$search_class}%'";
}

$select_clause = implode(", ", $select__args);
$from_clause = implode(",", $from__args);
$where_clause = "(" . implode(") AND (", $where__args) . ")";

$query = "SELECT {$select_clause} FROM {$from_clause} WHERE {$where_clause}";

我在这里缺少什么?我想要的是通过名称或类在两个字段上进行实时搜索。如果有两(2)名学生的名字是:&#39; Nathan Siafa&#39;但是在两(2)个不同的班级(1年级和2年级)我将不得不按名称和班级进行搜索。这不是我得到的结果。

更新

我已更改我的代码以匹配@ maksbd19的答案。它对我有点影响,但我没有得到我想要的预期结果(在两个领域的实时搜索体验)。我刚刚意识到可能还有其他问题。防爆。如果有两个学生 - John Amos Doe John James Doe 和班级(9年级和10年级)。我意识到,如果搜索John Amos Doe,他的班级是9年级,那就可以正常工作并返回正确的记录,但如果我现在想要John James Doe的班级是10年级的记录,我会得到John Amos Doe的记录(注意:我的查询按姓氏和名字搜索)。

我添加了一个单独的字段来区分记录。现在有了@ maksbd19,如果我想要John James Doe的记录和搜索是&#34; John Doe&#34;我仍然得到了#Am; Doos Doe&#34;即使我为#34; John James Doe&#34;在类字段中它保持不变。

我获得精确记录的方式是为#34; John James Doe&#34;放置并假装删除我当前的搜索值&#34; John Doe&#34;它的工作原理。对我来说,它就像ajax只是在名字字段上进行实时搜索。

注意:在我的应用程序中不需要中间名,这就是我没有尝试对其执行查询的原因,但有没有办法可以利用搜索的强大功能通过学生的全名(第一,中,最后)即使并非所有学生都有中间名?

更新2

根据我在这里的代码,我设法让实时搜索工作在两(2)个字段中。我现在的问题是我的桌子里有两(2)名学生 - &#39; John Amos Doe(10年级)&#39;和John Lewis Doe(9年级)&#39;。如果我用名字搜索他们的特定类,它会返回所需的结果。

如果我搜索John Doe&#39;它带来了John Amos Doe&#39;例如,如果我现在想要John Lewis Doe&#39;记录我必须在类字段中输入精确的类(9级),它不会返回任何内容。

我还尝试在搜索查询中包含中间名但无济于事。 这是我尝试的方式:

$where__args[] = "(CONCAT(first_name,' ',middle_name,' ',surname) LIKE '%{$search_name}%') OR (CONCAT(first_name,' ',surname) LIKE '%{$search_name}%')";

1 个答案:

答案 0 :(得分:1)

如果我没弄错的话,你会得到预期的结果。让我解释一下。

在你的表单中,ajax函数没问题,只是在服务器中传输值并返回查询结果。我认为你需要优化你的mysql查询。

在您的查询中,有三个OR条件,其结果将返回任何匹配的任何内容。

  student_id      current_class_id       first_name          last_name
---------------+---------------------+------------------+-----------------
     1         |          1          |       Emma       |       Stone
---------------+---------------------+------------------+-----------------
     2         |          1          |       Emma       |       Roberts
---------------+---------------------+------------------+-----------------
     3         |          2          |       Emma       |       Watson
---------------+---------------------+------------------+-----------------
     4         |          3          |       Julia      |       Roberts
---------------+---------------------+------------------+-----------------
     5         |          3          |       Jane       |       Smith
---------------+---------------------+------------------+-----------------
     6         |          1          |       John       |       Roberts
---------------+---------------------+------------------+-----------------

让我们检查一下这个样本数据。

假设您在名称字段中键入Jane且未选择类ID。您的mysql查询将查找与您使用连接的first_name和last_name last_name 键入的名称匹配的学生ID。由于您已经连接了两个名称,因此可以省略最后一个名称或将两者分开。

$query = "SELECT student_id FROM students WHERE CONCAT(first_name,' ',surname) LIKE '%{$search_name}%'";

$query = "SELECT student_id FROM students WHERE first_name LIKE '%{$search_name}%' OR surname LIKE '{%$search_name}%'"

使用其中之一,两者都会产生相同的结果。

注意:如果您要搜索Emma Roberts,则查询可能如下 -

$query = "SELECT student_id FROM students WHERE CONCAT(first_name,' ',surname) LIKE '%{$search_name}%' OR first_name LIKE '%{$search_name}%' OR surname LIKE '{%$search_name}%'"

通过这种方式,您可以告诉mysql将第一个,最后一个或整个名称与数据库匹配。

允许搜索 Emma (区分大小写)

  student_id      current_class_id       first_name          last_name
---------------+---------------------+------------------+-----------------
     1         |          1          |       Emma       |       Stone
---------------+---------------------+------------------+-----------------
     2         |          1          |       Emma       |       Roberts
---------------+---------------------+------------------+-----------------
     3         |          2          |       Emma       |       Watson
---------------+---------------------+------------------+-----------------

Roberts

  student_id      current_class_id       first_name          last_name
---------------+---------------------+------------------+-----------------
     2         |          1          |       Emma       |       Roberts
---------------+---------------------+------------------+-----------------
     4         |          3          |       Julia      |       Roberts
---------------+---------------------+------------------+-----------------
     6         |          1          |       John       |       Roberts
---------------+---------------------+------------------+-----------------

Emma Roberts

  student_id      current_class_id       first_name          last_name
---------------+---------------------+------------------+-----------------
     2         |          1          |       Emma       |       Roberts
---------------+---------------------+------------------+-----------------

现在让我们来看看current_class_id部分的第二个子句。我相信你想在这里进行AND操作。因为搜索艾玛或来自class_id 1 的学生没有任何意义。此搜索应从class_id 1

的学生中搜索Emma
$query = "SELECT student_id FROM students WHERE current_class_id like '%{$search_class}%'";

现在让我们结合使用,以实现您的目标。

$query = "SELECT student_id FROM students WHERE (CONCAT(first_name,' ',surname) LIKE '%{$search_name}%' OR first_name LIKE '%{$search_name}%' OR surname LIKE '{%$search_name}%') AND current_class_id like '%{$search_class}%'";

这基本上告诉mysql在first_name和surname列中查找Emma并且还与特定的current_class_id相关联。

注意

上面的查询示例有一点小问题。如果您在参数中未包含current_class_id,则查询也应省略它。在我的例子中,这些类型的过滤器通常接受大量参数。我喜欢分成不同的部分。

$select_clause = implode(", ", $select__args);
$from_clause = implode(",", $from__args);
$where_clause = "(" . implode(") AND (", $where__args) . ")";
$query = "SELECT {$select_clause} FROM {$from_clause} WHERE {$where_clause}";

然后根据我提供给过滤器脚本的参数,相应地填充这些子句。在您的情况下,您可以拥有以下内容 -

$select__args = array();
$from__args = array();
$where__args = array("1=1"); // this is necessary because when this array is going to be imploded then if the array is empty there will be empty string, so mysql would return no result.

$search_name = $_POST['searchName']; // please escape, by all means...
$search_class = $_POST['current_class']; // please escape, by all means...

$select__args[] = "student_id";
$from__args[] = "students";
$where__args[] = "(CONCAT(first_name,' ',surname) LIKE '%{$search_name}%' OR 

first_name LIKE'%{$ search_name}%'或姓LIKE'{%$ search_name}%')“;

if( $search_class != '' ){
    $where__args[] = "current_class_id like '%{$search_class}%'";
}

通过这种方式,我可以控制连接表,选择列并根据参数更改条件。