使用JQuery自动完成强制选择

时间:2012-11-23 17:32:14

标签: php jquery mysql autocomplete

我之前已经问过这个问题,但我找不到任何最新或有效的答案(至少对我的申请而言)。

我的JQuery自动完成框使用mysql数据库作为其源。我希望用户能够输入以获取推荐,但是在他们提交表单之前,他们必须从下拉选项中进行选择。

我的Javascript:

    <script type="text/javascript">
    $.widget( 'ui.autocomplete', $.ui.autocomplete, {
        _renderMenu: function( ul, items ) {
            var that = this;
            $.ui.autocomplete.currentItems = items;
            $.each( items, function( index, item ) {
                that._renderItemData( ul, item );
            });
        }        
    });
    $.ui.autocomplete.currentItems = [];

    $(function() {

        $("#college").autocomplete({
            source: "search.php",
            minLength: 5
        });
    });

    var inputs = {college: false};

    $('#college').change(function(){
        var id = this.id;
        inputs[id] = false;

        var length = $.ui.autocomplete.currentItems.length;
        for(var i=0; i<length; i++){
            if($(this).val() == $.ui.autocomplete.currentItems[i].value){
                inputs[id] = true;
            }
        }
    });

    $('#submit').click(function(){
        for(input in inputs){
            if(inputs.hasOwnProperty(input) && inputs[input] == false){
                alert('incorrect');
                return false;
            }
        }
        alert('correct');
        $('#college_select_form').submit();
    });
    </script>

我的表格:

<form action="choose.php"  method="post" id="college_select_form" name="college_select_form">
                                        <input type="text" id="college"  name="college" class="entry_field" value="Type your school" onclick="this.value='';" onfocus="this.select()" onblur="this.value=!this.value?'Type your school':this.value;" /><input type="submit" id="submit" name="submit" class="submitButton" value="Go" title="Click to select school" />
                                    </form>

的search.php:

<?php

try {
  $conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
}
catch(PDOException $e) {
    echo $e->getMessage();
}

$return_arr = array();

if ($conn)
{
    $ac_term = "%".$_GET['term']."%";
    $query = "SELECT * FROM college_list where name like :term";
    $result = $conn->prepare($query);
    $result->bindValue(":term",$ac_term);
    $result->execute();

    /* Retrieve and store in array the results of the query.*/
    while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
        array_push($return_arr, array('label' => $row['name'], 'value' => $row['name']));
    }


}
/* Free connection resources. */
//$conn = null; 
/* Toss back results as json encoded array. */
echo json_encode($return_arr);

?>

那么这样做的最佳方法是什么?我能想到的唯一解决方案是使用PHP来验证文本框的值是否与数据库中的值匹配,但我不确定如何使用当前代码实现该值。

6 个答案:

答案 0 :(得分:1)

在我的项目中,我通过检查焦点来处理它,如果在自动填充字段中输入的文本实际上与我的下拉选项匹配。如果不是我只是删除它。

change: function(event, ui) {  
        if (!ui.item) {  
            this.value = '';  
        }  
    }

请在此处查看我的完整示例 - Jquery auto comp example

它有一个嵌入式小提琴,你可以直接检查小提琴

http://jsfiddle.net/9Agqm/3/light/

答案 1 :(得分:1)

在实例化自动完成对象之前,将此代码添加到JavaScript中:

$.widget( 'ui.autocomplete', $.ui.autocomplete, {
    _renderMenu: function( ul, items ) {
        var that = this;
        $.ui.autocomplete.currentItems = items;
        $.each( items, function( index, item ) {
            that._renderItemData( ul, item );
        });
    }        
});
$.ui.autocomplete.currentItems = [];

只要菜单出现,您就可以在$.ui.autocomplete.currentItems中找到用户可以选择的当前项目列表。然后,您可以使用它来检查提交表单的时间。当然,您实现此部分的方式取决于您的表单的动态程度,但这里有一个示例,需要对输入字段列表进行硬编码并确保它们都有ID。

//create an object that contains every input's id with a starting value of false
var inputs = {college: false};

