Title: Questions about Tabs Post by: tslatt on November 29, 2011, 02:34:09 PM I am still having some issues with tabs and with getting portals to work inside tabs. The problems are as follows:
(1) Instead of using the tab's title in tab operations, I need to be able to use a unique id for each tab. In my case, each tab will hold a portal containing a person's information, and the title of the tab will be that person's name. However, two people might have the same name (but of course, different information). So I need a unique identifier for each tab to use when selecting that tab and performing actions on that tab. My Question: Is there currently a way to assign and use unique ids instead of titles on tabs? I saw ellisgl's code, but it was a modification of a much earlier release of easyUI. (2) In addition to having a 'close' button on each tab, I need to be able to have other buttons that perform other actions. That ability doesn't seem to be built in, and since the easyUI code is obscured, I couldn't find a way to edit it to add that ability. In the end I developed a hack that roughly accomplishes this, but it would be better if you could just specify when creating a tab which buttons it should have. In my case, I wanted a popup button that would pop that tab & its content up into a new window and remove it from the main tab bar. My Question: Is there a better way to do this? (3) I'm having trouble getting a portal to load inside a tab, except in ideal circumstances that I won't always be able to guarantee. The content of each of my tabs is a portal. When the tab is loaded, I call the code that initializes the portal that's in it. This works well, as long as another tab is not added until the portal is done loading. I don't know of any way to guarantee that this will always happen. For example, in my test code, if I have only one tab added on page load, and I don't do anything else until it's done, the tab loads, its portal then initializes, the portal's panels are loaded, and the portal displays and functions correctly. However, if I have two tabs added to the page on load, the first tab loads, its portal then initializes, and the portal's panels are loaded, BUT, the portal is squashed. Each of its three columns is about 10 pixels wide. Dragging a panel into the 3rd column causes the 3rd column to expand to fill the tab width, but the other columns remain squashed. In the second tab, nothing shows up at all. It appears that instead of loading the 2nd tab's portal, it attempts to load the first tab's portal again. It seems this is because I don't have any way to identify which portal to initialize other than the one of the currently selected tab, and instead of finding the one in tab 2, it's finding the one in tab 1. My Questions: How can I make sure that one portal is completely loaded before trying to load another? Is there a better way to identify which portal should be initialized? Any help that anyone can give me would be greatly appreciated. Every time I seem to be getting close to a working solution, I find a new stumbling block. I'm fairly new to jquery, so I'm learning as I go. The easyUI library is awesome, but I'm having some trouble understanding how to use parts of it and how to extend it. The code I'm using is shown below. My jQuery Code: Code: <script type="text/javascript"> $(document).ready(function() {//begin on page load ////////////////////////////////////////////////////////////////////////////////////// //TAB FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ////////////////////////////////////////////////////////////////////////////////////// //add a way to identify tabs by a unique id, instead of by the tab title. there needs to be the ability to have tabs that have the same title!! //initialize the main tabs & add events to the main tabs $('#main-tab-bar').tabs({//for all tabs onAdd: function(title) {//do this on add tab addTabPopup(title);//add the tab popup links. note: find a better way to do this! },//end on add tab onLoad: function(p) {//do this when a tab's href is loaded //figure out which tab was loaded. get its portal's id. initialize that portal. //problems: // (1) this assumes this tab is still selected, when getting the id of the portal // (2) if another tab is loaded quickly, the 1st tab's portal is squashed, and the 2nd tab doesn't load one //find the unique id of the portal to load (there is only one per tab, the same div that has the class "aportal") var thisPortal = $(".aportal").attr("id"); //load the portal if (thisPortal != undefined) {//if the portal's id was found initializePortal(thisPortal); //initialize that portal } },//end on tab load });//end for all tabs //end init tabs & add events to all tabs $('#main-tab-bar').tabs('resize'); //now that the tabs are initialized, resize the main tab bar (to set its initial size correctly) //add tabs that should appear on page load if ($("body#home").length != 0) {//if this is the home page and not the popup //note: these two tabs are only added on page load during testing. later, clicking on a link will cause a new tab to appear addMainTabAjax("Test A", "include/portal-testA.asp?test=Hello", "icon-reps-profile", true); addMainTabAjax("Test B", "include/portal-testB.asp?test=World", "icon-reps", true); } $("#reloadTab").live("click", function(){//now and in the future, reload a tab's href via ajax when clicked var tabTitle = getTabProperty("title");//get this tab's title (find a way to use an id instead of title) $('#main-tab-bar').tabs('getTab', tabTitle).panel('refresh');//refresh this tab (reload its content via ajax) }); //when the tab popup button is clicked, pop up that tab in a new window $(".tabs-popup").live("click", function(){ //get the title, icon & content of this (the currently selected) tab var tabTitle = getTabProperty("title"); var tabIcon = getTabProperty("icon"); var tabContent = getTabProperty("content"); //note: this only returns the content if it was added dynamically var tabHref = getTabProperty("href"); //note: this only returns the href if the tab has one. //find a way to get the tab's unique id also //open a new window with that info //figure out how to encrypt this query string to hide it from the user var url = "popup_tab.asp?title=" + tabTitle + "&icon=" + tabIcon + "&content=" + tabContent + "&href=" + tabHref; url = encodeURI(url); var windowName = tabTitle; var windowOptions = "width=1000,height=700,scrollbars=yes,location=yes,menubar=no,resizable=yes,status=yes,toolbar=no"; window.open(url, windowName, windowOptions); //close the tab that was popped up $('#main-tab-bar').tabs('close', tabTitle);//find a way to use an id instead of title });//end handle tab popup //add the popup icon and link to a new tab //this is a hack, because I can't read the easyUI code, so can't tell how to add a button to the tab properly function addTabPopup(title) { var newTab = $('#main-tab-bar').tabs("getTab", title); //get the tab that was just added if (newTab.panel('options').closable) {//if this tab can be closed $('#main-tab-bar .tabs-header .tabs-wrap .tabs li .tabs-title').each(function() {//for all tabs in the main tabs if ($(this).text() == title) {//if this is the tab that was added $(this).parent().next().before('<a href="javascript:void(0)" class="tabs-popup"><\/a>');//add the popup link before the close link }//end if this is the tab that was added });//end for all tabs }//end if this tab can be closed }//end add the popup icon and link //add a tab to the main tab bar, load content by href (ajax) function addMainTabAjax(tabTitle, tabContent, tabIcon, tabClose){ //title of the tab, url for its content, what icon to show, whether to show the close button on the tab //find a way to set a unique id for the tab if ($('#main-tab-bar').tabs('exists', tabTitle)){//if the tab to add already exists (find a way to test by id, not title) $('#main-tab-bar').tabs('select', tabTitle);//go to that tab and select it (don't add it twice) }//end if the tab exists else {//else the tab does not already exist $('#main-tab-bar').tabs('add',{ //add the new tab title: tabTitle, //tab title href: tabContent, //url to load via ajax cache: true, //cache the content so the tab doesn't reload it every time this tab is selected closed: true, //close the tab: misnomer... for some reason the href was loaded twice. setting closed to true makes it only load once. the tab isn't really closed. http://www.jeasyui.com/forum/index.php?topic=29.0 iconCls: tabIcon, //tab icon closable: tabClose, //whether to show the close button on the tab selected: true //whether this tab should be selected after it is added });//end add the new tab }//end else the tab is new }//end add a tab to the main tab bar //get a property of a specific tab or of the entire tab group in the main tab bar function getTabProperty(prop, num) {//property to find, which tab (use selected tab if null) //usage: getTabProperty("title") or getTabProperty("title", 3) var selectedTab; //which tab to find the property for var tabs = $('#main-tab-bar').tabs('tabs'); //get array of all tabs if (num != undefined) {//if the tab # was sent in, use it selectedTab = tabs[num]; //get specific tab } else {//else use the currently selected tab selectedTab = $('#main-tab-bar').tabs('getSelected'); //get the currently selected tab } switch(prop) {//find the property //per tab properties case 'closable': return selectedTab.panel('options').closable; break;//return whether the tab can be closed case 'title': return selectedTab.panel('options').title; break; //return tab's title case 'icon': return selectedTab.panel('options').iconCls; break; //return tab's icon case 'content': return selectedTab.panel('options').content; break; //return tab's content case 'href': return selectedTab.panel('options').href; break; //return tab's href case 'index': //return the tab's number var tindex = 0; //start at first tab var tlength = $('#main-tab-bar').tabs('tabs').length; //number of tabs var ttitle = ""; //title of that tab for (tindex = 0; tindex < tlength; tindex++) {//for all tabs ttitle = tabs[tindex].panel('options').title; //get that tab's title if (ttitle == selectedTab.panel('options').title) {//if that tab's title = the selected tab's title return tindex; //return that index }//end if }//end for return null; //else return null if not found (although it should be) break; //global propties of tab group case 'width': return $('#main-tab-bar').tabs('options').width; break; //return tab container's width case 'height': return $('#main-tab-bar').tabs('options').height; break; //return tab container's height case 'plain': return $('#main-tab-bar').tabs('options').plain; break; //return tab container's plain case 'fit': return $('#main-tab-bar').tabs('options').fit; break; //return tab container's fit case 'border': return $('#main-tab-bar').tabs('options').border; break; //return tab container's border case 'scrollIncrement': return $('#main-tab-bar').tabs('options').scrollIncrement; break; //return tab container's scrollIncrement case 'scrollDuration': return $('#main-tab-bar').tabs('options').scrollDuration; break; //return tab container's scrollDuration case 'length': return $('#main-tab-bar').tabs('tabs').length; break; //return tab container's number of tabs default: return null; //else not found }//end find the property }//end get tab property ////////////////////////////////////////////////////////////////////////////////////// //TEST FOR COOKIES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ////////////////////////////////////////////////////////////////////////////////////// function checkCookies() {//check to see if cookies are enabled $.setCookie("MyTest", "testing if cookies are enabled", {expires: 1});//try to set a test cookie var myCookie = $.getCookie("MyTest"); //try to load the test cookie if (myCookie == null) {//if the test cookie was not found return false; //cookies aren't enabled }//end if the cookie was not found else {//else the test cookie was found $.removeCookie("MyTest"); //delete the test cookie return true; //cookies are enabled }//end else the test cookie was found }//end check to see if cookies are enabled ////////////////////////////////////////////////////////////////////////////////////// //SET UP PORTAL DEFAULTS/VARIABLES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ////////////////////////////////////////////////////////////////////////////////////// //the default values for the portal var wDefaults = {//this is an object containing portal default properties //each item holds all panels that can go in that portal //panel id, whether closed, whether collapsed, which column "testAPortal":{ "w001":{"wclosed":false,"wcollapsed":true,"pcol":0}, "w002":{"wclosed":false,"wcollapsed":true,"pcol":1}, "w003":{"wclosed":false,"wcollapsed":true,"pcol":2} }, "testBPortal":{ "w004":{"wclosed":false,"wcollapsed":true,"pcol":0}, "w005":{"wclosed":false,"wcollapsed":true,"pcol":1}, "w006":{"wclosed":false,"wcollapsed":true,"pcol":2} } } //end the default values for the portal //the current values for the portal var wCurrent = {}; //end the current values for the portal ////////////////////////////////////////////////////////////////////////////////////// //ADD THE PORTAL PANELS TO THE PAGE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ////////////////////////////////////////////////////////////////////////////////////// //set up the portal function initializePortal(pID){ //add portal functionality to the div with that pID $('#' + pID).portal(); //turn the three column portal area into a portal //load the portal settings to use into wCurrent if (checkCookies()) {//if cookies are enabled wCurrent = $.getCookie("MyPortal2-" + <%=session("UserIDInt")%>); //try to load the cookie values into the "current" portal object for this user's id if (wCurrent == null || wCurrent == "") {//if the cookie was not found //the user does not have any portal settings saved, so we will set them up with the defaults $.setCookie("MyPortal2-" + <%=session("UserIDInt")%>, wDefaults, {expires: 3650});//save the default portal values in the cookie for this user's id wCurrent = $.getCookie("MyPortal2-" + <%=session("UserIDInt")%>); //load the cookie values into the "current" portal object }//end if the cookie was not found }//end if cookies are enabled else {//else cookies are disabled wCurrent = wDefaults; //load the default panels into the "current" portal object $('#cookieError').css('display', 'block'); //show the error message }//end else cookies are disabled //now the portal settings to use are saved in wCurrent addPortalWidgets(pID); //add panels into the pID portal }//end set up the portal //dynamically add all panels to the portal function addPortalWidgets(pID){//add all panels to the pID portal var tid, tcol, tclosed, tcollapsed; //panel properties var colAlt = 0; //alternating column values $.each(wCurrent[pID], function(widgetID) {//for each panel in the pID portal tid = widgetID; //get its id tcol = wCurrent[pID][widgetID].pcol; //get which column it goes in tclosed = wCurrent[pID][widgetID].wclosed; //get whether it is closed tcollapsed = wCurrent[pID][widgetID].wcollapsed; //get whether it is collapsed addPortalWidget(pID, tid, tcol, tclosed, tcollapsed); //add that panel to the portal });//end for each panel in the pID portal //add: resize the portal to adjust its width }//end add all panels to the pID portal //dynamically add a single panel to the portal function addPortalWidget(pID, wID, cID, isClosed, isCollapsed){//add a single panel wID to the pID portal //portal id, panel id, which column, whether closed, whether collapsed //moves the panel from the staging area into the portal area specified and gives it these properties if ($("#" + wID).length) { //if the panel exists (if this user is allowed to see it) //determine whether to initially collapse it if (isCollapsed == false || isCollapsed == "false") {//if it is NOT supposed to be collapsed $("#" + wID).panel("expand");//expand it }//end if it is supposed to be collapsed else {//else if it IS supposed to be collapsed $("#" + wID).panel("collapse");//collapse it }//end determine whether to initially collapse it //determine whether to initially close it if (isClosed == true || isClosed == "true") {//if it is supposed to be closed $("#" + wID).panel("close");//close it }//end if it is supposed to be closed else {//else it is NOT supposed to be closed $("#" + wID).panel("open");//open it }//end determine whether to initially close it //add it to the portal at the bottom of the specified column //Note: panels are saved in the order they appear, so when we add them to the portal from the saved values, it automatically puts them back in the correct order $("#" + pID).portal('add', { panel: $("#" + wID), columnIndex: cID }); //this seems redundant, but adding a closed panel to the portal opens it, so we need to close it again if (isClosed == true || isClosed == "true") { //if the panel is closed $("#" + wID).panel("close");//close it }//end if the panel is closed }//end if the panel exists (if this user is allowed to see it) //else the panel was not allowed, so don't add it to the portal }//end add a single panel wID to the pID portal });//end on page load </script> Title: Re: Questions about Tabs Post by: stworthy on November 30, 2011, 12:33:01 AM 1) Another way to find and use a tab, users can pass the tab title or tab index. This feature will be supported in version 1.2.5.
2) In version 1.2.5, users can define mini tools on tabs. See the demo http://www.jeasyui.com/easyui/demo/tabs.html. 3) Place a portal to a tab panel, set 'fit' property to true for the portal is a good idea. Title: Re: Questions about Tabs Post by: tslatt on November 30, 2011, 08:16:51 AM Goodie! I wasn't aware that 1.2.5 was available yet! Where can it be downloaded? There is not a link on the downloads page: http://www.jeasyui.com/download/index.php
Title: Re: Questions about Tabs Post by: tslatt on December 01, 2011, 03:12:05 PM (1) The ability to access a tab by index is more helpful than by title (at least it's unique), but how do I know what its index is? The only way I know of to find the index is to loop through the tabs counting them, until the selected tab's title is found. But doing that still has the issue that I can't have tabs that share the same title. Can you provide any documentation or examples using the index?
(2) The new version totally solves this issue. Thank you sooo much! (3) Using fit:true on my portals within tabs does not help. It actually makes things worse. If I set fit:true, the portal does not show up at all, because I have the portal div inside another div that is inside the tab. Because of this, it sets a height of "0" on the portal div when I use fit. If I remove the div that I put around the portal and use fit, then the portal winds up wider than the tab, and I get a horizontal scrollbar. I think that my problems in issue #3 could actually be solved if there is way to solve issue #1. If I can set a unique id on the tab, then I can make sure that the correct portal is being initialized, instead of just trying to initialize the portal in the currently selected tab, when what's selected can change before that action is complete. Title: Re: Questions about Tabs Post by: stworthy on December 01, 2011, 08:13:03 PM For the portal issue, if the horizontal scrollbar is generate by tab panel, set the 'overflow:hidden' style for that tab panel:
<div id="tt" fit="true"> <div title="Title1"></div> <div title="Portal Title" style="overflow:hidden"> <div id="pp" style="position:relative"> </div> </div> You can try another way: when select the portal tab panel, call 'resize' method to reset the portal size: $('#tt').tabs({ onSelect:function(title){ if (title == 'Portal Title'){ $('#pp').portal('resize'); } } }); Title: Re: Questions about Tabs Post by: tslatt on December 06, 2011, 03:53:28 PM I found a solution (hack) to using titles instead of unique ids. I include a unique identifier within the tab title surrounded by a <strong> tag that has a style of display: none.
Example Titles: "John Smith<strong>ID0123456<\/strong>" and "John Smith<strong>ID7890123<\/strong>". The css: .tabs li a.tabs-inner strong { display: none; } Title: Re: Questions about Tabs Post by: tslatt on December 19, 2011, 09:21:45 AM It turns out that the problem with issue #3 is due to the calculations that are made when the portal is initialized. If the tab that the portal is in is NOT the currently selected tab, then that means that its tab is hidden. And, because its tab is hidden, when the portal initialization tries to build the table that holds the portal, it calculates the widths of everything incorrectly.
This is discussed more in another forum post: http://www.jeasyui.com/forum/index.php?topic=253.0 (http://www.jeasyui.com/forum/index.php?topic=253.0) Title: Re: Questions about Tabs Post by: ellisgl on April 05, 2012, 08:39:05 PM I'm surprised to see that tab operation based on ID hasn't been coded. I see that 1.2.6 is in the works via the SVN. I'll see if I have any time next week to look at updating my code to work with it.
Title: Re: Questions about Tabs Post by: ellisgl on April 05, 2012, 08:43:28 PM Well, he's not putting out the un mangled source on the SVN anymore... =/
Title: Re: Questions about Tabs Post by: stworthy on April 06, 2012, 08:32:56 PM The way to find tab is unique. We can find specify tab object even though the tab title is duplicate. Extend and implement a new find method is a good idea. Below code is the implementation of a find method that can find tab object via its property:
Code: $.fn.tabs.methods.getTabByProperty = function(jq, param){ var tabs = jq.tabs('tabs'); for(var i=0; i<tabs.length; i++){ var tab = tabs[i]; if (tab.panel('options')[param.prop] == param.value){ return tab; } } return null; } When add a new tab panel, we can add some usefully unique properties that help us to find that panel: Code: var index = 0; $('#tt').tabs('add',{ title:'...', closable:true, mydata:'tab-'+(++index), // add customized property //... }); On above code we add new tab panel that including a customized property named 'mydata'. Now we can call 'getTabByProperty' method to find our tab panel: Code: var tab = $('#tt').tabs('getTabByProperty', { prop: 'mydata', value: 'tab-1' }); var index = $('#tt').tabs('getTabIndex', tab); // get tab index May be finding by tab id is more usefully. Download a fixed panel plugin from http://www.jeasyui.com/easyui/plugins/jquery.panel.js can solve this issue. Code: $('#tt').tabs('add',{ id:'tab-1', // assign an id property title:'...', //... }); var index = $('#tt').tabs('getTabIndex', $('#tab-1')); // get tab index |