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

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

ただいまの
回答率

90.12%

foreach内で選択された値をjsに渡したい

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,630

tarao

score 26

foreachで存在する数分のカテゴリformを作り,それぞれボタンが押せるようにしています。
そのボタンをクリックしてajaxで一致するサブカテゴリを呼び出したいのですが、
どのボタンを押しても一番目の値しか入りません。
繰り返し処理中、そのボタンを押した時に入っている値が飛ぶ認識でいました。
ご教示お願いします。

<?php
      foreach((array)$main as $key => $mains){
      ?>
        <form method="post">
          <input type="hidden" name="main_type" class="main-type" value="<?php echo $mains->id ?>">
          <input type="hidden" name="cate_name" class="cate-name" value="<?php echo $mains->cate_name ?>">
          <button type="button" class="mains-btn"><?php echo $mains->cate_name ?></button>
        </form>

      <?php    
      }
      ?>
$(".mains-btn").on('click',function(){

        var mainType = $(".main-type");
        var  type = mainType.val();

        var mainName = $(".cate-name");
        var name = mainName.val();


            alert(type+"/"+name);

    });


上記だと全部最初の値だけが表示されます。
selectで試すとうまくいきます↓

<select class="mains-btn">
      <?php
      foreach((array)$main as $key => $mains){
      ?>
        <option value="<?php echo $mains->id ?>"><?php echo $mains->cate_name ?></option>

      <?php    
      }
      ?>
</select>

<script>
$(".mains-btn").on('change',function(){

        var mainType = $(".mains-btn");
        var  type = mainType.val();

            alert(type);
    });
</script>


これはどうしてなのでしょうか?

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+2

$( '.mains-btn' ).on( 'click', function() {
    var $_t = $( this ).parent();
    var mainType = $_t.find( '.main-type' );
    var  type = mainType.val();
    var mainName = $_t.find( '.cate-name' );
    var name = mainName.val();
    alert(type+'/'+name);
} );

【jQueryで親要素を取得する:parent(), parents(), closest() | UX MILK】
http://uxmilk.jp/8150

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/06/29 14:32 編集

    確かにそうですね。
    私の場合、今回の「$mains->id」のようにidが明示されてると使いたくてウズウズしてしまいます・・。

    キャンセル

  • 2017/06/29 15:00

    回答ありがとうございます。
    教えていただいたコードで思い通りにできました!

    クリックした.mains-btnの親要素内にある.main-typeの値を取得しているということでしょうか?
    ここでまた疑問なのですが、別々のidを振らなくてもそれぞれの値を取得できてるのは
    この親要素が関係しているのですか?

    キャンセル

  • 2017/06/29 16:37

    度々すいません。
    いただいたサイトを見ながら試して見て、理解することができました!
    とても参考になりました!
    どうもありがとうございました。

    キャンセル

+2

それぞれ個別の form が用意されているので、form から取得したほうが楽かもしれませんね。

    var form = $(this).closest('form')[0];
    var type = form.elements['main_type'].value;
    var name = form.elements['cate_name'].value;


HTMLFormElement.elements
https://developer.mozilla.org/ja/docs/Web/API/HTMLFormElement/elements

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/06/29 14:43

    var form = $(this).closest('form').get(0);
    では?

    キャンセル

  • 2017/06/29 14:55

    あ、そうですね。修正します。

    キャンセル

  • 2017/06/29 15:36

    回答ありがとうございます!
    closest('form')でformから直近の親要素を取得して
    elementsでform内の要素を取得しているのですね。
    思い通りの結果を取得できました!
    ありがとうございました!

    キャンセル

checkベストアンサー

+1

これはどうしてなのでしょうか?

同名classがページ内に複数回出てきているためです。
.mains-btnもその他取得情報も全て複数でてきていますよね。
それぞれ適切にIDを振って対応すべきと思います。

追記:

繰り返し処理中、そのボタンを押した時に入っている値が飛ぶ認識でいました。

