Liferay and ExtJS - javascript

I have the application with Servlets, CSS, JS and JSON. It's working with ExtJS 3 library (I keep the code in another project).
The goal is to run this application inside a Liferay Portlet.
I created new Portlet called "portal-portlet".
Added all my Java classes to new src folder. Am I suppose to refractor code?
Added all ExtJS code from WebContent folder to docroot > js > extjs3 folder of the Portlet.
Modified view.jsp:
<div id="invoice_form"></div>
It links with application.js:
Ext.onReady(function() {
// code responsible for rending main window
var main = new Ext.Viewport({
layout: 'border',
renderTo: 'invoice_form',
id: 'main',
items: [{
5.. Modified liferay-portlet.xml with lines look like this one:
<header-portlet-javascript> /js/extjs3/adapter/ext/ext-base.js </header-portlet-javascript>
6.. Created new Theme Project and added CSS to custom.css and portlet.css (to override Liferay default CSS). I copied CSS from ExtJS.
Here what I've got.
My new ExtJS Portlet cover all page and contain almost nothing. It's suppose to have data table in right column and file manager in left column. Now you can see only bar that's suppose to separate file-tree from table
So I'm ready to do it from scratch. Should I use hook or theme project and what I did wrong, how make it work?
Thanks for reading.

The problem is that Liferay portlets are rendered into a div and when you try to embed an existing Sencha application you will notice that many nodes are just placed as child of the body. Thus its totally corrupting your Sencha application and mostly it end ups in a white screen.
This is how I fixed it for large Sencha application which luckily wrapped everything already into a Ext.Viewport object :
Now place in your view.jsp (portlet) this here :
Then setup up your Sencha panels and put them into a Viewport object :
this._viewport = new Ext.Viewport({
layout : 'border',
margins : '0 0 0 0',
renderTo:Ext.get(Repository.Config.GUI_PARENT),
defaults : {
renderTo:Ext.get(Repository.Config.GUI_PARENT)
}, // default config for all child widgets
items : [
new Ext.Panel({ // Header panel for login and toolbar
region : 'north',
height : 60,
margins : '0 0 0 0',
border : true,
items :[
{ // Header with logo and login
region: 'north',
html: Repository.Templates.login.apply({
currentUser : this._currentUser,
isPublicUser : this._currentUser=='public'
}),
height: 30,
renderTo:Ext.get(Repository.Config.GUI_PARENT)
},
this._controls.toolbar
] // Toolbar
}), // Panel
this._controls.centerPanel,
this._controls.leftPanel,
this._controls.rightPanel
]
});
Notice that the renderTo:Ext.get(Repository.Config.GUI_PARENT) literal doesn't seem to fix the problem yet but !
Now replace in ext-all.js this
Ext.Viewport = Ext.extend(Ext.Container, {
this.el = Ext.getBody()
with
Ext.Viewport = Ext.extend(Ext.Container, {
this.el = Ext.get(Repository.Config.GUI_PARENT);
where Repository.Config.GUI_PARENT is simply a constant : "root"
I am not sure this is still the right in general way but it seems to work now very fine.

Related

Render Extjs 4.2 app inside Div tag

I want to render my viewport inside div tag. If i change "Ext.container.Viewport" to any other container, that works in development mode but not in Build mode. In Build mode it displays nothing.
I found similar question on Stackoverflow like Render Ext.application in a div but answer in this question suggest to use different container, but in my case if I replace viewport to a container, nothing is displaye din Build mode(Empty console log).
Here is my code of viewport :
Ext.define('PfalzkomApp.view.Viewport', {
extend: 'Ext.container.Viewport',
requires:[
'Ext.layout.container.Fit',
'Papp.view.PopUpWindow'
],
type: 'fit',
renderTo: Ext.Element.get("REA_TasklistEntry"),
items: [{
xtype: 'app-popUpWindow'
}]
});
Can anyone help me?
Thanks for your time.

ExtJS paging toolbar malformed

Using ExtJS 4.2.1 I added a paging toolbar to a grid panel. Everything works fine except that the toolbar is rendered malformed. The page input field is far to small and has some weird frames around it. With a little luck I can type something into the field but I can't read anything. I see this with both default theme, neptune and gray theme and it is the same for Chrome and Firefox:
I used the default themes. Any idea about this?
In case this is a theme or CSS related problem (is it?) here is what I am including currently (trying neptune theme):
<link rel='stylesheet' id='extjsstyle-css' href='http://127.0.0.1/wordpress/wp-includes/js/extjs/resources/css/ext-all-neptune-debug.css?ver=3.8.1' type='text/css' media='all' />
<script type='text/javascript' src='http://127.0.0.1/wordpress/wp-includes/js/extjs/ext-dev.js'></script>
When adding the following include as proposed in another thread it gets a little better (frames little more centric) but still no number visible and toolbar still much to high:
<script type='text/javascript' src='http://127.0.0.1/wordpress/wp-includes/js/extjs/ext-theme-neptune.js'></script>
This is the code that fails for me:
var dummyStore = Ext.create('Ext.data.Store', {
storeId: 'DummyStore',
pageSize: 1,
fields: [ 'Data' ],
data: [ { Data: 0 } ]
});
var pagingToolbar = Ext.create('Ext.toolbar.Paging', {
store: dummyStore,
dock: 'bottom',
displayInfo: true
});
var panel = Ext.create('Ext.grid.Panel', {
title: 'Test',
store: dummyStore,
columns: [ { text: 'Data', dataIndex: 'Data', flex: 1 } ],
height: 550,
width: 620,
renderTo: 'myHtmlDiv',
dockedItems: [ pagingToolbar ]
});
However I don't think this problem is data store related.
I did not do any stylings on my own.
UPDATE: If I copy the essential code and the includes into a blank HTML file, everything is displayed properly. Obviously this is a problem that arises due to something that Wordpress adds to the page. In the moment I have no clue how to tackle such a problem.
Using Chrome developer tools I compared the HTML representations of the input field table of my broken toolbar and the Sencha example. There are differences. The broken input field sub tree has:
"numberfield-1014" -> "top: 13px" instead of 1px
"numberfield-1014-bodyEl" -> additional class "x-form-trigger-wrap-focus"
"numberfield-1014-inputEl" -> additional classes "x-form-focus x-field-form-focus x-field-default-form-focus"
Thinking more about this.... CSSs could accidentally change the formatting of the input field (based on element classes and a lot of other element features). But how does it come that the classes of the wellformed and malformed elements are different? CSSs do not change class attributes, do they? Where could this difference come from?
I also checked the CSS rules. I could identify one rule in the wordpress twentyfourteen theme that makes the outer frame visible:
table,
th,
td {
border: 1px solid rgba(0, 0, 0, 0.1);
}
This is part of the reset section of the theme. When disabling it, the frame disappears.
Another rule is this one:
.entry-content td,
.comment-content td {
padding: 8px;
}
It prevents the input field from showing correctly. After disabling this only the vertical positions of all items in the bar must be fixed to make the bar look correctly.
Any idea what the root cause of these effects is?
I did not find a satisfying solution. Also the manufacturer of ExtJS (Sencha) could not give me a solution. It seems currently the only way to safely embed ExtJS content without CSS collisions is to use an iframe. I read about similar problems using other JS frameworks too so I suppose this generally is a problem.

ExtJS Panel always "in front" / always "on top"

Scenario description: I have a border layout with an ExtJS container containing one-to-many windows an a panel (acting as a Taskbar). I want the taskbar to be always on top. If a Window is active and consequently in front, calling toFront does not put it in front as expected.
The ExtJS Windows which remain in front is within the center area of the Border layout, whereas the panel acting as taskbar is within the south area, as follows:
items: [
{
xtype: 'maincontainer', id:'maincontainer',
region : 'center'
},
{
xtype: 'launchpanel', id:'launchpanel',
region: 'south',
collapsible : true,
}
],
where maincontainer and launchpanel extend Ext.container.Container and Ext.panel.Panel respectively. This code is within the main container which is the only item in the ExtJS MVC application's Viewport.
How do I get the launchpanel to be always in front / on top?
From what I've read in the meantime what appears in front is determined by the CSS z-index property.
Then I found this answer about how to set the z-index for a panel. Hence I set the z-index for the Panel each time it is rendered by having the following snippet in the controller:
'launchpanel': {
expand: function(panel) {
panel.getEl().setStyle('z-index','80000');
},
...
Still, if anyone has a better way of doing the above, please share!

Need help to figure out which layout to use?

I need some help on understanding layouts better. I watched some of the screencasts and the examples, etc. But I can't get done what I need and I think I'm not understanding things correctly.
I want to create a page with a Grid on top with a 100% width of the viewport. (Actually in my real page it's in a specific div but let's just assume...) Then below this grid, I need a TreePanel on the left for 1/3 of the width and the other 2/3 by a second Grid.
I'm trying to use the TableLayout so that I can have the first Grid span the two columns on the first row and second row would have the tree and the 2nd grid one besides the other.
I have my top grid and my tree on the page but the height of the top grid is not calculated automatically, it's just a few pixel high no matter how many rows are in there, and if I resize the browser window I don't get horizontal scrollbars on the grid.
So, my guess is that really the TableLayout is not what I should be using, but maybe I'm wrong. How can I achieve this layout ? Would I be better off using the BorderLayout ?
Here's the JS code I have (distributePMPanel is just a plain div on the page and I have another JS component that is loaded after that creates the Tree with a renderTo of 'mytree' so the Tree outputs in the second item's div):
_I.mainPanel = new Ext.Panel({
id:'main-panel',
renderTo: 'distributePMPanel',
baseCls: 'x-plain',
layout:'table',
layoutConfig: {columns:2},
items: [
new Ext.grid.GridPanel({
store: new Ext.data.JsonStore({
fields: Ext.decode(_I.options.pmStore),
root: 'pmData',
idProperty: 'id',
data: Ext.decode(_I.options.pmData)
}),
colModel: new Ext.grid.ColumnModel({
defaults: {
sortable : true
},
columns: Ext.decode(_I.options.pmColumns)
}),
colspan: 2
}),
{
id: 'mytree'
},
{
html: 'Grid 2'
}
]
});
};
Also, I have the following CSS:
#distributePMPanel table.x-table-layout { width: 100%; }
#distributePMPanel .x-panel-body { border-width: 0; }
I would definitely look at borderlayout.
Your grid is North
Your tree is West
Your other grid is Center
Should be a snap with borderlayout.

Is there any way to get an ExtJS GridPanel to automatically resize its width, but still be contained inside some non-ExtJS-generated HTML?

I want to include an ExtJS GridPanel inside a larger layout, which in turn must be rendered inside a particular div in some pre-existing HTML that I don't control.
From my experiments, it appears that the GridPanel only resizes itself correctly if it's within a Viewport. For instance, with this code the GridPanel automatically resizes:
new Ext.Viewport(
{
layout: 'anchor',
items: [
{
xtype: 'panel',
title: 'foo',
layout: 'fit', items: [
{
xtype: 'grid',
// define the grid here...
but if I replace the first three lines with the lines below, it doesn't:
new Ext.Panel(
{
layout: 'anchor',
renderTo: 'RenderUntoThisDiv',
The trouble is, Viewport always renders directly to the body of the HTML document, and I need to render within a particular div.
If there is a way to get the GridPanel to resize itself correctly, despite not being contained in a ViewPort, that would be ideal. If not, if I could get the Viewport to render the elements within the div, I'd be fine with that. All of my ExtJS objects can be contained within the same div.
Does anybody know of a way to get a GridPanel to resize itself correctly, but still be contained inside some non-ExtJS-generated HTML?
To resize Ext JS components when they are not in a Viewport, you need to pass along browser window resize events.
Ext.EventManager.onWindowResize(panel.doLayout, panel);
In your example, store the Panel into var panel, and then set up the event handler after the var declaration but still inside of Ext.onReady.
Here is a full single page solution:
<html>
<head>
<link rel="stylesheet" href="ext-3.1.1/resources/css/ext-all.css" />
<script src="ext-3.1.1/adapter/ext/ext-base.js"></script>
<script src="ext-3.1.1/ext-all-debug.js"></script>
<script>
Ext.BLANK_IMAGE_URL = 'ext-3.1.1/resources/images/default/s.gif';
Ext.onReady(function(){
var panel = new Ext.Panel({
renderTo: 'areaDiv',
layout: 'fit',
items: [{
height: 200,
title: 'foo',
xtype: 'grid',
cm: new Ext.grid.ColumnModel([
{header: "id", width: 400},
{header: "name", width: 400}
]),
store: new Ext.data.ArrayStore({
fields: ['id','name'],
data: [[1,'Alice'],[2,'Bill'],[3,'Carly']]
})
}]
});
//pass along browser window resize events to the panel
Ext.EventManager.onWindowResize(panel.doLayout, panel);
});
</script>
</head>
<body>
header
<div id="areaDiv" style="padding:30px;"></div>
footer
</body>
</html>
Note that I've removed the redundant panel (a GridPanel is a Panel, so no need to wrap it), and used layout fit instead of anchor. Layout fit is actually the key to a fluid layout. Make the browser smaller, then bigger. You'll see the grid always fills the entire width, with the exception of the padding.
I don't have enough reputation to "comment anywhere" yet, but I do have a fix to the "not working when window is resized smaller" problem described by HOCA. I was having the same problem too, using the solution outlined by this answer. After Googling around for a while, I found this thread on the sencha.com website. Using a similar technique to the one described there seems to work better cross-browser (using the exact solution offered there seems to work somewhat differently between FF/IE).
Ext.EventManager.onWindowResize(function() {
// pass "true" to get the contendWidth (excluding border/padding/etc.)
mainPanel.setWidth(Ext.getBody().getWidth(true));
// seems to be no need to call mainPanel.doLayout() here in my situation
});
In IE6 and Chrome your solution doesn't seem to work when the browser window is resized/made smaller that the original size. It does, however, resize properly when the browser window is resized larger. Does the Ext.EventManager.onWindowResize(panel.doLayout, panel) not fire when the browser window is made smaller?
I solved it by setting the layout: 'fit' to the panel that contains the grid
var myGridTab = new Ext.Panel({
layout: 'border',
region: 'center',
autoScroll: true,
animCollapse: false,
forceFit: true,
title: ' My Grid Tab ',
split: true,
border: false,
items: [
{
region: 'center',
**layout: 'fit',**
autoScroll: true,
items: [myGrid],
height: 150,
forceFit: true
}]
});

Categories

Resources