0

同じhtmlページに複数の語彙テーブルがあります。

各語彙テーブルの上で、ユーザーがテキスト入力フィールドに単語またはフレーズを入力して、入力された文字列(単語またはフレーズ)を含むテーブル行のみを表示できるようにしたいと思います。たとえば、テキスト入力フィールドに「good」と入力すると、文字列「good」を含まないテーブル行は表示されなくなります。http://www.amanado.com/idioma-colombiano/にアクセスし、「Vocabulario(oficial y de jerga)-palabras y frases comunes」をクリックしてアコーディオンセクションを展開し、「good」と入力すると、これはすでに機能しています。 「Ingresapalabraofrase en el siguiente campo parafiltrarlainformacióndelatabla」という単語の下のテキスト入力フィールドにあります。テキスト入力フィールドに「good」と入力すると、語彙テーブルの7行を除くすべてが消えます(7行が残ります)。

私は次の3つの問題を抱えています:

1)大文字と小文字がすでに正常に無視されているのと同じように、アクセント(たとえば、é、ñ、ü)を無視することはできません。たとえば、ユーザーが入力フィールドに「que」と入力した場合、「que」と「qué」を含む行が消えることはありません。ただし、「que」と入力すると、「qué」を含む行が誤って表示されなくなります。ご覧のとおり、入力フィールド(引用符を除く)に「que」と入力すると、「que」を含む2つのレコードが残ります。また、入力フィールド(引用符を除く)に「qué」と入力または貼り付けると、「qué」を含む6つのレコードが残ります。

2) jquery.highlight.jsのバージョンを使用して、残っている/消えない行の文字列の一致を強調表示しようとしています。これが視覚的にどのように見えるかの例として、この質問の要約の2番目の段落で指示されている入力フィールドに「que」と入力すると、文字列「que」が残り/消えない2行で強調表示されます。スクリプト"$(" table td ")。highlight(" que ");"を挿入して "que"ハイライトをハードコーディングしたため、これは正しく機能しないことに注意してください。(a)jquery.highlight.jsがアクティブ/機能していることを示し、(b)強調表示されたテキストがどのように表示されるかを視覚的に示すために、htmlページの「head」セクションに挿入します。

3)ユーザーがフィールドに単語またはフレーズを入力して、入力された単語またはフレーズを含むテーブル行のみを表示できるようにするjavascriptに加えて、アクセント(たとえば、é、ñ、ü)を正常に無視できません。これは望ましい動作です。 jquery.highlight.jsスクリプトも、アクセント(たとえば、é、ñ、ü)を正常に無視していません。たとえば、この質問の概要の2番目の段落で指示されている入力フィールドに「pues」と入力すると、文字列「Qué」と「qué」の複数のケースが、残っている/消えない行で正常に強調表示されません。スクリプト「$( "tabletd")。highlight( "que");」を挿入して、「que」ハイライトをハードコーディングしたことを思い出してください。HTMLページのセクションに挿入するので、文字列「que」、「qué」、「Que」、「Qué」文字列「que」、「qué」、「Que」、または「Qué」のいずれかが入力フィールドに入力された場合に残る/消えないテーブル行ですべて強調表示する必要があります。 (b)アクセント(例、é、ñ、ü)は無視されます。私が使用しているjquery.highlight.jsのバージョンには、「ignoreAccents」の機能が含まれていることに注意してください。

以下は次のとおりです。

(a)私のhtmlに表示される入力フィールド。

(b)ユーザーがフィールドに単語またはフレーズを入力して、入力された単語またはフレーズを含むテーブル行のみを表示できるようにするために使用しているJavaScript(簡潔にするために、これを以下「フィルターJavaScript」と呼びます) ); と

(c)テキストを強調表示するために使用しているjquery.highlight.jsjavascriptのバージョン。

注:私はソフトウェアエンジニアではありませんが、誰かが具体的に何をすべきかを教えてくれた場合、変更を実装する方法を知っています(たとえば、この正確な変更を行ってから、この正確な変更を行ってから、この正確な変更を行います)。私は誰もが提供できるどんな援助にも感謝します、そして文字通りの指示は特にありがたいです。そして、最大限の成果を上げるために、最小限のコード(javascript、css、htmlなど)を使用することが常に私の意図です。

