- completed the fix of the user object history (Trac #48)

- completed the implementation of truncated lists (Trac #61)
- Fixed the handling of the search form in the details page (Trac #29)

SVN:trunk[214]
This commit is contained in:
Denis Flaven
2009-12-29 14:02:18 +00:00
parent e91b81c777
commit cc4219714a
12 changed files with 139 additions and 20 deletions

View File

@@ -131,7 +131,7 @@ abstract class cmdbAbstractObject extends CMDBObject
$oPage->add("<h1>".MetaModel::GetName(get_class($this)).": <span class=\"hilite\">".$this->GetDisplayName()."</span></h1>\n");
// history block (with toggle)
$oHistoryFilter = new DBObjectSearch('CMDBChangeOpSetAttribute');
$oHistoryFilter = new DBObjectSearch('CMDBChangeOp');
$oHistoryFilter->AddCondition('objkey', $this->GetKey());
$oHistoryFilter->AddCondition('objclass', get_class($this));
$oBlock = new HistoryBlock($oHistoryFilter, 'toggle', false);
@@ -269,6 +269,8 @@ abstract class cmdbAbstractObject extends CMDBObject
//public static function GetDisplaySet(web_page $oPage, CMDBObjectSet $oSet, $sLinkageAttribute = '', $bDisplayMenu = true, $bSelectMode = false)
public static function GetDisplaySet(web_page $oPage, CMDBObjectSet $oSet, $aExtraParams = array())
{
global $g_oConfig;
static $iListId = 0;
$iListId++;
@@ -341,7 +343,16 @@ abstract class cmdbAbstractObject extends CMDBObject
}
$aValues = array();
$oSet->Seek(0);
while ($oObj = $oSet->Fetch())
$bDisplayLimit = isset($aExtraParams['display_limit']) ? $aExtraParams['display_limit'] : true;
$iMaxObjects = -1;
if ($bDisplayLimit)
{
if ($oSet->Count() > $g_oConfig->GetMaxDisplayLimit())
{
$iMaxObjects = $g_oConfig->GetMinDisplayLimit();
}
}
while (($oObj = $oSet->Fetch()) && ($iMaxObjects != 0))
{
$aRow['key'] = $oObj->GetKey();
if ($bSelectMode)
@@ -354,6 +365,7 @@ abstract class cmdbAbstractObject extends CMDBObject
$aRow[$sAttCode] = $oObj->GetAsHTML($sAttCode);
}
$aValues[] = $aRow;
$iMaxObjects--;
}
$oMenuBlock = new MenuBlock($oSet->GetFilter());
$sHtml .= '<table class="listContainer">';
@@ -367,7 +379,22 @@ abstract class cmdbAbstractObject extends CMDBObject
//$aMenuExtraParams['linkage'] = $sLinkageAttribute;
$aMenuExtraParams = $aExtraParams;
}
$sHtml .= '<tr class="containerHeader"><td>&nbsp;'.$oSet->Count().' object(s)</td><td>';
if ($bDisplayLimit && ($oSet->Count() > $g_oConfig->GetMaxDisplayLimit()))
{
// list truncated
$divId = $aExtraParams['block_id'];
$sFilter = $oSet->GetFilter()->serialize();
$aExtraParams['display_limit'] = false; // To expand the full list
$sExtraParams = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
$sHtml .= '<tr class="containerHeader"><td>'.$g_oConfig->GetMinDisplayLimit().' object(s) displayed out of '.$oSet->Count().'&nbsp;&nbsp;<a href="Javascript:ReloadTruncatedList(\''.$divId.'\', \''.$sFilter.'\', \''.$sExtraParams.'\');">Display All</a></td><td>';
$oPage->add_ready_script("$('#{$divId} table.listResults').addClass('truncated');");
$oPage->add_ready_script("$('#{$divId} table.listResults tr:last td').addClass('truncated');");
}
else
{
// Full list
$sHtml .= '<tr class="containerHeader"><td>&nbsp;'.$oSet->Count().' object(s)</td><td>';
}
$sHtml .= $oMenuBlock->GetRenderContent($oPage, $aMenuExtraParams);
$sHtml .= '</td></tr>';
}
@@ -570,9 +597,11 @@ abstract class cmdbAbstractObject extends CMDBObject
$sHtml .= "</table>\n";
foreach($aExtraParams as $sName => $sValue)
{
$sHtml .= "<input type=\"hidden\" name=\"$sName\" value=\"$sValue\">\n";
$sHtml .= "<input type=\"hidden\" name=\"$sName\" value=\"$sValue\" />\n";
}
$sHtml .= "<input type=\"hidden\" name=\"dosearch\" value=\"1\">\n";
$sHtml .= "<input type=\"hidden\" name=\"class\" value=\"$sClassName\" />\n";
$sHtml .= "<input type=\"hidden\" name=\"dosearch\" value=\"1\" />\n";
$sHtml .= "<input type=\"hidden\" name=\"operation\" value=\"search_form\" />\n";
$sHtml .= "</form>\n";
$sHtml .= "</div><!-- Simple search form -->\n";
@@ -598,7 +627,7 @@ abstract class cmdbAbstractObject extends CMDBObject
{
$sHtml .= "<input type=\"hidden\" name=\"$sName\" value=\"$sValue\" />\n";
}
$sHtml .= "<input type=\"hidden\" name=\"operation\" value=\"search_form\" />\n";
$sHtml .= "<input type=\"hidden\" name=\"operation\" value=\"search_oql\" />\n";
$sHtml .= "</table></form>\n";
$sHtml .= "</div><!-- OQL query form -->\n";
return $sHtml;

