ExtJS Tab Panel Loader can't load the html page's javascript - javascript

index.html
<script type="text/javascript" src="resources/js/ext-all.js?"></script>
<script type="text/javascript" src="resources/js/tabs-adv.js?"></script>
tabs-adv.js
create a tab panel then load the vehicle.html with loader
....
var tabs = Ext.widget('tabpanel', {
renderTo: 'tabs',
id : 'tabspanel',
cls : 'MainPanel',
resizeTabs: true,
enableTabScroll: true,
width: window.innerwidth,
height: window.innerHeight - 30, //30 because menu height is 30px
tabBar: {
layout: { pack: 'center' }
},
defaults: {
autoScroll: false, //close the tab scrolling
bodyPadding: 0 //must 0,not margin at all
},
items: [
{
closable: false,
//html: '<div style="width:100%; height:100%; background-color:#cccccc;"><iframe src="vehicle/vehicle.html" frameborder=0 scrolling="no" style="width:100%; height:100%;"></iframe></div>',
loader: {
autoLoad:true,
url :'vehicle/vehicle.html'
},
iconCls: 'bus32',
title: 'Vehicle Manage'
}]
})
vehicle.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- Ext includes -->
<script type="text/javascript" src="vehicle.js?<?php echo time(); ?>"></script>
<title>Untitled Document</title>
</head>
<body>
aa
<div id="toolbar"></div>
</body>
Unfortunately Loader didn't load the vehicle.js
loader only load the html content, but not included vehicle.html javascript.
any way to solve this problem?
p/s: i m facing this problem EXT JS failed to load multi pages at the same time , both tabs are load at the same time with the ext-all.js will cause the application error, i have to try to use loader to prevent this happen,
I have tried, if the tabs are loaded with different ext-all.js will not be occured error, example first tab load ext-all.js, second tabs will load ext-all1.js 3th tab will load ext-all2.js.
UPDATE
vehicle.js and driver.js also having the grid panel
vehicle.js
Ext.define('MyApp.view.MyVehicleGridPanel', {
id:'mygridpanel',
extend: 'Ext.grid.Panel',
renderTo: Ext.getBody(),
width: window.innerWidth,
header: false,
height: window.innerHeight,
store: UserStore,
multiSelect: false,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
columns: [
{
xtype: 'gridcolumn',
dataIndex: '_id',
text: 'Vehicle ID'
},
{
xtype: 'gridcolumn',
width: 126,
dataIndex: 'Plat_No',
text: 'Plat Number'
},
{
xtype: 'gridcolumn',
width: 200,
dataIndex: 'Name',
text: 'Added By'
}
],listeners: {
itemclick: function(dv, record, item, index, e) {
if (record.get('_id') > 0){
Ext.getCmp('BtnEdit').enable();
Ext.getCmp('BtnDelete').enable();
}else{
Ext.getCmp('BtnEdit').disable();
Ext.getCmp('BtnDelete').disable();
};
}},
dockedItems: [
{
xtype: 'toolbar',
dock: 'top',
items: [
{
xtype: 'button',
cls: '',
width: 65,
id : 'BtnAdd',
icon: '',
iconCls: 'add',
text: 'Add'
},
{
xtype: 'button',
cls: '',
id : 'BtnEdit',
width: 65,
icon: '',
iconCls: 'edit',
disabled: true,
text: 'Edit'
},
{
xtype: 'button',
cls: '',
id : 'BtnDelete',
width: 65,
icon: '',
iconCls: 'delete',
disabled: true,
text: 'Delete'
},
{
xtype: 'button',
cls: '',
id : 'BtnRefresh',
width: 65,
icon: '',
iconCls: 'refresh',
text: 'Refresh'
}
]
}
]
});
me.callParent(arguments);
}
});
var gridwin = Ext.create('MyApp.view.MyVehicleGridPanel');

The loader is not supposed to load your javascript. With extjs, you should have only one javascript file. Use events to execute javascript code while rendering your panels, especially use the render event.
Put your vehicle.js in your main .js file and remove the last line. This one goes into the event listener.
Change your tab item using an event handler
items: [{
closable: false,
loader: {
autoLoad:true,
url :'vehicle/vehicle.html'
},
iconCls: 'bus32',
title: 'Vehicle Manage',
listeners: {
render: function(){gridwin = Ext.create('MyApp.view.MyVehicleGridPanel')}
}
}]
General remark 1: Do your homework and read the documentation. Stick to the recommended way. Why are you trying to work in such a convoluted way ? It shows that you didn't take the time to read and apply the basics.
General remark 2: You should concatenate all your .js sources in the production environment. The best thing is to use sencha cmd. You have to create an empty app, an then copy all your project into that empty app.

