2

我知道以前有人问过这个问题,但我找不到任何最新或实用的答案(至少对于我的应用程序而言)。

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

搜索.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 来验证文本框的值是否与数据库中的值匹配,但我不确定如何用我当前的代码实现它。

4

6 回答 6

1

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

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

在这里查看我的完整示例-Jquery auto comp example

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

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

于 2012-11-23T17:53:51.977 回答
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();
});


更新

我们的两个示例(一个有效,一个无效)之间的唯一区别是您将其他事件绑定到您的输入元素,onclick并且onblur. 因此,通过将我们的侦听器从 更改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);
    }
});
于 2012-11-27T00:30:19.013 回答
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']) ."%";

您还可以在用户提交之前检查表单,以使其更加用户友好(用户不想等待几秒钟来刷新页面并显示错误!)

所以也许这样的事情会有所帮助:为表单提交事件监听器

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

var myform = document.myForm;
myform.setAttribute('action', 'javascript:evtSubmit();');
于 2012-11-28T23:21:26.610 回答
1

在表单中添加一个隐藏的输入元素:

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

将选择事件处理程序添加到您的自动完成中,将选定的值复制到隐藏的输入:

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

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

于 2013-02-12T11:55:14.720 回答
0

由于这是 javascript,您唯一关心的应该是是否从自动完成列表中选择了一个项目。这可以简单地通过在选择时将变量设置为 true 并在更改时设置为 false 来完成。这足以防止普通用户在不选择学校的情况下继续使用。为防止滥用,您需要在发布后检查价值服务器端。所有普通用户都将通过该检查。

于 2012-11-27T23:47:14.673 回答
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);
});

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

在这里提琴

于 2012-11-29T11:14:53.617 回答