如何在自动填充中建议相似的字词

时间:2017-02-14 11:09:29

标签: jquery jquery-ui autocomplete jquery-ui-autocomplete

我有一个带有jquery-ui-autocomplete的位置的输入字段。

<script type="text/javascript">
    $(document).ready(function(){
        var location_input=$('input[id="location-autocomplete"]');
        var cityNames = [
            { value: 'Mallorca' },
            { value: 'Berlin' },
            { value: 'London' },
            // many other elements
        ];
        location_input.autocomplete({
          source: cityNames,
          minLength: 2
        });
      } );

    //   keeps same width as box
      jQuery.ui.autocomplete.prototype._resizeMenu = function () {
          var ul = this.menu.element;
          ul.outerWidth(this.element.outerWidth());
        }
</script>

但是,当相同的位置可以有不同的名称时,我不满意。

例如,让我们说用户想要寻找马洛卡。他可以写: Mallorca Majorca Palma de Mallorca PMI Palma

我的第一个想法是使用label属性

var cityNames = [
    { value: 'Mallorca', label: 'Palma de Mallorca' },
    { value: 'Mallorca', label: 'Mallorca' },
    { value: 'Mallorca', label: 'Majorca' },
    // etc
    ];

然而,这可能会令人困惑。写 Ma 自动完成将显示 Mallorca Palma de Mallorca Majorca ,即使它们是同一个地方。

Autocomplete with three different names for the same place

我希望在输入 Ma 时,用户只能获得一个建议。同样,无论用户输入 Maj Mal 还是 Pal ,他都应该只为马洛卡提供一个建议条款。

理想情况下,一个名为input的附加属性作为要搜索的输入关键字将是完美的。然后,拥有一个具有属性valueinput的数组,就可以完成这个任务。不幸的是,我没有在文档中找到这样的东西。

如您所见,我使用array作为源类型。对于我所读到的内容,也许function类型允许我做这样的事情,但我不清楚如何,因为我不熟悉js并且没有找到任何明确的例子。< / p>

我怎样才能以简单的方式实现这一目标?

2 个答案:

答案 0 :(得分:3)

经过一些额外的研究和许多尝试后,我找到了一种方法。这是特定于Django ,因此任何其他更通用的提案当然是非常受欢迎的。

该解决方案基于this tutorial,但有一些修改。

首先,在模板中导入jQuery和jQueryUI:

CREATE PROCEDURE [dbo].[RequestHttpWebService]
@Url varchar(1024),
@HttpMethod varchar(10),
@ParamsValues varchar(1024),    -- param1=value&param2=value
@SoapAction varchar(1024) = null
AS
BEGIN
SET NOCOUNT ON;

--set @Url = 'http://localhost/service.asmx'
--set @HttpMethod = 'soap'
--set @ParamsValues = 'login=tr2280&password=Qwe12345&domain=webtech.development'
--set @SoapAction = 'Authenticate'


if @HttpMethod in ('get','GET') and len(@ParamsValues) > 0
begin
    set @Url = @Url + '?' + @ParamsValues
end

declare @obj int
    ,@response varchar(8000)
    ,@responseXml xml
    ,@status varchar(50)
    ,@statusText varchar(1024)
    ,@method varchar(10) = (case when @HttpMethod in ('soap','SOAP') then 'POST' else @HttpMethod end)

exec sp_OACreate 'MSXML2.ServerXMLHttp', @obj out
exec sp_OAMethod @obj, 'Open', null, @method, @Url, false

if @HttpMethod in ('get','GET')
begin
    exec sp_OAMethod @obj, 'send'
end
else if @HttpMethod in ('post','POST')
begin
    exec sp_OAMethod @obj, 'setRequestHeader', null, 'Content-Type', 'application/x-www-form-urlencoded'
    exec sp_OAMethod @obj, 'send', null, @ParamsValues
