PDA

View Full Version : HtmlLayout - Use Ext components in plain HTML



Condor
31 Aug 2009, 11:17 PM
HtmlLayout is a small extension of the standard ContainerLayout. It allows you to use components inside plain HTML while still maintaining the container structure. This has the advantage that the components will still be managed (e.g. destroying the container doesn't leak memory for the contained components).

The extension:

Ext.ns('Ext.ux.layout');
Ext.ux.layout.HtmlLayout = Ext.extend(Ext.layout.ContainerLayout, {
renderItem: function(c, position, target){
if(c.renderTarget){
target = Ext.DomQuery.selectNode(c.renderTarget, Ext.getDom(target));
}else if(c.applyTarget){
var el = Ext.DomQuery.selectNode(c.applyTarget, Ext.getDom(target));;
if(!c.rendered){
c.el = el;
}
target = el.parentNode;
}
Ext.ux.layout.HtmlLayout.superclass.renderItem.call(this, c, undefined, target);
}
});
Ext.Container.LAYOUTS['ux.html'] = Ext.ux.layout.HtmlLayout;

Example usage:

Ext.onReady(function() {
var panel = new Ext.Panel({
title: 'HtmlLayout test',
autoHeight: true,
layout: 'ux.html',
html: '<table><tr><td>Please enter your name </td><td></td><td> and password </td><td><input type="password" /></td><td>.</td></tr></table>',
defaultType: 'textfield',
items: [{
name: 'username',
renderTarget: 'td:nth(2)'
},{
name: 'password',
applyTarget: 'input[type=password]'
}]
}).render(Ext.getBody());
});

steffenk
1 Sep 2009, 1:04 AM
nice one! It also shows how to integrate a custom layout.

Do you ever sleep? :)

deepak
1 Sep 2009, 1:04 AM
Hmm, going to give it a spin /:)

aconran
1 Sep 2009, 1:42 AM
Nice layout condor

mystix
1 Sep 2009, 10:03 AM
neat trick!

Animal
3 Sep 2009, 11:22 AM
Yes! nice piece of lateral thinking!

dbassett74
12 Aug 2010, 9:15 AM
Just what I was looking for, thanks!

dbassett74
12 Aug 2010, 10:06 AM
One quick question. Instead of placing the html inline in the code with the "html" config, how can I reference an html table from some other file? The reason I ask is that it is much cleaner (especially on a complex table) to have this in a separate file. Thanks.

xmttkx
12 Aug 2010, 5:47 PM
very nice!

Condor
15 Aug 2010, 1:49 AM
@dbassett74: Instead of 'html' you could also use 'el', 'applyTo' or 'contentEl' (depending on what you are looking for exactly).

j-joey
22 Aug 2010, 12:03 PM
thanks condor, this will be very useful for me.

jcmartinez
7 Sep 2010, 1:54 PM
Hi, I just implemented this solution in a tab. But I have a problem, because the Ext components are not rendering the first time I select the tab. I have to do this:

a) Select the tab where I have this component. I just see the HTML items.
b) I select another tab
c) I select the tab with the component, and I see the Ext components

Do I need to do something special when I integrate this component in a tab ?

I appreciate your help.

Regards

Juan Martinez

Condor
7 Sep 2010, 10:25 PM
Did you configure the tabpanel with layoutOnTabChange:true?

anestesiadorhvs
2 Oct 2010, 1:05 AM
I´m trying to render an inline form using your extension, so I´m using inline function and htmllayout together, however I can´t understand the way htmllayout renders Ext's componentes. I´ve been searching about applyTarget and renderTarget in ext's api and I can´t find them.

I show you my code

This is the html form I want to render:


<form id="form1" name="form1" method="post" action="enviar.asp">

<input type="text" name="texto" id="texto" />
<select name="select" id="select">
<option value="1">uno</option>
<option value="2">dos</option>
</select>
<input type="text" name="nombre" id="nombre" />
</form>

any sugestion?, thanks in advance and sorry about my english

