JQuery从XML自动完成

时间:2011-06-13 09:06:29

标签: jquery xml jquery-ui search jquery-autocomplete

我正在玩jquery ui autocomplete。并对如何查询XML数据提出疑问。我有一个XML文件,其中包含一个位置列表,类似于:

<geoname>
    <name_en>The Tower of London</name_en>
    <name_fr>Example text</name_fr>
    <lat>51.5082349601834</lat>
    <lng>-0.0763034820556641</lng>
    <geonameId>6286786</geonameId>
    <countryCode>GB</countryCode>
    <countryName>United Kingdom</countryName>
    <fcl>S</fcl>
    <fcode>CSTL</fcode>
    <web>http://www.exmaple.com</web>
</geoname>

我的jQuery是:

jQuery(document).ready(function() {
    lang = 'en';        
    $.ajax({
        url: "places.xml",
        dataType: "xml",
        success: function( xmlResponse ) {
            var data = $( "countryCode", xmlResponse ).map(function() {
                return {
                    value: $( "name", this ).text(),
                    id: $( "geonameId", this ).text(),
                    countryName: $( "countryName", this ).text(),
                    link: $( "web", this ).text(),
                    code: $( "countryCode", this ).text()
                };
            }).get();

            $( "#results" ).autocomplete({
                source: data,
                minLength: 0,
                select: function( event, ui ) {
                        $('#foo').html('');
                        $('#foo').html(ui.item.code).slideDown();

                }
            });
        }
    });
});

我遇到的问题是,我想指定一个变量,当我将其设置为EN时仅搜索name_en,而在其他情况下,只有在设置为FR时才搜索name_fr。当我将语言设置为EN时,我不希望name_fr结果返回。提前谢谢。

1 个答案:

答案 0 :(得分:3)

首先,我会发布代码:

<强> HTML

<select id="lang">
    <option value="en">EN</option>
    <option value="fr">FR</option>
</select>
<input type="text" id="results" />
<span id="foo" />

<强> XML

<list>
<geoname>
    <name_en>The Tower of London</name_en>
    <name_fr>Example text</name_fr>
    <lat>51.5082349601834</lat>
    <lng>-0.0763034820556641</lng>
    <geonameId>6286786</geonameId>
    <countryCode>GB</countryCode>
    <countryName>United Kingdom</countryName>
    <fcl>S</fcl>
    <fcode>CSTL</fcode>
    <web>http://www.exmaple.com</web>
</geoname>
<geoname>
    <name_en>En name</name_en>
    <name_fr>Fr name</name_fr>
    <lat>51.5082349601834</lat>
    <lng>-0.0763034820556641</lng>
    <geonameId>6286786</geonameId>
    <countryCode>GB2</countryCode>
    <countryName>United Kingdom</countryName>
    <fcl>S</fcl>
    <fcode>CSTL</fcode>
    <web>http://www.exmaple.com</web>
</geoname>
</list>

<强> JS

jQuery(document).ready(function() {       
    var lang = "en";
    $("#lang").bind("change", function() {
        lang = this.value;
    });
    $.ajax({
        url: "/echo/xml/",
        dataType: "xml",
        success: function( xmlResponse ) {
            var data = $("geoname", xmlResponse ).map(function() {
                return {
                    value: "",
                    name_en: $( "name_en", this ).text(),
                    name_fr: $("name_fr", this).text(),
                    id: $( "geonameId", this ).text(),
                    countryName: $( "countryName", this ).text(),
                    link: $( "web", this ).text(),
                    code: $( "countryCode", this ).text()
                };
            }).get(); 
            $( "#results" ).autocomplete({
                source: function(req, add) {
                 var source = [];
                 for (var i = 0; i < data.length; i++)
                 {               
                    if (lang == "en")
                    {
                     data[i].value = data[i].name_en;   
                    }
                    else if (lang == "fr")
                    {
                        data[i].value = data[i].name_fr;  
                    }
                 if (data[i].value.substr(0, req.term.length).toLowerCase() == req.term.toLowerCase())
                 {
                     source.push(data[i]);   
                 }
                 } 
                 add(source);
                },
                minLength: 0,
                select: function( event, ui ) {
                        $('#foo').html('');
                        $('#foo').html(ui.item.code).slideDown();

                }
            });
        }
    });
});

这是我测试的 JSFiddle 解决方案

http://jsfiddle.net/pinusnegra/KFHnd/

它有点乱,但如果你想要你可以做得更好。我告诉你它是如何工作的:

首先,您会收到我认为的“geoname”节点列表,而不仅仅是一个:

var data = $("geoname", xmlResponse ).map(function() {
                return {
                    value: "",
                    name_en: $( "name_en", this ).text(),
                    name_fr: $("name_fr", this).text(),
                    id: $( "geonameId", this ).text(),
                    countryName: $( "countryName", this ).text(),
                    link: $( "web", this ).text(),
                    code: $( "countryCode", this ).text()
                };
            }).get(); 

您获取name_en和name_fr值,并将'value'设置为空字符串('value'将是jQuery自动完成文本)。

在jQuery自动完成中,您可以为源设置一个函数,该函数具有'req'对象和'add'回调。

'req'对象包含'term'属性,它是实际的文本框输入。 'add'回调添加匹配项的列表(数组)。

所以你初始化一个'source'数组:

source: function(req, add) {
                 var source = [];

然后迭代'data'数组,并根据当前'lang',使用实际的'name_en'或'name_fr'设置'value'属性。

在此之后,您可以测试'object.value',如果它符合要求:

if (data[i].value.substr(0, req.term.length).toLowerCase() == req.term.toLowerCase())
                 {
                     source.push(data[i]);   
                 }

如果是,则推入'source'数组。

和...     添加(源); '返回'实际列表。

请注意,每次发生新的自动完成搜索时,都会调用自动完成对象的源函数,因此每次都会返回正确的项集合。

当然,如果符合您的要求,您可以制作更复杂和优化的解决方案。

欢呼,negra