搜索自动提示功能的实现

上一条:Facebook 详解


SELECT [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo], [t0].[class_id], [t0].[class_type], [t0].[class_name], [t0].[class_show_name], [t0].[class_parent_id], [t0].[class_id_path], [t0].[class_name_path], [t0].[class_show_name_path], [t0].[class_depth], [t0].[class_order], [t0].[class_content], [t0].[class_img], [t0].[a_model_name] FROM [dbo].[mvc_content_view] AS [t0] WHERE ([t0].[a_id] = @p0) AND ([t0].[a_type] = @p1) -- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [5074] -- @p1: Input BigInt (Size = 0; Prec = 0; Scale = 0) [236] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1 SELECT TOP (1) [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo], [t0].[class_id], [t0].[class_type], [t0].[class_name], [t0].[class_show_name], [t0].[class_parent_id], [t0].[class_id_path], [t0].[class_name_path], [t0].[class_show_name_path], [t0].[class_depth], [t0].[class_order], [t0].[class_content], [t0].[class_img], [t0].[a_model_name] FROM [dbo].[mvc_content_view] AS [t0] WHERE ([t0].[a_type] = @p0) AND ([t0].[a_id] < @p1) ORDER BY [t0].[a_id] DESC -- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [236] -- @p1: Input BigInt (Size = 0; Prec = 0; Scale = 0) [5074] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1 SELECT TOP (1) [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo], [t0].[class_id], [t0].[class_type], [t0].[class_name], [t0].[class_show_name], [t0].[class_parent_id], [t0].[class_id_path], [t0].[class_name_path], [t0].[class_show_name_path], [t0].[class_depth], [t0].[class_order], [t0].[class_content], [t0].[class_img], [t0].[a_model_name] FROM [dbo].[mvc_content_view] AS [t0] WHERE ([t0].[a_type] = @p0) AND ([t0].[a_id] > @p1) ORDER BY [t0].[a_id] -- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [236] -- @p1: Input BigInt (Size = 0; Prec = 0; Scale = 0) [5074] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1 SELECT [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo] FROM [dbo].[mvc_content] AS [t0] WHERE ([t0].[a_id] = @p0) AND ([t0].[a_type] = @p1) -- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [5074] -- @p1: Input BigInt (Size = 0; Prec = 0; Scale = 0) [236] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1 UPDATE [dbo].[mvc_content] SET [a_hits] = @p19 WHERE ([a_id] = @p0) AND ([a_site] = @p1) AND ([a_model] = @p2) AND ([a_type] = @p3) AND ([a_special] = @p4) AND ([a_name] = @p5) AND ([a_from] = @p6) AND ([a_from_url] IS NULL) AND ([a_author] IS NULL) AND ([a_editor] IS NULL) AND ([a_describe] IS NULL) AND ([a_content] = @p7) AND ([a_create_date] = @p8) AND ([a_tag] = @p9) AND ([a_hits] = @p10) AND (NOT ([a_commend] = 1)) AND (NOT ([a_istop] = 1)) AND (NOT ([a_isimg] = 1)) AND ([a_cacheimg] IS NULL) AND ([a_imgurls] IS NULL) AND ([a_imgurl] = @p11) AND (NOT ([a_ismedia] = 1)) AND ([a_mediaurl] IS NULL) AND (NOT ([a_iscomment] = 1)) AND (NOT ([a_isRecycle] = 1)) AND ([a_weight] = @p12) AND ([a_status] = @p13) AND ([a_url] IS NULL) AND ([a_file_path] IS NULL) AND ([a_contentfile] IS NULL) AND ([a_comment] = @p14) AND ([a_ispass] = @p15) AND ([a_bury] = @p16) AND ([a_dig] = @p17) AND ([a_score] = @p18) AND ([a_diguser] IS NULL) AND ([a_buryuser] IS NULL) AND ([a_viewip] IS NULL) AND ([a_lastviewdate] IS NULL) AND ([a_neworimageorvideo] IS NULL) SELECT [t1].[a_weights], [t1].[a_rank] FROM [dbo].[mvc_content] AS [t1] WHERE ((@@ROWCOUNT) > 0) AND ([t1].[a_id] = @p20) -- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [5074] -- @p1: Input BigInt (Size = 0; Prec = 0; Scale = 0) [197] -- @p2: Input BigInt (Size = 0; Prec = 0; Scale = 0) [24] -- @p3: Input BigInt (Size = 0; Prec = 0; Scale = 0) [236] -- @p4: Input BigInt (Size = 0; Prec = 0; Scale = 0) [0] -- @p5: Input NVarChar (Size = 11; Prec = 0; Scale = 0) [搜索自动提示功能的实现] -- @p6: Input NVarChar (Size = 4; Prec = 0; Scale = 0) [2064] -- @p7: Input NVarChar (Size = 8215; Prec = 0; Scale = 0) [{$ad$}

使用 jQuery(Ajax)/PHP/MySQL实现自动完成功能

一如往常,demo和源码的zip包在文章最后,慢慢欣赏吧!

我觉得我有必要写这个教程,因为曾经见到的大部分关于自动完成的应用程序都只是给你一个程序源码包,然后告诉你怎么使用,而不是告诉你它是如何工作的以及为什么这样做。而知道这些可以让你对这个插件可以进一步的按自己的需求定制(关于这一点我在我的blog里写过不少关于其他应用的文章)。

好,我们现在开始。

JavaScript代码

<script src="jquery-1.2.1.pack.js" type="text/javascript"></script>
<script type="text/javascript">

function lookup(inputString) {
    if(inputString.length == 0) {
        // Hide the suggestion box.
        $(‘#suggestions’).hide();
    } else {
        $.post("rpc.php", {queryString: ""+inputString+""}, function(data){
            if(data.length >0) {
                $(‘#suggestions’).show();
                $(‘#autoSuggestionsList’).html(data);
            }
        });
    }
} // lookup

function fill(thisValue) {
    $(‘#inputString’).val(thisValue);
   $(‘#suggestions’).hide();
}

</script>

JS的解释:

 好,从上面的代码看到,我们需要连接到一个叫做rpc.php的文件,这个文件处理所有的操作。

lookup函数使用从文本输入框中得到的单词然后使用jQuery中Ajax的方法POST把它传给rpc.php。

如果输入字符 ‘inputString’是‘0’(Zero,译注:在这里是指在搜索框中没输入任何内容),建议框就被隐藏,这也很人性化,你想,如果在搜索框中没有输入任何东西,你也不期望会出现个建议提示框。

如果输入框中有内容,我们就得到了这个 ‘inputString’并传递给rpc.php页面,然后jQuery 的$.post()函数被使用,如下:

$.post(url, [data], [callback])

‘callback’部分可以关联一个函数,这个比较有意思,只有在数据(data)被加载成功的时候才会执行(译注:此处为意译,没看懂原文:<).

如果返回的数据(data)不为空(也就是说,有东西要显示),那就显示搜索提示框并且使用返回的数据(data)来代替其中的html代码。

就这么简单!

{$p$}{$ad$}

PHP后台程序(rpc.php):

如你所知(译注:不好意思,看王小波就学会了这么个口头禅),我的php后台程序都叫做rpc.php(RPC指远程过程调用),而没用它实际执行的功能来命名,但是也还不错了。

// PHP5 Implementation - uses MySQLi.
$db = new mysqli(‘localhost’, ‘root’ ,”, ‘autoComplete’);
if(!$db) {
    // Show error if we cannot connect.
    echo ‘ERROR: Could not connect to the database.’;
} else {
    // Is there a posted query string?
    if(isset($_POST[‘queryString’])) {
        $queryString = $_POST[‘queryString’];
        // Is the string length greater than 0?
        if(strlen($queryString) >0) {
        // Run the query: We use LIKE ‘$queryString%’
        // The percentage sign is a wild-card, in my example of countries it works like this…
        // $queryString = ‘Uni’;
        // Returned data = ‘United States, United Kindom’;
        $query = $db->query("SELECT value FROM countries WHERE value LIKE ‘$queryString%’ LIMIT 10");
        if($query) {
            // While there are results loop through them - fetching an Object (i like PHP5 btw!).
            while ($result = $query ->fetch_object()) {
                // Format the results, im using <li> for the list, you can change it.          
                // The onClick function fills the textbox with the result.
                echo ‘<li onclick="fill(’‘.$result->value.’‘);">’.$result->value.‘</li>’;
            }
        } else {
            echo ‘ERROR: There was a problem with the query.’;
        }
    } else {
        // Dont do anything.
    } // There is a queryString.
} else {
    echo ‘There should be no direct access to this script!’;
}
}

?>

PHP代码解释

鉴于代码中我已经加了很多注释,在这里我就不再说的很详细了。

一般情况下,需要接收这个 ‘QueryString’ 然后在其最后使用通配符产生一个查询语句。

这意味着在这种情况下,每次敲进去一个字符都需要产生一个查询语句,如果一直都这样做的话,恐怕MYSQL会受不了。但是为了尽量的简化这个过程,这种做法对一个规模较小的应用应该没什么问题。

这段php代码你需要在自己的系统中稍作修改,比如你需要更新‘$query’到你自己的数据库,需要看在哪里放你数据库表的列名等等。

CSS样式

我使用的是CSS3,天哪,它真的很好用,虽然在Firefox 或者Safari浏览器上会有功能限制。

<style type="text/css">
.suggestionsBox {
    position: relative;
    left: 30px;
    margin: 10px 0px 0px 0px;
    width: 200px;
    background-color: #212427;
    -moz-border-radius: 7px;
    -webkit-border-radius: 7px;
    border: 2px solid #000;
    color: #fff;
}

.suggestionList {
    margin: 0px;
    padding: 0px;
}

.suggestionList li {
    margin: 0px 0px 3px 0px;
    padding: 3px;
    cursor: pointer;
}

.suggestionList li:hover {
    background-color: #659CD8;
}
</style>

CSS代码都很标准,没什么需要特别指出的。

{$p$}{$ad$}

主文件HTML

<div>
       <div>

      Type your county (for the demo):
<input size="30" id="inputString" onkeyup="lookup(this.value);" type="text" />

    </div>      <div class="suggestionsBox" id="suggestions" style="display: none;">

      <img src="upArrow.png" style="position: relative; top: -12px; left: 30px" alt="upArrow" />

      <div class="suggestionList" id="autoSuggestionsList">

</div>

    </div>

</div>

这是主文件的部分html代码,你需要添加的就是一个输入框,并且把 ‘onkeyup’ 函数设置为lookup(this.value)。另外,我建议你不要修改它的ID,如果你不想修改上面的Javascript代码的话。

截图

我想你应该会想要看看最后的效果是什么样子,OK。

还有,

最后就是有用的链接了,我想你应该期待很久了。

演示Auto Complete Demo
源文件AutoComplete Source ZIP

] -- @p8: Input DateTime (Size = 0; Prec = 0; Scale = 0) [2008-3-19 18:48:37] -- @p9: Input NVarChar (Size = 14; Prec = 0; Scale = 0) [搜索,自动,提示,功能,实现] -- @p10: Input BigInt (Size = 0; Prec = 0; Scale = 0) [3966] -- @p11: Input NVarChar (Size = 0; Prec = 0; Scale = 0) [] -- @p12: Input BigInt (Size = 0; Prec = 0; Scale = 0) [0] -- @p13: Input Int (Size = 0; Prec = 0; Scale = 0) [0] -- @p14: Input BigInt (Size = 0; Prec = 0; Scale = 0) [0] -- @p15: Input Int (Size = 0; Prec = 0; Scale = 0) [0] -- @p16: Input BigInt (Size = 0; Prec = 0; Scale = 0) [0] -- @p17: Input BigInt (Size = 0; Prec = 0; Scale = 0) [0] -- @p18: Input Float (Size = 0; Prec = 0; Scale = 0) [0] -- @p19: Input BigInt (Size = 0; Prec = 0; Scale = 0) [3967] -- @p20: Input BigInt (Size = 0; Prec = 0; Scale = 0) [5074] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1 SELECT TOP (10) [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo], [t0].[class_id], [t0].[class_type], [t0].[class_name], [t0].[class_show_name], [t0].[class_parent_id], [t0].[class_id_path], [t0].[class_name_path], [t0].[class_show_name_path], [t0].[class_depth], [t0].[class_order], [t0].[class_content], [t0].[class_img], [t0].[a_model_name] FROM [dbo].[mvc_content_view] AS [t0] WHERE ([t0].[a_type] IN (@p0)) AND (NOT ([t0].[a_isRecycle] = 1)) ORDER BY [t0].[a_id] DESC -- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [236] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1