end
else if @HttpMethod in ('soap','SOAP')
begin
    if @SoapAction is null
        raiserror('@SoapAction is null', 10, 1)

    declare @host varchar(1024) = @Url
    if @host like 'http://%'
        set @host = right(@host, len(@host) - 7)
    else if @host like 'https://%'
        set @host = right(@host, len(@host) - 8)

    if charindex(':', @host) > 0 and charindex(':', @host) < charindex('/', @host)
        set @host = left(@host, charindex(':', @host) - 1)
    else 
        set @host = left(@host, charindex('/', @host) - 1)

    declare @envelope varchar(8000) = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><{action} xmlns="http://tempuri.org/">{params}</{action}></soap:Body></soap:Envelope>'
    declare @params varchar(8000) = '' 

    WHILE LEN(@ParamsValues) > 0
    BEGIN
        declare @param varchar(256),
                @value varchar(256)

        IF charindex('&', @ParamsValues) > 0
        BEGIN

            SET @param = left(@ParamsValues, charindex('&', @ParamsValues) - 1)
            set @value = RIGHT(@param, len(@param) - charindex('=', @param))
            set @param = left(@param, charindex('=', @param) - 1)
            set @params = @params + '<' + @param + '>' + @value + '</'+ @param + '>'
            SET @ParamsValues = right(@ParamsValues, LEN(@ParamsValues) - LEN(@param + '=' + @value + '&'))
        END
        ELSE
        BEGIN
            set @value = RIGHT(@ParamsValues, len(@ParamsValues) - charindex('=', @ParamsValues))
            set @param = left(@ParamsValues, charindex('=', @ParamsValues) - 1)

            set @params = @params + '<' + @param + '>' + @value + '</'+ @param + '>'
            SET @ParamsValues = NULL
        END
    END

    set @envelope = replace(@envelope, '{action}', @SoapAction)
    set @envelope = replace(@envelope, '{params}', @params)

    set @SoapAction = 'http://tempuri.org/' + @SoapAction

    print @host
    print @SoapAction
    print @envelope

    exec sp_OAMethod @obj, 'setRequestHeader', null, 'Content-Type', 'text/xml; charset=utf-8'
    exec sp_OAMethod @obj, 'setRequestHeader', null, 'Host', @host
    exec sp_OAMethod @obj, 'setRequestHeader', null, 'SOAPAction', @SoapAction
    exec sp_OAMethod @obj, 'send', null, @envelope
end

exec sp_OAGetProperty @obj, 'responseText', @response out
exec sp_OADestroy @obj

select @status as [status], @statusText as [statusText], @response as [response]
END
GO

然后,在模板本身中,您需要为输入标记分配一个id。请注意,此id是jquery将以何种形式识别运行自动完成的方式。

<link rel="stylesheet" href="http://code.jquery.com/ui/1.8.18/themes/base/jquery-ui.css" type="text/css" media="all" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>

javascript代码如下:

<div class="ui-widget">
  <label for="cities">City: </label>
  <input id="autocomplete-cities">
</div>

<script type="text/javascript"> $(document).ready(function(){ var location_input=$('input[id="autocomplete-city"]'); location_input.autocomplete({ source: "/api/get_city_names/", minLength: 2 }); } ); // keeps same width as box jQuery.ui.autocomplete.prototype._resizeMenu = function () { var ul = this.menu.element; ul.outerWidth(this.element.outerWidth()); } </script> 文件需要相应修改:

urls.py

最后创建django视图。该函数的名称必须与# urls.py import yourapp.views urlpatterns = [ ..., url(r'^api/get_city_names/', yourapp.views.get_city_names), ..., ] 中编写的函数和javascript的urls.py中编写的函数相同。

source

自动完成功能应该有效。

答案 1 :(得分:1)

你快到了。您可以使用response函数(see in API)从结果中删除备用拼写。最后拼写最好的拼写(在这种情况下是“马洛卡”)。看看这个,我希望这些评论足以得到逻辑。尝试输入“Ma”或“Maj”并选择唯一选项。在这两种情况下,它都会显示“Mallorca”

 $( function() {
    var availableTags = [      
    { value: 'Mallorca', label: 'Palma de Mallorca' },
    { value: 'Mallorca', label: 'Majorca' },
    { value: 'Mallorca', label: 'Mallorca' },
    { value: 'Madrid', label: 'Madrid' }
    ];
    $( "#tags" ).autocomplete({
      source: availableTags,      
      response: function( event, ui ) {
        var added = [];//Keep here the unique labels that are already in the list
        for(var i=ui.content.length-1;i>=0;i--){//Start a loop, itterate all items backwards
          var cur = ui.content[i].value;//Value of the item
          if($.inArray(cur,added)==-1){//If not already loaded
            added.push(cur);//Put the new item in the list
          }else{            
            ui.content.splice(i,1);//If already loaded remove it from the results
          }
        }        
      }
    });
  } );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="ui-widget">
  <label for="tags">Tags: </label>
  <input id="tags">
</div>