追加のメモ/考慮事項は、この質問の要約の下部に含まれています。

(a)入力フィールドはここから始まります

<form class="live-search" action="" method="post">
<p>Ingresa palabra o frase en el siguiente campo para filtrar la información de la tabla</p>
<input class="input-text-tr" type="text" value="Mostrar sólo filas que contengan..." />
<span class="filter-count-tr"></span>
</form>

(a)入力フィールドはここで終了します

(b)フィルターjavascriptはここから始まります

$(function() {
$(".input-text-tr").on('keyup', function(e) {
var disallow = [37, 38, 39, 40];//ignore arrow keys    
if($.inArray(e.which, disallow) > -1) {
return true;
}
var inputField = this,
val = this.value,
pattern = new RegExp(val, "i"),
$group = $(this).closest(".group"),
$trs = $group.find(".myTable tbody tr"),
$s;
if(val === '') {
$s = $trs;
}
else {
$s = $();
$trs.stop(true,true).each(function(i, tr) {
if(val !== inputField.value) {//if user has made another     keystroke
return false;//break out of .each() and     hence out of the     event handler
}
$tr = $(tr);
if ($tr.text().match(pattern)) {
$s = $s.add(tr);
}
});
//$trs.not($s).fadeOut();
$trs.not($s).hide();
}
$group.find(".filter-count-tr").text("(" + $s.show        ().length + ")");
}).on('focus blur', function() {
if (this.defaultValue == this.value) this.value = '';
else if (this.value == '') this.value = this.defaultValue;
});

$(".group").each(function() {
$this = $(this);
$this.find(".filter-count-tr").text("(" + $this.find("tbody     tr").length + ")");
});
});

(b)フィルターjavascriptはここで終了します

(c)jquery.highlight.jsjavascriptはここから始まります

jQuery.extend({
highlight: function (node, re, nodeName, className,     ignoreAccents) {
if (node.nodeType === 3) {

var nodeData = node.data;
if (ignoreAccents) {
nodeData = jQuery.removeDiacratics(nodeData);
}
var match = nodeData.match(re);
if (match) {
var highlight = document.createElement(nodeName || 'span');
highlight.className = className || 'highlight';    var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);    
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
return 1; //skip added node in parent
}
} else if ((node.nodeType === 1 && node.childNodes) && //     only element nodes that have children
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
!(node.tagName === nodeName.toUpperCase() &&
node.className === className)) { // skip if already     highlighted
for (var i = 0; i < node.childNodes.length; i++) {
i += jQuery.highlight(node.childNodes[i], re, nodeName, className, ignoreAccents);
}
}
return 0;
},

removeDiacratics : function(str) {
var rExps = [
{re:/[\xC0-\xC6]/g, ch:'A'},
{re:/[\xE0-\xE6]/g, ch:'a'},
{re:/[\xC8-\xCB]/g, ch:'E'},
{re:/[\xE8-\xEB]/g, ch:'e'},
{re:/[\xCC-\xCF]/g, ch:'I'},
{re:/[\xEC-\xEF]/g, ch:'i'},
{re:/[\xD2-\xD6]/g, ch:'O'},
{re:/[\xF2-\xF6]/g, ch:'o'},
{re:/[\xD9-\xDC]/g, ch:'U'},
{re:/[\xF9-\xFC]/g, ch:'u'},
{re:/[\xD1]/g, ch:'N'},
{re:/[\xF1]/g, ch:'n'}
];
for (var i = 0, len = rExps.length; i < len; i++) {
str = str.replace(rExps[i].re, rExps[i].ch);
}
return str;
}

});

jQuery.fn.unhighlight = function (options) {
var settings = { className: 'highlight', element: 'span' };
jQuery.extend(settings, options);

return this.find(settings.element + "." +     settings.className).each(
function () {
var parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
}).end();
};

