Custom ExtJS widget extending Ext.Component adds a div - extjs

I am creating an ExtJS widget which extends Ext.Component. The following is the sample code.
Ext.define('test.widget',{
extend: 'Ext.Component',
initComponent: function() {
this.callParent();
},
onRender: function() {
this.callParent(arguments);
Ext.create('Ext.form.Label', {
html: '<img src="Available.png" /> Test',
renderTo: me.renderTo
});
}
});
The above widget renders into the browser as below
<div id="ext-comp-1014" class="x-component x-component-default" role="presentation"></div>
<label for="" id="label-1028" class="x-component x-component-default" role="presentation"><img src="Available.png" > Test</label>
How do I get rid of the div tag? or is there any way to convert the div to span?

You can convert the default div to a span tag. You can also use any other html tag in place of the div. Components have an autoEl attribute which allows you to specify any html tag as well as any html tag attributes.
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.AbstractComponent-cfg-autoEl
Ext.define('test.widget',{
extend: 'Ext.Component',
autoEl: {tag:'span'},
initComponent: function() {
this.callParent();
},
onRender: function() {
//...
}
}

Related

Extjs html editor and how to customize the editor

Hi i have been using Extjs html editor.I want to customize the html editor like i have to display a customized alert box when we click button in toolbar.how can we do that?
thanks in advance.
Ext.define('MyApp.ux.MyOwnHtmlEditor',{
extend: 'Ext.form.field.HtmlEditor',
xtype: 'myhtmleditor',
getToolbarCfg: function() {
// get original toolbar:
var toolbar = this.callParent(arguments);
// add custom item:
toolbar.items.push({
xtype: 'button',
iconCls: 'x-fa fa-question-circle',
handler: function() {
Ext.Msg.alert('Dear user!', 'No, we won\'t help you!');
}
});
// Modify handler of existing button:
toolbar.items[3].handler = function() {
Ext.MessageBox.alert('Dear user!', 'If you want Italic, please go to Italy!');
};
// return toolbar to calling function
return toolbar;
}
})
And use it e.g. like this:
{
xtype: 'myhtmleditor'
}
Example fiddle

ExtJs TextField with small button

How to create small button with icon inside textfield, like with datefield? In previous version of ExtJS there was a CompositeField but cant find it in ExtJS 4.
Just extend http://docs.sencha.com/ext-js/4-1/#!/api/Ext.form.field.Trigger You can change the icon of the trigger field with CSS and implement the behavior of clicking the icon in the onTriggerClick template method
Ext.define('Ext.ux.CustomTrigger', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.customtrigger',
// override onTriggerClick
onTriggerClick: function() {
Ext.Msg.alert('Status', 'You clicked my trigger!');
}
});
Ext.create('Ext.form.FormPanel', {
title: 'Form with TriggerField',
renderTo: Ext.getBody(),
items:[{
xtype: 'customtrigger',
fieldLabel: 'Sample Trigger',
emptyText: 'click the trigger'
}]
});
Is the icon clickable? If so, you are looking for Ext.form.field.Trigger. If not, you might try overriding the Text field's getSubTplMarkup() function to provide some custom dom.
For example:
Ext.define('MyField', {
extend: 'Ext.form.field.Text',
getSubTplMarkup: function() {
return this.callParent(arguments) + '<span class="my-icon"></span>';
}
});

how to add a click event to extjs autoel?

If i add a button like this
xtype: 'component',
autoEl: {
html: '<input type="submit" class="custom_loginbtn" value="Submit" id="login"/>'
}
any idea how to add a click event to this ?
Regards
try adding listener
listeners: {
render: function(component){
component.getEl().on('click', function(e){
console.log(component);
alert('test');
});
}
}
check this
xtype : 'component',
itemId : 'submitbtn',
autoEl : {
html : '<input type="submit" class="custom_loginbtn" value="Login" id="login"/>'
},
listeners : {
el : {
delegate : 'input',
click : function()
{
}
}
}
This is the best approach, notice the use of a managed listener with .mon() in place of .on() which is better to use when you're listening to DOM elements from components that could be destroyed
xtype: 'component'
,html: '<input type="submit" class="custom_loginbtn" value="Submit" id="login"/>'
,listeners: {
afterrender: function(inputCmp) {
inputCmp.mon(inputCmp.el, 'click', function(){alert('click!')}, this, {delegate:'input'});
}
,single: true
}
Also, your use of autoEl is analogous to just setting the html property of the component, other options in autoEl let you manipulate type and attributes of the outer tag that is automatically created to encompass the component
If you did this instead you could turn turn the component itself into an <input> and avoid the wrapping <div>:
xtype: 'component'
,autoEl: {
tag: 'input'
,cls: 'custom_loginbtn'
,type: 'submit'
,value: 'Submit'
}
,listeners: {
afterrender: function(inputCmp) {
// no delegate needed, since inputCmp.el is the <input>
inputCmp.mon(inputCmp.el, 'click', function(){alert('click!')}, this);
}
,single: true
}
You are using a standard submit button, why not use an xtype button? - it has a handler you can specify for your click event.

Using more than one controller with ExtJS 4 MVC