It's definitely possible to mix up ExtJS with static pages - rather suitable for print previews or alike.
A secondary DOM needs to be created within an iFrame, which will cause the JS on page to execute - because it circumvents the ExtJS Loader completely - and therefore scripts will be properly parsed.
Here's an example, proven to be working (reduced to the least required):
items : [{
xtype: 'component',
autoEl: {tag: 'iframe', src: ''}
}],
listeners: {
boxready: function(){
this.items.items[0].el.dom.src='vehicle.html';
}
}
The listener for boxready causes some delay in execution (which was required for what I did).
When reading other answers, I'd comment: How about thinking out of the box, once?
... which even literally applies in this particular case :)
One simply has to know the rules in order to break them - the other way around won't work.

Related

Rendering custom xtype widget to a container

I create a custom xtype widget from a promooted class. When I want to render the widget to a container I get an error Cannot read property 'dom' of null.
cont is my container
var d = Ext.widget('MultiViewComponent', {
renderTo: cont
});
I have tried renderTo:cont.getLayout().
I have also tried using cont.add and then cont.doLayout();
For 'renderTo' documentation states:
Do not use this option if the Component is to be a child item of a Container. It is the responsibility of the Container's layout manager to render and manage its child items.
When using add to add multiple times. All components are visible on the screen but only one is inside cont.items.items(last one added) So when using cont.removeAll() only one is removed.
What am I missing here or doing wrong? Please help and advise.
UPDATE: If try to remove the widgets from container using container.removeAll()
only one of the widgets is deleted. Looking into container.items.items only one was there even if multiple components were added.
var d = Ext.widget('MultiViewComponent', {
});
cont.add(d);
cont.doLayout();
//later
cont.removeAll();
MultiViewComponent
Ext.define('myApp.view.MultiViewComponent', {
extend: 'Ext.container.Container',
alias: 'widget.MultiViewComponent',
requires: [
'Ext.form.Label',
'Ext.grid.Panel',
'Ext.grid.View',
'Ext.grid.column.Date',
'Ext.grid.column.Number'
],
height: 204,
itemId: 'multiViewComponent',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
layout: {
type: 'vbox',
align: 'stretch'
},
items: [
{
xtype: 'label',
itemId: 'multiViewLabel',
text: 'My Label'
},
{
xtype: 'gridpanel',
itemId: 'multiViewGrid',
width: 498,
title: 'My Grid Panel',
store: 'Document',
columns: [
{
xtype: 'datecolumn',
dataIndex: 'dateCreated',
text: 'DateCreated'
},
{
xtype: 'gridcolumn',
dataIndex: 'documentType',
text: 'DocumentType'
},
{
xtype: 'gridcolumn',
dataIndex: 'description',
text: 'Description'
},
{
xtype: 'gridcolumn',
dataIndex: 'name',
text: 'Name'
},
{
xtype: 'gridcolumn',
dataIndex: 'creator',
text: 'Creator'
},
{
xtype: 'numbercolumn',
dataIndex: 'fileId',
text: 'FileId'
},
{
xtype: 'numbercolumn',
dataIndex: 'metaFileId',
text: 'MetaFileId'
},
{
xtype: 'gridcolumn',
dataIndex: 'uid',
text: 'Uid'
}
]
}
]
});
me.callParent(arguments);
}
});
cont.items is an Ext.util.MixedCollection, not an array. The underlying array is at cont.items.items. Anyway, you don't want to touch that. Use Ext.container.Container#remove to remove your child component afterward.
Your docs quote says it all... Containers do plenty of things with their components, most notably rendering, layout, and ComponentQuery wiring. You can't just change their DOM elements or javascript member variable and expect them to work. They have to be aware of when their state change to react accordingly, that's why you should always use the documented public methods to manipulate them. To let them know something happen and give them the chance to act on it.
Update
Given your feedback, it seems apparent that you're doing something funky with your code. Can't say because you haven't posted it... But here's a complete working example of what you want to do. Check your own code against it.
Ext.define('My.Component', {
extend: 'Ext.Component'
,alias: 'widget.mycmp'
,html: "<p>Lorem ipsum dolor sit amet et cetera...</p>"
,initComponent: function() {
if (this.name) {
this.html = '<h1>' + this.name + '</h1>' + this.html;
}
this.callParent();
}
});
Render a container with two initial children:
var ct = Ext.widget('container', {
renderTo: Ext.getBody()
,items: [{
xtype: 'mycmp'
,name: 'First static'
},{
xtype: 'mycmp'
,name: 'Second static'
}]
});
Adding a child dynamically post creation:
// Notice that layout is updated automatically
var first = ct.add({
xtype: 'mycmp'
,name: 'First dynamic'
});
// Possible alternative:
var firstAlt = Ext.widget('mycmp', {
name: 'First dynamic (alternative)'
});
ct.add(firstAlt);
And so on...
var second = ct.add({
xtype: 'mycmp'
,name: 'Second dynamic'
});
Removing a given child by reference:
ct.remove(first);
Removing a component by index:
ct.remove(ct.items.getAt(1));
Removing all components:
ct.removeAll();
Update 2
Your error is the itemId. One container must not have two items with the same itemId.
I don't know your app's architecture, but i think you could try show the widget when some container's event fired (beforerender for example).

