読者です 読者をやめる 読者になる 読者になる

バイト数でのTextFieldのmaxLengthバリデーション

Ext.JSのTextFieldでは、こんな感じで入力できる文字数の制限を設けてバリデーションを行うことができます。

var myField = new Ext.form.TextField({
    id: 'name',
    fieldLabel: '名前',
    maxLength: 50
});

私の環境はHTMLおよびDBの文字コードShift_JIS(Windows-31J)で、全角文字は2バイトとして扱ってバリデーションを行う必要があるため、カスタムバリデータを作成して対応しました。

// 文字列のバイト数をカウントする
function byteLen(s) {
    var r = 0;
    for (var i = 0; i < s.length; i++) {
        var c = s.charCodeAt(i);
        // Shift_JIS: 0x0 〜 0x80, 0xa0  , 0xa1   〜 0xdf  , 0xfd   〜 0xff
        // Unicode  : 0x0 〜 0x80, 0xf8f0, 0xff61 〜 0xff9f, 0xf8f1 〜 0xf8f3
        if ( (c >= 0x0 && c < 0x81) || (c == 0xf8f0) || (c >= 0xff61 && c < 0xffa0) || (c >= 0xf8f1 && c < 0xf8f4)) {
            r += 1;
        } else {
            r += 2;
        }
    }
    return r;
}

// バイト数での入力文字数validator
function byteMaxLengthValidator(val) {
	if(this.maxLength < byteLen(val)){
        	return String.format(this.maxLengthText, this.maxLength);
	}
	return true;
}

validatorとして使用するfunctionは、値が妥当な場合にはtrueを、そうでない場合にはエラーメッセージを返すようにします(APIドキュメントのTextFieldに説明があります)。
maxLengthの値とエラーメッセージはTextFieldのビルトインのmaxLengthを流用しています。

var myField = new Ext.form.TextField({
    id: 'userName',
    fieldLabel: '名前',
    maxLength: 50,
    validator: byteMaxLengthValidator
});

文字列のバイト数のカウントはこちらを参考にさせていただきました。