从多列自动完成建议并防止重复

Posted

技术标签:

【中文标题】从多列自动完成建议并防止重复【英文标题】:autocomplete suggest from multiple columns and prevent duplicate 【发布时间】:2018-12-28 14:13:03 【问题描述】:

我想从 mysql 数据库表的两列中自动完成值,一列有多个相似的值,在自动完成窗口中,如果相似,它应该只显示一个相似的值。并且在选择后不应该在下一行的自动完成窗口中建议它。

HTML

<tr>
    <td><input type="text" data-type="aTeam"  id="team_1" class="team"></td>
    <td><input type="text"  id="score_1" ></td>
</tr>
<button type="button" id="addRow">Add Row</button>

JS

$(document).on('focus','.team',function()
var type = $(this).data('type');
if(type ==='aTeam' )autoTypeNo= 0;
$(this).autocomplete(
    source: function( request, response ) 
        $.ajax(
            url : 'fetch.php',
            dataType: "json",
            method: 'post',
            data: 
               name_startsWith: request.term,
               type: type
            ,
             success: function( data ) 
                 response( $.map( data, function( item ) 
                    return 
                        label: item.aTeam,
                        value: item.aTeam,
                        data : item
                    ;
                ));
            
        );
    ,
    autoFocus: true,            
    minLength: 1,
    select: function( event, ui )                          
        id_arr = $(this).attr('id');
        id = id_arr.split("_");
        $('#team_'+id[1]).val(ui.item.data.aTeam);
        $('#score_'+id[1]).val(ui.item.data.score);
                   
  );
);

//add row
   var i=$('table tr').length;
   $("#addRow").on('click',function()
       html = '<tr>';
       html += '<td><input type="text" data-type="aTeam" id="team_'+i+'" class="team"></td>';
       html += '<td><input type="text" id="score_'+i+'"></td>';
       html += '</tr>';
       $('table').append(html);
       i++;
   );

PHP

<?php
    require_once("config.php");

    if(!empty($_POST['type']))
       $type = $_POST['type'];
       $name = $_POST['name_startsWith'];
       $query = $db->prepare("SELECT aTeam, bTeam FROM teams where UPPER($type) LIKE '".strtoupper($name)."%' limit 10 ");
       $query->execute();
       $data= array();

   $i = 0;
       while ($row = $query->fetch(PDO:: FETCH_ASSOC)) 

           $data[$i]['aTeam'] = $row['aTeam'];
           $data[$i]['bTeam'] = $row['bTeam'];
           $data[$i]['score'] = $row['score'];
   ++$i;
         
       echo json_encode($data);
  

【问题讨论】:

你能分享echo json_encode($output);的样本输出吗?将其添加到您的问题中,或者如果它太长,请通过 Pastebin.com 分享 @SallyCJ - 我在此列中有多个名称,这就是它显示多个相同名称的原因,这是输出 [aTeam: "john", aTeam: "john"] 0 : aTeam: "john" 1 : aTeam: "john" 请检查我的答案/代码,如果有帮助请告诉我。 ***.com/questions/20119410/… 100% 功能 ;) 【参考方案1】:

试试这个:(阅读 // comment here 并将代码与您的代码进行比较,看看有什么变化)

$(document).on('focus','.team',function()
let type = $(this).data('type');

// `autoTypeNo` isn't used anywhere, so I commented out this.
//if(type ==='aTeam' )autoTypeNo= 0;

$(this).autocomplete(
    source: function( request, response ) 
        $.ajax(
            url : 'fetch.php',
            dataType: "json",
            method: 'post',
            data: 
               name_startsWith: request.term,
               type: type
            ,
             success: function( data ) 
               let selected = [],
                   uniques = [],
                   choices = [];

               $('tr .team[id^="team_"]').each(function()
                 let value = this.value.trim().toLowerCase();
                 if (value && selected.indexOf(value) < 0) 
                   selected.push(value);
                 
               );

               data.forEach(item => 
                 let value = item.aTeam.trim().toLowerCase(),
                     value2 = item.bTeam.trim().toLowerCase();

                 if (uniques.indexOf(value) < 0 && selected.indexOf(value) < 0) 
                   choices.push(
                     label: item.aTeam,
                     value: item.aTeam,
                     data: item,
                     type: 'aTeam'
                   );
                   uniques.push(value);
                 

                 if (uniques.indexOf(value2) < 0 && selected.indexOf(value2) < 0) 
                   choices.push(
                     label: item.bTeam,
                     value: item.bTeam,
                     data: item,
                     type: 'bTeam'
                   );
                   uniques.push(value2);
                 
               );

               response(choices);
            
        );
    ,
    autoFocus: true,
    minLength: 1,
    select: function( event, ui ) 
        // Strips the 'team_' part, leaving just the number.
        let id_num = $(this).attr('id').substring(5);

        $(this).val(ui.item.value);
        $('#score_' + id_num).val(ui.item.data.score);
        $(this).attr('data-type', ui.item.type); // Change to the correct type?

        // Cancels default action, so that the above `jQuery.val()` call works.
        return false;
    
  );
);

//add row
// 'i' is too generic, so I renamed it to 'row_num'.
   var row_num=$('table tr').length;
   $("#addRow").on('click',function()
       // Increment before used.
       row_num++;

       let html = '<tr>';
       html += '<td><input type="text" data-type="aTeam" id="team_' + row_num + '" class="team"></td>';
       html += '<td><input type="text" id="score_' + row_num + '"></td>';
       html += '</tr>';
       $('table').append(html);

       // Optional, but I like to focus on the `input` in the row that was just added.
       $('#team_' + row_num).select();
   );

更新

我更新了JS代码(上图)

请注意,对于 PHP 部分,我将 $query 更改为:

$query = $db->prepare("SELECT aTeam, bTeam FROM teams where UPPER($type) LIKE '".strtoupper($name)."%' limit 10 ");

到:

$query = $db->prepare("SELECT aTeam, bTeam, score FROM teams where ( aTeam LIKE '".$name."%' OR bTeam LIKE '".$name."%' ) limit 10 ");

因为没有OR bTeam LIKE '".$name."%',例如,如果您输入“d”并且没有以“d”开头的aTeam,那么您就知道会发生什么了..

【讨论】:

对不起!我对问题进行了一些更改,您的代码使自动完成功能独一无二,这很有效。但它不能防止在下一行重复。我想搜索 aTeam 和 bTeam 以在同一字段中一起搜索,正如我在问题 I want autocomplete value from two columns of MySql database table 中所问的那样。选择后,我还想要相关团队的得分字段。感谢您的回答。 请根据我的新编辑对答案进行一些更改。 好的,所以input 框将显示来自 MySQL 表中 aTeambTeam 列的自动完成 suggestions,对吗?这意味着,如果有一行 aTeam 是“John”,bTeam 是“Johnny”,那么“John”和“Johnny”都会出现在 same 自动完成建议菜单中? 请查看更新后的答案。它对我来说效果很好,但如果它不适合你,请告诉我,我会相应地调整代码。 非常感谢它现在完美了。

以上是关于从多列自动完成建议并防止重复的主要内容,如果未能解决你的问题,请参考以下文章

角度材料自动完成 - 如何防止键盘输入以在建议面板中选择一个选项

MS Access 2010 多列组合框自动完成

Primefaces使用POJO和字符串值自动完成[重复]

HTML - 防止自动填充或自动完成字段(FF、IE、iPad)

MUI 自动完成:如何防止在焦点上打开,而不是在输入更改时打开?

Oracle:多列“最接近匹配”自动完成策略