jQuery.fn.highlight = function (words, options) {
var settings = { className: 'highlight', element: 'span',     caseSensitive: false, wordsOnly: false, ignoreAccents : true };
jQuery.extend(settings, options);

if (words.constructor === String) {
words = [words];
}
words = jQuery.grep(words, function(word, i) {
return word != '';
});
words = jQuery.map(words, function(word, i) {
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
});
if (words.length == 0) {
return this;
}

var flag = settings.caseSensitive ? "" : "i";
var pattern = "(" + words.join("|") + ")";
if (settings.wordsOnly) {
pattern = "\\b" + pattern + "\\b";
}

var re = [];
re.push(new RegExp(pattern, flag));

if (settings.ignoreAccents) {
var wordsNoAccents = jQuery.map(words, function(word, i) {
return jQuery.removeDiacratics(word);
});
var patternNoAccents;
if (settings.wordsOnly) {
// workaround for word separation using \\b
patternNoAccents = "( " + wordsNoAccents.join("|") + " )";
patternNoAccents = "\\b" + patternNoAccents + "\\b";
} else {
patternNoAccents = "(" + wordsNoAccents.join("|") + ")";
}
if (patternNoAccents!=pattern) {
re.push(new RegExp(patternNoAccents, flag));
}
}

return this.each(function () {
for (var i in re) {
jQuery.highlight(this, re[i], settings.element,     settings.className, settings.ignoreAccents);
}
});
};

(c)jquery.highlight.jsjavascriptはここで終了します

追加の注意事項/考慮事項はここから始まります

1)ユーザーがフィールドに単語またはフレーズを入力して、入力された単語またはフレーズを含むテーブル行のみを表示できるようにするために、すでに使用しているJavaScriptを拡張することを目的としています。これは、JavaScriptがすでに使用されているためです。上記の問題を除いて、usingは機能しています(私が公開した以前の質問に対するBeetrootの優れた貢献に感謝します)。

