質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

hidden属性を使わずにtableタグで表示されたある行のデータをPOSTで渡す手段

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 8,405

iarik

score 98

 やりたいこと

tableタグを使い画面上にデータを表示しています。
最終列には編集というボタンを用意しております。
編集ボタンを押すと、ボタンが押された行のデータを別のページにPOSTしたいと考えております。
POSTのハンドリグを行っているサーバはnode.jsになります

  • html(http://example.com/table)
<form role="form" name="form" method="post" action="./table/edit">
<table>
  <thead>
    <tr>
     <th>id</th>
     <th>name</th>
     <th>age</th>
     <th>編集</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>01</td>
      <td>suzuki</td>
      <td>18</td>
      <td><button type="submit" name="postData[]" onclick="GetTdData()">編集</button></td>
    </tr>
    <tr>
      <td>02</td>
      <td>tanka</td>
      <td>19</td>
      <td><button type="submit" name="postData[]" onclick="GetTdData()">編集</button></td>
    </tr>
    <tr>
      <td>03</td>
      <td>saitou</td>
      <td>2o</td>
      <td><button type="submit" name="postData[]" onclick="GetTdData()">編集</button></td>
    </tr>
    ・
  ・
  <<省略>>
  </tbody>
</table>
</form>

 やってみたこと

以下のようなjqueryを作成してみましたが、「data[]」に格納された配列データをhtml側で定義したname「postData[]」に配列データとしてキレイに渡す事が出来ません。

  • javascript(jquery)
function GetTdData(){
    // セレクタを指定したclickイベントでは要素が取得できないためonメソッドを利用
    $(document).on('click', ':button', function(){
      // tdの数
      var tdNum = $(this).closest('tr').children('td').length;
      var ti = 0;
      var data = new Array();
      for (ti=0; ti<tdNum; ti++) {
        data[ti] = $(this).closest('tr').children('td').eq(ti).text();
        $(':button[name="postData[]"]').eq(ti).val(data[ti]);
      };
};
  • node.js(express使ってます。だいぶ省略してすみません)
router.post('/edit', function(req, res, next) {
  console.log('call table edit page');
  console.log(req.body)
});


以下のような出力になってしまいます
{ targetTable_length: '10', 'postData[]': '0' }

今回のようにテーブルで表示されたデータから、ある行のデータを別のページに飛ばして利用したいと行った場合に「hidden」を使わずに飛ばすやり方を皆様はどのように実現されておりますか?
もし参考になるページやプログラムがあればご紹介頂けると嬉しいです

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2017/02/15 22:48

    例示用ドメインはご自身で所有されていない限り example.com, example.jp, example.co.jp など例示用に予約されたドメイン名を利用してください。 http://www.atmarkit.co.jp/fwin2k/win2ktips/801exampledom/exampledom.html

    キャンセル

  • iarik

    2017/02/15 22:53

    ご連絡ありがとございます。修正しました

    キャンセル

回答 2

+3

ちょっとツッコミいれると、
"別のページにPOSTしたい"という表現をつかってますが、

どういうこと?
1つのページに複数のページを同時に表示させる運用なの?
iframeで別のページを読み込んでいてそいつにPOSTするの?
プッシュ通知? 
WebSocket?
Server Sent Events? 
HTTP/2?

と質問を見た人にあらぬ混乱をさせてしまいます。
ようは、アドレスがページのアドレスじゃないけど、サーバーにデータをPOSTしたいっていう理解であってますよね?

もう一つツッコミ
インラインでonclick="GetTdData()"として、すでにボタンのイベントリスナーはってるのに、GetTdData()内でさらに$(document).on('click', ':button', ~でさらにイベントリスナーをはってる。これじゃ、クリックするたびにイベントリスナーはりまくって、1回のクリックで実行される回数がどんどん膨れ上がってしまう。
検証ページ

さて、一応私からも回答させていただきます。考え方はほぼ@kei344さんと同じですけど。
クリックされたところのデータを取得してPOSTするとなると<form>タグは不要かと思います。

<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>test</title>
        <meta charset="UTF-8">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
        <script defer src="postdata.js"></script>
    </head>
    <body>
        <table>
            <thead>
                <tr>
                    <th>id</th>
                    <th>name</th>
                    <th>age</th>
                    <th>編集</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>01</td>
                    <td>suzuki</td>
                    <td>18</td>
                    <td><button type="button">編集</button></td>
                </tr>
                <tr>
                    <td>02</td>
                    <td>tanka</td>
                    <td>19</td>
                    <td><button type="button">編集</button></td>
                </tr>
                <tr>
                    <td>03</td>
                    <td>saitou</td>
                    <td>20</td>
                    <td><button type="button">編集</button></td>
                </tr>
            </tbody>
        </table>
    </body>
</html>
// postdata.js (クライアント側)
$('button').click(function() {
    var memberNames = ['id', 'name', 'age']; // 全メンバー名
    var numMember = ['age']; // 数値メンバー
    var postData = {};
    $(this).parent().siblings().each(function(i) {
        var val = $(this).text();
        postData[memberNames[i]] = numMember.includes(memberNames[i]) ? +val : val;
    });
    $.ajax({
        type: 'POST',
        url: './table/edit',
        data: JSON.stringify(postData),
        contentType: 'application/json'
    });
});
// main.js (Node.jsサーバー側)
const express = require('express');
const bodyParser = require('body-parser');
const app = express();

app.use(express.static(__dirname));
app.use(bodyParser.json());

app.post('/table/edit', (req, res, next) => {
    // POSTデータをコンソールに表示
    console.log(req.body);
});

app.listen('9001');

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/16 11:08

    turbgraphics200様

    早朝に関わらず、コメント・ご回答ありがとございます。
    私の質問の内容が悪く、どういったことがやりたいのかが不透明な質問となってしまい
    大変申し訳ありませんでした。
    また、javascript側のご指摘について大変ありがとございます。
    ご共有頂いたサイトについてもこれから活用させて頂きたいと思います。

    今回やりたかったことの補足については、kei344様のコメントに記載させて頂いてある通りとなります。
    turbgraphics200様にもベストアンサー付けさせていただきたかったのですが、お一人しかつけることが出来ませんので第一回答者のkei344様に付けさせて頂きました。
    大変申し訳ありません。。。

    キャンセル

checkベストアンサー

+2

button要素にvalue属性を持たせることが出来るので、それで分岐は出来ると思います。(送るデータがテーブル内のほかの値なら事前に処理しておく)

【<input type=submit>は止めて<button type=submit>を使うべき - Qiita】
http://qiita.com/irxground/items/c8537d30e9760c5b3e5c

<form>
  <button type='submit' name='action' value='send'>送信</button>
  <button type='submit' name='action' value='save'>下書き保存</button>
</form>

【1つのform内で複数のsubmitボタンを作成する方法 - smallplaceの日記】
http://d.hatena.ne.jp/smallplace/20130708/1373287891


追記:

内容を読み違えていました。

<button type='submit' name='postData' value=''>編集</button>
$( 'button[name="postData"]' ).each( function() {
    var $_td = $( this ).closest( 'tr' ).children( 'td' );
    var data = [];
    $_td.each( function() {
        data.push( $( this ).text() )
    } );
    $( this ).val( JSON.stringify( data ) );
} ); // 未テスト

これでサーバ側で postData を JSON.parse() すれば良いような。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/16 11:12

    カスタムデータ属性 data-* を使うのってどうでしょうか?最近使いだしたんでよく理解していないのですが、こういう時に使えそうかと。

    キャンセル

  • 2017/02/16 11:19

    To: iarikさん
    tableを組む時点で何かしらのデータソースが有ると思いますが、そこにIDを持たして、そのIDを次のページに渡すのが一般的な実装かと思います。(編集するって言うことはデータとしてどこかに保存するということでしょ?)

    To: te2jiさん
    データを入れておくことは出来ますが、入れただけではPOSTできませんよ。

    キャンセル

  • 2017/02/16 11:31

    $( this ).text() を区別なく POST をするってのが、ちょっと気持ち悪いかなって思ったんですが、今回のケースだと冗長かもしれないですね。コメントありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る