celldblclick does not fired if the cell contains HTML extjs 3.4.0

I have the following EditorGridPanel on extJS:
http://jsfiddle.net/VDFsq/1/
Ext.onReady(function () {
var myData = [[ '<SPAN STYLE=\"text-align:Left;font-family:Segoe UI;font-style:normal;font-weight:normal;font-size:12;color:#000000;\"><P STYLE=\"font-family:Arial;font-size:16;margin:0 0 0 0;\"><SPAN><SPAN>HTML </SPAN></SPAN><SPAN STYLE=\"font-weight:bold;color:#FF0000;\"><SPAN>FORMAT</SPAN></SPAN><SPAN><SPAN> TEST<BR />TEST</SPAN></SPAN></P></SPAN>', "lisa#simpsons.com", "555-111-1224"],
[ 'Bart', "bart#simpsons.com", "555-222-1234"],
[ 'Homer', "home#simpsons.com", "555-222-1244"],
[ 'Marge', "marge#simpsons.com", "555-222-1254"]];
var store = new Ext.data.SimpleStore({
fields:[ {
name: 'name'
},
{
name: 'email'
},
{
name: 'phone'
}],
data: myData
});
var grid = new Ext.grid.EditorGridPanel({
renderTo: 'grid-container',
columns:[ {
header: 'Name',
dataIndex: 'name',
width:200
}
],
store: store,
frame: true,
height: 240,
width: 500,
enableColumnMove :false,
stripeRows: true,
enableHdMenu: false,
border: true,
autoScroll:true,
clicksToEdit: true,
title: 'HTML in Grid Cell',
iconCls: 'icon-grid',
sm: new Ext.grid.RowSelectionModel({
singleSelect: true
})
});
grid.on({
celldblclick: function() {alert(1);}
});
});
the problem is, when the gridCell contains HTML data (which is my situation) when you double click on the cell with html the grid does not fire the event celldblclick.
in my application I need to display that kind of html in the grid.
how can fix this problem? anyway to bubble the event from the html to the grid?
Thanks
It seems that there is some limits to dom tree deep inside your structure. I think it is not good idea to put html into grid - if you can unify it structure - may be templates would be more useful.
Try this instead of your HTML:
"<div ondblclick=\"alert('1!')\">1<div ondblclick=\"alert('2!')\">2<div ondblclick=\"alert('3!')\">3<div ondblclick=\"alert('4!')\">4</div>3</div>2</div>1</div>"
Event inheritance works fine in this HTML, but works only 2 levels deep in your EXt example.
NOTE: if you try
grid.on('rowdblclick', function(eventGrid, rowIndex, e) {
console.log('double click');
}, this);
you will not get problem (but, obviously, you can dblclick only rows in this way)

Getting height of ExtJS panel used as border region

