This Project Has Not Released Any Files
記述例
forms: { base: { form_name1: { fields: { } field_names: [ ] } } }, extend: { extend_form_name1: { fields: { }, field_names: [ ] }, } }
すべてのアイテムのカラムに対して、表示するべき入力フィールドの表示形態を定義する。ただし、拡張可能なエレメントの場合、拡張後の入力フィールドも含めて定義する。
拡張できないアイテムについてはbaseに。拡張可能なアイテムについてはextend以下に記述する。
フォームの処理はファイラーなどの処理と大きく違う部分がある。それは拡張エレメントはベースエレメントを継承して扱うことである。つまりベースエレメントの読み込みが完了していない限り、拡張エレメントを読み込むことができないのである。フォームから見て各フィールドは対等であるものの、同じように扱うことができないある。そこで、マニフェストをベースと拡張に分けることにした。ベースを先に読んで、後から拡張を読む二段階構成である。拡張フィールドはフォームのマニフェスト(ベース)を参照しながらデフォルト値を埋めていく。
このフォームの入力フィールドに関してhashで設定する。省略したときは空のhashが補充される。
形式はname > type > argsである 入力フィールドにはいくつかの階層がある。自分自身の階層、子の階層、孫の階層
入力フィールドの階層タイプを次の中から文字列で設定する。省略したときは'root'が補充される。
階層に必要なオプションを与えるための設定。記述するべき内容はタイプによって違ってくる。
typeでelementを選択したときに利用される。
この入力フィールドのモデル名に関して文字列で設定する。省略したときはフォーム名が補充される。ただし、フィールド名が.を含むとき、ピリオドより左の文字列が補充される。
この入力フィールドのカラム名に関して文字列で設定する。省略したときはフィールド名が補充される。ただし、フィールド名が.を含むとき、ピリオドより右の文字列が補充される。
この入力フィールドのラベルに関してhashで設定する。省略したときは空のhashが補充される。
形式はtype > argsである
入力フィールドのラベルタイプを次の中から文字列で設定する。省略したときは'default'が補充される。
一覧の処理に必要なオプションを与えるための設定。記述するべき内容はタイプによって違ってくる。
label typeでdefaultを選択したときに利用される。
label typeでnoneを選択したときに利用される。
この入力フィールドのタグに関してhashで設定する。省略したときは空のhashが補充される。
形式はtype > argsである
入力フィールドのタグタイプを次の中から文字列で設定する。省略したときは'none'が補充される。
ヘルパーの処理に必要なオプションを与えるための設定。記述するべき内容はタイプによって違ってくる。
helper typeでdefaultを選択したときに利用される。
この入力フィールドのヘルパーに関してhashで設定する。省略したときは空のhashが補充される。
形式はname > type > argsである
入力フィールドのヘルパータイプを次の中から文字列で設定する。省略したときは'none'が補充される。
ヘルパーの処理に必要なオプションを与えるための設定。記述するべき内容はタイプによって違ってくる。
helper typeでdefaultを選択したときに利用される。
ヘルパーを表示するためのテンプレートのファイル名を文字列で指定する。
ヘルパーのブロックを囲むdivタグが必要な場合、そのクラス名を文字列で設定する。デフォルトでは指定なし。
JavaScriptのコードからヘルパーの部品を操作するとき、必要な情報がヘルパーから得られなかったり、ヘルパーのブロックがどこにあるかを jqueryから検索できないようなことがある。このような場合、この設定を有効にすることでヘルパーをこのクラス名を持つdivタグで囲むことができるようになる。
現状では色を選択するヘルパーで利用している。コードの方もう少し整理すれば必要なくなるかもしれない。
画像のサイズ調整ヘルパーで利用する。ヘルパーのテンプレートからは幅サイズの調整をするためのヘルパーなのか、高さサイズのそれをするものなのかを判別することはできない。そこで、このオプションを使ってクラス名を埋め込むわけだが…もう少しうまい方法はないだろうか? 。
helper typeでnoneを選択したときに利用される。
この入力フィールドのに関してboolで設定する。省略したときはtrueが補充される。
このフォームの入力フィールドに関してで設定する。省略したときは空のが補充される。
入力フォームを表示するための設定。
formsはhash型である。 キーと値のペアになる。基本的には次のように各フォームの構成を個別に設定していく。
forms: { element_name1: { form_conf... }, element_name2: { form_conf... }, element_name3: { form_conf... }, element_name4: { form_conf... }, },
modelsと同じようにキーの表記揺れを解消できる。フォームごとの定義をform_confと呼ぶことにする。
大雑把に言うと、宣言のためのattributesとタグ出力するためのfieldsの二つに分かれている。 attributesで各フィールドがどのような振る舞いを期待されているかを記述し、fieldsでそれらをどのような順番で表示するかを記述する。
attributesはハッシュで記述し、キーにはフィールドの名前、値にはハッシュでフィールドの振る舞いを記述する。fieldsは配列で、attributesでキーにした名前の文字列を記述する。
forms: { element_name1: { attributes: { field_name1: { }, field_name2: { }, field_name3: { }, field_name4: { }, }, fields: [ 'field_name3', 'field_name1', 'field_name4', 'field_name2', ] }, },
element_name1というフォームには、四つのフィールドfield_name1,field_name2, field_name3,field_name4が存在し、ページ上にはfield_name3,field_name1,field_name4,field_name2の順序で表示される。
ベーシックな入力フォームを表示するだけなら、これだけで要件を満たせるのだが、現実は相当複雑な問題を抱えているので、膨大かつ難解なオプションを用意してある。ここからは、その難解さを説明してみる。
フィールドをページに表示する時の順序を保証するだけでよければ、attributesをハッシュではなく配列で記述すれば、わざわざ二段階に分離する必要は無い。
では、なぜこのようなニ段階構成になっているかというと、クラスを拡張できるモデルでは、ベースとなるモデルのフィールドを何度も定義する羽目になるからである。例えば、フキダシが拡張可能なエレメントである。フキダシはSpeechBalloonモデルをベースとして、拡張によってCircleSpeechBalloon、PlainSpeechBalloon、SquareSpeechBalloonの三つ(現時点で)に派生する。フキダシはこの分岐によって、入力フォームに必要なフィールドが変わってくる。最も分かりやすい例は「尻尾の角度」で、四角形、透明のフキダシにはそれを入力する必要がない(表示しなくて良い) 。それをサンプルにして、記述してみよう。
circle_speech_balloon: { r: { column: 'r', type: 'number', }, 'caption': { column: 'caption', type: 'text', }, }, plain_speech_balloon: { r: { column: 'r', type: 'hidden', }, 'caption': { column: 'caption', type: 'text', }, }, square_speech_balloon: { r: { column: 'r', type: 'hidden', }, 'caption': { column: 'caption', type: 'text', }, },
このような具合に違いが出る。ここではわかりやすくするために「尻尾の角度」「見出し」だけに絞って記述しているが、フキダシには(現状で)三十個ものフィールドがあるので、実際にはその全てのフィールドを記述しなければならない。これではフキダシが追加されるたびに、膨大な量の設定を記述せねばならず、メンテナンスにかかる労力が莫大となる。
これを回避するためにbaseが用意してある。
入力フォームはHTML上ではデータベースのテーブルと結合しているわけではない。テーブルとの結合はフレームワークレベルで行っている。つまり、一つの入力フォームに複数のテーブルの値が入力されてpostメソッドでサーバに送信される恐れがあるということである。そして、ぺったんRにはそれが実際に存在する。このような場合、Railsではテーブルの構造を厳格に区別するためにフィールドタグのname属性を[]で区切ることで対処している。
次の例は、通常のフィールドをタグにするケースで、エレメント名+カラム名で出力されるケース。
element_name[column_name] <input name="panel_picture[y]" size="5" type="number" value="121" />
問題が登場するのは「フキダシ」である。フキダシはエレメントパーツを持つ複合体のエレメントである。フキダシの下にバルーンとセリフが従属している。次の例は、エレメント名+エレメントパート名_attributes +カラム名で出力されるケース。
element_name[element_part_name_attributes][column_name] <textarea name="speech_balloon[speech_attributes][content]" cols="45" rows="5">バレンタイン</textarea>
どのモデル(入力フォーム)がどのタイプのエレメントなのかを判断することは、プログラム側からでは不可能なので、判断材料を何らかの形で記述しなければならない。これを回避するためにpartが用意してある。
baseとパート、この二つの配慮で大抵の表現に対応できると思う。しかしながら、入力フォームの表示の際に可変的な処理をする場合、何らかの形でパラメータを与える必要がある。細かいパラメータは必要な分だけ追加して行くよりない。ここまでに登場していない仕様をピックアップしておく。
ここからはパラメータの解説。
入力フォームにリンクしたモデルの名前を文字列で設定する。省略時はbaseが設定される。baseが設定されていなければ操作中のエレメント名が設定される。
このオプションは一つの入力フォームに複数のモデルのカラムを使う時を考慮して用意した。通常はエレメント名=モデル名なので設定する必要は無い。
baseが記述されている場合、ベースとなるエレメントのフィールドの設定も加えることができる。
入力フォームにリンクしたエレメントが拡張モデルの時にベースとなるエレメントのエレメント名を文字列で設定する。省略したときは設定なし。 通常はエレメントとモデルが一致しているのでmodelの設定と混乱しがちだが、この設定はあくまで入力フォームのフィールドをどう扱うかを決めるものである。この文字列を使ってモデルを検索してはいけない。
speech_balloon: { attributes: { 'speech_balloon.caption': { column: 'caption', type: 'text', }, }, circle_speech_balloon: { base: 'speech_balloon', attributes: { }, },
circle_speech_balloonはspeech_balloonを拡張したモデル。ベースのattributesでspeech_balloon.captionを設定しているので、拡張後のcircle_speech_balloonは、これといった記述がないにもかかわらず、speech_balloon.captionを利用できる。
ベースから拡張クラスを上書きするので設定を変えることもできる。
speech_balloon: { attributes: { 'balloon.r': { part: 'balloon', column: 'r', type: 'number', }, }, square_speech_balloon: { base: 'speech_balloon', attributes: { 'balloon.r': { part: 'balloon', column: 'r', type: 'hidden', }, }, },
フキダシの尻尾の角度はベースのspeech_balloonでは表示することになっているが、四角形や透明フキダシにはしっぽがないので表示しない方が見栄えが良い。そこで、これらのフキダシについては、後から表示を隠す設定に上書きしている。
入力フォームに登場するすべてのフィールドをハッシュで設定する。省略には空のハッシュ。
このフィールドにリンクしているモデルを文字列で指定する。省略時はデフォルトモデルが設定される。
一つの入力フォームに複数のモデルのフィールドが収まっているときにモデルを区別するために設定する。通常はエレメント名=モデル名なので設定する必要は無い
フィールドがelement_partの時に文字列で指定する。デフォルトでは nil
エレメントからエレメントパートを取得するためのメソッド名のこと。
speech_balloon: { attributes: { 'speech.content': { part: 'speech', column: 'content', type: 'text_area', }, }, },
セリフはエレメントパートである。その中のカラム「台詞」を記述している。
attributesのキーで'speech.content':といった具合にモデル名.カラム名のフォーマットで記述していることについて補足。エレメントのパートのように複数のモデルを一つのフォームで扱うとカラム名が重複することがある。例えば、フキダシとセリフともにXY幅高さのカラムがある。単にカラム名をキーにしてしまうと両者が衝突してしまう。そこで(冗長にはなるものの)モデル名を付加して対処している。
フィールドにリンクしているカラム名を文字列で指定する。省略はできない。
panel_picture: { attributes: { link: { column: 'link', }, }, },
コマ絵を入力するフォームのlinkをpanel_pictureモデルのlinkカラムに関連付けている。
入力インターフェイスの形式を次の中から文字列で指定する。省略はできない。
panel_picture: { attributes: { caption: { column: 'caption', type: 'text', }, }, },
コマ絵の入力フォームのcaptionは文字を入力するためのフィールドである。
入力フィールドの横にラベルを表示するための設定。
ラベルの表示形式を文字列で指定する。デフォルトではラベルを表示する。
ground_color: { panel_id: { column: 'panel_id', type: 'hidden', label: { type: 'hidden' }, }, }, },
ground_color: { attributes: { code: { column: 'code', type: 'hidden', label: { row_break: true }, }, }, },
背景色のパネルidはシステムが管理する値なので、フィールドと共にラベルも表示しない。しかし、カラーコードはフィールドを表示しないものの、ユーザがヘルパーを使って入力する値なので、ラベルは表示する。
ラベルの改行フラグをtrue/falseで指定する。デフォルトはfalse
表示スペースを縦方向に圧縮したい場合、ラベルとフィールドを左右に並べて表示する。ほとんどのフィールドは縦方向に圧縮したいのでこのパターンで良い。しかし、横方向に圧縮したいフィールドもある。この場合、この設定を無効にすることで改行タグを入れて上下に並べて表示する。
speech_balloon: { attributes: { 'speech.content': { part: 'speech', column: 'content', type: 'text_area', label: { row_break: true }, }, }, },
セリフのcontentのフィールドは長い文章を入力する必要があるため、サイズを最大限に大きくとっている。横幅を確保するためにラベルを改行してから表示する。
リキッドレイアウトにされているフィールドのブロックを改行するフラグをtrue/falseで指定する。デフォルトはfalse
フィールドのサイズを数値で設定する。テキストエリアでは幅×高さ(この場合は文字列)でも指定できる。デフォルトでは指定なし。
panel_picture: { attributes: { x: { column: 'x', type: 'number', label: { }, options: { size: 5, } }, y: { column: 'y', type: 'number', label: { }, options: { size: 5, row_break: true } }, }, },
ground_color: { attributes: { code: { column: 'code', type: 'hidden', label: { row_break: true }, options: { row_break: true } helpers: { color: { path: 'panels/color_helper', options: { }, wrapper: 'ground_color-code-wrap' } }, }, }, },
各フィールドがどのモデルとリンクしているかを取得する。フィールド出力はエレメント毎に処理されるので、モデル名はエレメントから求められるのではないか、と思いがちだが、そう簡単にはいかない。 一枚の入力フォームに複数のモデルをまたいだフィールドを表示することがあるからだ。例えば、吹き出しなどはエレメントとパートに分かれているので、フキダシとセリフとバルーンの三つのモデルのフィールドがチャンポンになっている。このためフィールドはエレメントなのかパートなのかを判別して、パートであれば該当するモデルをモデルの設計から取得してくることになる。もちろんフィールドがエレメントであればそこから求めればよい。
IDのフィールドは更新する時は表示しなければならないが、新規作成の時は表示してはならない。この判定のためにフィールドにリンクしたカラムがテーブルのprimary keyで無いかを所得しなければならない。これにはモデルの設定から拾ってくる必要がある。
入力フォームがどのモデルとリンクしているかを判別するためのパラメータ。
フィールドタグにはname属性を文字列で指定しなければならないが、 railsにはこの文字列を作成するための作法があるので、それにならって生成する必要がある。
命名規則の基本は
モデル名カラム名
だが、エレメントパートのように階層構造になっているモデルは特別に
となる
[PageInfo]
LastUpdate: 2014-01-30 08:32:53, ModifiedBy: yasushiito
[Permissions]
view:all, edit:login users, delete/config:members