Jquery Autocomplete case sensitive for utf-8 characters

爷,独闯天下 提交于 2019-12-20 02:11:12

问题


I am using jquery autocomplete plugin to search in a long list of names. It works fine for all latin and english characters, but with turkish characters I have problems, as the search will be case sensitive eg:

A and a would match all the cities containing the A or a.

İ and i would not match cities like İstambul and İzmir

This is the code:

<label for="PROVINCE_AC_LEFT" class="
      PROVINCE_AC_LEFT">İl</label><input   type="text" name="PROVINCE_AC_LEFT_autocomplete_label"  id="PROVINCE_AC_LEFT_autocomplete_label" 
             value="" maxlength="" size=""/><input   type="hidden" name="PROVINCE_AC_LEFT"  id="PROVINCE_AC_LEFT" 
             value="" />
            <script>
             $(function() {

                            var tags_PROVINCE_AC_LEFT = [




               { label: "Van" , value: "6500" },

               { label: "Yozgat" , value: "6600" },

               { label: "Zonguldak" , value: "6700" },

               { label: "Aksaray" , value: "6800" },

               { label: "Bayburt" , value: "6900" },

               { label: "Karaman" , value: "7000" },

               { label: "Kırıkkale" , value: "7100" },

               { label: "Batman" , value: "7200" },

               { label: "Şırnak" , value: "7300" },

               { label: "Bartın" , value: "7400" },

               { label: "Ardahan" , value: "7500" },

               { label: "Iğdır" , value: "7600" },

               { label: "Yalova" , value: "7700" },

               { label: "Karabük" , value: "7800" },

               { label: "Kilis" , value: "7900" },

               { label: "Osmaniye" , value: "8000" },

               { label: "Düzce" , value: "8100" },

               { label: "Adana" , value: "0100" },

               { label: "Adıyaman" , value: "0200" },

               { label: "Afyonkarahisar" , value: "0300" },

               { label: "Ağrı" , value: "0400" },

               { label: "Amasya" , value: "0500" },

               { label: "Ankara" , value: "0600" },

               { label: "Antalya" , value: "0700" },

               { label: "Artvin" , value: "0800" },

               { label: "Aydın" , value: "0900" },

               { label: "Balıkesir" , value: "1000" },

               { label: "Bilecik" , value: "1100" },

               { label: "Bingöl" , value: "1200" },

               { label: "Bitlis" , value: "1300" },

               { label: "Bolu" , value: "1400" },

               { label: "Burdur" , value: "1500" },

               { label: "Bursa" , value: "1600" },

               { label: "Çanakkale" , value: "1700" },

               { label: "Çankırı" , value: "1800" },

               { label: "Çorum" , value: "1900" },

               { label: "Denizli" , value: "2000" },

               { label: "Diyarbakır" , value: "2100" },

               { label: "Edirne" , value: "2200" },

               { label: "Elazığ" , value: "2300" },

               { label: "Erzincan" , value: "2400" },

               { label: "Erzurum" , value: "2500" },

               { label: "Eskişehir" , value: "2600" },

               { label: "Gaziantep" , value: "2700" },

               { label: "Giresun" , value: "2800" },

               { label: "Gümüşhane" , value: "2900" },

               { label: "Hakkari" , value: "3000" },

               { label: "Hatay" , value: "3100" },

               { label: "Isparta" , value: "3200" },

               { label: "Mersin" , value: "3300" },

               { label: "İstanbul" , value: "3400" },

               { label: "İzmir" , value: "3500" },

               { label: "Kars" , value: "3600" },

               { label: "Kastamonu" , value: "3700" },

               { label: "Kayseri" , value: "3800" },

               { label: "Kırklareli" , value: "3900" },

               { label: "Kırşehir" , value: "4000" },

               { label: "Kocaeli" , value: "4100" },

               { label: "Konya" , value: "4200" },

               { label: "Kütahya" , value: "4300" },

               { label: "Malatya" , value: "4400" },

               { label: "Manisa" , value: "4500" },

               { label: "Kahramanmaraş" , value: "4600" },

               { label: "Mardin" , value: "4700" },

               { label: "Muğla" , value: "4800" },

               { label: "Muş" , value: "4900" },

               { label: "Nevşehir" , value: "5000" },

               { label: "Niğde" , value: "5100" },

               { label: "Ordu" , value: "5200" },

               { label: "Rize" , value: "5300" },

               { label: "Sakarya" , value: "5400" },

               { label: "Samsun" , value: "5500" },

               { label: "Siirt" , value: "5600" },

               { label: "Sinop" , value: "5700" },

               { label: "Sivas" , value: "5800" },

               { label: "Tekirdağ" , value: "5900" },

               { label: "Tokat" , value: "6000" },

               { label: "Trabzon" , value: "6100" },

               { label: "Tunceli" , value: "6200" },

               { label: "Şanlıurfa" , value: "6300" },

               { label: "Uşak" , value: "6400" },



                            ];

                            $( "#PROVINCE_AC_LEFT_autocomplete_label" ).autocomplete({
                                source: tags_PROVINCE_AC_LEFT,
                                select: function(event, ui) {
                                    var selectedObj = ui.item;
                                    $( "#PROVINCE_AC_LEFT_autocomplete_label" ).val(selectedObj.label);
                                    $( "#PROVINCE_AC_LEFT" ).val(selectedObj.value);
                                    return false;
                                },
                                focus: function( event, ui ) { $(this).val( ui.item.label ); return false; }
                            });
                        });

             </script>

