プロが教える店舗&オフィスのセキュリティ対策術

CSVの会員名簿を読み込み、表にしてWEBに表示する為にjquery.csv2table.jsを使った
こちらのサイトを参考にさせて頂きました。

http://jsgt.org/lib/jquery/plugin/csv2table/v002 …

CSVを読み込み、表示は成功したのですが。
もともとのCSVデータが横長に項目が多い為
表示されるテーブルは横長の表となってしまいます。

出来れば一行をセルの結合で2段にまとめて表示したいと思っています。

<td colspan="2"><td rowspan="2">を使って
[1]はココに表示[2]はココに表示するみたいにテンプレ化して表示できればと思っていますが
セルの背景色は変更できてもセルの場所を任意に変更できません

やはりそういった事は難しいのでしょうか
どなたか詳しい方、教えて頂けますと幸いです。
よろしく願い致します。

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

return rec.split (/\t/g);



return rec.split (/,/g);
にでもしましょうか? ^^;

いい加減な回答で申し訳ない。以下を理解しないと私は先に進めません。そろそろ忙しくなってもきましたし・・・。
http://www.ietf.org/rfc/rfc4180.txt
    • good
    • 0
この回答へのお礼

babu_baboo様

何度もお答え頂きありがとうございました。
上記部分を修正しましたらちゃんとTDに入りました!
お忙しい中教えて頂きまして本当にありがとうございます。ペコリ ((-ω-('ω'〃)

お礼日時:2014/09/29 21:23

またも連投!



アルゴリズムを見直しました。
あくまでもcsvファイルの読み込みは簡易的なもの。
信用してはいけません。
テーブルヘッドとフッタはどこへ行った?

<!DOCTYPE html>
<meta charset="utf-8">
<title>テーブルをn行に?</title>

<style>
th { color: green; width: 6em;}
td { width:4em;}
tbody th { background: #efe;}
</style>

<body>
<table border="1" id="hoge"></table>

<script>

(function () {
 
 var reg_separator =
  /^\s*(\d+)(?:@([hd]?)(?:([Rr])([1-9][0-9]*)?)?(?:([Cc])([1-9][0-9]*)?)?)?\s*$/;
 
 //_____


 function Ary2table (table, order, template) {
  this.table = table;
  this.order = order;
  this.template = template;
 }
 
 
 function setTbody (ary) {
  if (1 > arguments.length)
   throw new Error ();
  
  for (var i = 0, rec; rec = ary[i++]; ) {
   for (var j = 0, e, J = rec.length; j < J; j++)
    if (e = this.order[j])
     e.textContent = rec[j] || '';

   this.table
    .appendChild (this.table.ownerDocument.createElement ('tbody'))
    .appendChild (this.template.cloneNode (true));
  }

  return this;
 }

 
 function load (name) {
  var req = new XMLHttpRequest;

  req.open ( 'GET', name, false);
  req.send (null);
  
  if (200 !== req.status )
   throw new Error;
  
  this.setTbody (
   req.responseText.trim ()
    .split (/\r\n|\n|\r/g).map (
     function (rec) {
      return rec.split (/\t/g);
     }
    )
  )
 }


 function createMap (format) {
  var doc = this;
  var fgm = doc.createDocumentFragment ();
  var tr = doc.createElement ('tr');
  var order = [ ];
  var i, j, J, buf, a, e, tr_;
  var rowMax = format.length;
  
  for (i = 0; buf = format[i++]; ) {
   fgm.appendChild (tr_ = tr.cloneNode (false));
   
   for (j = 0, J = buf.length; j < J; j++) {
    if (! (a = reg_separator.exec (String (buf[j]))))
     throw new Error ('Syntax error: ['+ i+ ','+ j+ ']='+ buf[j]);

    tr_.appendChild (order[+a[1]] = e = doc.createElement ((a[2] === 'h') ? 'TH': 'TD'));

    if (a[3]) e.setAttribute ('rowSpan', a[4] || rowMax);
    if (a[5]) e.setAttribute ('colSpan', a[6] || J); // J?
   }
  }
  return { order: order, template: fgm };
 }


 function create (table, format) {
  if (2 > arguments.length)
   throw new Error ();
  
  var map = createMap.call (table.ownerDocument, format);
  var obj = new Ary2table (table, map.order, map.template)

  return obj;
 }

 //_____
 
 Ary2table.create = create;
 Ary2table.prototype.setTbody = setTbody;
 Ary2table.prototype.load = load;

 this.Ary2table = Ary2table;
}) ();

//____

var format = [ // セルNo @ h r[rowspan] c[colspan]
 ['0@hr', 1, 4, 7],
 [  2, 5, 8],
 [  3, 6, 9]
];

Ary2table.create (document.getElementById ('hoge'), format).load ('test.csv');

</script>

この回答への補足

babu_baboo様

何度もお付き合いくださりありがとうございます。
上記スクリプトですが、私のせいか<TH>にCSV1行が入ってしまい、<TD>は空っぽとなってしまいました。。。
自分でもbabu_baboo様のように、ここまで書ければ良いのですが( p_q)

補足日時:2014/09/28 15:25
    • good
    • 0

いつもより、”やっつけ” で書きました。


テーブルを置き換えるのではなく、CSVを配列にした状態からテーブルを作成します。
正規表現が何を意味するのか理解できれば好いのですが。
まぁこれは書いた本人も微妙ですし…。
ろくに確かめてもいないし…。


<!DOCTYPE html>
<meta charset="utf-8">
<title>テーブルをn行に?</title>

<style>
th { color: green; width: 6em;}
thead, tfoot { background: #8c8;}
tbody th { background: #efe;}
.num { text-align : right; }
</style>

<body>
<table border="1" id="hoge"></table>

<script>


var D = /^(?:(?:(#)(?:\[(?:(\d+)(?:,(\d+)?)?)?\])?))?(.*)$/;//#[rowSpan,colspan]text


function C (a) {
 var b = D.exec (a), c;

 if (b[1]) {
  c = document.createElement ('th');
  c.textContent = b[4] || '';

  if (b[2])
   c.setAttribute ('rowSpan', b[2]);
  if (b[3])
   c.setAttribute ('colSpan', b[3]);
 }
 else {
  c = document.createElement ('td');
  c.textContent = a;
  if (! isNaN(a))
   c.className = ('num');
 }
 return c;
}


function B (a, b) {
 var c = document.createDocumentFragment ();
 var d = b.map (C);
 var i = 0, j, J, tr, m;
 
 for (i = 0; m = a[i++]; ) {
  tr = c.appendChild (document.createElement ('tr'));
  for (j = 0, J = m.length; j < J; j++) {
   tr.appendChild (d[m[j]])
  }
 }
 return c;
}



function A (a, b, c, d, e) {
 if (3 > arguments.length)
  throw new Error;
 
 var f = document, g;

 while (g = a.firstChild)
  a.removeChild (g);
 
 if (d)
  a.appendChild (f.createElement ('thead'))
   .appendChild (B (b, d));
 
 if (e)
  a.appendChild (f.createElement ('tfoot'))
   .appendChild (B (b, e));

 if (c)
  c.forEach (function (h) {
   a.appendChild (f.createElement ('tbody'))
    .appendChild (B (b, h));
  })
}

//______________

var body = [
 ['#[3]abcd',1,2,3,4,5,6,7,8,9],
 ['#[3]efgg',9,8,7,6,5,4,3,2,1]
];

var format = [
 [0, 1, 4, 7],
 [ 2, 5, 8],
 [ 3, 6, 9]
];

var head = ['#[3]Name', '#a', 'b', 'c', '#d', 'e', 'f', '#g', 'h', 'i'];
var foot = head;

A (document.getElementById ('hoge'), format, body, head, foot);

</script>

この回答への補足

babu_baboo様

何回もご回答頂き、本当にありがとうございます。
上に書いて下さったscriptは綺麗に表になっておりました!
ですが、私の頭が追いついておりません・・少し整理して理解しましたら改めてお礼をさせて下さい。

取り急ぎありがとうございます。

補足日時:2014/09/27 01:38
    • good
    • 0

こんにちは。

ANo3です。

「お薦めしない」といいながらも再度の投稿です(笑)

csv2tableがどのような処理をしているか把握していないので、データはもちろん文書の構造もいじらない方が無難かなと思った次第です。
そうすると、どうしても表示のレイアウトでなんとかしようということに…
HTMLが表示のためだけに利用されているなら、ANo4様の回答のように書き直しても問題は出ないでしょう。

>CSSで表示を変える方法は思案したのですが、やはりブラウザの差もあるので
>不安定と思い避ける事といたしました。
ご意見ごもっともと思いますし、回答にも懸念を記載した通りです。

と言いながら・・・
いっそのこと、各セルをabsoluteで個々に指定してしまえば、ブラウザの差異も少ないのではないかと想像します。(せいぜい20項目程度?)


決してお薦めするつもりではありません(笑)
    • good
    • 0
この回答へのお礼

fujillin様

再度ご回答頂きありがとうございます。
absoluteでの方法もあると言う事、参考にさせて頂きます。
ありがとうございました。

お礼日時:2014/09/27 01:43

連投すみません。


目が覚めて気がつきました。
プロの人達から指摘が入る前に自分で指摘しておきます。

このプログラムは、マークアップする側から見ればダメです。
1レコードをN行にするので、行数はN倍に増えます。
そこである適当な行に注目します。
その行には、1レコードの何行目かをしるすものがありません。
せめて、class を指定して1レコードの何行目か(もしくは1レコードの何番目)を付加するべきでした。

やはりこの場合、1レコードを1つのtbodyにして表を作成すべきです。
見た目は変わりませんが、スクリプトで単純に置き換えたダメな例ですね。
また見た目が近いとして hr で置き換えしているものも、マークアップとしては間違いです。
rowSpanで2行にしてグループにしておきながら、間に<hr>文脈がまったく関係なくなる区切りのタグを使うのは、やってはいけないことです。
    • good
    • 0

テーブルが表示された後に、実行する



もしくは、3秒後に実行されるようにする。
A(document.querySelector ('table'), [-1, 0, 0, 0, 1, 1, 1, 0, 1]);
を、
//
function AA () {
 A(document.querySelector ('table'), [-1, 0, 0, 0, 1, 1, 1, 0, 1]);
}

setTimeout (AA, 3000);

//
にする。

もちろん知っていると思うけど、2行以上でもOKだよ!

もしくは誰かに再度聞く。

もしくは・・・、指をくわえて諦める。
    • good
    • 0

間違えた。


 trs = [tr].concat (trs.reverse ());

 trs = [tr].concat (trs);
に!

(またも)すみません。
    • good
    • 0

ななめ下&横から


ながめて、使えますかね?


<!DOCTYPE html>
<meta charset="utf-8">
<title>テーブルをn行に?</title>

<body>
<table border="1">
 <tr>
  <th>A <th>B <th>C <th>D <th>E <th>F <th>G <th>H <th>I
 <tr>
  <td>1 <td>2 <td>3 <td>4 <td>5 <td>6 <td>7 <td>8 <td>9
</table>

<script>


function insertAfter (a) {
 this.parentNode.insertBefore (a, this.nextElementSibling);
}


function toAry (n) {
 return Array.prototype.slice.call (n, 0);
}



function B (tr) {
 var fmt = this;
 var thd = toAry (tr.children);
 var max = Math.max.apply (null, fmt);
 var trs = [];
 var e, i, n;

 for (i = 0; i < max; i++)
  trs.push (tr.cloneNode (false));

 trs.forEach (insertAfter, tr);
 trs = [tr].concat (trs.reverse ());
 max++;
 
 for (i = 0; e = thd[i]; i++) {
  switch (n = fmt[i]) {
  case 0 : case undefined : break;
  case -1: e.setAttribute ('rowSpan', max); break;
  default: trs[n].appendChild (e);break;
  }
 }
}


function A (table, format) {
 toAry (table.querySelectorAll ('tr')).forEach (B, format);
}

alert("Change!!");
A(document.querySelector ('table'), [-1, 0, 0, 0, 1, 1, 1, 0, 1]);

</script>

もっとコンパクトに書けそうだけれども…。

この回答への補足

babu_baboo様

ご回答ありがとうございます。
まさにやりたい表になっております!
ですが、私の知識不足の為jquery.csv2table.jsにどう組み込めばよいのか全く解りません。。

ためしに、babu_baboo様が書いて下さったスクリプトをHTMLに埋め込んでみたのですが
csv2tableで表が表示される前(ボタンで表示されます)にチェンジのアラートが出てしまい、結果何も起こらずじまいとなってしまいました。

わざわざここまで書いて下さったのに本当にすみません。
もっと勉強しないとダメですね( p_q)...

補足日時:2014/09/25 21:52
    • good
    • 0

少々無理やり感があるので、お薦めではありませんが…




tdをinline-blockなどにしておいて、trの中でレイアウトし直してしまえばデータはそのままで、表示のレイアウトだけを変えることができるようです。
CSSで細かに指定してあげる必要がありますが、これならデータのtable構成はそのままなので、ソートしても同じレイアウトを保つことが可能です。
とはいうものの、もともとがtable要素として作成されているものを、本来のtableでなくしてしまうところが問題かもしれませんが…
ブラウザによって同じ挙動をするかどうかまでは確認していませんが、Fxで簡単に試してみたところ可能なようです。

例えば、ANo1の補足のようなレイアウトなら、
 trをposition:relativeにしておく
 tdをfloat:leftにして高さと幅を指定
 項目B、Cだけ高さを半分に指定
 項目Cをposition:absoluteで項目Bの下に来るように位置指定
といった要領で、一応それらしき表示にすることが可能です。

nth-childで指定する必要がありそうですが、これが使えないブラウザを対象にするのであれば、csv2tableにonloadのオプションがありますので、そちらで対象とするセルにクラス名を設定しておいてそれを利用するなどの工夫が必要かもしれません。


先に書きましたようにお薦めの方法とは言えませんので、どうしようもない時のアイデアとして…
    • good
    • 0
この回答へのお礼

fujillin様

ご回答ありがとうございます。
CSSで表示を変える方法は思案したのですが、やはりブラウザの差もあるので不安定と思い避ける事といたしました。
わざわざ試して頂いて大変申し訳ございません。
ありがとうございます。

お礼日時:2014/09/25 21:40

なるほど、、、


そのようになると例示の場合にCSVの時点で項目Bと項目Cの間のカンマを<hr>にするのが一番簡単かと思います。

次点で、CSVを一行一行読み込む時に、○個目のカンマを<hr>にするという処理を加える方法です。
例えば2個目のカンマを<hr>に変えるにはstr_replaceと下記の正規表現で可能です。
^([^,]+(,)){2}
この方法はプラグインに直接手を加えなくてはならないのであまりよろしくないかもしれません。
    • good
    • 0
この回答へのお礼

ONEONEさま

ご回答ありがとうございます。
<hr>を入れる案、とても希望する形には近くはなるのですが、項目が1つに集約されてしまうのでソート機能もどちらかが機能しなくなってしまいます・・・

やはり、これは難しいのですね。別の方法も考えてみようと思います。
ご回答ありがとうございました。

お礼日時:2014/09/25 14:14

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