diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 3f2e08c79..111b870a6 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -560,8 +560,15 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay $sClassName = $oSet->GetFilter()->GetClass(); $aAttribs = array(); $sZListName = isset($aExtraParams['zlist']) ? ($aExtraParams['zlist']) : 'list'; - $aList = self::FlattenZList(MetaModel::GetZListItems($sClassName, $sZListName)); - $aList = array_merge($aList, $aExtraFields); + if ($sZListName !== false) + { + $aList = self::FlattenZList(MetaModel::GetZListItems($sClassName, $sZListName)); + $aList = array_merge($aList, $aExtraFields); + } + else + { + $aList = $aExtraFields; + } // Filter the list to removed linked set since we are not able to display them here foreach($aList as $index => $sAttCode) @@ -616,7 +623,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay { if (!$bSingleSelectMode) { - $aAttribs['form::select'] = array('label' => "", 'description' => Dict::S('UI:SelectAllToggle+')); + $aAttribs['form::select'] = array('label' => "", 'description' => Dict::S('UI:SelectAllToggle+')); } else { @@ -634,14 +641,14 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay $aValues = array(); $bDisplayLimit = isset($aExtraParams['display_limit']) ? $aExtraParams['display_limit'] : true; $iMaxObjects = -1; - if ($bDisplayLimit && $bTruncated) - { + //if ($bDisplayLimit && $bTruncated) + //{ if ($oSet->Count() > MetaModel::GetConfig()->GetMaxDisplayLimit()) { $iMaxObjects = MetaModel::GetConfig()->GetMinDisplayLimit(); $oSet->SetLimit($iMaxObjects); } - } + //} $oSet->Seek(0); while (($oObj = $oSet->Fetch()) && ($iMaxObjects != 0)) { @@ -699,58 +706,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay { $aExtraParams['query_params'][$sName] = $sValue; } - if ($bDisplayLimit && $bTruncated && ($oSet->Count() > MetaModel::GetConfig()->GetMaxDisplayLimit())) - { - // list truncated - $aExtraParams['display_limit'] = true; - $sHtml .= ''.$sCollapsedLabel.'  '.$sLinkLabel.''; - $oPage->add_ready_script( -<<Count() > MetaModel::GetConfig()->GetMaxDisplayLimit())) - { - // Collapsible list - $aExtraParams['display_limit'] = true; - $sHtml .= ''.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( -<<GetFilter()); @@ -768,6 +724,80 @@ EOF $sHtml .= $oPage->GetTable($aAttribs, $aValues); $sHtml .= ''; $sHtml .= ''; + if ($oSet->Count() > MetaModel::GetConfig()->GetMaxDisplayLimit()) + { + $iCount = $oSet->Count(); +$sHtml = +<< +

0 items.   item(s) selected.

+

