diff --git a/application/datatable.class.inc.php b/application/datatable.class.inc.php index 009937e88..adbeaecae 100644 --- a/application/datatable.class.inc.php +++ b/application/datatable.class.inc.php @@ -20,6 +20,8 @@ class DataTable { protected $iListId; // Unique ID inside the web page + /** @var string */ + private $sDatatableContainerId; protected $sTableId; // identifier for saving the settings (combined with the class aliases) protected $oSet; // The set of objects to display protected $aClassAliases; // The aliases (alias => class) inside the set @@ -29,10 +31,10 @@ class DataTable protected $bShowObsoleteData; /** - * @param $iListId mixed Unique ID for this div/table in the page - * @param $oSet DBObjectSet The set of data to display - * @param $aClassAliases array The list of classes/aliases to be displayed in this set $sAlias => $sClassName - * @param $sTableId mixed A string (or null) identifying this table in order to persist its settings + * @param string $iListId Unique ID for this div/table in the page + * @param DBObjectSet $oSet The set of data to display + * @param array$aClassAliases The list of classes/aliases to be displayed in this set $sAlias => $sClassName + * @param string $sTableId A string (or null) identifying this table in order to persist its settings * * @throws \CoreException * @throws \MissingQueryArgument @@ -42,6 +44,7 @@ class DataTable public function __construct($iListId, $oSet, $aClassAliases, $sTableId = null) { $this->iListId = utils::GetSafeId($iListId); // Make a "safe" ID for jQuery + $this->sDatatableContainerId = 'datatable_'.utils::GetSafeId($iListId); $this->oSet = $oSet; $this->aClassAliases = $aClassAliases; $this->sTableId = $sTableId; @@ -165,7 +168,7 @@ class DataTable $sDataTable = $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams); $sConfigDlg = $this->GetTableConfigDlg($oPage, $aColumns, $bViewLink, $iDefaultPageSize); - $sHtml = "iListId}\" class=\"datatable\">"; + $sHtml = "
sDatatableContainerId}\" class=\"datatable\">"; $sHtml .= "
"; $sHtml .= ""; $sHtml .= ""; @@ -201,7 +204,7 @@ class DataTable $aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings); } $sJSOptions = json_encode($aOptions); - $oPage->add_ready_script("$('#datatable_{$this->iListId}').datatable($sJSOptions);"); + $oPage->add_ready_script("$('#{$this->sDatatableContainerId}').datatable($sJSOptions);"); return $sHtml; } @@ -418,15 +421,15 @@ EOF; $sHtml .= "iListId}\" type=\"radio\" name=\"scope\" $sGenericChecked value=\"defaults\">

