PDA

View Full Version : small-button extjs object



geewhizbang
19 Dec 2009, 8:06 AM
Has anyone written a small-button ExtJS object? Someone wrote a link button extending the button object, but I don't understand how the render function worked so I could modify it to my own needs. It had layout that was way too complicated using an over-elaborate table to construct the elements. I just want to use some divs for my button.

I would like to have some buttons that are smaller than standard buttons, but it would be helpful if they are an ExtJS object.

What i would like is a button that is built approximately like this when it is rendered:

<div class="smallBtn" onmouseover="btnMO(this,true)" onmouseover = "btnMO(this,false)" onclick=handler(this)><div class='btnLeft'>&nbsp;</div><div class="btnText">Button Text</div><div class='btnRight'>&nbsp;</div></div>

Condor
19 Dec 2009, 8:48 AM
A simple BoxComponent could do that, e.g.

{
xtype: 'box',
autoEl: {
cls: 'smallBtn',
children: [{
cls: 'btnLeft',
cn: '&#160;'
},{
cls: 'btnText',
cn: 'Button Text'
},{
cls: 'btnRight',
cn: '&#160;'
}
},
listeners: {
render: function(c){
var el = c.getEl();
el.on({
mouseover: btnMO.createCallback(el.dom, true),
mouseout: btnMO.createCallback(el.dom, false),
click: handler.createCallback(el.dom)
});
}
}
}

geewhizbang
19 Dec 2009, 11:20 AM
That is helpful. But I also want it to inherit from button to have all of the useful states, and the ability to use the handler events with the button.

The example you just posted makes it clearer how to attach functions to an object, which is new to me.

Animal
20 Dec 2009, 9:35 AM
Use a Button:



new Ext.Button({
template: new Ext.Template(
'<div class="smallBtn">',
'<div class="btnLeft">&#160;</div>',
'<div class="btnText"></div>',
'<div class="btnRight">&#160;</div>',
'</div>'),
buttonSelector: '.btnText',
text: 'My Button',
renderTo: document.body,
handler: function() {
alert("You clicked?");
}
});

geewhizbang
20 Dec 2009, 4:41 PM
// a little helper function to write the modified button:
$KB.XButton = function (params)
{
params.template = new Ext.Template
(
'<div class="' + $KB.FixNull(params.cls, "SD_Btn") + '">',
'<div class="SD_L"> </div>',
'<div class="SD_Text"></div>', '<div class="SD_R"> </div>',
'</div>'
);
params.buttonSelector = 'SD_Text';
return new Ext.Button(params);
};


Using the button in some code where a standard button was too big, but otherwise worked OK:


kbForum.btnForumManage = $KB.XButton
(
{
text: 'Forum Management',
handler: kbForum.Manage,
id: 'btnForumManage'
}
);
var c = Ext.getCmp('forumButtonBar');
c.add(kbForum.btnForumManage);
//fails here:
c.doLayout();


Extjs code. I'm not sure which object this is from, since we have munged all the code together in one big file:


// internal function for auto removal of assigned event handlers on destruction
mon: function (item, ename, fn, scope, opt) {
this.createMons();
if (Ext.isObject(ename)) {
var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
var o = ename;
for (var e in o) {
if (propRe.test(e)) {
continue;
}
if (Ext.isFunction(o[e])) {
// shared options
this.mons.push({
item: item,
ename: e,
fn: o[e],
scope: o.scope
});
item.on(e, o[e], o.scope, o); //this line: o.scope is not defined
} else {
// individual options
this.mons.push({
item: item,
ename: e,
fn: o[e],
scope: o.scope
});
item.on(e, o[e]);
}
}
return;
}
this.mons.push({
item: item,
ename: ename,
fn: fn,
scope: scope
});
item.on(ename, fn, scope, opt);
},


My guess is that we need to pass scope somehow, but I have never needed to do that anywhere else as the default scope was fine. So I'm not exactly sure what scope needs to be passed for this to work.

Using a helper function to create the button for me is a bit easier to comprehend. I know that we should probably be using Ext.Extend to build this, but every attempt to do try tat so far has resulted in non-functional code.

BTW I don't see how this code passes the Button state to the html/CSS objects, BTW. If there are parameters that have to be included in the template for that to happen, I need to do that too.

geewhizbang
20 Dec 2009, 9:39 PM
The scope issue happens even if I don't use the helper function.

Animal
21 Dec 2009, 12:25 AM
Then use the documented way of telling the handler what scope to use!

geewhizbang
21 Dec 2009, 8:14 AM
I guess I will have to move my question to the premium area, where I get answers instead of insults.

I posted this here in the first place because I thought it would be of general use to develop a more easily skinned, simpler button object.

If I knew the answer to this I wouldn't be asking the questions. I am fairly familiar with the documentation by now, but there is still an ongoing problem of a lack of specific examples to make very complex concepts clear.

In this case, for example, why do I need to pass a scope? Why isn't it using the default scope for this object? Could this be a bug? Or is the button object overly dependent on the complex default format and barfs on this simpler one? The object name is "o" which also isn't very helpful to help me determine what scope to pass.

If Animal could take a few moments to answer the question with an example, then there would be a searchable answer to be found.

geewhizbang
21 Dec 2009, 12:12 PM
Going back to the original reply by condor, i made this:


Ext.ux.sButton = Ext.extend(
Ext.BoxComponent, {
initComponent: function () {
Ext.apply(
this, {
autoEl: {
cls: $KB.FixNull(this.initialConfig.cls, 'SD_btn'),
children: [{
cls: 'SD_L',
cn: ' '
},
{
cls: 'SD_Text',
cn: this.initialConfig.text
},
{
cls: 'SD_R',
cn: ' '
}]
}
});
Ext.ux.sButton.superclass.initComponent.apply(this, arguments);
},
onRender: function () {
Ext.ux.sButton.superclass.onRender.apply(this, arguments);
var el = this.getEl();
el.on({
mouseover: btnMO.createCallback(el.dom, true),
mouseout: btnMO.createCallback(el.dom, false),
click: this.initialConfig.handler.createCallback(el.dom)
})
}
});
Ext.reg('sbutton', Ext.ux.sButton);


how it gets used



if ($KB.LoggedIn) {
kbForum.btnForumManage = new Ext.ux.sButton({
text: 'Forum Management',
handler: kbForum.Manage,
id: 'btnForumManage'
});
var c = Ext.getCmp('forumButtonBar');
c.add(kbForum.btnForumManage);
c.doLayout();
}


This runs just fine now, but I want to add facilities to disable this button similar to a regular button. To do this it would be helpful to know how to make the btnMO handler code internal to this new object, and to have methods that enable/disable the button as well.

Currently the btnMO code just handles the mouseover by changing the style of the outer element to append "_mo" to the class name. The disable code needs to append "_dis" to the class name.

geewhizbang
21 Dec 2009, 3:41 PM
The remaining issue is how to apply margins to my object.


/*
* nGenera Knowledgebase
* Copyright(c) 2006-20010 nGenera, Inc.
*/
Ext.ux.btnMO = function (objOrId, bMO) {
var objBtn = $g(objOrId);
InitBtn(objBtn);
if (objBtn.disabled) return;
if (objBtn.moData == "") return;
if (IsImgBtn(objBtn)) {
objBtn.src = objBtn.moData + (bMO ? "_mo" : "") + objBtn.moExt;
} else {
objBtn.className = objBtn.moData + (bMO ? "_mo" : "");
}
objBtn.style.cursor = (bMO ? (Ext.isIE ? "hand" : "pointer") : "default");
function InitBtn(objBtn) {
if (typeof(objBtn.moData) != "undefined" && objBtn.moData != null) return;
var moData;
var aT;
if (IsImgBtn(objBtn)) {
var src = objBtn.src;
aT = src.split(".");
objBtn.moExt = "." + aT[aT.length - 1];
moData = src.substr(0, src.length - objBtn.moExt.length);
} else {
moData = objBtn.className;
}
aT = moData.split("_");
objBtn.disabled = (aT.length > 1) && (aT[aT.length - 1].toLowerCase() == "dis");
objBtn.moData = (objBtn.disabled ? moData.substr(0, moData.length - 5) : moData);
}
function IsImgBtn(objBtn) {
if (typeof(objBtn.IsImg) != "undefined") return objBtn.IsImg;
var tn = objBtn.tagName.toUpperCase();
objBtn.IsImg = ((tn == "IMG") || ((tn == "INPUT") && (objBtn.type.toUpperCase() == "IMAGE")))
return objBtn.IsImg;
}
};
Ext.ux.sButton = Ext.extend(
Ext.BoxComponent, {
initComponent: function () {
Ext.apply(
this, {
margins: this.initialConfig.margins,
autoEl: {
cls: $KB.FixNull(this.initialConfig.cls, 'SD_btn'),
children: [{
cls: 'SD_L',
cn: '&#160;'
},
{
cls: 'SD_Text',
cn: this.initialConfig.text
},
{
cls: 'SD_R',
cn: '&#160;'
}]
}
});
Ext.ux.sButton.superclass.initComponent.apply(this, arguments);
},
onRender: function () {
Ext.ux.sButton.superclass.onRender.apply(this, arguments);
var el = this.getEl();
el.on({
mouseover: Ext.ux.btnMO.createCallback(el.dom, true),
mouseout: Ext.ux.btnMO.createCallback(el.dom, false),
click: this.initialConfig.handler.createCallback(el.dom)
})
},
onDisable: function () {
var c = this.getEl().dom;
c.disabled = true;
c.className = $KB.FixNull(this.initialConfig.cls, 'SD_btn') + "_dis";
},
onEnable: function () {
var c = this.getEl().dom;
c.disabled = false;
c.className = $KB.FixNull(this.initialConfig.cls, 'SD_btn');
}
});
Ext.reg('sbutton', Ext.ux.sButton);

Animal
22 Dec 2009, 8:53 AM
I guess I will have to move my question to the premium area, where I get answers instead of insults.

You'll have to point to the post in which someone said "geewhizbang, You are a **** ****". I'll be sure to delete the offending post.