//for each input, you will have a function that updates your 'inputs' object
//as long as all inputs have id's and they all are using autocomplete,
//the first line could be written as: $('input').change(function(){ and the
//function would only need to be written once. It is easier to maintain 
//if you use seperate id's though like so:
$('#college').change(function(){
    var id = this.id;
    inputs[id] = false;

    var length = $.ui.autocomplete.currentItems.length;
    for(var i=0; i<length; i++){
        if($(this).val() == $.ui.autocomplete.currentItems[i].value){
            inputs[id] = true;
        }
    }
});

//when you submit, check that your inputs are all marked as true
$('#submit').click(function(){
    for(input in inputs){
        if(inputs.hasOwnProperty(input) && inputs[input] == false){
            return false; //one or more input does not have correct value
        }
    }
    //all inputs have a value generated from search.php
    $('#myform').submit();
});

<小时/> 的更新

我们的两个示例(一个有效且一个无效)之间的唯一区别是您将其他事件绑定到输入元素onclickonblur。因此,通过将我们的监听器从change更改为blur来解决问题。但是当按下回车键/返回键以提交表单时,它会产生一个新问题。因此,如果我们为该特定事件添加一个侦听器,那么一切正常。以下是代码的样子:

var validateInfo = function(elem){
    var id = elem.id;
    inputs[id] = false;

    var length = $.ui.autocomplete.currentItems.length;
    for(var i=0; i<length; i++){
        if($(elem).val() == $.ui.autocomplete.currentItems[i].value){
            inputs[id] = true;
        }
    }
}

$('#college').on('blur', function(){
    validateInfo(this);
}).on('keydown', function(e){
    if(e.which == 13){ //Enter key pressed
      validateInfo(this);
    }
});

答案 2 :(得分:1)

您应该始终在“choose.php”(服务器端)中进行检查,因为用户可以禁用JavaScript并在表单的输入中发布他们想要的内容

$college = mysql_real_escape_string($_GET['college']);
if ($college != "" || $college != null || $college != -1)
{
    //DO STUFF
}

注意:您应该始终使用“mysql_real_escape_string”来阻止SQL注入! 更多信息:http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php

因此在search.php中相应地改变了

$ac_term = "%".$_GET['term']."%";

$ac_term = "%". mysql_real_escape_string($_GET['term']) ."%";

您还可以在用户提交之前检查表单,以使其更加用户友好(用户不希望等待几秒钟才能刷新页面上的错误!)

所以也许这样的事情会有所帮助:Submit Event Listener for a form

function evtSubmit(e) {
  // code
  e.preventDefault();
 // CHECK IT HERE!
};

var myform = document.myForm;
myform.setAttribute('action', 'javascript:evtSubmit();');

答案 3 :(得分:1)

向表单添加隐藏的输入元素:

<input type="hidden" name="selectedvalue" id="selectedvalue" />

向自动完成添加一个select事件处理程序,将所选值复制到隐藏输入:

$("#college").autocomplete({
        source: "search.php",
        minLength: 5,
        select: function (event, ui) {
            $('#selectedvalue').val(ui.item.value);
        }
    });

然后忽略发布数据中的自动完成表单输入。

答案 4 :(得分:0)

由于这是javascript,您唯一需要关注的是从自动填充列表中选择一个项目。这可以通过在select上将变量设置为true而在更改时将false设置为false来完成。这足以阻止普通用户在没有选择学校的情况下继续学习。为了防止滥用,您需要在发布后检查值服务器端。所有普通用户都将通过该检查。

答案 5 :(得分:0)

如果我正确理解了这个问题,这是我之前遇到的问题。这里有一些代码几乎从另一个项目中解脱出来。我在这里使用了一个本地数据源,但是这个项目取消了使用远程数据所以没有区别:

var valueSelected = '';

$('#college').autocomplete({
    source: ['collegeA', 'collegeB', 'collegeC']
}).on('autocompletechange autocompleteselect', function (event, ui) {
    if (!ui.item) {
        valueSelected = '';
    } else {
        $('#submit').prop('disabled', false);
        valueSelected = ui.item.label;
    }
}).on('propertychange input keyup cut paste', function () {
    if ($(this).val() != valueSelected) {
        valueSelected = '';
    }
    $('#submit').prop('disabled', !valueSelected);
});

这将以编程方式启用和禁用提交按钮,具体取决于用户是否选择了某个值。

Fiddle here