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

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

ただいまの
回答率

90.34%

  • jQuery

    7125questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • HTML5

    4318questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • Node.js

    2013questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,447

iarik

score 87

 やりたいこと

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/15 23:02

    複数の値を配列的に送りたいならJSONにしてvalueに代入とか。(自分が質問を勘違いしている気が・・・)

    キャンセル

  • 2017/02/15 23:36

    質問余り読んでないですが、ボタンで処理を分岐させたいなら value を送ってサーバサイドで if 文で分岐より、 formaction で POST 先を変えたほうがよくないですか?

    キャンセル

  • 2017/02/15 23:59

    今もう一度質問を読みなおしたところ、
    「同じ行のtd要素の中身を配列にしてPOSTしたい」ということのようです。
    なので、前もってvalueにJSON化した配列を入れておいて、
    <button type='submit' name='postData' value=''>編集</button>
    でいいと思います。(受け取り側で分岐もなし)

    キャンセル

  • 2017/02/16 00:01

    send/saveというフラグじゃなくデータ自体をJSONで渡すのですか、ならformactionはいらないですね

    キャンセル

  • 2017/02/16 00:31 編集

    kei344 さんの回答で良いと思いますが、サーバサイドではfor-ofして一つ一つ JSON.parse する必要があるのでご注意ください。
    個人的にはまとめて JSON.parse したくなるので
    <input type="hidden" name="table" value="[[&quot;suzuki&quot;,&quot;18&quot;],[&quot;tanka&quot;,&quot;19&quot;],[&quot;saitou&quot;,&quot;2o&quot;]]" />
    を一つだけ生成して送信ですかね…。

    キャンセル

  • 2017/02/16 01:14

    To: think49さん
    多分ですが、1行目の button要素をクリックでPOSTして、
    [ '01', 'suzuki', '18' ]
    という配列を得たいのではないかと 予想して button要素に stringifyしたものを入れています。

    node.jsは不勉強なのですが、
    { targetTable_length: '10', 'postData': '["01","suzuki","18"]' }
    こういう結果を受け取って、
    let data = JSON.parse( req.body.postData );
    こういうことかなぁ、と。

    キャンセル

  • 2017/02/16 02:38

    To: kei344 さん
    同じく、Node.js は不勉強ですが、name="postData[]" から想像するにPHPと同様に配列でPOSTパラメータを受け取る動作を想定していました。
    var postData = ['["suzuki","18"]','["tanka","19"]','["saitou","2o"]'];
    console.log(JSON.stringify(postData)); // ["[\"suzuki\",\"18\"]","[\"tanka\",\"19\"]","[\"saitou\",\"2o\"]"] (初期状態)
    postData = postData.map(JSON.parse);
    console.log(JSON.stringify(postData)); // [["suzuki","18"],["tanka","19"],["saitou","2o"]] (JSON.parse 後)
    ですので、JSON.parse(postData); は SyntaxError になるのでご注意ください、と(間違っていたらすみません)。

    キャンセル

  • 2017/02/16 03:27

    To: think49さん
    > name="postData[]"
    そうなんですよ。確かにそう書かれているのですが、なんとなく質問者さんは「配列が受け取りたい」と思ってこう書いたのではないかとの予想(勘)です。なので私の回答では
    name="postData"
    としています。(そこにコメントを入れたほうがよかったですね)

    postData[]で送る場合は指摘いただいたとおり、気をつけないとエラーになります。

    キャンセル

  • 2017/02/16 11:01

    kei344様 lazex様 think49様

    まずは遅い時間にも関わらずコメント、ご回答ありがとございます。
    私の質問の書き方が悪いために、いろいろと想像頂いてコメントしてくださり申し訳ありませんでした。
    私のやりたかったことは概ねkei34様が予想で書いてあるとおりでした。

    もう少しやりたかった事を記載しますと「http://example.com/table」というテーブル形式でデータを表示するページを用意しており、表示されているテーブルのある行の編集ボタンを押下すると、「http://example.com/table/edit」というデータ編集ページに遷移して、押下した行のデータが表示・編集出来るようなページを作成しようとしておりました。

    質問した時点では、何となく配列形式でデータが渡さればといいなーぐらいの間隔でしたが、皆様のコメントに記載頂いてある通りJSON形式でPOSTして、アプリケーション側でパースする事で上手くデータを受取る事が出来ました。

    大変勉強になりました。ありがとございます。
    あと、kei344様のスクリプトからこんなスクリプトを考えてみました。
    ```
    $(document).on('click', ':button', function(){
    var $tdData = $(this).closest('tr').children('td');
    var data = [];
    $tdData.each(function(){
    data.push($( this ).text());
    });
    $(this).val(JSON.stringify(data));
    });
    ```

    キャンセル

  • 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で質問しよう!

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

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

  • jQuery

    7125questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • HTML5

    4318questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • Node.js

    2013questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。