「繰り返し処理(今回はforeach())」はあくまでサーバーサイドのプログラミング言語の都合であり、
PHPの処理が終了してからHTML出力されます。PHPの処理中に値が飛ぶ(送信される?取得される?ってこと?)ようなことはありません。
今回の場合はあくまで「ボタンクリックしたとき」に値を取得しにいっています。

 IDで取得するサンプル

作ってみたものの、あまり美しくないですが、ひとまず参考程度にしてもらえたらと・・・

<?php

$main = array(
    0=>array("id"=>1,"cate_name"=>"a"),
    1=>array("id"=>2,"cate_name"=>"b"),
    2=>array("id"=>3,"cate_name"=>"c"),
);

foreach($main as $key => $mains){
    ?>
        <form method="post" id="form_<?php echo $mains["id"]?>">
          <input type="hidden" name="main_type" class="main-type" value="<?php echo $mains["id"]?>">
          <input type="hidden" name="cate_name" class="cate-name" value="<?php echo $mains["cate_name"] ?>">
          <button type="button" class="mains-btn" data-id="<?php echo $mains["id"] ?>"><?php echo $mains["cate_name"] ?></button>
        </form>

<?php
}
?>
$(".mains-btn").on('click',function(){
    var formid = "form_" + $(this).data("id");
    var mainType = $("#"+ formid +" .main-type");
    var  type = mainType.val();
    var mainName = $("#"+ formid +" .cate-name");
    var name = mainName.val();
    alert(type+"/"+name);
});

解説:

  • IDを振るというのはclassの名前の付け方ではなくid属性をつけるという意味です。
    ID属性はページ内で唯一の存在であるという意味合いがあり(実際は同名複数可能ですがルール上は1ページ1つ)、jQueryで要素を取得する際にはIDをつけて取得する方がより望ましいとされています。
  • というわけでそれぞれの情報の親要素であるformにIDを振ります。form_{id} とか簡単なもので良いです
  • その他のclass名についてはそのままで結構ですが、親のIDを取得しなければならないのでボタンを押した際にIDを取得できるようにします。
    ここではdata属性を使ってますがもっとスマートなやり方がありそうです。
  • クリック時のイベントで自身のボタンについてるデータ属性の値を取得し、formにつけたIDの名前を決定します。
  • あとは $(#ID名 .クラス名)とすることで「指定ID配下にある要素」の情報を取得することができます。

もちろん、IDを振って取得さえできればページ内に1つしか出現しないので、

<input type="hidden" name="main_type" class="main-type" id="main-type_<?php echo $mains["id"]?>" value="<?php echo $mains["id"]?>">


のようにしておいて

var dataId = $(this).data("id");
var mainType = $("#main-type_"+dataId );


と書いても同様ですが、なるべくid振る場所を少なくしたかったのでformにのみ振っています。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/06/29 16:14

    とっても細かく説明していただいて、本当にありがとうございます!
    よくわかりました!
    <form method="post" id="form_<?php echo $mains["id"]?>">
    <button type="button" class="mains-btn" data-id="<?php echo $mains["id"] ?>/<?php echo $mains["cate_name"] ?>"><?php echo $mains["cate_name"] ?></button>
    </form>
    ↑このようにhiddenを使わなくても、希望通りに渡すことができました!

    今回色々な方法があるのだなと、大変勉強になりました!
    parent()やclosest()も使っていこうと思います。

    キャンセル

  • 2017/06/29 16:21

    まぁ、今回のように既に情報がきてるのであれば
    buttonに直接 onclick = "hoge('<?= $mains["id"]?>','<?= $mains["cate_name"]?>')" とか書いて
    function hoge(id,catname) {
    alert(id+"/"+catname);
    }
    でも 十分(hidden不要)だったりしますけどね・・。

    キャンセル

  • 2017/06/29 16:41

    今回のパターンだとこれでもいけるのですね。
    知識、勉強不足です。
    これもまた参考になりました!

    キャンセル

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

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

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