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

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

ただいまの
回答率

90.49%

  • Play Framework 2

    107questions

    Play Framework 2はPlayのメジャーバージョンです。現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。

【PlayFramework2.x】グルーピングされたradioボタンの値を取得する方法

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,110

Aipa

score 36

いつもお世話になっております。

Playframework2.4で、複数同じnameのradioボタン値の取得について、値を配列で取得する方法をご教授頂きたいです。

お問い合わせフォームを用意しました。

内容は、ユーザー名とユーザーの得意なITジャンル(Java、Perl、ネットワーク、などなど)をradioボタンで選択してもらう。また、それを複数人入力してもらうという内容です。

<div class="hogehoge-section">
  <div class="users-detail">
    <div class="user-name">
        <label>お問い合わせのお名前</label>
        <input id="user-name-multiple" class="form-control" type="text" name="user.user_name.multiple" value="" required="required">
    </divL
    <div class="user-radio">
      <label>
        <input id="radio-multiple" class="form-control" type="radio" name="user.radio_multiple" value="0" required="required">
        <input id="radio-multiple" class="form-control" type="radio" name="user.radio_multiple" value="1" required="required">
      </label>
    </div>
  </div>
  <!-- ↑の内容が入力する人数によって任意に増やすことができる -->
</div>

↑のようなdom構造を用意されている追加ボタンを押すことで増やせるviewを作りました。

ここでお気づきのかたは気づくかなと思いますが、radioボタンのnameは同じnameだとすべてリンクしてしまいます。

つまり、入力1のユーザーを「Java」と選択した後に、入力2のユーザーを「Perl」と選択してしまうと入力1のradioボタンが未選択の状態になってしまいます。

http://mashi.hatenablog.com/entry/2013/01/02/165548

でもこれはHtmlの仕様であることは理解しています。そこで。

<div class="hogehoge-section">
  <div class="users-detail">
    <div class="user-name">
        <label>お問い合わせのお名前</label>
        <input id="user-name-multiple" class="form-control" type="text" name="user.user_name.multiple" value="" required="required">
    </divL
    <div class="user-radio">
      <label>
        <input id="radio-multiple" class="form-control" type="radio" name="user.radio_multiple[0]" value="0" required="required">
        <input id="radio-multiple" class="form-control" type="radio" name="user.radio_multiple[0]" value="1" required="required">
      </label>
    </div>
  </div>
  <!-- ↑の内容が入力する人数によって任意に増やすことができる -->
</div>
<input ... name="user.radio_multiple[0]" value="1" required="required">

このようにグルーピング化すればいけると思いました。CakePHPとかだと似たような形式(name="data[User][0][radio_multiple]")でグルーピング化して渡せることができます。

しかし、レスポンスの中を確認すると配列では取得できずkeyがuser.radio_multiple[0]の文字列でセットされていました。

// debugした時の中身
"user.radio_multiple[0]" => ArrayBuffer(0)
"user.radio_multiple[1]" => ArrayBuffer(1)

// 本当はこうなってほしい
"user.radio_multiple" => ArrayBuffer(0,1)

これはどうすれば良いでしょうか。

http://mashi.hatenablog.com/entry/2013/01/02/165548

こちらの方はnameの末尾が"[]"であれば、自動的に変換されると書いています。

何か前提が必要などヒントや回答を頂けますと助かります。お手数をおかけいますが、よろしくお願いいたしますm(_ _ )m

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

check解決した方法

+1

自己解決しましたので、メモします。

結論からいうと、複数グルーピングしたradioボタンの値取得を配列で取得することはできませんでした。
※できるかもしれませんが、ソース読んでもよくわかりませんでした。。。Scalaむずい

なので、こんな感じの実装を追加してみました。

