duancan7914 2017-03-20 09:50
浏览 80
已采纳

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

I'm able to get jQuery AJAX live search working on an input field and it returns the desired result that I want. Now I want to do a compound search on two fields.

This is what I have but it is not working or returning any errors:

Form:

<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:

<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>

Query in 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}";

What am I missing here? What I want is a live search to be done on both fields either by name or by class. If there are two(2) students with the name: 'Nathan Siafa' but are in two(2) different classes(Grade 1 and 2) I will have to search by both name and class. Which is not the result I'm getting.

UPDATE

I have changed my code to match @maksbd19's answer. It works a little for me but I'm not getting the desired result that I want (live search experience on the two fields). I have just realized there maybe other problems. Ex. If there are two students - John Amos Doe and John James Doe with classes (grade 9 and 10). I realized that if a search is done for John Amos Doe whose class is grade 9 it works fine and returns the right record, but if I now want the record of John James Doe whose class is grade 10 I get the record of John Amos Doe (Note: my query searches by last name and first name).

I added a separate field to distinguish between the records. Now with @maksbd19 if I want John James Doe record and search is "John Doe" I still get "John Amos Doe" record even if I add the class for "John James Doe" in the class field it remains the same.

The way I get the precise record is by having the right class for "John James Doe" in placed and pretending to delete my current search value "John Doe" and it works. To me it's like ajax is only live searching on the name field.

Note: middle name is not require in my application that is why I'm not trying to perform a query on it, but is there a way that I can leverage the power of searching by a student full name(first, middle, last) even though not all student will have a middle name?

Update 2

I have manage to get the live search working the two(2) fields, based on the code I have here. My problem now is I have two(2) students in my tables - 'John Amos Doe(grade 10)' and 'John Lewis Doe(grade 9)'. If I search by first name with their specific classes it returns the desired result.

If I search 'John Doe' It brings 'John Amos Doe' record for example, and if I now want 'John Lewis Doe' record I have to put in the precise class (grade 9) in the class field which returns nothing.

I also tried to include the middle name in my search query but to no avail. Here is how I tried:

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

1条回答 默认 最新

  • duanlinma5885 2017-03-22 17:01
    关注

    If I'm not mistaken then you are getting the result as expected. Let me explain.

    In your form the ajax function is okay, its just transferring the values in the server and getting back the query result. I think you need to refine your mysql query.

    In your query there are three OR conditions for which the result would return anything matched by anything.

      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
    ---------------+---------------------+------------------+-----------------
    

    Lets examine this sample data.

    Assume you typed Jane in the name field with no class id selected. Your mysql query will look for student id which would match the name you typed with concatenated first_name and last_name, last_name. Since you already concatenated both names you can omit the last one or keep both separated.

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

    OR

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

    Use either, both would yield same result.

    Note: If you wanted to search for Emma Roberts then the query might be as following-

    $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}%'"
    

    In this way you can tell mysql to match first, last or whole name with the database.

    Lets search for Emma (case sensitive)

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

    And Roberts

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

    And Emma Roberts

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

    Now lets come to the second clause, the current_class_id part. I believe you would want an AND operation here. Because search for Emma or students from class_id 1 doesn't make any sense. This search should be search for Emma from students of class_id 1

    $query = "SELECT student_id FROM students WHERE current_class_id like '%{$search_class}%'";
    

    Now lets combine this to achieve you was intended.

    $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}%'";
    

    This is basically telling mysql to look for Emma in both first_name and surname columns AND also associated with a specific current_class_id.

    Note

    The query sample above has a little glitch. If you don't include a current_class_id in the param, the query should omit it as well. In my case these types of filters generally accept lots of parameters. I like to split in in different parts.

    $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}";
    

    And then based on the parameters I provide to the filter script these clauses are populated accordingly. In your case you can have like the following-

    $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}%' OR surname LIKE '{%$search_name}%')";

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

    In this way I have control of joining tables, selecting columns and change condition based on the parameters.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大