• 締切済み

[Javascript]セル内の文字列の部分一致でテーブルの列を絞り込

[Javascript]セル内の文字列の部分一致でテーブルの列を絞り込みたい。 現在、Javascriptを使って表のソートや絞り込みができるページを作っています。 http://www.asahi-net.or.jp/~mc9m-ehr/soft/script/filterSample_01.htm こちらのような感じで、 ドロップダウンリストからキーワードを選ぶと、 該当する列が絞り込み表示できるようにしたいのですが、 このままのスクリプトだと、セル内の文字列が完全に一致しないとできないようです。 現状はhead内に<script type="text/javascript" src="tablefilter.js"></script>と書き、 bodyの部分に <select onchange="tblfilter('tableID',this.options[this.selectedIndex].value,1,1,0);"> <option value="All">カテゴリー</option> <option value="ミステリ">ミステリ</option> <option value="恋愛小説">恋愛小説</option> <option value="ノンフィクション">ノンフィクション</option> ・ ・ ・ </select> のような感じでドロップダウンリストを付けています。 表の内容は左から順に以下のように並んでいます↓ [1]本の表紙画像 [2]本のカテゴリー(コミック、洋書、ミステリ、ホラー、純文学など1セルにつき一つ) [3]著者名:本の題名(例 村上春樹:ノルウェイの森) [4]100~200文字程度の感想+キーワード(恋愛、笑い、泣ける、映画原作など1セルに複数) [5]読了日(例 2010/10/07) キーワードは、セルの中にリストタグを入れて横並びで表現しています。 上で挙げたスクリプトを使うと、 [2]は1セルに1つなのでそれをドロップダウンリストに入れて絞り込むことはできるのですが、 [3]だと著者名と本の題名の両方が一致していないと絞り込めません。 [4]でキーワードにしてある言葉をドロップダウンリストに入れて、 該当するものを抽出できるようにもしたいのですが、これもできません。 これが出来るような配布スクリプトをご存じであれば教えてください。 もしくは、上記のスクリプト(tablefilter.js)に少し手を加えることで実現できるなら、 具体的にご教示いただけるとうれしいです。

みんなの回答

回答No.11

 TableViewer.prototype.reverse = reverse;  TableViewer.prototype.reset = reset;  TableViewer.prototype.limit = limit;  TableViewer.prototype.find = find; //____________  this.createTableViewer = create; })(); var table = createTableViewer (document.getElementById ('hoge')); </script>

回答No.10