View File

@@ -144,7 +144,10 @@ class DisplayBlock
public function Display(web_page $oPage, $sId, $aExtraParams = array())
{
$oPage->add($this->GetDisplay($oPage, $sId, $aExtraParams));
/*
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
$aExtraParams['block_id'] = $sId;
if (!$this->m_bAsynchronous)
{
// render now
@@ -171,12 +174,14 @@ class DisplayBlock
);
</script>'); // TO DO: add support for $aExtraParams in asynchronous/Ajax mode
}
*/
}
public function GetDisplay(web_page $oPage, $sId, $aExtraParams = array())
{
$sHtml = '';
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
$aExtraParams['block_id'] = $sId;
if (!$this->m_bAsynchronous)
{
// render now
@@ -188,17 +193,19 @@ class DisplayBlock
{
// render it as an Ajax (asynchronous) call
$sFilter = $this->m_oFilter->serialize();
$sExtraParams = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
$sHtml .= "<div id=\"$sId\" class=\"display_block loading\">\n";
$sHtml .= $oPage->GetP("<img src=\"../images/indicator_arrows.gif\"> Loading...");
$sHtml .= "</div>\n";
$sHtml .= '
<script language="javascript">
$.get("ajax.render.php?filter='.$sFilter.'&style='.$this->m_sStyle.'",
{ operation: "ajax" },
{ operation: "ajax", extra_params: "'.$sExtraParams.'" },
function(data){
$("#'.$sId.'").empty();
$("#'.$sId.'").append(data);
$("#'.$sId.'").removeClass("loading");
$("#'.$sId.' .listResults").tablesorter( { headers: { 0:{sorter: false }}, widgets: [\'zebra\']} ); // sortable and zebra tables
}
);
</script>'; // TO DO: add support for $aExtraParams in asynchronous/Ajax mode

View File

@@ -35,6 +35,7 @@ class iTopWebPage extends nice_web_page
$this->add_linked_script("../js/date.js");
$this->add_linked_script("../js/jquery.date.picker.js");
$this->add_linked_script("../js/jquery.tablesorter.min.js");
$this->add_linked_script("../js/utils.js");
//$this->add_linked_script("../js/jquery-ui-personalized-1.5.3.js");
$this->add_linked_script("../js/swfobject.js");
$this->add_linked_stylesheet("../css/jquery.treeview.css");

View File

@@ -2,6 +2,8 @@
require_once('../application/utils.inc.php');
$g_oConfig = new Config('../config-itop.php');
MetaModel::Startup('../config-itop.php');
?>

View File

@@ -159,6 +159,7 @@ class UILinksWizard
{
$('#SearchResultsToAdd table.listResults tbody').attr('height', tbodyHeight);
$('#SearchResultsToAdd .listResults tbody').css('overflow', 'auto');
$('#SearchResultsToAdd .listResults').tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
}
}
@@ -214,7 +215,7 @@ class UILinksWizard
}
$('.listResults tbody').append(data);
$('.listResults').trigger('update');
$('.listResults').tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
$('.listResults').tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
},
'html'
);
@@ -362,12 +363,12 @@ class UILinksWizard
public function SearchObjectsToAdd(web_page $oP, UserContext $oContext)
{
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
//$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
$oFilter = $oContext->NewFilter($this->m_sLinkedClass);
$oSet = new CMDBObjectSet($oFilter);
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock->Display($oP, 'ResultsToAdd', array('menu' => false, 'selection_mode' => true)); // Don't display the 'Actions' menu on the results
$oBlock->Display($oP, 'ResultsToAdd', array('menu' => false, 'selection_mode' => true, 'display_limit' => false)); // Don't display the 'Actions' menu on the results
}
public function DoAddObjects(web_page $oP, UserContext $oContext, $aLinkedObjectIds = array())

View File

@@ -663,3 +663,24 @@ div.HRDrawer {
.mandatory {
border: 1px solid #f00;
}
table.listResults tr td.truncated {
background: transparent;
}
table.listResults tr td.truncated {
background: url(../images/truncated.png) bottom repeat-x;
margin-bottom: -3px;
}
table.listResults tr.even td.truncated {
background: #f9f9f1 url(../images/truncated.png) bottom repeat-x;
}
table.listResults tr.even td.truncated.hover {
background: #E8FFD3 url(../images/truncated.png) bottom repeat-x;
}
table.listResults.truncated {
border-bottom: 0;
padding-bottom: 0;
}

19
js/utils.js Normal file
View File

@@ -0,0 +1,19 @@
// Some general purpose JS functions for the iTop application
/**
* Reload a truncated list
*/
function ReloadTruncatedList(divId, sSerializedFilter, sExtraParams)
{
$('#'+divId).addClass('loading');
//$('#'+divId).blockUI();
$.get('ajax.render.php?filter='+sSerializedFilter+'&style=list',
{ operation: 'ajax', extra_params: sExtraParams },
function(data){
$('#'+divId).empty();
$('#'+divId).append(data);
$('#'+divId).removeClass('loading');
$('#'+divId+' .listResults').tablesorter( { headers: { 0:{sorter: false }}, widgets: ['zebra']} ); // sortable and zebra tables
//$('#'+divId).unblockUI();
}
);
}

View File

@@ -74,7 +74,7 @@ switch($operation)
}
break;
case 'search_form':
case 'search_oql':
$sOQLClass = utils::ReadParam('oql_class', '');
$sOQLClause = utils::ReadParam('oql_clause', '');
$sFormat = utils::ReadParam('format', '');
@@ -128,7 +128,39 @@ switch($operation)
}
}
break;
case 'search_form':
$sClass = utils::ReadParam('class', '');
$sFormat = utils::ReadParam('format', 'html');
$bSearchForm = utils::ReadParam('search_form', true);
if (empty($sClass))
{
$oP->set_title("iTop - Error");
$oP->add("<p>'class' must be specifed for this operation.</p>\n");
}
else
{
$oP->set_title("iTop - Search results");
$oFilter = $oContext->NewFilter($sClass);
$oSet = new DBObjectSet($oFilter);
if ($bSearchForm)
{
$oBlock = new DisplayBlock($oFilter, 'search', false /* Asynchronous */, array('open' => true));
$oBlock->Display($oP, 0);
}
if (strtolower($sFormat) == 'csv')
{
$oBlock = new DisplayBlock($oFilter, 'csv', false);
$oBlock->Display($oP, 1);
$oP->add_ready_script(" $('#csv').css('height', '95%');"); // adjust the size of the block
}
else
{
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock->Display($oP, 1);
}
}
break;
case 'search':
$sFilter = utils::ReadParam('filter', '');
$sFormat = utils::ReadParam('format', '');
@@ -158,7 +190,7 @@ switch($operation)
else
{
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock->Display($oP, 0);
$oBlock->Display($oP, 1);
}
}
break;
@@ -173,6 +205,7 @@ switch($operation)
{
$oP->p("<h2>Results for '$sFullText':</h2>\n");
$iCount = 0;
$iBlock = 0;
// Search in full text mode in all the classes
foreach(MetaModel::GetClasses('bizmodel') as $sClassName)
{
@@ -198,7 +231,7 @@ switch($operation)
$oP->add("</div>\n");
$oLeafsFilter->AddCondition('pkey', $aLeafs, 'IN');
$oBlock = new DisplayBlock($oLeafsFilter, 'list', false);
$oBlock->Display($oP, 0);
$oBlock->Display($oP, $iBlock++);
}
}
}

