PDA

View Full Version : Rendering issue with menu and IE



stever
17 Apr 2007, 5:48 PM
Below is a sample file. I want to be able to construct a menu using inline script. In IE7 you can see the very different widths that are rendered in this example (FF is fine).


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Toolbar with Menus</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />

<!-- LIBS -->
<script type="text/javascript" src="../../yui-utilities.js"></script>
<script type="text/javascript" src="../../ext-yui-adapter.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="../../ext-all-debug.js"></script>


<script type="text/javascript">
/*<![CDATA[*/
function handleMenu(item)
{
if (item.link)
{
if (item.link.substring(0,11)=="javascript:")
eval(item.link.substring(11));
else
document.location.href = item.link;
}
}

function constructMenu(e) {
var items = [ ];

Ext.get(e).select('>li').each( function() {
// set current item properties
var img = this.select('>img');
var link = this.select('>a');
var icon = null;
var cls = null;
if (img.elements.length)
{
icon = img.item(0).dom.src;
cls = 'x-btn-icon';
}
if (img.elements.length && link.elements.length && link.item(0).dom.firstChild)
{
cls = 'x-btn-text-icon';
}
var currentItem={};
if (link.elements.length)
{
link = link.item(0).dom;
currentItem = {
text: link.innerHTML,
cls: cls,
id: link.id,
link: link.href,
icon: icon,
disabled: this.hasClass('disabled'),
handler: handleMenu
};
}
else if (img.elements.length)
currentItem = {
icon: icon,
cls: cls,
disabled: this.hasClass('disabled')
};
else
currentItem ='-';

// Check for sub menu.
var s = this.select('>ul');
if (s.elements.length) {
currentItem.menu = {items: constructMenu(s.item(0))};
}
items.push(currentItem);
});

return items;
}
/*]]>*/
</script>

</head>
<body>
<!-- YUI Document -->
<div id="yui-doc">

<!-- Header Section -->
<div id="yui-hd"></div>

<!-- Body Section -->
<div id="yui-bd">


<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->

<br>
<br>
<br>
<br>
<br>
<br>
<table cellpadding="0" cellspacing="0" border="0" class="Navigation">
<tr class="Row">
<td class="Cell Left">
<ul id='menudata' style='display:none'><li><a href="/Support/" id="ctl0"><u>V3 Community</u></a></li><li><a href="/Support/General/Forum/" id="ctl7"><u>Test Forum</u></a></li></ul>
<div id="menuspot"></div>
<div id="menuspot2"></div>
<div id="menuspot3"></div>
<div id="menuspot4"></div>

<script type="text/javascript">
/*<![CDATA[*/
var menu = new Ext.Toolbar('menuspot', constructMenu("menudata"));
//});
</script>

</td>
</tr></table>



<br /><br /><br /><br /><br />


<!-- End Body Section -->
</div>

<!-- Footer Section -->
<div id="yui-ft"></div>


<!-- End YUI Document -->
</div>


<script type="text/javascript">
/*<![CDATA[*/
var menu2 = new Ext.Toolbar('menuspot2', constructMenu("menudata"));
Ext.onReady(function(){
var menu3 = new Ext.Toolbar('menuspot3', constructMenu("menudata"));
});
/*]]>*/
</script>

</body>
</html>

jack.slocum
17 Apr 2007, 6:15 PM
Your code in executed inline. Please try it with Ext.onReady()

stever
17 Apr 2007, 6:26 PM
As the test shows, onReady works correctly. (menuspot2 and menuspot3 both work correctly -- one is later on the page, and one is using OnReady). The only problem is that the entire page starts jumping around as the various menus get loaded after rendering. That comes off looking cheap, so we can't do that. :(

tryanDLS
17 Apr 2007, 6:34 PM
That's part of your problem. Some stuff is being executed as the html is parsed and some is waiting until the document is loaded. I would suggest that it all goes in an onReady() in the head, rather than interspersed throughout the html.

stever
17 Apr 2007, 6:35 PM
I used IE Web Developer V2 to get the source of the rendered page. You can see how the HTML is different for the first one than it is for the next two:

The good ones have style="OVERFLOW-Y: hidden; OVERFLOW-X: hidden; OVERFLOW: hidden; WIDTH: 58px"




