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

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

ただいまの
回答率

87.48%

Playframeworkでのバリデーション

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 627

score 88

お世話になっております。

今、あるフォームにバリデーションを入れようとして、
フォームの上部にはバリデーションが入るようになった
のですが、テキストボックス直下にどうも上手く入らない
状況が続いているため、お助け下さい!

app/controller/Application.java

public class Application extends Controller {

    public String title = "入力画面";
    public String msg = "フォームを入力";

    public Result sendform(){
        Form<SampleData> dataform =  form(SampleData.class).bindFromRequest();
        if(!dataform.hasErrors()){
            SampleData nitta = dataform.get();
            nitta.save();
            flash("success", "きっちり入力できました!!");
            return redirect("/");
        }else {
            flash("error", "入力内容に誤りがあります!!");
            List<SampleData> datas = SampleData.find.all();
            return badRequest(mynum.render(title, msg, datas, dataform));
        }
    }
}


●Sampleform.java

package views.form;

import java.util.ArrayList;
import java.util.List;

import play.data.validation.ValidationError;
import play.i18n.Messages;

public class Sampleform {

    public String id ="";
    public String name ="";
    public String title ="";
    public String memo ="";

    public Sampleform(){}

    public Sampleform(String id,String name,String title,String memo) {
        this.id = id;
        this.name = name;
        this.title = title;
        this.memo = memo;
    }

    public List<ValidationError> validate(){

        List<ValidationError> errors = new ArrayList<ValidationError>();
        //名前
        if(name == null || name.length() == 0) {
            errors.add(new ValidationError("name",Messages.get("SampleData.name.error")));
        }
        //タイトル
        if(title == null || title.length() == 0) {
            errors.add(new ValidationError("title",Messages.get("SampleData.title.error")));
        }

        if(errors.size()>0) {
            System.out.println("Sampleform#validate errors");
            return errors;
        }

        return null;
    }

    @Override
    public String toString() {
        return "Sampleform[id=" + id + ", name=" + name + ", title="
        + title    + ", memo=" + memo + "]";
    }

models/SampleData.java

package models;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang3.StringUtils;

import com.avaje.ebean.Model;

import views.form.Sampleform;

@Entity(name="SampleData")
public class SampleData extends Model {

    @Id
    public Long id;

    @NotNull
    @Column(unique=true)
    public String name;

    @NotNull
    public String title;

    public String memo;

    public static Finder<Long, SampleData> find =
        new Finder<Long, SampleData>(Long.class, SampleData.class);   

    public static SampleData converttoModel(Sampleform sampleform) {
        // TODO 自動生成されたメソッド・スタブ
        SampleData Sam_data = new SampleData();
        Sam_data.id = StringUtils.isNotEmpty(sampleform.id)?Long.valueOf(sampleform.id):null;
        Sam_data.name = sampleform.name;
        Sam_data.title = sampleform.title;
        Sam_data.memo = sampleform.memo;
        return Sam_data;
    }