An example can be found at the second page of the registration questionnaire :

http://tr.mysurvey.com/index.cfm?action=Main.join


回答1:


I would recommend taking a look at the accent map demo on the jQueryUI examples page. The idea in the demo is to map accent characters to non-accented characters using a hash. I would change your code to look like that demo:

$("#PROVINCE_AC_LEFT_autocomplete_label").autocomplete({
    source: function(request, response) {
        var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
        response($.grep(tags_PROVINCE_AC_LEFT, function(value) {
            value = value.label || value.value || value;
            return matcher.test(value) || matcher.test(normalize(value));
        }));
    },
    select: function(event, ui) {
        var selectedObj = ui.item;
        $("#PROVINCE_AC_LEFT_autocomplete_label").val(selectedObj.label);
        $("#PROVINCE_AC_LEFT").val(selectedObj.value);
        return false;
    },
    focus: function(event, ui) {
        $(this).val(ui.item.label);
        return false;
    }
});

Example: http://jsfiddle.net/gZ8xz/

(I've only added a few character mappings in the demo)




回答2:


After years from the last reply, I just ran into the same problem.

Accent mapping is not good enough for Turkish because it is still matching "I" with "i" and vice versa. However, lowercase "I" is "ı" and uppercase "i" is "İ" in Turkish. So, when I type "I", "İzmir" should NOT be a match and when I type "İ", "Iğdır" should NOT be a match.

So I used the following:

function toLowerTurkish(str) {
  var letters = {
    'Ç': 'ç', 'Ğ': 'ğ', 'I': 'ı', 'İ': 'i', 'Ö': 'ö', 'Ş': 'ş', 'Ü': 'ü',
  };
  str = str.replace(/(([ÇĞIİÖŞÜ]))/g, function(letter) { return letters[letter]; });
  return str.toLowerCase();
}

function containsTurkish(txt, str) {
  return toLowerTurkish(txt).indexOf(toLowerTurkish(str)) >= 0;
}

var itemList = [
  { label: 'İzmir',    value: 'İzmir' },
  { label: 'istanbul', value: 'istanbul' },
  { label: 'Iğdır', value: 'Iğdır' },
  { label: 'ısparta', value: 'ısparta' }
];

function autocompleteSourceTurkish(request, response) {
  var matchList = [];
  itemList.forEach(function(item, index) {
    if (containsTurkish(item.label, request.term)) matchList.push(item);
  });
  response(matchList);
}

$(function() {
  $('#itemMenu').autocomplete({
    source: autocompleteSourceTurkish
  });
});

http://jsfiddle.net/emfy5gf9/



来源:https://stackoverflow.com/questions/11237394/jquery-autocomplete-case-sensitive-for-utf-8-characters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!