2)私が達成しようとしている機能に触れているjavascriptには、次の4つの例が含まれています(stackoverflowでは質問で2つ以上のリンクを使用できないため、「http://」を次のように置き換えました。以下の例の「[http:// here]」):

a) [http:// here]demopill.com/jquery-onpage-text-highlighter-and-filter.html[私が達成しようとしている機能に最もよく似ています。ユーザーが入力フィールドにテキストを入力すると、フィルターとハイライトが正常に行われるようです。大文字と小文字は正常に無視されますが、アクセント(たとえば、é、ñ、ü)は正常に無視されません];

b) [http:// here] stackoverflow.com/search?q=jquery.highlight.js(stackoverflow reのダイアログ:アクセント付き文字を無視する)

c) [http:// here] www.jquery.info/The-plugin-SearchHighlight(ハイライト機能を含む); と

d) [http:// here] docs.jquery.com/UI/Effects/Highlight(ハイライト機能が含まれています。この質問の概要の段落2で参照されているWebサイトですでに「jqueryui」を使用していることに注意してください)。

追加の注意事項/考慮事項はここで終了します

4

1 に答える 1

1

ハイライト

ページにjquery.highlight.jsインストールすると...

変化する :

$group.find(".filter-count-tr").text("(" + $s.show().length + ")");

に :

$group.find(".filter-count-tr").text("(" + $s.show().unhighlight().highlight(val).length + ")");

ただし、以下のアクセントを区別しないコードはこれを変更します。

アクセントの鈍感さ

これはほとんど不可能に思えましたが、アクセントを区別しない強調表示を提供するためにプラグインをどのように変更できるかを示す、これを見つけることに突破口がありました.hightlight

コードをよりよく理解するために、より良いプラグインにリファクタリングしました (とにかく私にとってはより良いものです)。jQuery名前空間にメンバーを配置せず(以前は 1 つ)、メンバーを 1 つjQuery.fn(以前は 2 つ) に配置するようになりました。新しいプラグインでは、ハイライトの設定と設定解除は次のように実行されます。

$(selector).highlight('set', words, options);
$(selector).highlight('unset', options);

説明とその他の例は、コードとともに提供されます (以下を参照)。

「set」設定には、「.accentInsensitive」オプションが含まれています。これは、キャッシュするプラグインのプライベート メンバーを使用して管理できる限り効率的に実装された、限られた数のハードコードされた (スペイン語の) アクセント付き文字グループで動作します (後悔しています)。後で「set」メソッドで使用するための再利用可能な正規表現と置換文字列。一般化された「Unicode 正規化」ソリューションを使用する方がはるかに優れていますが、それはまた別の機会にします。

新しいプラグインはまた、コードの一部を別のメソッドとして分割する機会を.makepattern提供しました. この機能により、ここでのもう 1 つの目的、つまりアクセントを区別しないフィルタリングを達成するためのリソースとしてプラグインを使用できるようになり、使用される RegExp パターン (強調表示とフィルタリングに) が同一であるという絶対的な確実性が得られます。

プラグインコードは次のとおりです。

/*
 * jQuery highlightIt plugin
 * by Beetroot-Beetroot
 * https://stackoverflow.com/users/1142252/beetroot-beetroot
 *
 * based on Highlight by Bartek Szopka, 2009
 * http://bartaz.github.com/sandbox.js/jquery.highlight.html,
 * based on highlight v3 by Johann Burkard
 * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
 *
 * Most important changes:
 * - Code refactored into jQuery preferred plugin pattern.
 * - Now called with : 
 *    - $(slector).highlight('set', words, options); previously $(slector).highlight(words, options);
 *    - $(slector).highlight('unset', options); previously $(slector).unhighlight(options);
 *    - $().highlight('makePattern', words, options); This new option returns a RegExp-ready pattern that can be used externally and/or re-injected for reuse (see .isPattern option below), thus avoiding remaking the pattern as might otherwise happen.
 *  - 'set' .isPattern option; When true, this new option indicates that the 'words' parameter is a prepared RegExp-ready pattern.
 *  - 'set' .accentInsensitive option; This new option is limited to operating on hard-coded character groups (eg, Spanish accented chars), not Unicode normalized (which would be a better approach but much harder to achieve and probably slower).
 *
 * Usage:
 *   // wrap every occurrance of text 'lorem' in content
 *   // with <span class='highlight'> (default options)
 *   $('#content').highlight('set', 'lorem');
 *
 *   // search for and highlight more terms at once
 *   // so you can save some time on traversing DOM
 *   $('#content').highlight(['set', 'lorem', 'ipsum']);
 *   $('#content').highlight('set', 'lorem ipsum');
 *
 *   // search only for entire word 'lorem'
 *   $('#content').highlight('set', 'lorem', { wordsOnly: true });
 *
 *   // don't ignore case during search of term 'lorem'
 *   $('#content').highlight('set', 'lorem', { caseSensitive: true });
 *
 *   // wrap every occurrance of term 'ipsum' in content
 *   // with <em class='important'>
 *   $('#content').highlight('set', 'ipsum', { element: 'em', className: 'important' });
 *
 *   // remove default highlight
 *   $('#content').highlight('unset');
 *
 *   // remove custom highlight
 *   $('#content').highlight('unset', { element: 'em', className: 'important' });
 *
 *   // get accent-insensitive pattern
 *   $().highlight('makePattern', { element: 'lorem', {'accentInsensitive':true});
 *
 *
 * Copyright (c) 2009 Bartek Szopka
 *
 * Licensed under MIT license.
 *
 */

(function($) {
    // **********************************
    // ***** Start: Private Members *****
    var pluginName = 'highlight';
    var accentedForms = [//Spanish accednted chars
        //Prototype ...
        //['(c|ç)', '[cç]', '[CÇ]', new RegExp('(c|ç)','g'), new RegExp('(C|Ç)','g')],
        ['(a|á)', '[aá]'],
        ['(e|é)', '[eé]'],
        ['(i|í)', '[ií]'],
        ['(n|ñ)', '[nñ]'],
        ['(o|ó)', '[oó]'],
        ['(u|ú|ü)', '[uúü]']
    ];
    //To save a lot of hard-coding and a lot of unnecessary repetition every time the "set" method is called, each row of accentedForms is now converted to the format of the prototype row, thus providing reusable RegExps and corresponding replacement strings.
    //Note that case-sensitivity is established later in the 'set' settings so we prepare separate RegExps for upper and lower case here.
    $.each(accentedForms, function(i, af) {
        af[2] = af[1].toUpperCase();
        af[3] = new RegExp(af[0], 'g');
        af[4] = new RegExp(af[0].toUpperCase(), 'g');
    });
    var h = function(node, re, settings) {
        if (node.nodeType === 3) {//text node
            var match = node.data.match(re);
            if (match) {
                var wordNode = node.splitText(match.index);
                wordNode.splitText(match[0].length);
                $(wordNode).wrap($("<" + settings.element + ">").addClass(settings.className));
                return 1;
           }
        } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
                !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
                !(node.tagName === settings.element.toUpperCase() && node.className === settings.className)) { // skip if already highlighted
            for (var i = 0; i < node.childNodes.length; i++) {
                i += h(node.childNodes[i], re, settings);
            }
        }
        return 0;
    };
    // ***** Fin: Private Members *****
    // ********************************

    // *********************************
    // ***** Start: Public Methods *****
    var methods = {
        //This is a utility method. It returns a string, not jQuery.
        makePattern: function (words, options) {
            var settings = {
                'accentInsensitive': false
            };
            $.extend(settings, options || {});
            if (words.constructor === String) {
                words = [words];
            }
            words = $.grep(words, function(word, i) {
              return word != '';
            });
            words = $.map(words, function(word, i) {
              return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
            });
            if (words.length == 0) { return ''; };
            var pattern = "(" + words.join("|") + ")";
            if (settings.accentInsensitive) {
                $.each(accentedForms, function(i, af) {
                    pattern = pattern.replace(af[3], af[1]).replace(af[4], af[2]);
                });
            }
            return pattern;
        },
        set: function (words, options) {
            var settings = {
                'className': 'highlight',
                'element': 'span',
                'caseSensitive': false,
                'wordsOnly': false,
                'accentInsensitive': false,
                'isPattern': false
            };
            $.extend(settings, options || {});

            var pattern = settings.isPattern ? words : methods.makePattern(words, settings);
            if (pattern === '') { return this; };
            if (settings.wordsOnly) {
                pattern = "\\b" + pattern + "\\b";
            }
            var flag = settings.caseSensitive ? "" : "i";
            var re = new RegExp(pattern, flag);
            return this.each(function () {
                h(this, re, settings);
            });
        },
        unset: function (options) {
            var settings = {
                className: 'highlight',
                element: 'span'
            }, parent;
            $.extend(settings, options || {});
            return this.find(settings.element + "." + settings.className).each(function () {
                parent = this.parentNode;
                parent.replaceChild(this.firstChild, this);
                parent.normalize();
            }).end();
        }
    };
    // ***** Fin: Public Methods *****
    // *******************************

    // *****************************
    // ***** Start: Supervisor *****
    $.fn[pluginName] = function( method ) {
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || !method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' + method + ' does not exist in jQuery.' + pluginName );
        }
    };
    // ***** Fin: Supervisor *****
    // ***************************
})( jQuery );