plalx
2 Oct 2010, 4:00 PM
renderTarget and applyTarget are config options that you specify on the items. These will be used by the HtmlLayout to find the element in which the item will be rendered or the element to which the item will be applied to. It is normal that you don't find anything in the docs about that since HtmlLayout is a ux.

In your example, if you want an Ext.form.TextField as the first input, you would use applyTarget: 'input[name=texto]' as a config option on the first item of the container that is using the HtmlLayout.


*** Btw, great layout Condor! ***

anestesiadorhvs
3 Oct 2010, 10:24 PM
thanks a lot scarsick. I´m trying now with select tag....

Condor
3 Oct 2010, 11:01 PM
For the select tag you probably want to use the transform config option, which HtmlLayout currently doesn't support.

You will need to create the combobox (with the transform config option) in the render event and add it to the container yourself.

dbassett74
2 Dec 2010, 8:49 AM
If adding a Panel to a <td> element using renderTarget, how can I specify that the panel takes up 100% width/height of that <td>?

The following doesn't work:


var commentsPanel = new Ext.Panel({
anchor: '100% 100%',
renderTarget: "td:nth(10)"
});

plalx
2 Dec 2010, 1:44 PM
Anchor won't do it since the HtmlLayout doesn't extend the AnchorLayout. Not sure if it's going to work or if it's going to create other problems, but you can always try using style: 'height: 100%; width: 100%;'.

Condor
2 Dec 2010, 11:41 PM
HtmlLayout doesn't do sizing of it's child items.

Instead, you could configure the commentsPanel with the FitToParent plugin.

dbassett74
3 Dec 2010, 7:37 AM
The "style" method doesn't work. Can you show me how I might use the FitToParent plugin with the above code? For example, with the FitToParent plugin, it seems you have to specify the element, but in this case, we are using "renderTarget". Would "td:nth(10)" be the "element" in this case?


Also, where do I download it from? Thanks.

Condor
3 Dec 2010, 7:41 AM
If you don't specify a target for FitToParent, it will use the element the component is rendered to (which would be the renderTarget).

dbassett74
3 Dec 2010, 10:44 AM
This almost works! It properly sets the height of the panel to fill the entire space, however, and this is a big issue. Even though I have set autoScroll: true, no scrollbars appear, rather, the panel keeps growing as more html is added.

I really need the panel to maintain the height of the parent, while also showing vertical scrollbar as needed. Is this possible?

dbassett74
3 Dec 2010, 1:59 PM
I was able to accomplish what I needed by embedding another panel within the panel that is using the FitToParent plugin. It works, but I really don't like the extra weight it brings.

dbassett74
1 Jan 2011, 8:32 AM
How can you set the style of a particular TD in the html table at run time? For example, I want to set the background-color to #FF0000 for "td:nth(1)". How would I accomplish this in code? Thanks.

Condor
1 Jan 2011, 9:13 AM
And you you applying or rendering something to that td?

dbassett74
1 Jan 2011, 9:32 AM
Not currently. It is simply an empty TD which will have some background color depending on the state of that row during run time.

dbassett74
2 Jan 2011, 1:44 PM
Sorry to bug, but any word on being able to do this?

Condor
2 Jan 2011, 11:21 PM
So this is completely unrelated to HtmlLayout? You just want to give a particular td a black background?


Ext.select('td:nth(1)').setStyle('backgroundColor', 'black');

dbassett74
3 Jan 2011, 8:51 AM
yes, this is related to HtmlLayout, as I'm using that for a Layout of a panel. It's just that this particular TD is only visual, there is nothing rendered to it. However, the above code does not seem to work. No error, but it doesn't change the background color of that cell to black. Any idea what I'm doing wrong?

dbassett74
3 Jan 2011, 8:56 AM
I see what the problem is now. It seems like once the HtmlLayout is rendered. trying to select td:nth(x) is considering EVERY td that is on the page, not just within that particular layout.

For some clarification, I am applying the HtmlLayout to an MANY individual panels that are then being rendered into a parent panel (sorta like my own grid). So as I'm loading, I'm able to refer td:nth(1) for each panel, but it seems like AFTER it's rendered, the TD count is then accumulative. Hopefully that makes some since.