/**
   * リクエストパラメータから指定したKeyの値をStringで取得する
   *
   * @param map request().body().asFormUrlEncoded()で取得したMap
   * @param k   リクエストパラメータのKey
   * @return
   */
  public static String getParam(Map<String, String[]> map, String k) {
    if (map.get(k) == null) {
      return null;
    } else {
      return map.get(k)[0];
    }
  }

  /**
   * リクエストパラメータから指定したKeyの値をStringで取得する
   *
   * @param request Httpリクエスト
   * @param k       パラメータのKey
   * @return リクエストパラメータの値
   */
  public static String getParam(Request request, String k) {
    return getParam(request.body().asFormUrlEncoded(), k);
  }

  /**
   * 登録できる利用同伴者数の最大
   */
  public static final Integer MAX_JOIN_USER_COUNT = 8;

  /**
   * 指定回数のループで取得してListにして返す
   * @return List<String>
   */
  public static List<String> getRadioValueList(Request request, String key) {
    List<String> resultList = new ArrayList<String>();
    for (Integer i = 0; i < MAX_JOIN_USER_COUNT; i++) {
      String countKey = key + '.' + i.toString();
      String str = RequestUtils.getParam(request, countKey);
      Option<String> strOptional = OptionUtil.apply(str);
      String getString = strOptional.getOrElse("");
      if (0 < getString.length()) {
        resultList.add(getString);
      }
    }
    return resultList;
  }

  public static mainMethod(Request request) {
    // ... 省略
    List<String> multipleUserList = getRadioValueList(request, "user.radio_multiple");
  }

// ... 省略
}
public class OptionUtil {

    public static <A> F.Option<A> apply(A value) {
        if(value != null) {
            return F.Option.Some(value);
        } else {
            return F.Option.None();
        }
    }
// ... 省略
}

view側は下記

<div class="hogehoge-section">
  <div class="users-detail">
    <div class="user-name">
        <label>お問い合わせのお名前</label>
        <input id="user-name-multiple" class="form-control" type="text" name="user.user_name.multiple" value="" required="required">
    </divL
    <div class="user-radio">
      <label>
        <input id="radio-multiple.0.1" class="form-control" type="radio" name="user.radio_multiple.0" value="0" required="required">
        <input id="radio-multiple.0.2" class="form-control" type="radio" name="user.radio_multiple.0" value="1" required="required">
      </label>
    </div>
  </div>
  <div class="users-detail">
    <div class="user-name">
        <label>お問い合わせのお名前</label>
        <input id="user-name-multiple" class="form-control" type="text" name="user.user_name.multiple" value="" required="required">
    </divL
    <div class="user-radio">
      <label>
        <input id="radio-multiple.1.1" class="form-control" type="radio" name="user.radio_multiple.1" value="0" required="required">
        <input id="radio-multiple.1.2" class="form-control" type="radio" name="user.radio_multiple.1" value="1" required="required">
      </label>
    </div>
  </div>
</div>

とりあえず、これでやりたいことはできるようになりました。ただ、ご覧の通りradioのグルーピング数が動的ではないので、数が変更になると、そのたびにコードを変更しなければならいため、良いコードとはいえないかなと思います。

ただ、play.data.Form.javaを読んでみると、何かしら[]の文字列で判断してリクエストの値を操作しているのが見受けられるので、その辺をうまく理解して処理を追加したりすると、もう少しコードがよくなるかなと思いました(多分)

ありがとうございました。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

htmlの中にid="radio-multiple"が2つありますが、予期せぬ動作につながると思われます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/05/07 15:27

    回答ありがとうございます!
    お返事が遅くなりすみません。

    idが複数あるのは確かにまずいですね。こちらは修正しますー。
    ありがとうございましたm(_ _ )m

    キャンセル

  • 2016/05/07 18:04

    自分もアンケートを実装した時にユーザ一覧表示をだして一部クイック選択できるようにした時に同じような問題に遭遇したのですが、playのフォームヘルパー側のコードにnameにindexをつけるようなコードをオーバーライドして対応した記憶があります。

    ただ記載されているURLみるとできそうな感じがしますね。

    カエルが表紙のplayframeworkの本が出てます。自分は書籍版とkindle版と2冊買いました。
    ネットで調べるより時間の節約になるかと思いますよ。

    キャンセル

  • 2016/05/17 10:15

    >自分もアンケートを実装した時にユーザ一覧表示をだして一部クイック選択できるようにし>た時に同じような問題に遭遇したのですが、playのフォームヘルパー側のコードにnameにi>ndexをつけるようなコードをオーバーライドして対応した記憶があります。

    そうなんですねー。やっぱり自分で書く力をつけないとダメですね。

    >カエルが表紙のplayframeworkの本が出てます。自分は書籍版とkindle版と2冊買いました。
    >ネットで調べるより時間の節約になるかと思いますよ。

    仰るとおりだと思います!

    ありがとうございました^^

    キャンセル

関連した質問

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

  • Play Framework 2

    107questions

    Play Framework 2はPlayのメジャーバージョンです。現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。