+ + + + + + + +
Pages: + items per page. 
+ + + +EOF +.$sHtml; + //$oP->add_ready_script("table.tablesorter( { headers: { 0: {sorter: false}}, widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $('#pager')});\n"); + $sExtraParams = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them + $sSelectMode = ''; + $sHeaders = ''; + if ($bSelectMode) + { + $sSelectMode = $bSingleSelectMode ? 'single' : 'multiple'; + $sHeaders = 'headers: { 0: {sorter: false}},'; + } + $sDisplayKey = ($bViewLink) ? 'true' : 'false'; + $sDisplayList = json_encode($aList); + $sCssCount = isset($aExtraParams['cssCount']) ? ", cssCount: '{$aExtraParams['cssCount']}'" : ''; + $oPage->add_ready_script("$('#{$iListId} table.listResults').tablesorter( { $sHeaders widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $('#pager{$iListId}'), totalRows:$iCount, filter: '$sFilter', extra_params: '$sExtraParams', select_mode: '$sSelectMode', displayKey: $sDisplayKey, displayList: $sDisplayList $sCssCount});\n"); + } + else + { + $sHeaders = ''; + if ($bSelectMode) + { + $sHeaders = 'headers: { 0: {sorter: false}},'; + } + $oPage->add_ready_script("$('#{$iListId} table.listResults').tablesorter( { $sHeaders widgets: ['myZebra', 'truncatedList']} );\n"); + // Manage how we update the 'Ok/Add' buttons that depend on the number of selected items + if (isset($aExtraParams['cssCount'])) + { + $sCssCount = $aExtraParams['cssCount']; + if ($bSingleSelectMode) + { + $sSelectSelector = ":radio[name^=selectObj]"; + } + else + { + $sSelectSelector = ":checkbox[name^=selectObj]"; + } + $oPage->add_ready_script( +<<add_linked_script("../js/ckeditor/ckeditor.js"); $this->add_linked_script("../js/ckeditor/adapters/jquery.js"); $this->add_linked_script("../js/jquery.qtip-1.0.min.js"); + $this->add_linked_script("../js/jquery.tablesorter.pager.js"); $this->m_sInitScript = <<< EOF try @@ -289,23 +290,6 @@ EOF // End of Tabs handling $("table.listResults").tableHover(); // hover tables - // Check each 'listResults' table for a checkbox in the first column and make the first column sortable only if it does not contain a checkbox in the header - $(".listResults").each( function() - { - var table = $(this); - var id = $(this).parent(); - var checkbox = (table.find('th:first :checkbox').length > 0); - if (checkbox) - { - // There is a checkbox in the first column, don't make it sortable - table.tablesorter( { headers: { 0: {sorter: false}}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables - } - else - { - // There is NO checkbox in the first column, all columns are considered sortable - table.tablesorter( { widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables - } - }); $(".date-pick").datepicker({ showOn: 'button', buttonImage: '../images/calendar.png', @@ -368,10 +352,6 @@ EOF // } // } - function formatItem(row) { - return row[0]; - } - function goBack() { window.history.back(); diff --git a/application/ui.extkeywidget.class.inc.php b/application/ui.extkeywidget.class.inc.php index 2d7c2ff03..b05dded8b 100644 --- a/application/ui.extkeywidget.class.inc.php +++ b/application/ui.extkeywidget.class.inc.php @@ -233,6 +233,7 @@ EOF $sHTML .= "\n"; $sHTML .= "iId}\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#ac_dlg_{$this->iId}').dialog('close');\">  "; $sHTML .= "iId}\" value=\"".Dict::S('UI:Button:Ok')."\" onClick=\"oACWidget_{$this->iId}.DoOk();\">"; + $sHTML .= "iId}\" value=\"0\">"; $sHTML .= "\n"; $sHTML .= ''; @@ -263,7 +264,7 @@ EOF { $oFilter = DBObjectSearch::FromOQL($sFilter); $oBlock = new DisplayBlock($oFilter, 'list', false); - $oBlock->Display($oP, $this->iId, array('this' => $oObj, 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'display_limit' => false)); // Don't display the 'Actions' menu on the results + $oBlock->Display($oP, $this->iId.'_results', array('this' => $oObj, 'cssCount'=> '#count_'.$this->iId, 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'display_limit' => false)); // Don't display the 'Actions' menu on the results } catch(MissingQueryArgument $e) { @@ -272,7 +273,7 @@ EOF $sOQL = 'SELECT '.$sRemoteClass; $oFilter = DBObjectSearch::FromOQL($sOQL); $oBlock = new DisplayBlock($oFilter, 'list', false); - $oBlock->Display($oP, $this->iId, array('menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'display_limit' => false)); // Don't display the 'Actions' menu on the results + $oBlock->Display($oP, $this->iId.'_results', array('cssCount'=> '#count_'.$this->iId, 'menu' => false, 'selection_mode' => true, 'selection_type' => 'single', 'display_limit' => false)); // Don't display the 'Actions' menu on the results } } diff --git a/application/ui.linkswidget.class.inc.php b/application/ui.linkswidget.class.inc.php index 69a367e65..3d722a72b 100644 --- a/application/ui.linkswidget.class.inc.php +++ b/application/ui.linkswidget.class.inc.php @@ -270,7 +270,8 @@ EOF $sHtml .= "

m_sAttCode}{$this->m_sNameSuffix}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n"; $sHtml .= "

".Dict::S('UI:Message:EmptyList:UseSearchForm')."