<TABLE class=Navigation cellSpacing=0 cellPadding=0 border=0><TBODY>
<TR class=Row>
<TD class="Cell Left">
<DIV style="hasLayout: 0">
<UL id=menudata style="DISPLAY: none">
<LI id=ext-gen7 _nodup="30806"><A id=ctl0 href="/Support/"><U>V3 Community</U></A>
<LI id=ext-gen10 _nodup="30806"><A id=ctl7 href="/Support/General/Forum/"><U>Test Forum</U></A></LI></UL>
<DIV id=menuspot>
<DIV class="x-toolbar x-small-editor">
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD>
<TABLE class="x-btn-wrap x-btn" id=ctl0 style="WIDTH: auto" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=x-btn-left><I>&nbsp;</I></TD>
<TD class=x-btn-center><EM><BUTTON class=x-btn-text id=ext-gen14><U>V3 Community</U></BUTTON></EM></TD>
<TD class=x-btn-right><I>&nbsp;</I></TD></TR></TBODY></TABLE></TD>
<TD>
<TABLE class="x-btn-wrap x-btn" id=ctl7 style="WIDTH: auto" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=x-btn-left><I>&nbsp;</I></TD>
<TD class=x-btn-center><EM><BUTTON class=x-btn-text id=ext-gen21><U>Test Forum</U></BUTTON></EM></TD>
<TD class=x-btn-right><I>&nbsp;</I></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></DIV></DIV>
<DIV id=menuspot2>
<DIV class="x-toolbar x-small-editor">
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD>
<TABLE class="x-btn-wrap x-btn" id=ctl0 style="WIDTH: auto" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=x-btn-left><I>&nbsp;</I></TD>
<TD class=x-btn-center><EM><BUTTON class=x-btn-text id=ext-gen36 style="OVERFLOW-Y: hidden; OVERFLOW-X: hidden; OVERFLOW: hidden; WIDTH: 72px"><U>V3 Community</U></BUTTON></EM></TD>
<TD class=x-btn-right><I>&nbsp;</I></TD></TR></TBODY></TABLE></TD>
<TD>
<TABLE class="x-btn-wrap x-btn" id=ctl7 style="WIDTH: auto" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=x-btn-left><I>&nbsp;</I></TD>
<TD class=x-btn-center><EM><BUTTON class=x-btn-text id=ext-gen44 style="OVERFLOW-Y: hidden; OVERFLOW-X: hidden; OVERFLOW: hidden; WIDTH: 58px"><U>Test Forum</U></BUTTON></EM></TD>
<TD class=x-btn-right><I>&nbsp;</I></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></DIV></DIV>
<DIV id=menuspot3>
<DIV class="x-toolbar x-small-editor">
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD>
<TABLE class="x-btn-wrap x-btn" id=ctl0 style="WIDTH: auto" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=x-btn-left><I>&nbsp;</I></TD>
<TD class=x-btn-center><EM><BUTTON class=x-btn-text id=ext-gen58 style="OVERFLOW-Y: hidden; OVERFLOW-X: hidden; OVERFLOW: hidden; WIDTH: 72px"><U>V3 Community</U></BUTTON></EM></TD>
<TD class=x-btn-right><I>&nbsp;</I></TD></TR></TBODY></TABLE></TD>
<TD>
<TABLE class="x-btn-wrap x-btn" id=ctl7 style="WIDTH: auto" cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD class=x-btn-left><I>&nbsp;</I></TD>
<TD class=x-btn-center><EM><BUTTON class=x-btn-text id=ext-gen65 style="OVERFLOW-Y: hidden; OVERFLOW-X: hidden; OVERFLOW: hidden; WIDTH: 58px"><U>Test Forum</U></BUTTON></EM></TD>
<TD class=x-btn-right><I>&nbsp;</I></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></DIV></DIV>
<DIV id=menuspot4></DIV></DIV>
<SCRIPT type=text/javascript>
/*<![CDATA[*/
var menu = new Ext.Toolbar('menuspot', constructMenu("menudata"));
//});
</SCRIPT>
</TD></TR></TBODY></TABLE>

stever
17 Apr 2007, 6:44 PM
That's part of your problem. Some stuff is being executed as the html is parsed and some is waiting until the document is loaded. I would suggest that it all goes in an onReady() in the head, rather than interspersed throughout the html.

Doing it two ways is just to show you a test page. Inline code is needed when not everything is created by JavaScript code. If everything was rendered via JS, it wouldn't be a problem. We have a menu in a table for example, and other things off to the side, and the whole page jumps around since we don't know what the height and width of the menu's toolbar will be.

So for this reason, onReady is not an option. :(

jack.slocum
17 Apr 2007, 9:04 PM
You can't do that with inline code in IE. You will have more issues than this, including the intermittent "operation aborted" in IE.

To prevent the "jumpy" menus in IE, just hide the menu markup.

stever
18 Apr 2007, 8:34 AM
I do hide the markup. It therefore takes up no space. And when the menu appears, the page shifts down from that point on. It is just the style sizing that is wrong. The "operation aborted" is another issue, but not one I'm having.

stever
18 Apr 2007, 11:30 AM
OK, I found a fix. in Ext.Button.render there is a check for IE to set autoWidth with a defer. But it doesn't do it for IE7 for some reason. If I remove the IE7 check all works perfectly.

That is, I change this:

if(Ext.isIE && !Ext.isIE7){
this.autoWidth.defer(1, this);
}else{
this.autoWidth();
}


to this


if(Ext.isIE ){
this.autoWidth.defer(1, this);
}else{
this.autoWidth();
}


And it is all fixed for me. There must be some reasoning behind exempting IE7 (thinking that some IE6 bug is fixed though I think it is not).

stever
18 Apr 2007, 4:05 PM
The above worked. So it did not have the page shifting because of the height of the added toolbar, it still displayed a toolbar that was originally too wide, then it made it smaller.

I found a better way that fixes things both ways.

Part one: change the CSS to not use auto width, but instead 100%.


.x-btn button{width:100%;}

And since TextMetrics.Instance.instance.getWidth() sets it back to auto again, change that code to


ml.dom.style.width = '100%';

This also fixed some other odd shifting things on both IE7 and FF2.


Hmm... maybe only the CSS needs to change.

jack.slocum
18 Apr 2007, 6:37 PM
Can I ask what you are trying to do or what the problem is exactly? It seems you are spending time changing code that has been thoroughly tested, when I would suggested the cause is elsewhere.

stever
18 Apr 2007, 6:56 PM
Humm... I thought I had posted one last time, but I guess it got lost or I closed the browser before I hit the reply button....

Anyhow, I found that if I wanted to do inline creation as in the example I posted, that the browser would incorrectly calculate the width of buttons. The cheap fix is to change the CSS style .x-btn button where is says width:auto to width:100%. Since I can do that as a CSS override, I have been able to solve the problem. :)

In the mean time, I have read a lot of Ext code... :)