通过jqGrid filterToolbar不区分大小写的搜索找不到特殊的土耳其字符

通过jqGrid filterToolbar不区分大小写的搜索找不到特殊的土耳其字符

问题描述:

我在使用jqGrid filterToolbar时出现问题。工具栏进行搜索,但无法找到包含"ı"的字符。例如,我可以搜索"yapi"单词,但搜索工具栏找不到"yapı"通过jqGrid filterToolbar不区分大小写的搜索找不到特殊的土耳其字符

jQuery("#grid-table").jqGrid('filterToolbar', 
    { stringResult: false, searchOperators: false, defaultSearch: "cn" }); 

我的页面编码是;

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 

和我的AJAX职位是这里

$阿贾克斯({ 类型: “邮报”, 网址: “页/ get.aspx, 的contentType:” 应用/ json; charset = utf-8“, dataType:”json“, data:”{}“, success:function(){ // }, error:function(){ // } });

我确定问题在于您使用的HTML页面的编码。我试图重现这个问题,并打开一个保存在ANSI编码中的旧演示。在数据中插入测试yapı并保存后,我可以再现问题,但验证代码表明字符串yapı由于ANSI编码而被保存为yapi。然后我使用记事本打开了相同的演示(我在Windows计算机上工作)重复相同的操作,并且使用SaveAs可以选择UTF-8编码。现在,人们可以在网格中显示yapı字符串,而不是yapi,我可以成功筛选字符串。因为我在两次实验中都有<meta charset="utf-8">

因此,您应该验证不仅<meta charset="utf-8">存在于您的HTML页面的<head>中,而且数据也使用UTF-8编码。在嵌入数据的情况下(如在我的实验中),文件需要以UTF-8格式保存。

更新:在评论的讨论表明,主要的问题是土耳其文的不区分大小写的过滤。

问题是绝对新的我,但土耳其语有 i:一个点上i,另一个没有ıi都有相应的资本IİI。所有的信息与许多其他语言没有什么不同。主要问题在于选择4个字符的Unicode表示法:土耳其字符iI使用相同的代码,如拉丁字符U+0069U+0049。只有字符ıİ将映射到U+0131U+0130(请参阅here)。这种映射使得不可能实现不区分大小写的比较或JavaScript函数.toUpperCase().toLowerCase()。如果输入的文本包含拉丁文字母i,那么函数.toUpperCase()应将其转换为I,但它对土耳其语不正确,应改为İ.toLowerCase()对于土耳其文应该产生ı,对于英文文本应该产生i

因此,第一个重要信息:如果不知道输入语言,就不可能实现一个通用版本的不区分大小写的比较。

好的。现在回到问题。如何在土耳其语文本中实现不区分大小写的搜索?在版本4.7.1中更改了jqGrid的许可协议后,我继续开发免费版本(在MIT和GPL v2许可下),名称为free jqGrid。我在免费jqGrid的第一个版本中实现了许多新功能:4.8版。 the wiki article中描述的“自定义过滤”功能可以帮助实施。

基于我创建的功能the following demo。在实现期间,我在免费jqGrid的代码中进行了一些小错误修复。所以我在演示中使用GitHub(http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js)的最新源代码(有关URL,请阅读wiki)。

我用下面的选项中的jqGrid

ignoreCase: false, 
customSortOperations: { 
    teq: { 
     operand: "==", 
     text: "Turkish insensitive \"equal\"", 
     filter: function (options) { 
      var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(), 
       searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(); 
      return fieldData === searchValue; 
     } 
    }, 
    tne: { 
     operand: "!=", 
     text: "Turkish insensitive \"not equal\"", 
     filter: function (options) { 
      var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(), 
       searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(); 
      return fieldData !== searchValue; 
     } 
    }, 
    tbw: { 
     operand: "^", 
     text: "Turkish insensitive \"begins with\"", 
     filter: function (options) { 
      var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(), 
       searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(); 
      return fieldData.substr(0,searchValue.length) === searchValue; 
     } 
    }, 
    tbn: { 
     operand: "!^", 
     text: "Turkish insensitive \"does not begin with\"", 
     filter: function (options) { 
      var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(), 
       searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(); 
      return fieldData.substr(0,searchValue.length) !== searchValue; 
     } 
    }, 
    tew: { 
     operand: "|", 
     text: "Turkish insensitive \"end with\"", 
     filter: function (options) { 
      var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(), 
       searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(), 
       searchLength = searchValue.length; 

      return fieldData.substr(fieldData.length-searchLength,searchLength) === searchValue; 
     } 
    }, 
    ten: { 
     operand: "[email protected]", 
     text: "Turkish insensitive \"does not end with\"", 
     filter: function (options) { 
      var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(), 
       searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(), 
       searchLength = searchValue.length; 

      return fieldData.substr(fieldData.length-searchLength,searchLength) !== searchValue; 
     } 
    }, 
    tcn: { 
     operand: "~", 
     text: "Turkish insensitive \"contains\"", 
     filter: function (options) { 
      var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(), 
       searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(); 
      return fieldData.indexOf(searchValue,0) >= 0; 
     } 
    }, 
    tnc: { 
     operand: "!~", 
     text: "Turkish insensitive \"does not contain\"", 
     filter: function (options) { 
      var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(), 
       searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(); 
      return fieldData.indexOf(searchValue,0) < 0; 
     } 
    } 
} 

选项customSortOperations定义新的自定义操作不区分大小写土耳其文本的比较。要使用该选项一个只需要指定searchoptions的操作对于其中包含土耳其文本列:

searchoptions: { sopt: ["tcn", "tnc", "teq", "tne", "tbw", "tbn", "tew", "ten"] } 

由于过滤使用“TCN”(Turkish insensitive "contains")作为默认过滤操作的结果。如果使用filterToolbarsearchOperators: true选项,则可以选择其他搜索操作。我希望所有上述定制比较操作都是正确的,并且可以在土耳其网格中使用。

更新2:我发现了一个更多的兴趣执行选项:支持参数的方法localeCompare。我测试了谷歌浏览器

"i".localeCompare("İ", "tr", { sensitivity: "base" }) === 0 
"i".localeCompare("I", "tr", { sensitivity: "base" }) === 1 
"ı".localeCompare("I", "tr", { sensitivity: "base" }) === 0 
"ı".localeCompare("İ", "tr", { sensitivity: "base" }) === -1 

"i".localeCompare("İ", "tr", { sensitivity: "accent" }) === 0 
"i".localeCompare("I", "tr", { sensitivity: "accent" }) === 1 
"ı".localeCompare("I", "tr", { sensitivity: "accent" }) === 0 
"ı".localeCompare("İ", "tr", { sensitivity: "accent" }) === -1 

但在IE11相同的测试失败相反the information about the browser compatibility。以上所有呼叫localeCompare在IE11中返回0。可以使用其他值sensitivity来获得预期结果。对于localeCompare以上的调用,IE9会返回1或-1。我想它只考虑第一个参数并忽略"tr", { sensitivity: "base" }部分。在Chrome结果看起来那么

enter image description here

一个具有相同的结果在Firefox

enter image description here

但不是在IE11

enter image description here

一个更多的选择将是使用The ECMAScript Internationalization APIIntl.Collator (见ecma-402here),像

new Intl.Collator("tr", { sensitivity: "base" }).compare("i", "İ") 

例如,但IE浏览器似乎是在情况也好不了多少。

以任何方式,我想可以通过包含浏览器检测部分来改进上述解决方案,该部分为比较的实现选择闭包,以及稍后在customSortOperations之内使用最佳实现。不过上面的代码工作安全,但可能原因不那么高雅。

+0

非常感谢@Oleg。 – 2015-04-07 05:21:11

+0

@MuratFurkanSönmez:不客气! – Oleg 2015-04-07 07:24:03