EasyUI Forum
October 13, 2024, 07:22:12 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News:
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Questions about Tabs  (Read 67662 times)
tslatt
Jr. Member
**
Posts: 85



View Profile
« 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>
Logged
stworthy
Administrator
Hero Member
*****
Posts: 3581


View Profile Email
« Reply #1 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.
Logged
tslatt
Jr. Member
**
Posts: 85



View Profile
« Reply #2 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
Logged
tslatt
Jr. Member
**
Posts: 85



View Profile
« Reply #3 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.
Logged
stworthy
Administrator
Hero Member
*****
Posts: 3581


View Profile Email
« Reply #4 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');
      }
   }
});
Logged
tslatt
Jr. Member
**
Posts: 85



View Profile
« Reply #5 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; }
Logged
tslatt
Jr. Member
**
Posts: 85



View Profile
« Reply #6 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
Logged
ellisgl
Newbie
*
Posts: 15


View Profile
« Reply #7 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.
Logged
ellisgl
Newbie
*
Posts: 15


View Profile
« Reply #8 on: April 05, 2012, 08:43:28 PM »

Well, he's not putting out the un mangled source on the SVN anymore... =/
Logged
stworthy
Administrator
Hero Member
*****
Posts: 3581


View Profile Email
« Reply #9 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
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines Valid XHTML 1.0! Valid CSS!