Home   Single Page

入力制御

入力制御のセットはXULコンポーネントセット中でサポートされています。:textbox、 intbox、 decimalbox、 doublebox、 datebox、combobox、bandbox。
それらによって、ユーザーは異なったタイプのデータを入力できます。

<zk>
    <textbox/>    
    <datebox/>    
</zk>

【ヒント】:comboboxとbandboxは特別な入力ボックスです。その二つはここに書いたプロパティを共有しています。後に出てくるcomboboxesとbandboxesセクション中でそれら独特な特徴が議論されます。

typeプロパティ

textboxコンポーネントのtypeプロパティをpasswordに指定することで、ユーザーが何を入力したかは表示されません。

Username: <textbox/>
Password: <textbox type="password"/>

format プロパティ

フォーマットフィールドによって、入力制御のフォーマットを選択できます。
デフォルトはnullです。databoxでは、デフォルトはyyyy/mm/ddです。intboxとdecimalでは、デフォルトは何のフォーマットもなしです。

<datebox format="MM/dd/yyyy"/>
<decimalbox format="#,##0.##"/>

他のプロパティのように、以下に書いてあるように、動的にフォーマットを変えることができます。

<datebox id="db"/><button label="set MM-dd-yyyy" onClick="db.setFormat(&quot;MM-dd-yyyy&quot;)"/>

マウスを使わずに入力:datebox

  • Alt+DOWNはカレンダーをポップアップさせます。

  • LEFT, RIGHT, UP, DOWNでカレンダーから選択された日を変えます。

  • ENTERで選択された日を有効にします。(dateboxに選択した日をコピーすることによって)

  • Alt+UP またはESCは選択をあきらめ、カレンダーを閉じます。

入力条件

constraintプロパティの使用によって、入力制御が受け取る値を規制します。
Positive、negative、no zero、no empty、no future、no past、no today、regular expressionを組み合わせて使用することができます。
初めの三つの規制はintboxとdecimalboxだけに適用できます。no future、no past、no todayの規制はdateboxにのみ適用できます。
no emptyの規制はどのタイプのコンポーネントにも適用できます。
regular expressionsの規制はtextbox、combobox、bandboxのようなストリングを入力するコンポーネントにのみ適用できます。

二つ以上の規制を指定するために、コンマ(,)を使って以下のように分けます。

<intbox constraint="no negative,no zero"/>

regular expressionを指定する時に、/を使って以下のようにregular expressionを閉じます。

<textbox constraint="/.+@.+\.[a-z]+/"/>

メモ:

  • 上のステートメントはXMLなので、\\でバックスラッシュを表現しないでください。
    一方で、Javaで書いているなら、バックスラッシュを\\で表現しなければなりません。

new Textbox().setContraint("/.+@.+\\.[a-z]+/");
  • カンマで分けることで、別の規制を持つregular expressionと混在に使うことができます。

デフォルトの代わりに、アプリケーション依存のメッセージを表示する場合、規制の後ろにコロンを使って、失敗したときに表示したいメッセージを加えます。

<textbox constraint="/.+@.+\.[a-z]+/: e-mail address only"/>

<datebox constraint="no empty, no future: now or never"/>

メモ:

  • エラーメッセージを指定する場合は最後の要素で指定しコロンで始めます。

  • 多言語をサポートするのに、国際化の章で説明されている l functionを使用します。

<textbox constraint="/.+@.+\.[a-z]+/: ${c:l('err.email.required')}"/>

Datebox の条件

上記の説明に加えて(no future と 正規表現のような)、datebox はデータの範囲をサポートします。例えば、

<datebox constraint="between 20071225 and 20071203"/>
<datebox constraint="before 20071225"/>
<datebox constraint="after 20071225"/>

注目

  1. 条件内の date のフォーマットは yyyMMdd です。これはロケールに依存します。

  2. 条件内に date 指定が含まれます。例えば、 "before 20071225"は 「December 25, 2007 とそれ以前の毎日」を含みます。

  3. 条件( constraint )は実に org.zkoss.zul.SimpleDateConstraint のインスタンスです。パースした結果の開始日と最終日は getBeginDate と getEndDate メソッドを使って取得できます。

((SimpleDateConstraint)datebox.getConstraint()).getBeginDate();

Custom規制

Custom Constraints

より複雑な規制をするなら、org.zkoss.zul.Constraintインターフェースを実装するオブジェクトを指定します。

<window title="Custom Constraint">
    <zscript><![CDATA[    
Constraint ctt = new Constraint() {
    public void validate(Component comp, Object value) throws WrongValueException {    
        if (value =e= null || ((Integer)value).intValue() < 100)        
            throw new WrongValueException(comp, "At least 100 must be specified");            
    }    
}
    ]]></zscript>    
    <intbox constraint="${ctt}"/>    
