View Full Version : Tabs in the tab strip not "merging" into active Ta
Animal
09-18-2006, 09:06 AM
My tabPanel does not look like the example.
Specifically, there's no outline round the whole tabpanel/tab entity.
The individual tabs in the tabstrip have an outline at left, top and bottom, but then both tab panel items just sem to have a top outline, seperate from the tabstrip, no left, bottom and right outlines.
Here's how I create them:
function bodyOnLoad()
{
list = new AspicioList("content", "CountrySubEntity");
}
function AspicioList(container, entityType)
{
this.id = "aspicioList" + (new Date()).valueOf();
window[this.id] = this;
if (container.constructor == YAHOO.ext.Element)
{
this.container = container;
}
else
{
this.container = new YAHOO.ext.Element(container, true);
}
this.container.update("");
this.tabPanelContainer = document.createElement("div");
YAHOO.util.Dom.generateId(this.tabPanelContainer);
this.formTabContainer = document.createElement("div");
this.formTabContainer.className = "tab-content";
this.formTabContainer.style.height = "500px";
this.formTabContainer.style.overflow = "auto";
YAHOO.util.Dom.generateId(this.formTabContainer);
this.listTabContainer = document.createElement("div");
this.listTabContainer.style.height = "500px";
this.listTabContainer.className = "tab-content";
YAHOO.util.Dom.generateId(this.listTabContainer);
this.tabPanelContainer.appendChild(this.formTabContainer);
this.tabPanelContainer.appendChild(this.listTabContainer);
this.container.dom.appendChild(this.tabPanelContainer)
this.tabset = new YAHOO.ext.TabPanel(this.tabPanelContainer);
this.formTab = this.tabset.addTab(this.formTabContainer.id, entityType);
this.ListTab = this.tabset.addTab(this.listTabContainer.id, entityType + " List");
this.formTabUpdateManager = this.formTab.getUpdateManager();
this.edit(0);
}
AspicioList.prototype =
{
edit: function(row)
{
this.formTabUpdateManager.update("/aspicio/editUser.do?type=CountrySubEntity&id=" + row + "&listId=" + this.id);
this.formTab.activate();
},
loadListTab: function(form)
{
// Use YAHOO's Connection to collect all form values (Except uuid and version) into a string.
form.uuid.disabled = true;
form.version.disabled = true;
YAHOO.util.Connect.setForm(form);
form.uuid.disabled = false;
form.version.disabled = false;
// Switch to the list tab, create the dynamically loaded grid
this.ListTab.activate();
this.Grid = YAHOO.ext.grid.AspicioGrid(YAHOO.util.Connect._sFormData, this.listTabContainer);
}
}
</script>
<body onload="bodyOnLoad()">
</body>
<div id="content">
</div>
</body>
What am I diong wrong?
jack.slocum
09-18-2006, 04:13 PM
It's set in the CSS:
#yourtabsId .yui-ext-tabbody {border:1px solid #999;border-top:none;}
I probably should have included this by default in tabs.css:
.yui-ext-tabbody {border:1px solid #999;border-top:none;}
Now if I do I will break people who have added their own borders. :(
Animal
09-19-2006, 05:14 AM
Thanks for that, I've added the general case. Now there's a border round the panel items.
But the tab strip is completely seperate. There's one pixel line of whitespace under the tabstrip, and then the outline that's just been added round the panel items.
The active tab of the tab strip does not merge into its panel item.
Sorry I can't post up a link, we're developing a new product on JBoss with Hibernate and MySQL, and the external server just runs Tomcat. I think it will be a long time before we can expose any running code to the world.
Here is the source code of the page though:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<link rel="stylesheet" href="/aspicio/Aspicio.css">
<script type="text/javascript" src="/aspicio/dwr/engine.js"></script>
<script type="text/javascript" src="/aspicio/dwr/util.js"></script>
<script type="text/javascript" src="/aspicio/js/yahoo.js" ></script>
<script type="text/javascript" src="/aspicio/js/event.js"></script>
<script type="text/javascript" src="/aspicio/js/dom.js"></script>
<script type="text/javascript" src="/aspicio/js/logger.js"></script>
<script type="text/javascript" src="/aspicio/js/connection.js"></script>
<script type="text/javascript" src="/aspicio/js/animation.js"></script>
<script type="text/javascript" src="/aspicio/js/dragdrop.js"></script>
<script type="text/javascript" src="/aspicio/js/treeview.js"></script>
<script type="text/javascript" src="/aspicio/js/container.js"></script>
<script type="text/javascript" src="/aspicio/js/menu.js"></script>
<script type="text/javascript" src="/aspicio/js/YahooExtensions.js"></script>
<script type="text/javascript" src="/aspicio/js/yui-ext.js"></script>
<script type="text/javascript" src="/aspicio/js/fcl.js"></script>
<title>CountrySubEntity Maintenance</title>
</head>
<body onload="bodyOnLoad()" >
<div id="message">
</div>
<div id="content">
<script type="text/javascript" src="/aspicio/dwr/interface/RemoteEntityLister.js"></script>
<script type="text/javascript" src="/aspicio/js/AspicioGrid.js"></script>
<script type="text/javascript" src="/aspicio/js/AspicioGridDataModel.js"></script>
<script type="text/javascript">
function bodyOnLoad()
{
list = new AspicioList("content", "CountrySubEntity");
}
function AspicioList(container, entityName)
{
this.id = "aspicioList" + (new Date()).valueOf();
window[this.id] = this;
if (container.constructor == YAHOO.ext.Element)
{
this.container = container;
}
else
{
this.container = new YAHOO.ext.Element(container, true);
}
this.container.update("");
this.entityName = entityName;
this.tabPanelContainer = document.createElement("div");
YAHOO.util.Dom.generateId(this.tabPanelContainer);
this.formTabContainer = document.createElement("div");
this.formTabContainer.className = "tab-content";
this.formTabContainer.style.height = "500px";
this.formTabContainer.style.overflow = "auto";
YAHOO.util.Dom.generateId(this.formTabContainer);
this.listTabContainer = document.createElement("div");
this.listTabContainer.style.height = "500px";
this.listTabContainer.className = "tab-content";
YAHOO.util.Dom.generateId(this.listTabContainer);
this.tabPanelContainer.appendChild(this.formTabContainer);
this.tabPanelContainer.appendChild(this.listTabContainer);
this.container.dom.appendChild(this.tabPanelContainer)
this.tabset = new YAHOO.ext.TabPanel(this.tabPanelContainer);
this.formTab = this.tabset.addTab(this.formTabContainer.id, entityName);
this.listTab = this.tabset.addTab(this.listTabContainer.id, entityName + " List");
this.formTabUpdateManager = this.formTab.getUpdateManager();
this.edit(0);
}
AspicioList.prototype =
{
edit: function(row)
{
this.formTabUpdateManager.update(fcl.util.getUrlContext() + "/form/" + this.entityName + ".jsp?id=" + row + "&listId=" + this.id);
this.formTab.activate();
},
loadListTab: function(form)
{
// Use YAHOO's Connection to collect all form values (Except uuid and version) into a string.
form.uuid.disabled = true;
form.version.disabled = true;
YAHOO.util.Connect.setForm(form);
form.uuid.disabled = false;
form.version.disabled = false;
// Switch to the list tab, create the dynamically loaded grid
this.listTab.activate();
this.grid = new YAHOO.ext.grid.AspicioGrid(YAHOO.util.Connect._sFormData, this.listTabContainer,
function()
{
// use 'mon' instead of 'on' to get a managed (normalized) event object
this.grid.grid.el.mon('dblclick', function yourHandler(e)
{
var row = this.grid.grid.getRowFromChild(e.getTarget());
if (row) // need this check in case they double clicked header instead of row
{
var id = this.grid.grid.getDataModel().getRowId(row.rowIndex);
this.edit(id);
}
}, this, true);
}, this);
}
}
</script>
</div>
</body>
</html>
jack.slocum
09-19-2006, 03:41 PM
Your code looks fine. I believe the tabs depend on reset.css. Do you have that included in your master css file? You may also try adding !important to some of the rules in the tabs css to make sure they are indeed overriding any global hd classes you have.
If I may make some suggestions on the rest of the code?
This code:
if (container.constructor == YAHOO.ext.Element)
{
this.container = container;
}
else
{
this.container = new YAHOO.ext.Element(container, true);
}
can be changed to this:
this.container = YAHOO.ext.Element.get(container);
//or shorthand
this.container = getEl(container);
YAHOO.ext.Element.get will check if it's already a YAHOO.ext.Element.
For the tabs, if you define a style in your CSS:
.aspicioList .yui-ext-tabitembody {
height: 500px;
overflow:auto;
}
You can get this code:
this.tabPanelContainer = document.createElement("div");
YAHOO.util.Dom.generateId(this.tabPanelContainer);
this.formTabContainer = document.createElement("div");
this.formTabContainer.className = "tab-content";
this.formTabContainer.style.height = "500px";
this.formTabContainer.style.overflow = "auto";
YAHOO.util.Dom.generateId(this.formTabContainer);
this.listTabContainer = document.createElement("div");
this.listTabContainer.style.height = "500px";
this.listTabContainer.className = "tab-content";
YAHOO.util.Dom.generateId(this.listTabContainer);
this.tabPanelContainer.appendChild(this.formTabContainer);
this.tabPanelContainer.appendChild(this.listTabContainer);
this.container.dom.appendChild(this.tabPanelContainer)
this.tabset = new YAHOO.ext.TabPanel(this.tabPanelContainer);
this.formTab = this.tabset.addTab(this.formTabContainer.id, entityName);
this.listTab = this.tabset.addTab(this.listTabContainer.id, entityName + " List");
Down to this code:
this.tabPanelContainer = document.createElement("div");
YAHOO.util.Dom.generateId(this.tabPanelContainer);
this.tabPanelContainer.className = 'aspicioList';
this.container.dom.appendChild(this.tabPanelContainer)
this.tabset = new YAHOO.ext.TabPanel(this.tabPanelContainer);
this.formTab = this.tabset.addTab(this.id+"Form", entityName);
this.listTab = this.tabset.addTab(this.id+"List", entityName + " List");
The TabPanel class already has Dom building code built-in, might as well use it and save some keystrokes.
Jack
Animal
09-20-2006, 06:30 AM
Thanks for that - I've added that style rule, so I don't have to explicitly style my tabpanel divs.
this.container = YAHOO.ext.Element.get(container);
Didn't work in all cases though, so I reverted.
Adding reset.css has scrunched a lot of elements closer together, but the tab panel item area still has a full top border, and the tabstrip is completely seperate.
What changes the look of the tab to make it merge with its tab panel item? I can't see a ".tabset li.active" style.
Hmm, Looking at the DOM inspector, I see you have two elements for each tab, one active and one inactive which are displayed/hidden?
Why not just have one, and change its class? The tabset in our old app who's custom tag library I wrote worked like this (I wrote the tag library before I understood about Javascript objects, so there's no object encapsulating the tabs, each click handler has to examine the DOM around the "this" to determine what is going on):
<DIV title="Show the Details tab" onclick="tabButtonClick(this, 'detailstab')" class="tabsetbutton tabsetbuttonactive">
<SPAN class="label">Details</SPAN>
<SPAN class="tabright"/>
</DIV>
<DIV title="Show the Collection tab"
onclick="tabButtonClick(this, 'collectiontab')" class="tabsetbutton tabsetbuttoninactive">
<SPAN class="label">Collection</SPAN>
<SPAN class="tabright"/>
</DIV>
<DIV title="Show the Delivery tab"
onclick="tabButtonClick(this, 'deliverytab')" class="tabsetbutton tabsetbuttoninactive">
<SPAN class="label">Delivery</SPAN>
<SPAN class="tabright"/>
</DIV>
<DIV title="Show the Diary tab" onclick="tabButtonClick(this, 'diarytab')" class="tabsetbutton tabsetbuttoninactive">
<SPAN class="label">Diary</SPAN>
<SPAN class="tabright"/>
</DIV>
<DIV title="Show the e-Docs tab" onclick="tabButtonClick(this, 'edocstab')" class="tabsetbutton tabsetbuttoninactive">
<SPAN class="label">e-Docs</SPAN>
<SPAN class="tabright"/>
</DIV>
<DIV style="height: 510px;" class="tabsetcontainer" id="detailstab">
</DIV>
<DIV style="height: 510px;" class="tabsetcontainer notdisplayed notloaded" id="collectiontab"/>
<DIV style="height: 510px;" class="tabsetcontainer notdisplayed notloaded" id="deliverytab"/>
<DIV style="height: 510px;" class="tabsetcontainer notdisplayed notloaded" id="diarytab"/>
</DIV>
with style rules:
/*
Define styles for tabs
*/
.tabset {
color:white;
background-color:#185296;
overflow:hidden;
border-bottom:1px solid white;
margin-bottom:3px;
}
.tabsetbutton {
float:left;
position:relative;
top:1px;
}
.tabsetbuttonactive {
background:url("images/asp_ActiveTabLeft.gif") bottom left no-repeat;
color:white;
border-bottom:1px solid #999966;
}
.tabsetbuttoninactive {
background:url("images/asp_InactiveTabLeft.gif") bottom left no-repeat;
color:#cccc99;
border-bottom:1px solid white;
cursor:pointer;
}
.tabset .label
{
background-color:#999966;
vertical-align:bottom;
border-top:1px solid white;
padding:0px 10px 0px 10px;
margin:0px 0px 0px 3px;
font-size:11pt;
font-weight:bold;
}
.tabsetbuttonactive .tabright {
background:url("images/asp_InactiveTabRight.gif") bottom right no-repeat;
margin:1px 0px 0px 0px;
vertical-align:bottom;
height:18px;
padding-bottom:1px;
padding-right:3px;
display:inline-block;
}
.tabsetbuttoninactive .tabright {
background:url("images/asp_ActiveTabRight.gif") bottom right no-repeat;
margin:1px 0px 0px 0px;
vertical-align:bottom;
height:18px;
padding-bottom:1px;
padding-left:3px;
display:inline-block;
}
.tabsetcontainer {
clear:left;
border:1px solid white;
background-color:#999966;
z-index:100;
}
.notdisplayed {
display:none;
overflow:hidden;
}
With the tag handlers adding this script to the page for dynamic loading on first select (note that the inactive tabs have the "notloaded" class because I haven't visited them):
document.getElementById("detailstab").src="AspBkGeneric001Header.jsp";
document.getElementById("collectiontab").src="AspBkGenericCollection.jsp";
document.getElementById("deliverytab").src="AspBkGenericDelivery.jsp";
document.getElementById("diarytab").src="DiaryList.jsp?diarytype=1&diarycontrol=2RMI0638001&containerstyle=height:440px;overflow:scroll&tablestyle=width:890px&from=AspBkGeneric001.jsp";
document.getElementById("edocstab").src="CorrespondenceList.jsp?tmode=1&jobref=2RMI0638001&containerstyle=height:405px;overflow:scroll&tablestyle=width:890px&from=AspBkGeneric001.jsp";
The tabs (Class "tabsetbutton") are positioned relative at top:1px, so that they are bumped down by 1px. The active one merges in by having a border-bottom color that's the same as the background color of the tab container.
To see it, go to https://secure0.forward-comp.co.uk/fcl_asp
Log in using
Customer ID: ultimate
User ID: ul1
Password: ul1
Click "On-Line Bookings"
Click "Submit" - the defaults filter should find two.
Click the icon in the first column of the second row.
You should get to the consignment details screen which is a tabset of 5 tabs.
A lot of the stuff I'm looking to replace is on there.
For instance, if you go to the "Post/Area" input, clear the field, and then click the "..." button, you should get a popped up selection list which lists the postal codes, and loads more as you scroll. Same for the Currency field.
It's all done in a non object based way - I'm replacing that with your Grid with the new self loading DataModel.
jack.slocum
09-20-2006, 04:23 PM
Didn't work in all cases though, so I reverted.
I use that code in thousands of places and have never had a problem. If you run into one again can you trap it and let me know? That method is the root of the entire library.
The reason for the two elements was to support Yahoo's design pattern tabs. They actually have a different element structure instead of a class for selected vs non-selected.
The tab component's UI could use a refactor. The actually tab strips could/should be built in a more standard way, with some CSS that is modifiable as well. The pattern tabs CSS is so tangled it is extremely difficult to work with IMO.
To find the CSS rule that is making the tabs overlap, search for "-1px".
Animal
09-21-2006, 03:55 AM
I don't really understand how design pattern guidelines could mandate an over-complex DOM/CSS structure.
I think however than I'm seeing a Mozilla issue. I'm on 1.5.07. It works fine on IE7.
But I think Mozilla has it right.
The class="tabset" div has border-bottom-width:1px, so THAT is the line which must be "broken" when the tab merges with its panel.
It's the tabstrip ul INSIDE that that has the margin-bottom:-1px style. There are no elements after the ul to move upwards by 1px! The ul is the only child in the tab-strip div.
Nothing you do to the styles of the descendant elements of the class="tabset" div is going to make them overlay that div's bottom border to create the merging apperance - they are inside that div.
jack.slocum
09-21-2006, 06:20 AM
I don't really understand how design pattern guidelines could mandate an over-complex DOM/CSS structure.
The markup and CSS is straight from the pattern page. It's hideous mangled mess of html and css but it's cross browser which is why I used it.
It's the tabstrip ul INSIDE that that has the margin-bottom:-1px style. There are no elements after the ul to move upwards by 1px! The ul is the only child in the tab-strip div.
The tabset parent draws the line across the bottom of the tab-strip. The UL has margin -1px (which basically means I overlap my parent by 1px). That's what creates the overlap.
Think about it like this. If you added 1px margin to the child UL, it would create a 1px space between the UL and the tabset div. The opposite is also true. If you say -1px margin, it will overflow it's parent by 1px.
IE doesn't support it, but does support position:relative overflowing it's parent, which is why it is working for you in IE.
Animal
09-21-2006, 07:55 AM
It's only working in FF in quirks mode. Try a tab panel with a page in strict mode.
I'm trying to be standards compliant on Yahoo A grade browsers. With this being a vertical market app, we can specify support for A grade browsers only (which covers most of the browser userbase anyway)
jack.slocum
09-21-2006, 04:15 PM
The example is in strict mode:
http://www.jackslocum.com/blog/examples/tabs.htm
There is something odd going on on your page, but it's obviously not easy to track. Are you applying any global styles to li, ul, or .hd?
Animal
09-22-2006, 03:23 AM
The example is in strict mode:
http://www.jackslocum.com/blog/examples/tabs.htm
There is something odd going on on your page, but it's obviously not easy to track. Are you applying any global styles to li, ul, or .hd?
Yes, that page works in my browser. Curiouser and curiouser.
I'm not applying global styles to any of those elements.
jack.slocum
09-22-2006, 04:44 AM
Can you put up a page? Or use IE to do a page save and zip it all up and email it to me?
Animal
09-22-2006, 06:13 AM
I can't expose this app. I've zipped up te results of s "save web page" operation, and emailed it to you.
jack.slocum
10-15-2006, 08:35 AM
From the zip file you sent me, this is what IE expanded the saved CSS to:
.yui-ext-tabbody {
BORDER-RIGHT: #999 1px solid; BORDER-TOP: #999 1px; BORDER-LEFT: #999 1px solid; BORDER-BOTTOM: #999 1px solid
}
It appear it is ignoring the none:
.yui-ext-tabbody {border:1px solid #999;border-top:none;}
This fixes it:
.yui-ext-tabbody {border:1px solid #999;border-top:0px none;}
I accidentally ran into this when fooling around with a new tab skin and said - hey that looks just like Nige's page.
amit.shukld
05-13-2008, 08:06 AM
Hi ani,
i have a small problem as my form is disabled text in the text boxes just gets dull is there any way you know the my text is bold or highlighted or something when my form is disabled
My tabPanel does not look like the example.
Specifically, there's no outline round the whole tabpanel/tab entity.
The individual tabs in the tabstrip have an outline at left, top and bottom, but then both tab panel items just sem to have a top outline, seperate from the tabstrip, no left, bottom and right outlines.
Here's how I create them:
function bodyOnLoad()
{
list = new AspicioList("content", "CountrySubEntity");
}
function AspicioList(container, entityType)
{
this.id = "aspicioList" + (new Date()).valueOf();
window[this.id] = this;
if (container.constructor == YAHOO.ext.Element)
{
this.container = container;
}
else
{
this.container = new YAHOO.ext.Element(container, true);
}
this.container.update("");
this.tabPanelContainer = document.createElement("div");
YAHOO.util.Dom.generateId(this.tabPanelContainer);
this.formTabContainer = document.createElement("div");
this.formTabContainer.className = "tab-content";
this.formTabContainer.style.height = "500px";
this.formTabContainer.style.overflow = "auto";
YAHOO.util.Dom.generateId(this.formTabContainer);
this.listTabContainer = document.createElement("div");
this.listTabContainer.style.height = "500px";
this.listTabContainer.className = "tab-content";
YAHOO.util.Dom.generateId(this.listTabContainer);
this.tabPanelContainer.appendChild(this.formTabContainer);
this.tabPanelContainer.appendChild(this.listTabContainer);
this.container.dom.appendChild(this.tabPanelContainer)
this.tabset = new YAHOO.ext.TabPanel(this.tabPanelContainer);
this.formTab = this.tabset.addTab(this.formTabContainer.id, entityType);
this.ListTab = this.tabset.addTab(this.listTabContainer.id, entityType + " List");
this.formTabUpdateManager = this.formTab.getUpdateManager();
this.edit(0);
}
AspicioList.prototype =
{
edit: function(row)
{
this.formTabUpdateManager.update("/aspicio/editUser.do?type=CountrySubEntity&id=" + row + "&listId=" + this.id);
this.formTab.activate();
},
loadListTab: function(form)
{
// Use YAHOO's Connection to collect all form values (Except uuid and version) into a string.
form.uuid.disabled = true;
form.version.disabled = true;
YAHOO.util.Connect.setForm(form);
form.uuid.disabled = false;
form.version.disabled = false;
// Switch to the list tab, create the dynamically loaded grid
this.ListTab.activate();
this.Grid = YAHOO.ext.grid.AspicioGrid(YAHOO.util.Connect._sFormData, this.listTabContainer);
}
}
</script>
<body onload="bodyOnLoad()">
</body>
<div id="content">
</div>
</body>
What am I diong wrong?
vBulletin® v3.8.4, Copyright ©2000-2009, Jelsoft Enterprises Ltd.