'; $sHtml .= ""; $sHtml .= '
$sObjectsCount$sToolkitMenu $sActionsMenu
'; - $sHtml .= ''; + $sHtml .= ''; $sHtml .= ''; - $sHtml .= ''; + $sHtml .= ''; $sHtml .= '
'; $sHtml .= ""; $sHtml .= ""; $sDlgTitle = addslashes(Dict::S('UI:ListConfigurationTitle')); - $oPage->add_ready_script("$('#datatable_dlg_{$this->iListId}').dialog({autoOpen: false, title: '$sDlgTitle', width: 500, close: function() { $('#datatable_{$this->iListId}').datatable('onDlgCancel'); } });"); + $oPage->add_ready_script("$('#datatable_dlg_{$this->iListId}').dialog({autoOpen: false, title: '$sDlgTitle', width: 500, close: function() { $('#{$this->sDatatableContainerId}').datatable('onDlgCancel'); } });"); return $sHtml; } @@ -745,12 +748,25 @@ EOF; } $sOQL = addslashes($this->oSet->GetFilter()->serialize()); $oPage->add_ready_script( -<<iListId} table.listResults'); +<<sDatatableContainerId} table.listResults'); oTable.tableHover(); -oTable.tablesorter( { $sHeaders widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $('#pager{$this->iListId}'), totalRows:$iCount, size: $iPageSize, filter: '$sOQL', extra_params: '$sExtraParams', select_mode: '$sSelectModeJS', displayKey: $sDisplayKey, table_id: '{$this->iListId}', columns: $sJSColumns, class_aliases: $sJSClassAliases $sCssCount}); -EOF - ); +oTable + .tablesorter({ $sHeaders widgets: ['myZebra', 'truncatedList']}) + .tablesorterPager({ + container: $('#pager{$this->iListId}'), + totalRows:$iCount, + size: $iPageSize, + filter: '$sOQL', + extra_params: '$sExtraParams', + select_mode: '$sSelectModeJS', + displayKey: $sDisplayKey, + table_id: '{$this->sDatatableContainerId}', + columns: $sJSColumns, + class_aliases: $sJSClassAliases $sCssCount + }); +JS + ); if ($sFakeSortList != '') { $oPage->add_ready_script("oTable.trigger(\"fakesorton\", [$sFakeSortList]);"); diff --git a/application/ui.extkeywidget.class.inc.php b/application/ui.extkeywidget.class.inc.php index 5ca0e3a81..6426ddf51 100644 --- a/application/ui.extkeywidget.class.inc.php +++ b/application/ui.extkeywidget.class.inc.php @@ -636,14 +636,22 @@ HTML $oSet->SetShowObsoleteData(utils::ShowObsoleteData()); $sHKAttCode = MetaModel::IsHierarchicalClass($this->sTargetClass); - $this->DumpTree($oPage, $oSet, $sHKAttCode, $currValue); + $bHasChildLeafs = $this->DumpTree($oPage, $oSet, $sHKAttCode, $currValue); $oPage->add('
'); $oPage->add(''); + + if ($bHasChildLeafs) + { + $oPage->add('
'.Dict::S("UI:Treeview:CollapseAll").' | '.Dict::S("UI:Treeview:ExpandAll").'
'); + } + $oPage->add("iId}\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_tree_{$this->iId}').dialog('close');\">  "); $oPage->add("iId}\" value=\"".Dict::S('UI:Button:Ok')."\" onClick=\"oACWidget_{$this->iId}.DoHKOk();\">"); $oPage->add(''); + + $oPage->add_ready_script("\$('#tree_$this->iId ul').treeview({ control: '#treecontrolid', persist: 'false'});\n"); $oPage->add_ready_script("\$('#tree_$this->iId ul').treeview();\n"); $oPage->add_ready_script("\$('#dlg_tree_$this->iId').dialog({ width: 'auto', height: 'auto', autoOpen: true, modal: true, title: '$sDialogTitle', resizeStop: oACWidget_{$this->iId}.OnHKResize, close: oACWidget_{$this->iId}.OnHKClose });\n"); } @@ -673,6 +681,18 @@ HTML } } + /** + * @param WebPage $oP + * @param \DBObjectSet $oSet + * @param string $sParentAttCode + * @param string $currValue + * + * @return bool true if there are at least one child leaf, false if only roots nodes are present + * @throws \ArchivedObjectException + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException + */ function DumpTree($oP, $oSet, $sParentAttCode, $currValue) { $aTree = array(); @@ -701,6 +721,9 @@ HTML { $this->DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue); } + + $bHasOnlyRootNodes = (count($aTree) === 1); + return !$bHasOnlyRootNodes; } function DumpNodes($oP, $iRootId, $aTree, $aNodes, $currValue) @@ -728,7 +751,7 @@ HTML $sSelect = ' '; } } - $oP->add('
  • '.$sSelect.''); + $oP->add('
  • '.$sSelect.''); $this->DumpNodes($oP, $id, $aTree, $aNodes, $currValue); $oP->add("
  • \n"); } diff --git a/css/light-grey.scss b/css/light-grey.scss index 864323835..bf5446f6a 100644 --- a/css/light-grey.scss +++ b/css/light-grey.scss @@ -3891,3 +3891,16 @@ input:checked + .slider:before { } } } + + + +.ui-dialog .ui-dialog-content .treecontrol { + padding-bottom:0.3em; + padding-left: 0.2em; + margin-top: -0.3em; + padding-top: 0; + +} +.ui-dialog .ui-dialog-content .treecontrol a { + font-size: small; +} \ No newline at end of file diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index 3fa9db8ab..a9852d686 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -423,6 +423,8 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Button:More' => 'More', 'UI:Button:Less' => 'Less', 'UI:Button:Wait' => 'Please wait while updating fields', + 'UI:Treeview:CollapseAll' => 'Collapse All', + 'UI:Treeview:ExpandAll' => 'Expand All', 'UI:SearchToggle' => 'Search', 'UI:ClickToCreateNew' => 'Create a new %1$s',