</window>

Javaクラスに規制を実装することができます。例えば、my.EmailValidatorの場合は:

<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<textbox constraint="${c:new('my.EmailValidator')}"/>
org.zkoss.zk.ui.WrongValueException

上の例ではorg.zkoss.ui.WrongValueExceptionを使用して、エラーを表します。
説明したように、エラーを発生させるコンポーネントを初めの引数に指定しなければなりません。そして、二つ目の引数にエラーメッセージを指定します。

どんなときでも、例えばonChangeイベントが以下のように受け取られたときに、この例外を使用することができます。

<textbox>
    <attribute name="onChange">    
        if (!self.value.equals("good")) {        
            self.value = "try again";            
            throw new WrongValueException(self, "Not a good answer!");            
        }        
    </attribute>    
</textbox>
エラー表示をカスタマイズする

前の例中で示されたデフォルトのエラーボックスの代わりに、規制を伴ったorg.zkoss.zul.CustomConstraintインターフェースを実装することでカスタムの外見を提供することができます。

CustomConstraintインターフェースはshowCustomErrorと呼ばれるメソッドをもち、例外が発生したとき、又はバリデーションが失敗したときに呼び出されます。以下は例です。

<window title="Custom Constraint" border="normal">
    <zscript><![CDATA[    
class MyConst implements Constraint, CustomConstraint {
    //Constraint//    
    public void validate(Component comp, Object value) {    
        if (value == null || ((Integer)value).intValue() < 100)        
            throw new WrongValueException(comp, "At least 100 must be specified");            
    }    
    //CustomConstraint//    
    public void showCustomError(Component comp, WrongValueException ex) {    
        errmsg.setValue(ex != null ? ex.getMessage(): "");        
    }    
}
Constraint ctt = new MyConst();
    ]]></zscript>    
    <hbox>    
        Enter a number at least 100:        
        <intbox constraint="${ctt}"/>        
        <label id="errmsg"/>        
    </hbox>    
</window>
応答速度の改善

応答はクライアントでより多く規制を承認(validate)することで改善できます。このためには、Constraint でorg.zkoss.zul.ClientConstraint インターフェースを実装しなければなりません。
クライアントですべてのバリデーションが行われると、isClientCompleteメソッドにtrueを返します。サーバー側へ送信し、バリデーションを行う必要がなくなります。

Validate_erroboxと呼ばれる要素を使用すれば、クライアントでJavaScriptコードだけで外見をカスタマイズすることができます。例えば、

<script type="text/javascript"><![CDATA[
    //Running at the browser    
    window.Validate_errorbox = function (id, boxid, msg) {    
        var html = '<div style="display:none;position:absolute" id="'        

+boxid+'">'+zk.encodeXML(msg, true)+'</div>';

            document.body.insertAdjacentHTML("afterbegin", html);return $e(boxid);}            
]]></script>

【メモ】: zscriptはサーバーで実行されているコードを示します。一方、scriptはブラウザで実行されているスクリプトコードを表します。

【メモ】:CustomConstraintが実装されているなら、すべての承認がサーバーで行われるためClientConstraintは無視されます。つまり、ClientConstraintを使用して、応答を改善する場合、Validate_erroboxを上書きすることがエラーメッセージの表示を変更する唯一の方法です。

onChangeイベント

コンテンツがユーザによって変更された場合、入力制御はonChangeイベントでアプリケーションに通知します。

onChangeのイベントリスナが呼び出された時、変数は設定されます。その時に不合理的な値を拒否するのは遅すぎます。
さもなければ、適切な値を再設定しなければなりません。より良い方法として、Custom Constraintsセクションで説明しているように、規制を使用することをお勧めします。

onChangingイベント

ユーザーがコンテンツを変更している最中にしても、入力制御はonChangingイベントでアプリケーションを通知します。

onChangingリスナが呼び出されたとき、値はまだ設定されていません。つまり、valueプロパティは古いままです。ユーザーが入力したものを取得するために、以下のようにイベントのvalueプロパティを参照しなければなりません。

<grid>
    <rows>    
        <row>The onChanging textbox:         
            <textbox onChanging="copy.value = event.value"/></row>            
        <row>Instant copy:        
            <textbox id="copy" readonly="true"/></row>            
    </rows>    
</grid>

ユーザーがまだ変更を終えていないので、onChangingイベントリスナの中で不合理的な変数を拒否したくても早すぎてできません。
より良い方法として、Custom Constraintsセクション中に書かれているように規制を使用することをお勧めします。