diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 47cd5a8e9..dc4e66cd3 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -240,7 +240,7 @@ abstract class cmdbAbstractObject extends CMDBObject 'object_id' => $this->GetKey(), 'target_attr' => $oAttDef->GetExtKeyToRemote(), 'view_link' => false, - 'menu' => false, + 'menu' => true, 'display_limit' => true, // By default limit the list to speed up the initial load & display ); } @@ -393,6 +393,7 @@ abstract class cmdbAbstractObject extends CMDBObject } } $bDisplayMenu = isset($aExtraParams['menu']) ? $aExtraParams['menu'] == true : true; + $bTruncated = isset($aExtraParams['truncated']) ? $aExtraParams['truncated'] == true : true; $bSelectMode = isset($aExtraParams['selection_mode']) ? $aExtraParams['selection_mode'] == true : false; $bSingleSelectMode = isset($aExtraParams['selection_type']) ? ($aExtraParams['selection_type'] == 'single') : false; $aExtraFields = isset($aExtraParams['extra_fields']) ? explode(',', trim($aExtraParams['extra_fields'])) : array(); @@ -460,7 +461,7 @@ abstract class cmdbAbstractObject extends CMDBObject $aValues = array(); $bDisplayLimit = isset($aExtraParams['display_limit']) ? $aExtraParams['display_limit'] : true; $iMaxObjects = -1; - if ($bDisplayLimit) + if ($bDisplayLimit && $bTruncated) { if ($oSet->Count() > utils::GetConfig()->GetMaxDisplayLimit()) { @@ -501,26 +502,67 @@ abstract class cmdbAbstractObject extends CMDBObject } $sHtml .= '
| '.Dict::Format('UI:TruncatedResults', utils::GetConfig()->GetMinDisplayLimit(), $oSet->Count()).' '.Dict::S('UI:DisplayAll').' | '; - $oPage->add_ready_script("$('#{$divId} table.listResults').addClass('truncated');"); - $oPage->add_ready_script("$('#{$divId} table.listResults tr:last td').addClass('truncated');"); + $aExtraParams['display_limit'] = true; + $sHtml .= ' | |||
| '.$sCollapsedLabel.' '.$sLinkLabel.' | ';
+ $oPage->add_ready_script(
+<<| '.Dict::Format('UI:CountOfResults', $oSet->Count()).''.Dict::S('UI:CollapseList').' | ';
+ }
+ $aExtraParams['truncated'] = false; // To expand the full list when clicked
+ $sExtraParamsExpand = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
+ $oPage->add_ready_script(
+<< | ';
+ state[ this.id ] = 'close';
}
+ $.bbq.pushState( state );
+ $(this).trigger(state[this.id]);
+ });
+
+ $('#trc_$divId').bind('open', function()
+ {
+ ReloadTruncatedList('$divId', '$sFilter', '$sExtraParamsExpand');
+ });
+
+ $('#trc_$divId').bind('close', function()
+ {
+ TruncateList('$divId', $iMinDisplayLimit, '$sCollapsedLabel', '$sLinkLabel');
+ });
+EOF
+);
if ($bDisplayMenu)
{
$oMenuBlock = new MenuBlock($oSet->GetFilter());
diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php
index 18d656f07..396443134 100644
--- a/application/itopwebpage.class.inc.php
+++ b/application/itopwebpage.class.inc.php
@@ -53,7 +53,7 @@ class iTopWebPage extends NiceWebPage
$this->add_linked_stylesheet("../css/jquery.autocomplete.css");
// $this->add_linked_stylesheet("../css/date.picker.css");
$this->add_linked_script('../js/jquery.layout.min.js');
- $this->add_linked_script('../js/jquery.history.js');
+ $this->add_linked_script('../js/jquery.ba-bbq.min.js');
// $this->add_linked_script("../js/jquery.dimensions.js");
$this->add_linked_script("../js/jquery.tablehover.js");
$this->add_linked_script("../js/jquery.treeview.js");
@@ -148,12 +148,73 @@ class iTopWebPage extends NiceWebPage
$("tbody tr.orange:even",table).removeClass('orange').removeClass('even').addClass('orange_even');
$("tbody tr.green:even",table).removeClass('green').removeClass('even').addClass('green_even');
}
- });
+ });
- // tabs
- $("div[id^=tabbedContent]").tabs( { show: function(event, ui) {
- window.location.href = ui.tab.href; // So that history can keep track of the tabs
- } });
+ // Tabs, using JQuery BBQ to store the history
+ // The "tab widgets" to handle.
+ var tabs = $('div[id^=tabbedContent]');
+
+ // This selector will be reused when selecting actual tab widget A elements.
+ var tab_a_selector = 'ul.ui-tabs-nav a';
+
+ // Enable tabs on all tab widgets. The `event` property must be overridden so
+ // that the tabs aren't changed on click, and any custom event name can be
+ // specified. Note that if you define a callback for the 'select' event, it
+ // will be executed for the selected tab whenever the hash changes.
+ tabs.tabs({ event: 'change' });
+
+ // Define our own click handler for the tabs, overriding the default.
+ tabs.find( tab_a_selector ).click(function()
+ {
+ var state = {};
+
+ // Get the id of this tab widget.
+ var id = $(this).closest( 'div[id^=tabbedContent]' ).attr( 'id' );
+
+ // Get the index of this tab.
+ var idx = $(this).parent().prevAll().length;
+
+ // Set the state!
+ state[ id ] = idx;
+ $.bbq.pushState( state );
+ });
+
+ // Bind an event to window.onhashchange that, when the history state changes,
+ // iterates over all tab widgets, changing the current tab as necessary.
+ $(window).bind( 'hashchange', function(e)
+ {
+ // Iterate over all tab widgets.
+ tabs.each(function()
+ {
+ // Get the index for this tab widget from the hash, based on the
+ // appropriate id property. In jQuery 1.4, you should use e.getState()
+ // instead of $.bbq.getState(). The second, 'true' argument coerces the
+ // string value to a number.
+ var idx = $.bbq.getState( this.id, true ) || 0;
+
+ // Select the appropriate tab for this tab widget by triggering the custom
+ // event specified in the .tabs() init above (you could keep track of what
+ // tab each widget is on using .data, and only select a tab if it has
+ // changed).
+ $(this).find( tab_a_selector ).eq( idx ).triggerHandler( 'change' );
+ });
+
+ // Iterate over all truncated lists to find whether they are expanded or not
+ $('a.truncated').each(function()
+ {
+ var state = $.bbq.getState( this.id, true ) || 'close';
+ if (state == 'open')
+ {
+ $(this).trigger('open');
+ }
+ else
+ {
+ $(this).trigger('close');
+ }
+ });
+ });
+
+ // End of Tabs handling
$("table.listResults").tableHover(); // hover tables
$(".listResults").tablesorter( { headers: { 0:{sorter: false }}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables
$(".date-pick").datepicker({
@@ -170,12 +231,12 @@ class iTopWebPage extends NiceWebPage
$('#ModalDlg').dialog({ autoOpen: false, modal: true, width: 0.8*docWidth }); // JQuery UI dialogs
ShowDebug();
$('#logOffBtn>ul').popupmenu();
- $.history.init(history_callback);
- $("a[rel='history']").click(function()
- {
- $.history.load(this.href.replace(/^.*#/, ''));
- return false;
- });
+// $.history.init(history_callback);
+// $("a[rel='history']").click(function()
+// {
+// $.history.load(this.href.replace(/^.*#/, ''));
+// return false;
+// });
}
catch(err)
{
@@ -189,17 +250,17 @@ EOF
$sUserPrefs = appUserPreferences::GetAsJSON();
$this->add_script(
<< | |