\n"; $sHtml .= "
\n"; - $sHtml .= "m_sAttCode}{$this->m_sNameSuffix}').dialog('close');\">  "; + $sHtml .= "m_sAttCode}{$this->m_sNameSuffix}\" value=\"0\"/>"; + $sHtml .= "m_sAttCode}{$this->m_sNameSuffix}').dialog('close');\">  m_sAttCode}{$this->m_sNameSuffix}\" type=\"submit\" value=\"".Dict::S('UI:Button:Add')."\">"; $sHtml .= "\n"; $sHtml .= "\n"; $sHtml .= "\n"; @@ -332,12 +333,23 @@ EOF } $oSet = new CMDBObjectSet($oFilter); $oBlock = new DisplayBlock($oFilter, 'list', false); - $oBlock->Display($oP, 'ResultsToAdd', array('menu' => false, 'selection_mode' => true, 'display_limit' => false)); // Don't display the 'Actions' menu on the results + $oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", array('menu' => false, 'cssCount'=> '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true, 'display_limit' => false)); // Don't display the 'Actions' menu on the results } - public function DoAddObjects(WebPage $oP, $aLinkedObjectIds = array()) + public function DoAddObjects(WebPage $oP, $sRemoteClass) { - $aTable = array(); + if ($sRemoteClass != '') + { + // assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass)); + $oFullSetFilter = new DBObjectSearch($sRemoteClass); + } + else + { + // No remote class specified use the one defined in the linkedset + $oFullSetFilter = new DBObjectSearch($this->m_sRemoteClass); + } + $aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter); + foreach($aLinkedObjectIds as $iObjectId) { $oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId); diff --git a/application/utils.inc.php b/application/utils.inc.php index 2c89efb1a..a75f238a6 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -217,6 +217,43 @@ class utils return $oDocument; } + /** + * Interprets the results posted by a normal or paginated list (in multiple selection mode) + * @param $oFullSetFilter DBObjectSearch The criteria defining the whole sets of objects being selected + * @return Array An arry of object IDs corresponding to the objects selected in the set + */ + public static function ReadMultipleSelection($oFullSetFilter) + { + $aSelectedObj = utils::ReadParam('selectObject', array()); + $sSelectionMode = utils::ReadParam('selectionMode', ''); + if ($sSelectionMode != '') + { + // Paginated selection + $aExceptions = utils::ReadParam('storedSelection', array()); + if ($sSelectionMode == 'positive') + { + // Only the explicitely listed items are selected + $aSelectedObj = $aExceptions; + } + else + { + // All items of the set are selected, except the one explicitely listed + $aSelectedObj = array(); + $oFullSet = new DBObjectSet($oFullSetFilter); + $sClassAlias = $oFullSetFilter->GetClassAlias(); + $oFullSet->OptimizeColumnLoad(array($sClassAlias => array('friendlyname'))); // We really need only the IDs but it does not work since id is not a real field + while($oObj = $oFullSet->Fetch()) + { + if (!in_array($oObj->GetKey(), $aExceptions)) + { + $aSelectedObj[] = $oObj->GetKey(); + } + } + } + } + return $aSelectedObj; + } + public static function GetNewTransactionId() { return privUITransaction::GetNewTransactionId(); diff --git a/application/webpage.class.inc.php b/application/webpage.class.inc.php index 6bf1acee9..b26583ec4 100644 --- a/application/webpage.class.inc.php +++ b/application/webpage.class.inc.php @@ -154,27 +154,33 @@ class WebPage $sHtml .= "\n"; foreach($aData as $aRow) { - if (isset($aRow['@class'])) // Row specific class, for hilighting certain rows - { - $sHtml .= "\n"; - } - else - { - $sHtml .= "\n"; - } - foreach($aConfig as $sName=>$aAttribs) - { - $aMatches = array(); - $sClass = isset($aAttribs['class']) ? 'class="'.$aAttribs['class'].'"' : ''; - $sValue = ($aRow[$sName] === '') ? ' ' : $aRow[$sName]; - $sHtml .= "$sValue\n"; - } - $sHtml .= "\n"; + $sHtml .= $this->GetTableRow($aRow, $aConfig); } $sHtml .= "\n"; $sHtml .= "\n"; return $sHtml; } + + public function GetTableRow($aRow, $aConfig) + { + $sHtml = ''; + if (isset($aRow['@class'])) // Row specific class, for hilighting certain rows + { + $sHtml .= ""; + } + else + { + $sHtml .= ""; + } + foreach($aConfig as $sName=>$aAttribs) + { + $sClass = isset($aAttribs['class']) ? 'class="'.$aAttribs['class'].'"' : ''; + $sValue = ($aRow[$sName] === '') ? ' ' : $aRow[$sName]; + $sHtml .= "$sValue"; + } + $sHtml .= ""; + return $sHtml; + } /** * Add some Javascript to the header of the page