Let's say I have a main controller, then my application has a controller for each "module". This main controller contains the viewport, then a header (with a menu) + a "centered" container, which is empty at the beginning.
A click in the menu will change the current module/controller and the adhoc view (which belongs to this controller) will be displayed in the centered container.
I think it's a very simple scenario, but strangely I didn't find the proper way to do it. Any ideas? Thanks a lot!
Here is what I do: I have a toolbar on top, a left navigation and the center location is work area (basically a tab panel) like you mentioned. Lets take each part fo the application and explain.First, here is how my viewport look like:
Ext.define('App.view.Viewport',{
extend: 'Ext.container.Viewport',
layout: 'border',
requires: [
'App.view.menu.NavigationPane',
'App.view.CenterPane',
'App.view.menu.Toolbar'
],
initComponent: function() {
Ext.apply(this, {
items: [{
region: 'north',
xtype: 'panel',
height: 24,
tbar: Ext.create('App.view.menu.Toolbar')
},{
title: 'Navigation Pane',
region: 'west',
width: 200,
layout: 'fit',
collapsible: true,
collapsed: true,
items: Ext.create('App.view.menu.NavigationPane')
},{
region: 'center',
xtype: 'centerpane'
}]
});
this.callParent(arguments);
}
});
You can see that I have a toolbar (App.view.menu.Toolbar) with menu and left navigation (App.view.menu.NavigationPane). These two, components make up my main menu or gateway to other modules. Users select the menu item and appropriate module views (like form, grid, charts etc) get loaded into the 'centerpane'. The centerpane is nothing but a derived class of Ext.tab.Panel.
Like you said, I have a main controller that handles all the requests from the toolbar and navigation pane. It handled only the toolbar and navigation pane's click actions. Here is my AppController:
Ext.define('CRM.controller.AppController',{
extend: 'Ext.app.Controller',
init: function() {
this.control({
'apptoolbar button[action="actionA"]' : {
click : function(butt,evt) {
this.application.getController('Controller1').displayList();
}
},
.
. // Add all your toolbar actions & navigation pane's actions...
.
'apptoolbar button[action="actionB"]' : {
click : function(butt,evt) {
this.application.getController('Controller2').NewRequest();
}
}
});
}
});
Look at one of my button's handler. I get hold of the controller through the 'application' property:
this.application.getController('Controller2').NewRequest();
With the help of getController method, I get the instance of the controller and then call any method inside my controller. Now lets have a look at the skeleton of my module's controller:
Ext.define('CRM.controller.Controller2',{
extend: 'Ext.app.Controller',
refs: [
{ref:'cp',selector: 'centerpane'}, // reference to the center pane
// other references for the controller
],
views: ['c2.CreateForm','c2.EditForm','c2.SearchForm','c2.SearchForm'],
init: function() {
this.control({
'newform button[action="save"]' : {
// Do save action for new item
},
'editform button[action="save"]' : {
// update the record...
},
'c2gridx click' : {
// oh! an item was click in grid view
}
});
},
NewRequest: function() {
var view = Ext.widget('newform');
var cp = this.getCp(); // Get hold of the center pane...
cp.add(view);
cp.setActiveTab(view);
},
displayList: function() {
// Create grid view and display...
}
});
My module's controller have only the actions related to that module (a module's grid, forms etc). This should help you get started with rolling in right direction.
In main controller add child controller in the click event handler of menu
Ext.define('MyAPP.controller.MainController',{
...
init:function()
{
this.control({
'menulink':
{
click:this.populateCenterPanel
}
});
},
populateCenterPanel:function()
{
this.getController('ChildController');
}
});
In launch function add listener to controller add event like this -
Ext.application({
...
launch:function(){
this.controllers.addListener('add',this.newControllerAdded,this);
},
newControllerAdded:function(idx, ctrlr, token){
ctrlr.init();
}
});
Now put code for dynamically embedding views in the viewport in init method of ChildController.
Ext.define('MyAPP.controller.ChildController',{
...
refs: [
{ref:'displayPanel',selector:'panel[itemId=EmbedHere]'}
]
init:function(){
var panel=this.getDisplayPanel();
panel.removeAll();
panel.add({
xtype:'mycustomview',
flex:1,
autoHeight:true,
...
});
}
});
HTH :)

extjs adding icons to the titlebar of an extended window widget (two levels of extension)

I am new to extjs....
I am trying to add icons to the title bar of a window.
I am not able to figure out the error in my code
i tried using tools config for the window
Here is my code:
**Ext.ns('DEV');
DEV.ChartWindow = Ext.extend(Ext.ux.DEV.SampleDesktopWidget, {
width:740,
height:480,
iconCls: 'icon-grid',
shim:false,
animCollapse:false,
constrainHeader:true,
layout: 'fit',
initComponent : function() {
this.items = [
new Ext.Panel({
border:true,
html : '<iframe src="" width="100%" height="100%" ></iframe>'
})
];
DEV.ChartWindow.superclass.initComponent.apply(this, arguments);
},
getConfig : function() {
var x = DEV.ChartWindow.superclass.getConfig.apply(this, arguments);
x.xtype = 'DEV Sample Window';
return x;
},
tools: [{
id:'help',
type:'help',
handler: function(){},
qtip:'Help tool'
}]
});
Ext.reg('DEV Sample Window', DEV.ChartWindow);**
SampleDesktopWidget is an extension of Window
Can somebody help me with this
Thanks in advance
I believe title is part of the header. I dont think you can do this with initialConfig programmatically but you can either override part of component lifecycle or hook in with an event. E.g. add this to config. You might (probably) be able to hook in at any early stage after init maybe, but thats an experiment for you.
listeners: {
render: {
fn: function() {
this.header.insert(0,{
xtype: 'panel',
html: '<img src="/img/titleIcon1.gif"/>'
});
}
}
}
However for this particular scenario I would use iconCls
iconCls: 'myCssStyle'
Then include a CSS file with:
.myCssStyle {
padding-left: 25px;
background: url('/ima/titleIcon.gif') no-repeat;
}
This is a good example that might help, using extjs 3.2.1.
Adding tools dynamically

Resources