<script type="application/javascript; version=1.8"> (function () { // Asymmetrical JavaScript Abridgment Exclusively  var getTR = // tr を集める   (function (collect)    function (table)      Array.reduce (table.tBodies, collect, []))   (function (result, tbody)    result.concat (Array.slice (tbody.rows, 0)));  var ariaHidden = // mode によって、それようの関数を返す   function (mode)    let (state = String (!!mode))     function (tr) tr.setAttribute ('aria-hidden', state); //____________  var TableViewer = function (node) { // オブジェクト   this.table = node;   this.reset ();  };  var reset = // 初期化。すべて表示にする   function ()    (Array.forEach (getTR (this.table), ariaHidden (false)), this);  var limit = // 表示数の制限をする   function (n)    let (tr = getTR (this.table))    let (after = Array.slice (tr, n))     (Array.forEach (after, ariaHidden (true)), this);  var reverse = // 表示状態を反転する   (function (toggle)    function ()     (Array.forEach (getTR (this.table), toggle), this))   (function (tr)    tr.setAttribute ('aria-hidden', String (tr.getAttribute ('aria-hidden') === 'false')));  var find = // 検索   (function (checker, setter)    function (reg, index)     (Array.forEach (getTR (this.table), checker (reg, index, setter)), this))      (function (reg, index, setter)    'undefined' === typeof index // index により用途に合った関数を返す     ? function (tr) (! reg.test (tr.textContent)) && setter (tr) // 行全体で検索     : function (tr) (! reg.test (tr.cells[index].textContent)) && setter (tr), // セル単体で検索    ariaHidden (true)); // = setter 非表示用の関数にする    var create =   function (table)    ('tagName' in table && 'TABLE' === table.tagName)     ? new TableViewer (table)     : null; //____________

回答No.9

かきなおし。 <!DOCTYPE html> <title></title> <style type="text/css"> tr[aria-hidden="true"] { visibility: collapse; } </style> <form> <p> <select onchange="table && table.find(new RegExp( this.value ), 1)"> <option value="">- <option value="岩手">岩手県 <option value="青森">青森県 </select> <select onchange="table && table.find(new RegExp( this.value ), 2)"> <option value="">- <option value="市">市 <option value="町">町 </select> <select onchange="table && table.find(new RegExp( this.value ), 3)"> <option value="">- <option value="おいしい">おいしい <option value="おしい">おしい <option value="お.*しい">お*しい </select> <select onchange="table && table.limit(this.value)"> <option value="100">- <option value="1">1件 <option value="3">3件 <option value="5">5件 </select> <input type="button" value="Reverse" onclick="table && table.reverse ()"> <input type="button" value="Reset" onclick="table && table.reset ()"> </p> </form> <table border="1" id="hoge"> <thead> <tr> <th>No <th>Prefecture <th>Cities <th>Comments </thead> <tbody> <tr> <td>1 <td>岩手県 <td>洋野町 <td>ウニがおいしい <tr> <td>2 <td>青森県 <td>八戸市 <td>イカがおいしい <tr> <td>3 <td>岩手県 <td>久慈市 <td>美しすぎる海女さんで、おしい <tr> <td>4 <td>青森県 <td>八戸市 <td>美しすぎる市議会議員で、さわがしい <tr> <td>5 <td>岩手県 <td>洋野町 <td>鮑がおいしい <tr> <td>6 <td>青森県 <td>八戸市 <td>B級グルメ「せんべい汁」がおいしい <tr> <td>7 <td>岩手県 <td>洋野町 <td>天然ホヤがおいしい </table>

回答No.8

ていせいのやつに、ついかです。 <style type="text/css"> tr[aria-hidden="true"] { display: none; } </style> visibility:hidden; とか いろいろ、やりようがあるようです

回答No.7

ていせい。 <script type="application/javascript; version=1.8"> (function () { // Asymmetrical JavaScript Abridgment Exclusively function TableViewer (node) {  this.table = node;  this.reset (); } var reset =  (function (toDisp)   function () {    var tr = this.table.querySelectorAll ('tbody > tr');    Array.forEach (tr, toDisp);    return this;   })(function (tr) tr.setAttribute ('aria-hidden', 'false')); var limit =  (function (toHide)   function (n) {    var tr = this.table.querySelectorAll ('tbody > tr[aria-hidden="false"]');    Array.forEach (Array.slice (tr, n), toHide);    return this;   }  )(function (tr) tr.setAttribute ('aria-hidden', 'true')); var reverse =  (function (toDisp, toHide)   function () {    var tr_disp = this.table.querySelectorAll ('tbody > tr[aria-hidden="false"]');    var tr_hide = this.table.querySelectorAll ('tbody > tr[aria-hidden="true"]');    Array.forEach (tr_disp, toHide);    Array.forEach (tr_hide, toDisp);    return this;   }  )(function (tr) tr.setAttribute ('aria-hidden', 'false'),   function (tr) tr.setAttribute ('aria-hidden', 'true')); var find =  function (reg, index) {   Array.forEach (    this.table.querySelectorAll ('tbody > tr[aria-hidden="false"]'),    function (tr)     (! reg.test (('undefined' === typeof index ? tr: tr.cells[index]).textContent)) &&     tr.setAttribute ('aria-hidden', 'true'));   return this;  }; function create (tableNode) {  if ('tagName' in tableNode)   if ('TABLE' === tableNode.tagName)    return new TableViewer (tableNode); } TableViewer.prototype.reverse = reverse; TableViewer.prototype.reset = reset; TableViewer.prototype.limit = limit; TableViewer.prototype.find = find; this.createTableViewer = create; })(); var table = createTableViewer (document.getElementById ('hoge')); table.find (/市/).limit(3).reverse(); </script>

回答No.6

てーぶるのすぐしたについかしてね! <script type="application/javascript; version=1.8"> (function () {    var filter =   (function (tr)    function (cbObj) {     Array.forEach (this.tBodies, tr, cbObj);     return this;    })   (function (tbody) Array.forEach (tbody.rows, this.func, this));      function TableViewer (node) {   this.table = node;  }  var search = function (td) {     }    var reset =   (function (disp)    function () {     filter.call (this.table, { func: disp });     return this;    })(function (tr) tr.style.display = 'table-row');  var limit =   (function (tr)    function (n) {     filter.call (this.table, { func: tr, count: n || 0 });     return this;    })   (function (tr) {    if (tr.style.display !== 'none')     if (0 < this.count) {      tr.style.display = 'table-row';      this.count--;     }     else      tr.style.display = 'none';    });      var find =   (function (tr)    function (index, reg) {     filter.call (this.table, { func: tr, regExp: reg, cellIndex: index });     return this;    }   )(function (tr)     let (s = tr.style)     let (t = (this.cellIndex < 0 ? tr: tr.cells[this.cellIndex]).textContent)      s.display = this.regExp.test (t) ? 'table-row': 'none');      function create (tableNode) {   if ('tagName' in tableNode)    if ('TABLE' === tableNode.tagName)     return new TableViewer (tableNode);  };  TableViewer.prototype.reset = reset;  TableViewer.prototype.limit = limit;  TableViewer.prototype.find = find;  this.createTableViewer = create; })(); var table = createTableViewer (document.getElementById ('hoge')); table.reset ().find (3, /しい/).limit(4); </script>

回答No.5

ぶらうざをえらぶけど、たいこうして(?)かいてみた。 ぜんかくくうはくははんかくに。たぶんながいのでぶんかつ。 <!DOCTYPE html> <title></title> <table border="1" id="hoge"> <thead> <tr> <th>abc <th>def <th>ghi <th>jkl </thead> <tbody> <tr> <td>1 <td>岩手県 <td>洋野町 <td>ウニがおいしい <tr> <td>2 <td>青森県 <td>八戸市 <td>イカがおいしい <tr> <td>3 <td>岩手県 <td>久慈市 <td>美しすぎる海女さんで、おしい <tr> <td>4 <td>青森県 <td>八戸市 <td>美しすぎる市議会議員で、さわがしい <tr> <td>5 <td>岩手県 <td>洋野町 <td>鮑がおいしい <tr> <td>6 <td>青森県 <td>八戸市 <td>B級グルメ「せんべい汁」がおいしい <tr> <td>7 <td>岩手県 <td>久慈市 <td>天然ホヤがおいしい </tbody> </table>

  • think49
  • ベストアンサー率59% (285/482)
回答No.4

#2, 3 です。 質問者さんの要件を満たすコードを作成してみました。 #2 で紹介したリンク先から辿れます。(URLが変更される可能性があるので、ここには書きません)

liebeslide
質問者

お礼

ありがとうございます!!! テストで実装してみたのですが、きちんと部分一致で絞り込みできるようになりました。 #3でおっしゃっていた現象は、バグのようですね。気がつきませんでした。 ただ、ちょっと分からないことがあるのですが、 サンプルページの「rowFilter() のサンプル1」は何を意味しているのでしょう? とりあえず今必要なのはサンプル2だけかなと思い、スクリプトもそれだけ書いてあります。 それから、設置して絞り込みはちゃんとできているのですが、 「オブジェクトがありません」というエラーが出てしまいます。 該当箇所は if (element.addEventListener) { というところのようですが、これはどうしてなのでしょう???

  • think49
  • ベストアンサー率59% (285/482)
回答No.3

#2 です。 > http://www.asahi-net.or.jp/~mc9m-ehr/soft/script/filterSample_01.htm このスクリプト、挙動がおかしくないでしょうか? 左の selectボックスで [1] を選択してから、[2] を選択すると全て消えてしまいます。 常に絞り込み検索をしているようですが、これが期待通りの動作なのでしょうか…。

  • think49
  • ベストアンサー率59% (285/482)
回答No.2

作ってみました。 gist: 616387 (tableEditor.js) - GitHub http://gist.github.com/616387 --- var table = new TableEditor(document.getElementsByTagName('table')[0]); table.rowFilter(/Comic/, true, 0); table.rowFilter(/foo/, true, 1); --- rowFilter(searchReg, narrowFlag, cellIndex)  searchReg … マッチングさせる正規表現  narrowFlag … 絞り込み検索フラグ [true = 絞り込み検索する / false = 絞り込み検索しない(デフォルト)]  cellIndex … 検索対象となる列番号(DOM の cellIndex と同様 "0" を開始番号とする)。未指定時のデフォルトは全ての列から検索する。

関連するQ&A

  • 一致する文字を見つけ、それのみ表示させる方法

    javascriptを使って<body>内の<div>に含まれる文字と一致するものを絞り込み、残りは非表示にする方法を教えてください。 ドロップダウンで文字を選びOKボタンを押すと あ の場合は<div>内の「あ」が1つなので1つだけ表示され い は2つあるので2つ表示され う は3つ、というように idやclassをつけて判断させるのではなく、中身の文字のみを判断できるようにしたいです。 <html> <head> <title></title> <script type="text/javascript"> </script> </head> <body> <form> <select> <option value="">あ</option> <option value="">い</option> <option value="">う</option> </select> <input type="button" value="OK" onclick=""> </form> <div>あ</div> <div>い</div> <div>う</div> <div>い</div> <div>う</div> <div>う</div> </body> </html>

  • 【Excel】セル結合すると、ドロップダウンの表示文字が小さくなる

    結合しているセルに、入力規制の設定で、ドロップダウンの設定をしました。 ところが、ドロップダウンの文字があまりにも小さくて読み取れません。 おそらく、セルを10列分結合しているせいだと思うのですが・・・。 ドロップダウンのリストの文字を、結合セルの大きさで表示できる方法を教えて下さい。

  • エクセル 文字列のセルが###表示になります

    エクセル2000です。 文字列のセルで <SELECT name=show><OPTION selected value=_unselected_カラーを選択して下さい>カラーを選択して下さい</OPTION><OPTION value=カラー:BLACK&BLACK>カラー: BLACK&BLACK</OPTION><OPTION value=カラー:GOLD&GOLD>カラー: GOLD&GOLD</OPTION></SELECT> だと、表示されるのに、 <SELECT name=show><OPTION selected value=_unselected_カラーを選択して下さい>カラーを選択して下さい</OPTION><OPTION value=カラー:BLACK&BLACK>カラー: BLACK&BLACK</OPTION><OPTION value=カラー:GOLD&GOLD>カラー: GOLD&GOLD</OPTION><OPTION value=カラー:CLOME SILVER>カラー: CLOME SILVER</OPTION></SELECT> だと、#########表示になります。 セルの幅を広げても変化ありません。 数式バーにカーソルを置くと(文字を入力する状態にすると)数式バーにもセルにも内容は表示されますが、確定するとセルは###表示に戻ります。(確定後も数式バーには内容が表示されています) セルの書式設定は、どちらも文字列で、配置なども全く同じです。"折り返して表示"や"縮小して表示"なども試しましたが、変わりません。 セルの書式設定で表示形式を色々試してみたところ、サンプル表示で###になるのは、「標準・会計・文字列」でした。その他の表示形式にすると(数値など)にすると正しく表示されます。 表示形式を「数値」にしてもよいのですが、できれば「文字列」で統一しておきたいのですが・・・。 原因はわかりますでしょうか?

  • エクセル リスト 一致文字列セル抽出

    エクセルでランダムにあるリストの中から 末尾が一致する文字列のセルだけ抽出することは出来ますか 例えば、下記のよなリストの場合「~丼」だけ抽出することは出来ますか 焼肉定食 餃子 イクラ丼 すき焼き スパゲッティー ピザ うな丼 親子丼 ハンバーグ シューマイ 玉子丼 お願い致します。

  • A列と完全一致したセルとその右隣だけを残す

    A列に10000行ほど、キーワードが記入されています。 B列~Q列にもキーワードが記入されていて、 そのB列~Q列内で、A列と完全一致したセルとその右隣だけを残す(他のセルは空欄にする) という風にしたいです。 例: A列 B列 C列 D列 E列 東京 東京 ラーメン 大阪 ケーキ 神奈川 岡山 お好み焼き 広島 イカ焼き 静岡 沖縄 そば 石川 パスタ 大阪 滋賀 コーヒー 大阪 たこ焼き ↓ A列 B列 C列 D列 E列 東京 東京 ラーメン 神奈川 静岡 大阪 大阪 たこ焼き このような形になるのが理想です。 これは、マクロでできるでしょうか? どのような記述でできますか? よろしくお願いいたします。

  • Excelのリストで1文字目のみをセルに表示したい

    質問させていただきます。 Excelでドロップダウンリストに表示される文字の一文字目のみをセルに表示したいのですが何か方法はありますか? ドロップダウンリストには 1 トマト 2 スイカ 3 リンゴ と表示されて選択をするとセルには一文字目の数字のみが出るというような形です。 よろしくお願いいたします。

  • [JavaScript]ドロップコンボで文字列から指定したい!

    こんにちわ。 現在簡単なウェブ画面を作成中ですが行き詰った部分がどうしても乗り切れないのでお聞きします。 宜しくお願い致します。 まず、 <SELECT name="country"> <OPTION value="1">JAPAN</OPTION> <OPTION value="2">USA</OPTION> </SELECT> というドロップコンボがあるとします。 これをJavaScriptで指定する場合、 document.myform.country.options[0].selected = true; という形でするのはわかりますが、JAPANやUSAから指定することはできませんか? こんなコマンドあればうれしいんですが・・・(汗 document.myform.country.selectitem = "JAPAN"; ないですかね・・・こういう方法は。 お手数をお掛け致しますが宜しくお願い致します。

  • JavaScripで使える文字列

    JavaScriptで下記のように0~50までの数字を書き出すスクリプトを使いたいのですが、使っているショッピングカートの関係で<select>文の中のnameタグにo-a、o-Aなど、o(アルファベット小文字のオー)と-(ハイフン)を記述しないといけない状態なのですが、o-を記述するとJavascriptが動かなくなります。。。 恐らくハイフンだと思うのですが、プラグラム上の仕様なのでしょうか。。。 A:<select name="o-A" onChange="check(this)"> <option value = '' selected>選択してください</option> <script language="javascript"> for ( var i = 0; i < 51; i++ ){ var sDat = ( "00" + i ).match( /..$/ ); document.write( "<option value = '" + sDat + ")'>" + sDat + "</option>\n" ); } </script> </select> どなたかおわかりになる方、ご教授頂ければ幸いです。

  • 一致する文字列がある行だけを、別BOOKのプルダウンリストに表示させる方法

    OFFICE 2003のエクセルで作成した下記のような3つのBOOKがそれぞれあり、BOOK1のシートはマスターで、「案件NO」「案件名」「進捗」「メンバ1」「メンバ2」「メンバ3」の項目がある。 BOOK2とBOOK3のシートには「案件NO」「案件名」「進捗」「概要」「報告」の項目があります。 例えば、BOOK1のセルD2~F2の中のいずれかのセルに表示されているメンバの名前を参照し、「山田」と名前が入っているセルがある場合は、その同じ行の「A列、B列、C列」のセルをBOOK2の「A列、B列、C列」に設定したプルダウンリストの中に表示させる。 (つまり、山田さんの名前が入っている案件情報だけをプルダウンリストに表示する) また同様に、メンバ欄に「森」が入っている行の「A列、B列、C列」のセルをBOOK3の「A列、B列、C列」に設定したプルダウンリストの中に表示させる。 (森さんの名前が入っている案件情報だけをプルダウンリストに表示する) 上記のように、案件マスターを参照し、担当者ごとに作成している別ブックのセルにに設定してあるドロップダウンリストの中に、メンバ欄の中に自分の名前が入っている案件だけをリストアップすることは、可能でしょうか? ※ BOOK1は、自由に編集することができ、数千件のデータが入っている ※ BOOK2とBOOK3の「A,B,C」各列はドロップダウン設定がされている。   BOOK1のデータとリンクしており、自分が担当している案件だけが、ドロップダウンリストの中に表示される。担当以外の情報は表示されない。)   列(D,E)は、自由に編集できるようになっている。 BOOK1のシート(1) 「案件情報マスター」    A      B      C      D      E     F 案件NO   案件名   進捗   メンバ1   メンバ2   メンバ3 1 111111   あああ    A    山田    吉田      森 2 222222    いいい    B     森    吉田     佐藤 3 333333   ううう     C     伊藤     吉田      佐藤 4 444444   えええ     A     佐藤     森      佐藤 5 555555   おおお     B     吉田    山田      佐藤 ---------------------------------------------------------------- BOOK2のシート(1) 「山田さんのブック」    A       B       C      D      E       案件NO    案件名    進捗    概要    報告 1 11111     あああ      A     ****    ○○○  2 555555    おおお    B     ****    △△△ ---------------------------------------------------------------- BOOK3のシート(1) 「森さんのブック」    A       B       C      D      E      案件NO    案件名    進捗    概要    報告 1 11111    あああ     A     ****    ○○○ 2 222222    いいい     B     ****    ××× 3 444444    えええ     A     ****    □□□ ---------------------------------------------------------------- わかりずらい文章ですみません m(_ _;)m メニューの「挿入」→「名前」→「定義」名前の定義をすれば、別シートのリストをプルダウンで表示させることができ、またINDIRECT関数を利用すれば3つのドロップダウンリストを連動させることができると言うことは調べてみてわかったのですが… 他のBOOKを参照し、複数のセル(D列~F列)を参照し、そのいずれかのセルに一致する文字列がある場合のみ、その行の複数セル(A列~C列)を 別BOOKに設定しているドロップダウンリストに表示させることができるようにし、各メンバごとに管理できるBOOKを作成したいと思っております。 よい方法があれば教えていただけると幸いでございます。 宜しくお願い致します。

  • エクセルのセル内にある文字列を特定語で抽出したい

    エクセルでQ&A集を作っています。各セルに文字列で質問と回答を文字列で入力していますが、その際に、キーワードですぐに抽出できるようにしたいです。「検索」機能だと抽出リストが出来ず、「リスト」機能だと文章中の特定語での抽出が出来ず、困っています。宜しくお願いします。