ユーザー入力を受け付けるアプリケーションは、通常、入力値の有効性を検証する必要があります。Curl® GUI Toolkit の検証パッケージ
CURL.GUI.CONTROL-VALIDATION は、データ入力の検証メカニズムを提供します。このパッケージは Curl API バージョン 5.0 から追加されました。
さまざまなレベルの検証を実行できます。たとえば、ユーザーのキーストロークに即座に反応して値を検証したり、入力が完了したフォームまたはダイアログのすべてのコントロールの検証を実行したりできます。問題が見つかった場合は、入力中のフォーム内やポップアップ ダイアログにその内容を表示できます。
多くの場合、アプリケーションで検証イベントを直接処理する必要はありません。通常は、次のオブジェクトを組み合わせて使用します。
検証パッケージには、次に示す各種検証クラスが含まれています。
コントロールは個別に検証できますが、多くの場合、
Dialog (
RecordForm、
HttpForm などのサブクラスを含む) でグループ化されたコントロールに対して検証が実行されます。検証サイクルは、入力が変更されると開始し、すべての必要なフィードバックを表示して終了します。
現在のコントロールが
Dialog に含まれていない場合、検証イベントは現在のコントロールでのみ発生します。コントロールが Dialog に含まれている場合は、検証サイクルによってダイアログ内の他のコントロールとそのダイアログ自体の有効性が検証されます。検証サイクルの間、コントロールはタブ トラバーサルの順序で検証されます。
現在の入力が無効な場合は、ダイアログ内の他のコントロールを検証する必要はありませんが、それらのコントロールにエラーを通知する必要があります。コントローラは
ValidationComplete イベントを他のコントロールおよびそのコントロールを含む
Dialog で発生させるため、適切な方法 (無効状態に変更するなど) でエラーに対処できます。
Curl 検証 API には、多数の各種データ入力用の検証クラスが含まれています。「
検証クラス」を参照してください。
検証システムは、エラーを
MessageDisplay に表示します。既定のメッセージ表示は
MessageDialog です。これは
MessageDisplay のサブクラスで、収集した検証メッセージをポップアップ ダイアログに表示します。ポップアップ ダイアログはダイアログやフォームの領域を使用しませんが、フォームにメッセージ用の余裕がある場合は、
MessageDisplay を使用した方がメッセージをよりわかりやすく表示できます。1 つの
MessageDisplay を多くのコントロールで共有できます。
例:
数値入力の検証 |
|
{let numeric-val:TextField =
{TextField
width = 3cm,
{validate-with {NumericValidator}}
}
}
{HBox "Number:", numeric-val}
| |
エラー メッセージを表示するには、UI に表示オブジェクトを追加する必要があります。
例:
MessageDisplay でのエラー表示 |
|
{let md:MessageDisplay = {MessageDisplay}}
{let numeric-val:TextField =
{TextField
width = 3cm,
message-display = md,
{validate-with {NumericValidator}, required? = true}
}
}
{HBox spacing = 3pt, "Number:", numeric-val, md}
| |
例:
MessageDisplay プロパティの変更 |
|
{let md:MessageDisplay =
{MessageDisplay
invalid-entry-background = "magenta",
required-entry-background = "lime",
message-color = "magenta"
}
}
{let numeric-val:TextField =
{TextField
width = 3cm,
message-display = md,
{validate-with {NumericValidator}, required? = true}
}
}
{HBox spacing = 3pt, "Number:", numeric-val, md}
| |
これまでに示した例では、コントロールを個別に検証しました。通常のケースでは、ダイアログ内の複数のコントロールに対して検証を行います。たとえば、ダイアログ内のすべてのコントロールに有効なデータが入力されていることを確認するユーザー インターフェイスを設計できます。
次の例は、ダイアログ内のコントロールをグループ化し、そのダイアログに対して検証を実行します。この例のポイントを次に示します。
例:
CommandButton を使用した Dialog の検証 |
|
{let md:MessageDialog = {MessageDialog title = "Input error"}}
{let numeric-val:TextField =
{TextField
{validate-with
{NumericValidator},
dialog-on-finished? = false,
required? = true
}
}
}
{let string-val:TextField =
{TextField
{validate-with
{StringValidator min-chars = 5, max-chars = 10},
dialog-on-finished? = false,
required? = false
}
}
}
{let validate-button:CommandButton =
{CommandButton
label = "Validate",
{on Action at cb:CommandButton do
{if {validate-dialog {non-null cb.dialog}} then
{popup-message "Submitted"}
}
}
}
}
{Dialog
margin = 6pt,
message-display = md,
{VBox
width = 3cm,
"Number:",
numeric-val,
"String:",
string-val,
validate-button
}
}
| |
ダイアログレベルの検証では、ダイアログ内の該当するデータ入力がすべて有効な場合にコマンド ボタンを有効にすることができます。次の例では、
DialogValidator を使用してダイアログを検証します。3 つのテキスト フィールドすべての入力が有効な場合は、ダイアログの検証が完了すると、
ValidationComplete イベントのイベント ハンドラによってコマンド ボタンが有効になります。
[Email] フィールドが必須でないため、[String] フィールドと [Number] フィールドに有効な値が入力されるとすぐにダイアログは有効となります。ただし、[Email] フィールドに無効な値が入力された場合は、ダイアログは有効とは見なされなくなります。
例:
有効な Dialog を使用した CommandButton の有効化 |
|
{let md:MessageDisplay = {MessageDisplay}}
{let string:TextField =
{TextField
width = 3cm,
message-display = md,
name = "string",
{validate-with
{StringValidator min-chars = 2, max-chars = 10},
required? = true
}
}
}
{let number:TextField =
{TextField
width = 3cm,
message-display = md,
name = "number",
{validate-with {NumericValidator}, required? = true}
}
}
{let email:TextField =
{TextField
width = 3cm,
message-display = md,
name = "email",
{validate-with ValidationPattern.email-address}
}
}
{let cb-val:CommandButton =
{CommandButton
label = "Press",
name = "button",
{on Action do
{popup-message
{VBox
"You entered:",
string.value,
number.value,
email.value
}
}
}
}
}
{Dialog
{Table
columns = 2,
"String:", string,
"Number:",number,
"Email:", email,
cb-val, md
},
{validate-with {DialogValidator}},
{on vc:ValidationComplete at d:Dialog do
set {d.get-by-name "button"}.enabled? = d.valid?
}
}
| |
次の例では、numeric-3 ではなく numeric-1 フィールドと numeric-2 フィールドを使用してコマンド ボタンを検証します。必須の数字をすべて入力すると、ボタンが有効になります。
例:
CommandButton の検証 |
|
{let numeric-1:TextField =
{TextField
name = "numeric-1",
{validate-with {NumericValidator}, required? = true}
}
}
{let numeric-2:TextField =
{TextField
name = "numeric-2",
{validate-with {NumericValidator}, required? = true}
}
}
{let numeric-3:TextField =
{TextField
name = "numeric-3",
{validate-with {NumericValidator}, required? = true}
}
}
{let enter-data:CommandButton =
{CommandButton
name = "button",
label = "Enter Data",
{validate-with
{EnablingValidator "numeric-1", "numeric-2"}
},
{on Action do
{popup-message
"You entered:"
& " " & {value numeric-1.value}
& " " & {value numeric-2.value}
}
}
}
}
{Dialog
{VBox
"Enter three numbers:",
numeric-1,
numeric-2,
numeric-3,
enter-data
},
{validate-with {DialogValidator}}
}
| |
ValidationController は、ダイアログ内のコントロールに検証イベントを送信す際、ダイアログ内のオブジェクトのタブ順序に従います。これは検証によってコマンド ボタンを有効にするような場合に重要なポイントです。コントロールが正しい順序で検証されなければ、システムは不完全な情報に基づいて動作する場合があるためです。
この問題を次の例に示します。前の例と同様に、コマンド ボタンはリストされたコントロールが有効な場合に有効になります。ただし、この例では、コマンド ボタンはダイアログ内の最初のオブジェクト、つまりタブ順序として最初に設定されているオブジェクトです。いずれかのテキスト フィールドに数字を入力してください。入力が完了するとすぐにコマンド ボタンが有効になります。
値の入力によって検証サイクルが開始され、現在のコントロールの次に、タブ順序の最初にあるコマンド ボタンが検証されます。他の 2 つのテキスト フィールドはまだ検証されていないため、これらのフィールドの検証結果が得られません。そのため、コマンド ボタンは、変更した 1 つのコントロールにのみ基づいて検証されます。
例:
タブ順序の制御 |
|
{let numeric-1:TextField =
{TextField
||-- tab-index = 3,
name = "numeric-1",
{validate-with {NumericValidator}, required? = true}
}
}
{let numeric-2:TextField =
{TextField
||-- tab-index = 2,
name = "numeric-2",
{validate-with {NumericValidator}, required? = true}
}
}
{let numeric-3:TextField =
{TextField
||-- tab-index = 1,
name = "numeric-3",
{validate-with {NumericValidator}, required? = true}
}
}
{let enter-data:CommandButton =
{CommandButton
||-- tab-index = 4,
name = "button",
label = "Enter Data",
{validate-with
{EnablingValidator "numeric-1", "numeric-2", "numeric-3"}
},
{on Action do
{popup-message
"You entered:"
& " " & {value numeric-1.value}
& " " & {value numeric-2.value}
& " " & {value numeric-3.value}
}
}
}
}
{Dialog
{VBox
enter-data,
"Enter numbers:",
numeric-1,
numeric-2,
numeric-3
},
{validate-with {DialogValidator}}
}
| |
このセクションでは、
MessageDisplay をサブクラス化して、コントロール、ラベル、およびメッセージをグループとして保持するオブジェクトの作成方法を説明します。各要素は GUI コンテナ (
Box のサブクラス) に配置されています。通常、このコンテナは
Table です。
コンストラクタは、複合メッセージ画面を構成するさまざまな UI 要素を作成します。これらの要素は、コンストラクタに渡される
Box に追加されます。オーバーライドする必要があるメソッドは
MessageDisplay.show のみです。
例:
MessageDisplay のサブクラスの作成 |
|
{define-class public open CompoundMessageDisplay {inherits MessageDisplay}
let public constant columns:int = 3
field protected prefix:Frame
field protected target:Graphic
field protected suffix:Frame = {Frame}
field protected message:Frame
{constructor public {default
box:Box,
label:Visual,
target:Graphic,
message-width:Distance = 2in,
...
}
{construct-super ...}
set self.prefix = {Frame}
set self.target = target
set self.message = {Frame}
{self.prefix.add label}
set self.message-display = self
{box.add self.prefix}
{box.add {HBox self.target, {Fill width = 4px}, self.suffix}}
{box.add self.message}
set self.target.message-display = self
}
|| Visual.clear をオーバーライドし、
|| もし表示されているメッセージがあれば、クリアします。
{method public {clear}:void
{self.message.clear}
}
|| イベントに添付されたエラーを表示します。
{method public open {show
vc:ValidationComplete,
target:ActiveTraversor
}:void
|| どのような場合も、変数suffixと適切な色を表示します。
{self.show-colors target}
{self.suffix.clear}
{if vc.controller.required? then
{self.suffix.add {HBox "*", {Fill}}}
}
let display?:bool = not vc.consumed? and vc.display?
{vc.consume}
{if-non-null tvr = target.validation-result then
{if tvr.invalid? and display? then
set self.message.color = self.message-color
{self.message.add replace? = true, tvr.message}
set target.control-content-background =
self.invalid-entry-background
{return}
}
}
{unset target.control-content-background}
}
}
{let tbl:Table = {Table columns = CompoundMessageDisplay.columns}}
{do
{CompoundMessageDisplay tbl, "Name:",
{TextField
width = 1.5in,
name = "name",
{validate-with {StringValidator}, required? = true}
}
}
{CompoundMessageDisplay tbl, "Password:",
{TextField
width = 1.5in,
name = "password",
{validate-with
{StringValidator min-chars = 6}, required? = true
}
}
}
{CompoundMessageDisplay tbl, "Confirm:",
{TextField width = 1.5in,
name = "confirm",
{validate-with {StringValidator}, required? = true},
{on ve:Validate at tf:TextField do
let pf:TextField =
{tf.dialog.get-by-name "password"} asa TextField
{if ve.current? and ve.partial? then
{if not {pf.value.prefix? tf.value} then
{tf.mark-invalid
message =
{hlmessage
Confirmation does not match password.
}
}
elseif pf.value != tf.value then
{tf.mark-invalid} || incomplete
}
elseif pf.value != tf.value then
{tf.mark-invalid
message =
{hlmessage
Confirmation does not match password.
}
}
}
}
}
}
{CompoundMessageDisplay tbl, "e-mail address:",
{TextField width = 1.5in,
name = "e-mail",
{validate-with ValidationPattern.email-address}
}
}
{tbl.add
{row
{skip}
{cell
{HBox
{ok-button label = "&Login", name = "login",
width = 1.5in,
{validate-with
{EnablingValidator
"password", "name", "confirm", "e-mail"
}
},
{on Action at cb:CommandButton do
{type-switch cb.dialog
case form:HttpForm do
{form.submit}
else
{popup-message "Logging in..."}
}
}
}
}
}
{cell * Entry required}
}
}
}
{Dialog
background = "white",
margin = 6pt,
tbl,
{validate-with {DialogValidator}}
}
| |
この例では、
Validate のイベント ハンドラを使用して特殊な検証を実行する方法も示します。この例の目的は、パスワードの確認入力がパスワード入力と一致しない場合に、ユーザーに警告することです。確認入力が途中で (
partial? フラグで示されます)、パスワードの先頭部分に一致している限り、メッセージは表示されません。フィールドが無効とマークされると、ログイン ボタンは無効なままになります。ユーザーはフィールドの色でエラーを識別できます。パスワードに一致しない文字を入力した場合は、すぐにメッセージが表示されます。フィールドをそのままにしようとすると、
partial? フラグが false になり、確認入力がパスワードに一致しなければメッセージが表示されます。
また、電子メールの入力はオプションですが、入力した場合は、有効な値でなければログイン ボタンは有効にはなりません。
プロシージャ
非ローカル オプション
その他のプロパティ
Copyright © 1998-2019 SCSK Corporation.
All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation.
that are registered in the United States. Surge
Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE)
logo are trademarks of SCSK Corporation.