extjs 4: how to add button to any custom form - javascript

I am currently trying to add a custom button that will be able to call when ever the user wants to add a new button using EXTJS 4.
Here is the TimeButton.js file that i want to use to create the button
Ext.namespace("Ext.controls");
Ext.create('Ext.Button', {
text: 'Time',
renderTo: Ext.getBody(),
handler: function() {
alert('The current time is '+Date())
}
});
Ext.reg('timebutton', Ext.controls.TimeButton);
but when ever i try add it to any form i get the following error
types[config.xtype || defaultType] is not a constructor
Or would it be better to do something like this
Ext.controls.TimeButton = Ext.extend(Ext.Panel, {
initComponent: function(){
Ext.apply(this, {
frame: true
,height: 330
,layout: 'border'
,layout: 'column'
,split: true
,cls: 'DocumentWindow'
,items: []
});
this.documentGrid = new Ext.controls.DocumentGrid({height: 220,
agentId : this.agentId,
columnWidth: 0.5})
Ext.controls.DocumentPanel.superclass.initComponent.apply(this, arguments);
}
From what i understand this happens when trying to instantiate (create) a component that does not exist but i do not see where the error might be! is there an error in the code that I have posted?

Define your button as a class, register it for using with xtype by providing alias property and instantiate it in the parent items container. Here is an example.

Related

Extjs opening new Ext.window.Window by clicking a button

I'm trying to edit open source program called PartKeepr (v0.1.9). In a specific part of program I want to add a button that opens a new Ext.window.Window. My codes are as following which doesn't work (I'm pretty new in extjs but I'm given a hard task I guess, so I'm open to all advice for where to start learning, I'm just trying to learn from existing codes and apply some things by looking similar parts of available code)
Ext.define('PartKeepr.FindWindow',{
extend:'Ext.window.Window',
constrainHeader: true,
title: i18n("Find Number"),
initComponent: function() {
this.okButton=Ext.create("Ext.button.Button",{
text:i18n("OK")});
this.buttons=[this.okButton];
}
});
{
xtype: 'button',
text: i18n("Find"),
name: 'findButton',
handler: Ext.bind(this.findNumber, this)
}
findNumber: function(){
var j = new PartKeepr.FindWindow();
j.show();
}
Edit: When I press the find button, console giving me the following error: ext-all.js:21 Uncaught TypeError: Cannot read property 'insert' of undefined
You need to call the superclass initComponent method:
Ext.define('PartKeepr.FindWindow', {
extend: 'Ext.window.Window',
constrainHeader: true,
title: i18n("Find Number"),
initComponent: function() {
this.okButton = Ext.create("Ext.button.Button", {
text: i18n("OK")
});
this.buttons = [this.okButton];
this.callParent();
}
});

ExtJS error in initial page load due to Ext.getBody() not yet being defined

I'm trying to create a dialog window in ExtJS to perform a save function, but I'm getting problems loading the page.
A (reduced) example of the code window definition is:
Ext.define('MyRequest.SaveDraftOrTemplateWindow', {
extend: 'Ext.window.Window',
alias: 'widget.saveDraftOrTemplateWindow',
requires: ['Ext.toolbar.Toolbar'],
modal: true,
initComponent: function() {
this.items = [ saveDraftOrTemplateForm ];
Ext.apply(this, {
dockedItems: [{
xtype: 'toolbar',
items: [
{
iconCls: 'saveas-draft',
text: '<b>Save</b>',
id: 'saveDraftTemplate',
handler: saveAsDraftRequest(textFieldDraftOrTemplateName.getValue(), checkBoxSaveAsTemplate.getValue()),
scope: this
}
]
}]
});
this.callParent();
}
});
function saveAsDraftRequest(draftName, isTemplate) {
Ext.getBody().mask('Saving draft request...'); // Errors actually occurs on this line
}
// This line is the start of the stack causing the problem...
var saveDraftOrTemplateWindowInstance = Ext.create('MyRequest.SaveDraftOrTemplateWindow', {
Id: 'saveDraftOrTemplateWindow',
xtype: 'saveDraftOrTemplateWindow',
width: 400,
height: 180,
bodyPadding: 0
});
The problem is that is seems to be 'calling' the saveAsDraftRequest() function when the page initially loads which gives the Javascript error "Uncaught TypeError: Cannot read property 'mask' of null", and prevents the page loading. I don't really understand why the function is getting called at this point, as the handler presumably shouldn't be called until the button is actually clicked.
I assume that if the page were already correctly loaded then Ext.getBody() would correctly return a result instead of null, but why is this getting called during the initial page load?
You are invoking saveAsDraftRequest function in initComponent in line:
handler: saveAsDraftRequest(textFieldDraftOrTemplateName.getValue(), checkBoxSaveAsTemplate.getValue())
You should change it to
handler: saveAsDraftRequest
Then you need resolve draftName and isTemplate in handler. You can for example assign them to button:
handler: saveAsDraftRequest,
draftName: textFieldDraftOrTemplateName.getValue(),
isTemplate: checkBoxSaveAsTemplate.getValue()
Then you can access them in handler like so:
function saveAsDraftRequest(sender) {
console.log(sender.draftName);
console.log(sender.isTemplate);
}
Ah, #Lolo has given me the hint I need - I see now that the initialisation code was invoking the function to get the handler to use - what I could have done is:
handler: function() {
saveAsDraftRequest(textFieldDraftOrTemplateName.getValue(), checkBoxSaveAsTemplate.getValue());
},
... if I wanted to invoke it there.

ExtJS getCmp Panel by id doesn't serialize?

unfortunately I wasn't able to find any useful info about getting 'Ext.tab.Panel' by id. I'll be more specific with a source:
I'm defining a panel to work with:
Ext.define('MyMobileApp.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
id: 'mainTabPanel',
....
In currently active view, which is contained in this panel I created a button and put a handler on it:
xtype: 'button',
text: 'Switch View',
handler: function () {
var main = Ext.getCmp('mainTabPanel'); //.getActiveTab();
main.setActiveTab(Ext.getCmp('AnotherView'));
...
Where 'AnotherView' is id of a view which is also part of the panel.
But i'm getting error when trying to 'setActiveTab':
Uncaught TypeError: Object [object Object] has no method 'setActiveTab'
Looks like extjs is finding an object, but can't serialize?
All I want to do is switch views by custom buttons handlers.
The problem ist, that the Tab Panel doesn't have the function 'setActiveTab'
You have to use 'setActiveItem' instead.
Sencha Touch 2 Api: http://docs.sencha.com/touch/2-1/#!/api/Ext.tab.Panel-method-setActiveItem
xtype: 'button',
text: 'Switch View',
handler: function () {
var main = Ext.getCmp('mainTabPanel'); //.getActiveTab();
main.setActiveItem(Ext.getCmp('AnotherView'));
//main.setActiveItem(1); //You can also set the new item with the index of it
...

Extending MessageBox as View - Ext JS 4.1

I'm trying to extend a MessageBox within a view so I can reuse it throughout my application.
It seems that when I do so, I lose some of the default functionality that makes the messagebox useful (msg, button definitions, icon definitons, default drag constraints, etc). Documentation is a little confusing as it seems configs should be defined within the show() function, and I'm unsure of how to set them within my view.
How can I truly extend a messagebox component as a view?
Basic MessageBox (what I want to create with my view):
Ext.Msg.show({
title:'Error',
msg: 'There was an error.',
buttons: Ext.Msg.YESNOCANCEL,
icon: Ext.Msg.QUESTION
});
Renders:
but when I show my view:
Ext.create('IOL.view.app.Message').show();
I basically end up with a vanilla Panel/Window component
Ext.define('IOL.view.app.Message', {
extend : 'Ext.window.Window',
config: {
},
constructor: function(config) {
this.initConfig(config);
this.callParent(arguments);
},
initComponent : function() {
Ext.apply(this, {
xtype: 'messagebox',
width: 400,
height: 200,
title:'Error',
html: 'There was an error.',
buttons: [
{ text: 'Button 1' }
]
});
this.callParent(arguments);
}// initComponent
});
Renders:
It seems you are extending an Ext.window.Window and applying the messagebox configs to it. Why not just extend Ext.window.MessageBox:
Ext.define('IOL.view.app.Message', {
extend : 'Ext.window.MessageBox',
width: 400,
height: 200,
title: 'Error',
html: 'There was an error.',
buttons: Ext.Msg.YESNOCANCEL,
icon: Ext.Msg.ERROR,
// whatever else you want to do
initComponent : function() {
this.callParent(arguments);
}
});
#EricCook brings up a good point below. The MessageBox class is designed for reuse in the app as a singleton not really for subclassing.
In your question you said:
I'm trying to extend a MessageBox within a view so I can reuse it
throughout my application
I can understand that if you want to create a different type of messagebox that you would call with the normal Ext.Msg.show method, you could extend the MessageBox with your own buttons or icons I suppose.
But for regular use this isn't something you need to extend. For repeated use in your app you could hold a reference to the message box config you want in the controller like:
// SomeController.js
errorMsg: {
title:'Error',
msg: 'There was an error.',
buttons: Ext.Msg.YESNOCANCEL,
icon: Ext.Msg.QUESTION
},
Then whenever you want to call that type of message you could use (assuming the scope is the controller itself, or you could get a reference to the controller beforehand):
Ext.Msg.show(this.errorMsg);

Set focus for text input in just created window

I have trivial window:
this.window = Ext.widget('window', {
title: 'Find',
closeAction: 'hide',
width: 300,
layout: 'fit',
items: form
});
with trivial form in it
var form = Ext.widget('form', {
layout: {
type: 'vbox',
align: 'stretch'
},
border: false,
bodyPadding: 10,
items: [
this.findInput,
]
});
which only has one item
this.findInput = Ext.widget('textfield', {
name: 'find'
});
The issue is: how to set focus right after window is shown? I tried to call .focus() method of this.findInput in almost every window event handler with no luck.
Seems like even afterrender is called synchronously before DOM has created all the elements completely.
What have I missed? What event should I bind to to have all the elements rendered and able to accept the focus?
PS: if I call the same .focus() after small interval like 10ms - I get it focused, but it's not a solution
Check out activeItem property - http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.Panel-cfg-activeItem
or you can also use defaultFocus: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.window.Window-cfg-defaultFocus

Categories

Resources