View File

@@ -73,11 +73,11 @@ if ($oFilter != null)
{
$oSet = new CMDBObjectSet($oFilter);
$oBlock = new DisplayBlock($oFilter, 'search', false);
$oBlock->Display($oP, 0);
$oBlock->Display($oP, 0, array('open' => true));
// Search results
$oResultBlock = new DisplayBlock($oFilter, 'list', false);
$oResultBlock->RenderContent($oP);
$oResultBlock->Display($oP, 1);
// Menu node
$sFilter = $oFilter->ToOQL();

View File

@@ -100,6 +100,12 @@ switch($operation)
case 'ajax':
if ($sFilter != "")
{
$sExtraParams = stripslashes(utils::ReadParam('extra_params', ''));
$aExtraParams = array();
if (!empty($sExtraParams))
{
$aExtraParams = json_decode(str_replace("'", '"', $sExtraParams), true /* associative array */);
}
if ($sEncoding == 'sibusql')
{
$oFilter = CMDBSearchFilter::FromSibusQL($sFilter);
@@ -109,7 +115,7 @@ switch($operation)
$oFilter = CMDBSearchFilter::unserialize($sFilter);
}
$oDisplayBlock = new DisplayBlock($oFilter, $sStyle, false);
$oDisplayBlock->RenderContent($oPage);
$oDisplayBlock->RenderContent($oPage, $aExtraParams);
}
else
{

View File

@@ -109,8 +109,8 @@ try
{
$oP->add("<h3>Query results</h3>\n");
$oSet = new CMDBObjectSet($oFilter);
cmdbAbstractObject::DisplaySet($oP, $oSet);
$oResultBlock = new DisplayBlock($oFilter, 'list', false);
$oResultBlock->Display($oP, 1);
$oP->p('');
$oP->StartCollapsibleSection('More info on the query', false);

View File

@@ -47,7 +47,7 @@ if (!empty($sExpression))
}
$sUrl = "$sProtocol://{$sServerName}{$sPort}/pages/";
$oP->set_base($sUrl);
cmdbAbstractObject::DisplaySet($oP, $oSet, array('menu' => false));
cmdbAbstractObject::DisplaySet($oP, $oSet, array('menu' => false, 'display_limit' => false)); // no menu, no truncated list
break;
case 'csv':