So what I'm wondering is how to properly reference a particular TD after they have all been rendered. Seems like maybe I need to render a DIV or some other light weight control to that TD at load time and then set the style of that??

Condor
3 Jan 2011, 11:18 PM
Don't forget to specify the root element for the Ext.select.

dbassett74
4 Jan 2011, 4:43 AM
In my case, I'm not sure what the root is. Per the doc, it says the root is the "HTMLElement". For me, I have a Panel that has this HTMLLayout. How do I specify the panel? Is it the var name I assigned the panel (var row = new Ext.Panel...)? I tried Ext.select("td:nth(1)", true, row), but it did not work.

Condor
4 Jan 2011, 4:58 AM
In that case the root is panel.body.

dbassett74
4 Jan 2011, 7:27 AM
Doesn't seem to work. Here is what I'm using:

Ext.select("td:nth(1)", true, row.body).setStyle("backgroundColor", "black");

Condor
4 Jan 2011, 8:33 AM
OK, it should be:

Ext.select("td:nth(1)", true, row.body.dom).setStyle("backgroundColor", "black");
(and of course only after the panel is rendered)

dbassett74
4 Jan 2011, 9:15 AM
HAHA, that was it! Thanks so much!

Now, next and hopefully last question. I tried to render a ToolTip to a TD, but it doesn't seem to work. Is there something special I have to do? Here's is what I tried:



var tt = new Ext.ToolTip({
title: "Levels",
html: "test",
renderTarget: "td:nth(1)"
});

Condor
4 Jan 2011, 10:56 AM
No, I don't think you want to render the tooltip to that td; I think you want to show that tooltip with the td as the target.

dbassett74
4 Jan 2011, 11:30 AM
Ok, I tried putting it in the render event for the panel, but the tooltip doesn't appear. Here is what I have:



listeners: {
render: function(p) {
var tt = new Ext.ToolTip({
title: "Levels",
html: "test",
target: "td:nth(1)"
});
}
},


Do I need to somehow specify the parent as I did with the Ext.select in the earlier messages in this thread?

Condor
4 Jan 2011, 11:22 PM
No, 'target' can't be a selector. You will also need to specify it as:

target: Ext.select("td:nth(1)", true, row.body.dom)

dbassett74
5 Jan 2011, 8:44 AM
Doesn't seem to work:



render: function(p) {
var tt = new Ext.ToolTip({
title: "Levels",
html: "test",
target: Ext.select("td:nth(1)", true, p.body.dom)
});
}

Condor
6 Jan 2011, 2:01 AM
What is inside this td? You can only apply a ToolTip to a top-level element. It doesn't work if the <td> is covered by another element.

dbassett74
6 Jan 2011, 8:08 AM
There is nothing inside the TD. It is empty at all times.

jcmartinez
3 Jan 2012, 5:31 PM
Hi,

I am migrating my application to Ext 4, but I'm using the component: Ext.ux.layout.HtmlLayout that is in Ext 3. I'm looking for this component for Ext 4, does anybody can help me ?

Regards

Juan Carlos

jcmartinez
4 Jan 2012, 11:17 AM
I did some changes to the component, but it is not rendering correctly,


Ext.define('Ext.ux.layout.HtmlLayout', {
extend: 'Ext.layout.container.Container',
alias: ['layout.ux.html'],
alternateClassName: 'Ext.layout.HtmlLayout',
renderItem: function (c, target, position) {
if (!c.rendered) {
if (c.renderTarget) {
target = Ext.DomQuery.selectNode(c.renderTarget, Ext.getDom(target));
} else if (c.applyTarget) {
var el = Ext.DomQuery.selectNode(c.applyTarget, Ext.getDom(target));
if (!c.rendered) {
c.el = el;
}
target = el.parentNode;
}
Ext.layout.HtmlLayout.superclass.renderItem.call(
this, c, target, position);
}
}
});




I got this, I don't see the Date Icon (to the right) and the datefields are at the left (they should have to be on top of "IMPORTE"). Does anybody can help me ?
30452

regards and thank's in advance