View Full Version : [Solved] NumberFieldにおけるカンマ編集
Ext.form.NumberFieldで作成された入力フィールドがあります。
ここに数値が入力されたとき、自動的に3桁ごとのカンマ区切りを入れる方法はあるでしょうか?
具体的な動作としては次のようなイメージです。
・フォーカス時(入力状態)には、「1234.56」のように表示される。
・フォーカスを失うと、「1,234.56」のようにカンマ編集結果が表示される。
グリッド内(EditorGridPanel)のフィールドであれば、対象カラムのrendererとしてカンマ編集する関数を指定するだけで上記の仕様が実現できました。
通常のフォーム(FormPanel)においてはどのように実現したら良いのでしょう?
Tommy1969
5 Jun 2009, 8:28 AM
DataField みたいに、format が指定できればいいんですが、NumberField には見当たりませんね。
なければ作ってしまいましょう! …で、やってみたのが、blur を拾って、カンマ編集する方法。これで、ひとまずはうまくゆきます。:)
Ext.onReady(function() {
var format_number = function (field) {
var val = field.getRawValue();
for(i = 0; i < val.length/3; i++) {
val = val.replace(/^([+-]?[0-9]+)([0-9]{3})/, '$1,$2');
}
field.setRawValue(val);
};
var view = new Ext.Viewport({
items: [{
xtype: 'form',
items: [
{xtype: 'numberfield', fieldLabel: 't1', listeners: {blur: format_number}},
{xtype: 'numberfield', fieldLabel: 't2'}
]
}]
});
});
…しかし…。
Ext JS が内部的に数値変換する処理はカンマを想定していませんから、いろいろとおかしな動作をします (タブキー何度もおしてフォーカスを移しているとすぐに分かります)。それらを解決する処理をいろいろと追加しなければならないでしょうね…。
私なら、表示/編集用の TextField と、値を格納しておく HiddenField と用意するか、あるいは入力は NumberField のままで、すぐ下にカンマ編集した数字列を表示してあげるとか…。
Blurイベントを受けてカンマ編集する仕組みは、私も少し前に試したことがありますが、NumberField のバリデーションで不正と判定されてしまい、なかなか上手く行きません。
本格的に対応するには、Tommy1969さんがおっしゃる通り TextField をカスタマイズするしかないような気がします。
NumberField と同じ位置・同じサイズのTextFieldを重ねて配置し、入力はNumberFieldで受け付け、編集結果をTextFieldで表示するという”力技”で乗り切るか・・・
それにしても、z-Indexの操作などかなり無理矢理な感じになりそうです。
あきらめたほうが良さそうですね。
mashiki
6 Jun 2009, 5:36 AM
厳密にテストしていませんが、こんな感じでNumberFieldを拡張してみては?
Ext.form.NumberFieldC = Ext.extend(Ext.form.NumberField, {
style: 'text-align: right',
initEvents : function(){
var allowed = this.baseChars + ',';
if (this.allowDecimals) {
allowed += this.decimalSeparator;
}
if (this.allowNegative) {
allowed += '-';
}
this.maskRe = new RegExp('[' + Ext.escapeRe(allowed) + ']');
Ext.form.NumberField.superclass.initEvents.call(this);
},
parseValue : function(value){
value = parseFloat(String(value).replace(/,/g, '').replace(this.decimalSeparator, "."));
return isNaN(value) ? '' : value;
},
setValue : function(v){
v = typeof v == 'number' ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
v = isNaN(v) ? '' : String(v);
v += (v.match(/[.]/))?'':'.' ;
var re = RegExp('(.*['+this.baseChars+'])(['+this.baseChars+']{3}[^'+this.baseChars+'])');
while (v.match(re)) {
v = v.replace(re, '$1,$2');
}
v = v.replace(/[.]$/,'').replace(".", this.decimalSeparator);
return Ext.form.NumberField.superclass.setValue.call(this, v);
},
validateValue : function(value){
return Ext.form.NumberFieldC.superclass.validateValue.call(this, value.replace(/,/g,''));
},
onFocus : function(){
Ext.form.NumberField.superclass.setValue.call(this, this.getValue());
Ext.form.NumberFieldC.superclass.onFocus.call(this);
}
});
Ext.reg('numberfieldc', Ext.form.NumberFieldC);
Ext.onReady(function() {
var view = new Ext.Viewport({
items: [{
xtype: 'form',
items: [
{xtype: 'numberfieldc', fieldLabel: 't1', value:'12345'},
{xtype: 'numberfieldc', fieldLabel: 't2', value:'12345678'}
]
}]
});
});
意図した通りの仕様が実現できていて、パーフェクトです!
引き続きいろいろなケースで動作テストをしてみますが、基本的にはこれで行けそうです。
mashiki さん、ありがとうございました。
蛇足ですが、スタイルで右詰めを指定すれば、より一層、数値項目らしくなりますね。
items: [
{ xtype: 'numberfieldc', fieldLabel: 't1', value: '12345', style: 'text-align: right' },
{ xtype: 'numberfieldc', fieldLabel: 't2', value: '12345678', style: 'text-align: right' }
]
mashiki
8 Jun 2009, 7:04 AM
うまく動いて何よりでした。
Ext.form.NumberField自体は小さなファイルですのでソースを印刷して
軽く眺めてみるといいと思いますよ。
http://extjs.com/deploy/ext-3.0-rc2/docs/source/NumberField.html
3.0のマニュアルから、メソッド名やコンフィグオプション名をクリックすると、
定義しているソースコードが表示されるので、すごく便利になりましたね。
Ext.form.NumberField
http://extjs.com/deploy/ext-3.0-rc2/docs/?class=Ext.form.NumberField
kuroさんの右寄せスタイルですが、クラスのほうに書いとくと楽かもしれませんね。
Ext.form.NumberFieldC = Ext.extend(Ext.form.NumberField, {
style: 'text-align: right', // here
initEvents : function(){
var allowed = this.baseChars + ',';
if (this.allowDecimals) {
allowed += this.decimalSeparator;
}
:
:
みたいな。
mashiki さん、このたびはいろいろとありがとうございました。大変参考になりました。
ときどき Ext wiki (http://www123.ddo.jp/extwiki/) のほうも拝見しています:>
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.