I'm struggling mightily to get the height of an ExtJS panel and the only reason I can think it's any different is that it's the panel defined as a border region, because I've not had this problem otherwise (maybe I need to report a bug to them). I'll begin with some code that demonstrates how I'm trying to get the height, with results demonstrating what the height really is, what ExtJS says it is, and how it's not an issue with a panel using a different layout (one of the panels inside the border region):
'cmBuildTab #cmProductExplorer': {
afterrender: function(productExplorer) {
var domNode = Ext.getDom(productExplorer.el),
savedSearchesPanel = productExplorer.down('#savedSearchesPanel');
console.log('productExplorer.getHeight(): ' + productExplorer.getHeight());
console.log(productExplorer.componentLayout);
console.log(productExplorer.componentLayout.lastComponentSize);
console.log(domNode);
console.log('domNode.style.height: ' + domNode.style.height);
console.log('savedSearchesPanel.getHeight(): ' + savedSearchesPanel.getHeight());
}
},
I was initally encouraged I might have a couple of alternate ways to get the height, via the dom node, or via componentLayout.lastComponentSize but neither of these are accessible to Javascript code, only the chrome console. My final try then would be to parse the returned dom string but that is a horrible hack. Suggestions appreciated; below the console.log results is the pertinent portion of my view config.
console.log results:
productExplorer.getHeight(): 2
Ext.Class.newClass
autoSized: Object
borders: Object
calculateDockBoxes_running: false
childrenChanged: true
frameSize: Object
id: "dock-1155"
info: Object
initialized: true
initializedBorders: true
lastComponentSize: Object
height: 787
width: 254
__proto__: Object
layoutBusy: false
layoutCancelled: false
onLayout_running: false
owner: Ext.Class.newClass
previousComponentSize: undefined
targetInfo: Object
__proto__: Class.registerPreprocessor.prototype
undefined
<div id=​"panel-1049" class=​"x-panel x-box-item x-panel-default" role=​"presentation" aria-labelledby=​"component-1198" style=​"margin:​ 0px;​ width:​ 254px;​ height:​ 787px;​ left:​ 0px;​ top:​ 0px;​ ">​…​</div>​
domNode.style.height:
savedSearchesPanel.getHeight(): 151
View config (partial):
},{
region: 'west',
collapsible: true,
title: 'Product Explorer',
itemId: 'cmProductExplorer',
split: true,
width: '20%',
minWidth: 100,
layout: {
type: 'vbox',
pack : 'start',
},
items: [{
collapsible: true,
width: '100%',
border: false,
title: 'Search',
itemId: 'savedSearchesPanel',
items: [{
border: false,
xtype: 'cmSearchTermAccordionPanel'
},{
border: false,
margin: '5 20 0 20',
html: 'Saved Searches:<hr>'
}]
},{
afterrender is not the event you want to use to determine the heights of components, it fires when the elements have been rendered not after they have been sized. If you are using 4.1 you can use the boxready event which fires only once the the container is intially sized http://docs.sencha.com/ext-js/4-1/#!/api/Ext.AbstractComponent-event-boxready . If not you can use the afterlayout event to determine size but that event fires every layout.
Also fyi widths as percentages are not documented as supported in 4.0, I've seen them work and I've seen them fail.
Here is some code I hijacked from the Viewport example thanks to a court ruling this is ok.
4.1
Ext.create('Ext.container.Viewport', {
layout: 'border',
items: [{
region: 'north',
html: '<h1 class="x-panel-header">Page Title</h1>',
border: false,
margins: '0 0 5 0'
}, {
region: 'west',
collapsible: true,
title: 'Navigation',
width: 150,
//ADD LISTENERS
listeners: {
afterrender:function(){console.log( 'afterrender ' +this.getHeight())},
boxready:function(){console.log( 'boxready ' +this.getHeight())}
}
// could use a TreePanel or AccordionLayout for navigational items
}, {
region: 'south',
title: 'South Panel',
collapsible: true,
html: 'Information goes here',
split: true,
height: 100,
minHeight: 100
}, {
region: 'east',
title: 'East Panel',
collapsible: true,
split: true,
width: 150
}, {
region: 'center',
xtype: 'tabpanel', // TabPanel itself has no title
activeTab: 0, // First tab active by default
items: {
title: 'Default Tab',
html: 'The first tab\'s content. Others may be added dynamically'
}
}]
});
Output :
afterrender 2
boxready 276

Column layout in EXTJS

I am new to ExtJs. I need to create an entry form in 2 columns using column layout.
My code is as follows:
Ext.onReady(function(){
var patientForm = new Ext.FormPanel({
renderTo: "patientCreation",
frame: true,
title: 'Search Criteria',
labelAlign: 'left',
labelStyle: 'font-weight:bold;',
labelWidth: 85,
width: 900,
items: [
{
layout:'column',
items:[
{ // column #1
columnWidth: .33,
layout: 'form',
items: [
{ xtype: 'textfield',
fieldLabel: 'FirstName',
name: 'firstName',
vtype : 'alpha',
allowBlank:false
},{
xtype: 'textfield',
fieldLabel: 'MiddleName',
name: 'middleName',
vtype : 'alpha'
}
] // close items for first column
}]
}]
});
var win = new Ext.Window({
layout:'form',
closable: false,
resizable: false,
plain: true,
border: false,
items: [patientForm]
});
win.show();
});
But when I run the code, I got h is undefined error. How to design a form in column layout? Is there any procedure, steps or links which give a clear idea?
I have run the same code with ExtJs 3.2.2 and got a similar error. But when I removed renderTo: "patientCreation"
code worked:
That part is not necessary 'cause you are placing the form in a the window.
I do not know anything about ExtJS 3. If you are using ExtJS 4, then you have specified layout config at wrong place. You have specified it inside items config, it should not be inside items config.
Layout can be specified as follows in ExtJS 4:
Ext.define('your_domain_name.viewName', {
extend : 'Ext.panel.Panel',
alias : 'widget.any_name_you_want',
layout : 'column',
initComponent : function() {
this.items = [
// all items inside form/panel will go here
];
this.callParent(arguments);
}
});
You can get sample code about all the panels here
try applying renderTo config to window instead of form
check example

Why am I getting errors in ext-all-debug.js in lines 4236 - 4242?

I've developed a PHP framework that generates ExtJS code in the form of an application.
This involves building the full ExtJS object literal on the first call, e.g.:
Ext.onReady(function(){
menuItemStart = new Ext.Panel({
id: 'panelStart',
title: 'Start',
html: 'This is the start menu item.',
cls:'menuItem'
});
...
and then navigation in the application consists of event handlers which load PHP files via AJAX that output ExtJS code, and then execute this code with this function:
function loadViewViaAjax(url, paramTargetRegion) {
Ext.Ajax.request({
url: url,
success: function(objServerResponse) {
var responseText = objServerResponse.responseText;
var scripts, scriptsFinder=/<script[^>]*>([\s\S]+)<\/script>/gi;
while(scripts=scriptsFinder.exec(responseText)) {
eval(scripts[1]);
}
}
});
}
This works well. However, I now have this situation where when a page is loaded from PHP instead of via a triggered ExtJS event handler, I get errors that are varied but all come from one block of code in the ext-all-debug.js file, namely in line 4236 and line 4242:
Has anyone experienced anything similar or know what could be causing this?
Addendum
Yes #ChrisR, here is an error I can reproduce on my machine:
It says it is getting the error in the fourth line of this code, but if I click on it, it takes me to line 4242 shown above in the ExtJS library code.
<script type="text/javascript">
clearExtjsComponent(targetRegion);
var panel_form = new Ext.FormPanel({
labelWidth: 100,
frame:true,
style: 'margin: 10px',
title: 'Test Product (TEST PAGE 2)',
bodyStyle:'padding:5px 5px 0',
width: 500,
defaultType: 'textfield',
items: [{
fieldLabel: 'ID',
value: "111",
name: 'id',
width: 370,
hidden: false,
style: 'text-align: right',
name: 'id',
width: 50,
hidden: false,
},{
fieldLabel: 'Product',
value: "Paper",
xtype: 'displayfield',
name: 'product',
width: 370,
hidden: false,
},{
fieldLabel: 'Label',
value: "none",
name: 'product3',
width: 370,
hidden: false,
},{
fieldLabel: 'Label',
value: "first line\<br/>second line\<br/>third line",
xtype: 'displayfield',
height: 100,
xtype: 'displayfield',
name: 'product4',
width: 370,
hidden: false,
}
],
buttons: [{
text: 'Save',
handler: function() {
if(panel_form.getForm().isValid()){
panel_form.getForm().getEl().dom.action = 'backend/application/help/test';
panel_form.getForm().getEl().dom.method = 'POST';
panel_form.getForm().submit({
success : function(form, action) {
replace_region_with_uri_content('backend/modules');
}
})
} else {
Ext.Msg.minWidth = 360;
Ext.Msg.alert('Invalid Form', 'Some fields are invalid, please correct.');
}
}
},{
text: 'Cancel',
handler: function(){
replace_region_with_uri_content('backend/modules');
}
}]
});
replaceComponentContent(targetRegion, panel_form);
hideComponent(regionHelp);
</script>
Is this on IE? If so, all the trailing commas in your code may be the issue (they certainly are an issue). Also, lots of duplicate configs in your first item. Try running JSLint on your code from time to time to catch stuff like that.

Categories