magicfrog
18 Jun 2008, 7:45 AM
Hi
As promised, here is my very first extension.
I guess it s not the cleanest Extjs ux in the world but it works.
This is a toolbar button that pops up a calculator when clicked.
It also support keyboard typing.
(I extended Ext.Toolbar.Button because that was my need but maybe it would be more appropriate to extend Ext.Pane. I tried to but as i don t manage to make the KeyMap work i prefer posting a working stuff)
Hope that will help, and pls let me know about some way to improve it.
Ext.ns('Ext.ux');
Ext.ux.ButtonCalculator = Ext.extend(Ext.Toolbar.Button, {
errorText: (this.errorText)?this.errorText:'Error',
typeVal: function(options) {
var key;
if(options.text) {
key = options.text;
} else {
key = options;
}
var field = this.field;
var value = field.getValue();
var isOperand = this.operands.indexOf(key) > -1;
// If last character is an operand and again operand is specified, ignore it
if(isOperand && this.lastIsOperand() && key!='-') {
return;
}
if(value=='0' || value==this.errorText) {
value = '';
}
result = value + key;
field.setValue(result);
},
lastIsOperand: function() {
var isOperand = false;
var value = this.field.getValue();
var lastChar = value.substr(value.length-1,1);
if(this.operands.indexOf(lastChar) > -1) {
isOperand = true;
}
return isOperand;
},
calculate: function() {
if(this.lastIsOperand()) {
return;
}
var field = this.field;
try {
var value = eval(field.getValue());
if (value) {
field.setValue(value);
} else {
throw this.errorText;
}
}
catch (ex) {
field.setValue(this.errorText);
}
},
resetVal: function() {
this.field.setValue('0');
},
operands: ['+','-','*','/'],
handler: function() {
var firstTime = false;
if(!this.calcWin) {
firstTime = true;
this.field = new Ext.form.Field({
colspan:5,
border:false,
xtype:'field',
readOnly:true,
value:'0',
width:180,
handler: null,
style: 'text-align:right; margin-bottom: 5px;'
});
var calcWin = new Ext.Window({
iconCls: (this.iconCls)?this.iconCls:null,
title: (this.title)?this.title:'Calculator',
resizable: false,
width: 204,
height: 152,
closeAction: 'hide',
bodyStyle: { padding: '5px' },
layout:'table',
layoutConfig:{columns: 5},
defaults: {layout: 'fit', xtype: 'button', minWidth: 35, handler: this.typeVal, scope: this},
items: [this.field,
{
text:'7'
},{
text:'8'
},{
text:'9'
},{
text:'/'
},{
text:'('
},{
text:'4'
},{
text:'5'
},{
text:'6'
},{
text:'*'
},{
text:')'
},{
text:'1'
},{
text:'2'
},{
text:'3'
},{
text:'-'
},{
text:'C',
handler: this.resetVal
},{
text:'0'
},{
text:'00'
},{
text:'.'
},{
text:'+'
},{
text:'=',
handler: this.calculate
}]
});
this.calcWin = calcWin;
}
this.calcWin.show();
if(firstTime) {
new Ext.KeyMap(
this.calcWin.el,
[
{
key:[40,41,42,43,45,46,47,48,49,50,51,52,53,54,55,56,57],
fn: function(key,e){
this.typeVal(String.fromCharCode(e.getKey()));
},
scope: this
},{
key:[8,127],
fn: function(key,e){
e.stopEvent();
this.resetVal();
},
scope: this
},{
key:[13],
fn: function(key,e){
e.stopEvent();
this.calculate();
},
scope: this
}
],
'keypress'
)
}
}
});
Ext.reg('calculator', Ext.ux.ButtonCalculator);
The component now suports title, iconCls and errorText external options :
{
xtype: 'calculator',
title: 'Calculatrice',
iconCls: 'btn_calculator',
errorText: 'Erreur',
}
Updated 19/06/08
- Original code replaced by durlabh's optimized version
- Added support for negative numbers
- Added iconCls & title config options
As promised, here is my very first extension.
I guess it s not the cleanest Extjs ux in the world but it works.
This is a toolbar button that pops up a calculator when clicked.
It also support keyboard typing.
(I extended Ext.Toolbar.Button because that was my need but maybe it would be more appropriate to extend Ext.Pane. I tried to but as i don t manage to make the KeyMap work i prefer posting a working stuff)
Hope that will help, and pls let me know about some way to improve it.
Ext.ns('Ext.ux');
Ext.ux.ButtonCalculator = Ext.extend(Ext.Toolbar.Button, {
errorText: (this.errorText)?this.errorText:'Error',
typeVal: function(options) {
var key;
if(options.text) {
key = options.text;
} else {
key = options;
}
var field = this.field;
var value = field.getValue();
var isOperand = this.operands.indexOf(key) > -1;
// If last character is an operand and again operand is specified, ignore it
if(isOperand && this.lastIsOperand() && key!='-') {
return;
}
if(value=='0' || value==this.errorText) {
value = '';
}
result = value + key;
field.setValue(result);
},
lastIsOperand: function() {
var isOperand = false;
var value = this.field.getValue();
var lastChar = value.substr(value.length-1,1);
if(this.operands.indexOf(lastChar) > -1) {
isOperand = true;
}
return isOperand;
},
calculate: function() {
if(this.lastIsOperand()) {
return;
}
var field = this.field;
try {
var value = eval(field.getValue());
if (value) {
field.setValue(value);
} else {
throw this.errorText;
}
}
catch (ex) {
field.setValue(this.errorText);
}
},
resetVal: function() {
this.field.setValue('0');
},
operands: ['+','-','*','/'],
handler: function() {
var firstTime = false;
if(!this.calcWin) {
firstTime = true;
this.field = new Ext.form.Field({
colspan:5,
border:false,
xtype:'field',
readOnly:true,
value:'0',
width:180,
handler: null,
style: 'text-align:right; margin-bottom: 5px;'
});
var calcWin = new Ext.Window({
iconCls: (this.iconCls)?this.iconCls:null,
title: (this.title)?this.title:'Calculator',
resizable: false,
width: 204,
height: 152,
closeAction: 'hide',
bodyStyle: { padding: '5px' },
layout:'table',
layoutConfig:{columns: 5},
defaults: {layout: 'fit', xtype: 'button', minWidth: 35, handler: this.typeVal, scope: this},
items: [this.field,
{
text:'7'
},{
text:'8'
},{
text:'9'
},{
text:'/'
},{
text:'('
},{
text:'4'
},{
text:'5'
},{
text:'6'
},{
text:'*'
},{
text:')'
},{
text:'1'
},{
text:'2'
},{
text:'3'
},{
text:'-'
},{
text:'C',
handler: this.resetVal
},{
text:'0'
},{
text:'00'
},{
text:'.'
},{
text:'+'
},{
text:'=',
handler: this.calculate
}]
});
this.calcWin = calcWin;
}
this.calcWin.show();
if(firstTime) {
new Ext.KeyMap(
this.calcWin.el,
[
{
key:[40,41,42,43,45,46,47,48,49,50,51,52,53,54,55,56,57],
fn: function(key,e){
this.typeVal(String.fromCharCode(e.getKey()));
},
scope: this
},{
key:[8,127],
fn: function(key,e){
e.stopEvent();
this.resetVal();
},
scope: this
},{
key:[13],
fn: function(key,e){
e.stopEvent();
this.calculate();
},
scope: this
}
],
'keypress'
)
}
}
});
Ext.reg('calculator', Ext.ux.ButtonCalculator);
The component now suports title, iconCls and errorText external options :
{
xtype: 'calculator',
title: 'Calculatrice',
iconCls: 'btn_calculator',
errorText: 'Erreur',
}
Updated 19/06/08
- Original code replaced by durlabh's optimized version
- Added support for negative numbers
- Added iconCls & title config options