言語サイトのアプリケーション コードは次のとおりです。

$(function() {
    $(".text-input").on('keyup', function(e) {
        var disallow = [37, 38, 39, 40];//ignore arrow keys
        if($.inArray(e.which, disallow) > -1) {
            return true;
        }
        var $group = $(this).closest(".group"),
            accent_sensitive = false,
            case_sensitive = false,
            val = this.value,
            pattern = $().highlight('makePattern', val, {
                'accentInsensitive': !accent_sensitive,
                'caseSensitive': case_sensitive
            }),
            $trs = $group.find(".myTable tbody tr"),
            $s;
        if(val === '') {
            $s = $trs;
        }
        else {
            $s = $();
            $trs.stop(true,true).each(function(i, tr) {
                $tr = $(tr);
                //if ($tr.text().match(new RegExp(pattern, "i"))) {
                if ($tr.text().match(new RegExp(pattern, case_sensitive ? '' : "i"))) {
                    $s = $s.add(tr);
                }
            });
            $trs.not($s).hide();
        }
        $group.find(".filter-count-tr").text("(" + $s.show().highlight('unset').highlight('set', pattern, {
            'isPattern':true,
            'caseSensitive':case_sensitive
        }).length + ")");
    }).on('focus blur', function() {
        if (this.defaultValue == this.value) this.value = '';
        else if (this.value == '') this.value = this.defaultValue;
    });

    $(".group").each(function() {
        $this = $(this);
        $this.find(".filter-count-tr").text("(" + $this.find("tbody tr").length + ")");
    });
});

すべてテスト済みなので、正しくインストールすれば動作するはずです。

ところで、このページをスペイン語アクセント文字のソースとして使用しました。

于 2012-07-04T22:03:43.030 に答える