4

動的な html フォームを作成する方法を学習しようとしています。要素はデータベースで定義されます。ページが作成されると、ポストバック データがコントローラーによって処理され、データがデータベースに挿入されます。

playframework 1.2.4 を使用しています

ガイドライン/役立つリンクをいただければ幸いです

要素が何であるかを知っていればページを構築でき、コントローラーからrender(param object)を呼び出してビュー内のオブジェクトにアクセスすると、データベーステーブルから選択リストのデータを引き出すことができます。

これまでの私のハック:次の列を持つテーブルを作成しました

rid
HTMLElementType
ElementName
HTMLElementOptions [if the element type is select]
HTMLDefaultValue [default value for select like 'select a value from below']
HTMLElementEnabled

モデルを作成しました

package models;

import play.*;
import play.db.jpa.*;
import play.data.validation.*;

import javax.persistence.*;
import java.util.*;

@javax.persistence.Entity
@Table(name="mytable")
public class DynameForm extends Model{
     public String HTMLElementType;
     public String ElementName;
     public String HTMLElementOptions;
     public String HTMLDefaultValue;
     public String HTMLElementEnabled;
}

私の見解では、それが空のオプションであるかどうかを確認し、<select>そうであれば空のオプションを入れます。しかし、それが正しい方法かどうかはわかりません。さらに、私の見解では、そうでないかどうかも確認する必要があり<input type=>、完全なタグを挿入して構築する必要があります

さらに、例の姓/ ssn /などのように必要な特定のフィールドで検証を実施するにはどうすればよいですか? テーブルを変更して IsRequired 列を作成すると、役立つ可能性があります

ポストバックでデータをキャプチャする正しい方法がわからない

4

1 に答える 1

2

基本的に、問題は html フォームを生成することです。あなたは自分のモデルを理解したようです。欠けているのはビューです。simpleDB モデルのモデルを生成するために、次のようなことを一度行いました。

フィールドのリストを提供すると、フィールドに基づいて UI が生成されます。私はテキストフィールドしか持っておらず、2 つのケース (可視および不可視) フィールドのみが必要でした。ユースケースによってはより複雑になる場合があるため、必要に応じて適応させることができます。

dish.fields関連するメタデータを含むフィールドが含まれています。検証が必要、または isRequired などの特別なものは、その情報をビューに提供する必要があるため、フィールドを適切な方法でレンダリングできます。

それをモデル化する最も簡単な方法は、HTML フォームから始めて、一度に 1 つのフィールドを一般化することです。

  #{list items:dish.fields, as:'f'}
    #{field 'f'}
    #{if f.display } 
    <div class="control-group">
        <label class="control-label"> &{f.name} </label>
        <div class="controls">
            <input type="text" class="input-xlarge" placeholder="&{f.name}" name="${dish.getFieldId(f)}" value="${dish.getValue(f)}" ></input>
        </div>
    </div>
    #{/if}
    #{else}
    <input type="hidden" class="input-xlarge" placeholder="&{f.name}" name="${dish.getFieldId(f)}" value="${dish.getValue(f)}" ></input>
    #{/else}
    #{/field}

    #{/list}    
    #{else}
    No fields
    #{/else}

私は自分のフィールドを定義する必要がありましたが、アイデアを得ることができるはずです。

おそらく、さまざまなユースケースに対してさまざまな入力タイプを用意する必要があるため、単純なものから始めて、徐々に一般化していきます。CRUD モジュールの実装も確認できます。

私のDisplayAttributeクラス (フィールドのメタデータ) は次のようになります。出発点として使用できます。

public class DisplayAttribute {
    public Boolean display = Boolean.TRUE;
    public String type = "";
    public String  name;

    public DisplayAttribute(String name){
        this.name = name;
        this.display = Boolean.TRUE;
    }

    public DisplayAttribute(String name, Boolean display){
        this.name = name;
        this.display = display;
    }
... overridden equals and hash
}

edit フィールドはどのようにレンダリングされますか? コントローラはメタデータ( DisplayAttribute)をビューに渡します。この場合、メタデータにはフィールドの名前と表示可能かどうかのみが含まれます。

モデル

ここでモデルにはレンダリングするフィールドが含まれていますが、これらをデータベースから簡単に取得することもできます。私のモデルは汎用的です。なぜなら、複数のモデルに対して同じことを何度も繰り返していることに気付いたからです。

メソッドを提供する独自のインターフェイスを実装しますgetFields。また、属性を指定するとその DisplayAttribute を取得し、DisplayAttribute を指定するとその名前を取得できるように、2 つのマップも維持しています。必要に応じて、このモデルのメソッドをビューから呼び出します。

    public class GenericSimpleDBModel implements SimpleDBModel {

        public static AmazonSimpleDB sdb = null;
        private static final String bracketRemovalPattern = "(^.*?\\[|\\]\\s*$)";
        private Map<DisplayAttribute, Set<String>> data = new TreeMap<DisplayAttribute, Set<String>>(new UuidComparator());
        private Map<String, DisplayAttribute> attributeCache = new HashMap<String, DisplayAttribute>();
        protected final String DOMAIN_NAME;

        public GenericSimpleDBModel() {
            initialize(getFields());
            this.DOMAIN_NAME = "dishes";
        }

    protected void initialize(String[] fields) {
        data = new TreeMap<DisplayAttribute, Set<String>>(new UuidComparator());
        attributeCache = new HashMap<String, DisplayAttribute>();
        for (String f : fields) {
//            if (f.equals(getUUIDField()) || f.equals(getIntegrityField())) {
            if (f.endsWith("uuid") || f.endsWith("integrity")) {
                setValue(f, "", Boolean.FALSE);
            } else {
                setValue(f, "", Boolean.TRUE);
            }
        }
    }
   protected void initialize(Set<DisplayAttribute> fields) {
        data = new TreeMap<DisplayAttribute, Set<String>>(new UuidComparator());
        attributeCache = new HashMap<String, DisplayAttribute>();
        for (DisplayAttribute atr : fields) {
            setValue(atr.name, "");
        }
    }
... more methods
}
于 2012-10-30T20:31:00.130 に答える