1

jqGrid を使用しているときに問題が発生しましfilterToolbarた。ツールバーは検索を行いますが、含む文字を見つけることができません"ı"。たとえば、"yapi"単語を検索できますが、検索ツールバーでは"yapı".

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

私のページのエンコーディングは;

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

そして私のajax投稿はここにあります

$.ajax({ type: "Post", url: "page/get.aspx, contentType: "application/json; charset=utf-8", dataType: "json", data: "{}", success: 関数() { // }、エラー: 関数 () { // } });

4

1 に答える 1

1

問題は、使用している HTML ページのエンコーディングにあると確信しています。問題の再現を試み、ANSI エンコーディングで保存された古いデモを開きました。テストyapıをデータに挿入して保存した後、問題を再現できましたが、コードを検証すると、文字列がANSI エンコーディングのためyapıに保存されたことがわかりました。yapi次に、メモ帳 (私は Windows コンピューターで作業しています) を使用して同じデモを開き、同じことを繰り返し、SaveAs を使用して UTF-8 エンコーディングを選択できるようにしました。これで、以前ではなく実際yapıに文字列がグリッドに表示されるようになりyapi、文字列を正常にフィルター処理できました。もちろん、私は<meta charset="utf-8">両方の実験中に持っていました。

したがって、HTML ページに<meta charset="utf-8">存在するだけ<head>でなく、データが UTF-8 エンコーディングであることも検証する必要があります。埋め込みデータの場合 (私の実験のように)、ファイルは UTF-8 形式で保存する必要があります。

更新:コメントでの議論は、主な問題がトルコ語テキストの大文字と小文字を区別しないフィルタリングであったことを示しています。

この問題は私にとってまったく新しいものでしたが、トルコ語には2 iの問題がiあります。両方とも対応する大文字:と. すべての情報は、他の多くの言語と同じです。主な問題は、4 つの文字の Unicode 表現の選択にあります: トルコ語の文字 で、ラテン文字の:とのような同じコード を使用します。文字とのみが andにマップされます(こちらを参照)。このようなマッピングにより、大文字と小文字を区別しない比較または JavaScript 関数を実装できなくなりますıiIİIiIU+0069U+0049ıİU+0131U+0130.toUpperCase().toLowerCase()。入力テキストにラテン文字が含まれている場合i、関数.toUpperCase()はそれを に変換するI必要がありますが、トルコ語では間違っているため、İ代わりに変換する必要があります。同様に、トルコ語のテキストと英語のテキスト.toLowerCase()を生成する必要があります。ıi

したがって、最初の重要な情報:入力言語の知識がなければ、大文字と小文字を区別しない比較のユニバーサル バージョンを 1 つ実装することは不可能です

わかった。さて、問題に戻ります。トルコ語のテキスト内で大文字と小文字を区別しない検索を実装するには? バージョン 4.7.1 で jqGrid のライセンス契約が変更された後、私は free jqGrid という名前で (MIT および GPL v2 ライセンスの下で) 無料バージョンの開発を続けています。無料の jqGrid バージョン 4.8 の最初のリリースで、多くの新機能を実装しました。wiki 記事で説明されている「カスタム フィルタリング」機能は、実装に役立ちます。

機能に基づいて、次のデモを作成しました。無料の jqGrid のコードの実装中にいくつかの小さなバグ修正を行いました。http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.jsそのため、デモではGitHub ( ) の最新のソースを使用します ( 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: "!@",
        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"] }

その結果、フィルタリングはTurkish insensitive "contains"デフォルトのフィルタリング操作として「tcn」( ) を使用します。searchOperators: trueのオプションを使用するとfilterToolbar、別の検索操作を選択できます。上記のカスタム比較操作がすべて正しく、トルコのグリッドで使用できることを願っています。

更新 2:もう 1 つの興味深い実装オプションを見つけました:パラメータをサポートするメソッドlocaleCompareです。私はGoogle Chromeでそれをテストしました

"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 での同じテストは失敗しました。上記の呼び出しはすべて IE11 でlocaleCompare返さ0れます。sensitivityの別の値を使用して、期待される結果を得ることができる場合があります。IE9 は代わりに、上記の の呼び出しに対して 1 または -1 を返しますlocaleCompare。最初のパラメータだけを考慮し、"tr", { sensitivity: "base" }一部を無視していると思います。Chrome での結果は次のようになります

ここに画像の説明を入力

Firefoxでも同じ結果が得られます

ここに画像の説明を入力

しかしIE11にはありません

ここに画像の説明を入力

もう 1 つのオプションは、ECMAScript 国際化 APIクラスIntl.Collat​​or ( ecma-402hereを参照) を使用することです。

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

たとえば、IEはこの場合あまり優れていないようです。

いずれにせよ、compare の実装のためのクロージャを選択し、customSortOperations後で内部で最適な実装を使用するブラウザ検出部分を含めることで、上記のソリューションを改善できると思います。それにもかかわらず、上記のコードは安全に動作しますが、おそらくそれほどエレガントではないのが原因です。

于 2015-04-02T14:49:08.747 に答える