    @Override
    public String toString() {
        return "SampleData[id=" + id + ", name=" + name + ", title="
        + title    + ", memo=" + memo + "]";
    }
}


●aaa.scala.html

@(title: String, message: String, datas: List[SampleData], sampleform: Form[SampleData])


@main("HOME") {

<div class="container">

     <div class="row">
       <div class="col-sm-2"><h2>@title</h2></div>
       <div class="col-sm-2"></div>
       <div class="col-sm-6" style="margin-top: 20px; color:blue;"><p>@message</p></div>
      </div>

<!--  @if(flash.get("errormsg") != null){ <p>@flash.get("errormsg")</p> } -->

●aaa.html

↓ここでのバリデーションは出る
@if(flash.containsKey("error")){
<div class="row">
 <div class="col-md-12 well">
     <div id="error-message" class="text-danger">
         @flash.get("error")
     </div>
 </div>
</div>
}

<form class="form-horizontal" id="SampleData" role="form" action="/sendform" method="post">

   <!--name-->
   <div class="form-group">
        @defining(sampleform("name")){ nameField =>
        <label for="nameField.id" class="col-sm-2 control-label">名 前</label>
        <div class="col-sm-6">
          <input type="text" id="@nameField.id" class="form-control" name="@nameField.name" value="@nameField.value" placeholder="名前を入力">
        </div>
         ↓ここでのバリデーションは出ない
        @if(nameField.hasErrors){
          <span class="help-block" style="color: #F00;">@nameField.errors.mkString(",")</span>
        }
      }
    </div>
   <!--title-->
    <div class="form-group">
        @defining(sampleform("title")){ titleField =>
        <label for="titleField.id" class="col-sm-2 control-label">タイトル</label>
        <div class="col-sm-6">
          <input type="text" id="@titleField.id" class="form-control" name="@titleField.name" value="@titleField.value" placeholder="題目">
        </div>
         ↓ここでのバリデーションは出ない
        @if(titleField.hasErrors){
          <span class="help-block" style="color: #F00;">@titleField.errors.mkString(",")</span>
        }
        }
    </div>
    <!--memo-->
    <div class="form-group">
        @defining(sampleform("memo")){ memoField =>
        <label for="memoField.id" class="col-sm-2 control-label">メ モ</label>
        <div class="col-sm-6">
          <textarea rows="4" cols="40" id="@memoField.id" class="form-control" name="@memoField.name" value="@memoField.value" placeholder="色々書く"></textarea>
        </div>
        }
    </div>


<div class="btn-toobar">
 <div class="btn-group">

   <button type="submit">送 信</button>

   <button type="button" onclick="location.href='/Search'">検 索</button>

 </div>
</div>

</form>


●試した事
上記の2か所(バリデーションを出したい箇所)を以下に書き換え
@if(nameField.hasErrors){
<span class="help-block" style="color: #F00;">名前は必須です!!</span>
}
@if(titleField.hasErrors){
<span class="help-block" style="color: #F00;">タイトルは必須です!!</span>
}

その他にも、色々やりましがダメでした。
以上、よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

これだと、エラーメッセージどころか今入力した内容も表示されていないのではないでしょうか?

入力内容が正しかろうが、バリデータでエラーになろうが
Controllerでアドレス/ にリダイレクトしているので、
今利用しているdataformは何一つ活用されていないことが原因だと思います。

リファレンスの
https://www.playframework.com/documentation/2.5.x/JavaForms#Handling-binding-failure

とか

Formを利用したサンプルプロジェクト
https://github.com/playframework/play-java-forms-example/tree/2.5.x

がありますので動作を理解しながら実装を進めるべきだと思います。

https://github.com/playframework/play-java-forms-example/blob/2.5.x/app/controllers/WidgetController.java

のcreateWidget()がPostされた際のコントローラーのActionになります。
今回あげられた入力内容のバリデートの部分で参考になるサンプルです。

入力内容に問題がない場合は、リダイレクトしていますが

return redirect(routes.WidgetController.listWidgets());

これは結局

public Result listWidgets() {
        return ok(views.html.listWidgets.render(asScala(widgets), form));
}


が呼び出されているにすぎません。

逆に入力内容にエラーがある場合は

 return badRequest(views.html.listWidgets.render(asScala(widgets), boundForm));

となっていると思います。

どちらもlistWidgets.scala.htmlをrenderする際に、それぞれのFormのインスタンスが渡されていると思います。

boundFormは、入力内容をバリデートした結果も持ったFormなのでそのままViewに渡せばViewでエラーメッセージを表示しようとするだけです。

Nittaさんのプログラムだと常にリダイレクトしているので、最終的には

return ok(view.html.aaa.render(form));


が動作しているだけではないでしょうか?この時のFormは常に初期化されたFormのインスタンスなのではないでしょうか?

フレームワークを利用する際は、公式のリファレンスを読んで何ができるのか理解したうえで利用する方がよいと思います。今のままではうまくいかない度にここに書き込んで解決しようとしていますが、本質的に何も理解できていないように見えます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/03/29 15:13

    お世話になっております。
    上記のリファレンスから何とかバリエーションを
    出せるようになりました。
    今までのやり方を少し考え直し、本質を理解できるように
    していきたいと思います。
    今後ともよろしくお願いいたします。

    キャンセル

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

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

関連した質問

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