2015-04-02 60 views
1

我在使用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(){ // } });

回答

1

我確定問題在於您使用的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