2012-11-23 56 views
2

我知道這個問題以前已經被問過,但是我找不到任何答案是最新的或功能的(至少對於我的應用程序來說)。使用JQuery自動完成的力選擇

我的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來驗證文本框的值是否與數據庫中的值匹配,但我不確定如何使用當前的代碼實現該值。

+0

請參閱我的更新。 – Aust

+0

替換:'$('#college_select_form')。submit();' With:'if($('#college').length> 0){$('#college_select_form')。submit();} else {alert('你必須選擇一所學校!');}' 你應該看看:http://docs.jquery.com/Plugins/Validation – DevlshOne

回答

1

您應經常檢查它的「choose.php」(服務器端),因爲用戶可以禁用無論他們在表單的輸入

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

注意要在JavaScript和崗位:你應該總是使用「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();'); 
1

在我的項目中,我通過檢查焦點處理來處理它,如果在自動填充字段中輸入的文本實際上與我的下拉選項匹配。如果不是,我會簡單地將其刪除。

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

看到我的完整的例子這裏 - Jquery auto comp example

它有一個嵌入式的小提琴,你可以檢查小提琴直接還

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

+0

這是否會與外部(數據庫)源一起工作? – Jakemmarsh

+0

是的,因爲你不需要使用db驗證用戶輸入,你可以簡單地刪除任何不符合你的下拉列表的文本。下拉列表可以是ajax調用 – sayannayas

+0

這對我不起作用。由於我的表單只有一個輸入,用戶在填寫自動填充字段後立即提交。沒有時間根據下拉列表檢查輸入(我認爲) – Jakemmarsh

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(); 
}); 


UPDATE

我們的兩個例子之間唯一的區別(一個工作,一個是不)是你結合其他活動,你輸入元素,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); 
    } 
}); 
+0

我的表單只有一個輸入字段,如我的原始文章所示。我試着使用你的代碼,只改變ID來匹配我的表單的所有內容。它不會中斷我的表單或提交,但它不會阻止提交虛假輸入。我錯過了什麼嗎? – Jakemmarsh

+0

@Jakemmarsh - 很難說沒有看到你的代碼。 [**我寫了一個工作示例**](http://jsfiddle.net/5rwRy/1/),您可以比較您的代碼。 – Aust

+0

我用我現在使用的代碼更新了原始文章。你的jfiddle確實可以正常工作,但是當應用於我自己的代碼時出錯了。再次,沒有任何突破,但它不強迫選擇。我肯定錯過了什麼。 – Jakemmarsh

0

因爲這是javascript,所以您唯一的擔心應該是如果從自​​動完成列表中選擇一個項目。這可以簡單地通過在變化時將變量設置爲真來完成。這足以阻止普通用戶在未選擇學校的情況下繼續學習。爲防止濫用,您需要在發佈後檢查值服務器端。所有普通用戶都會通過該檢查。

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

1

一個隱藏的輸入元素添加到您的窗體:

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

添加選擇事件處理程序的自動完成,即複製選中的值給隱藏輸入:

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

然後只是忽略發佈數據中的自動完成表單輸入。