アプリ版:「スタンプのみでお礼する」機能のリリースについて

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

現在、Javascriptを使って表のソートや絞り込みができるページを作っています。
http://www.asahi-net.or.jp/~mc9m-ehr/soft/script …
こちらのような感じで、
ドロップダウンリストからキーワードを選ぶと、
該当する列が絞り込み表示できるようにしたいのですが、
このままのスクリプトだと、セル内の文字列が完全に一致しないとできないようです。

現状は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)に少し手を加えることで実現できるなら、
具体的にご教示いただけるとうれしいです。

A 回答 (11件中1~10件)

 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>
    • good
    • 0

<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;

//____________
    • good
    • 0

かきなおし。


<!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>
    • good
    • 0

ていせいのやつに、ついかです。



<style type="text/css">
tr[aria-hidden="true"] {
display: none;
}
</style>

visibility:hidden; とか いろいろ、やりようがあるようです
    • good
    • 0

ていせい。


<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>
    • good
    • 0

てーぶるのすぐしたについかしてね!



<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>
    • good
    • 0

ぶらうざをえらぶけど、たいこうして(?)かいてみた。


ぜんかくくうはくははんかくに。たぶんながいのでぶんかつ。

<!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>
    • good
    • 0

#2, 3 です。



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

ありがとうございます!!!
テストで実装してみたのですが、きちんと部分一致で絞り込みできるようになりました。
#3でおっしゃっていた現象は、バグのようですね。気がつきませんでした。

ただ、ちょっと分からないことがあるのですが、
サンプルページの「rowFilter() のサンプル1」は何を意味しているのでしょう?
とりあえず今必要なのはサンプル2だけかなと思い、スクリプトもそれだけ書いてあります。

それから、設置して絞り込みはちゃんとできているのですが、
「オブジェクトがありません」というエラーが出てしまいます。
該当箇所は

if (element.addEventListener) {

というところのようですが、これはどうしてなのでしょう???

お礼日時:2010/10/09 02:17

#2 です。



> http://www.asahi-net.or.jp/~mc9m-ehr/soft/script …

このスクリプト、挙動がおかしくないでしょうか?
左の selectボックスで [1] を選択してから、[2] を選択すると全て消えてしまいます。
常に絞り込み検索をしているようですが、これが期待通りの動作なのでしょうか…。
    • good
    • 0

作ってみました。



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" を開始番号とする)。未指定時のデフォルトは全ての列から検索する。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!