Enrich display of an object
Prerequisite: You must be familiar with the Syntax used in Tutorials and have already created an extension.
- learning:
- Add information to the display of an object
- level:
- Intermediate
- domains:
- PHP, Presentation
- methods:
- DisplayBareRelations, SetCurrentTab, IsValidClass, GetKey, FromOQL, GetFilter, DisplayBlock::Display
- min version:
- 2.1.0
🚧 Add screenshots of the examples result. Add an explanation to present the various examples, and what they bring.
Email members of a team
In this example, we will add a feature to an existing tab of an object details. We want to offer a mean to directly open a new email form in your favorite email client, with the team members already added in TO field.
We will just add in the tab displaying the team members, a
mailto
html link with the list of email addresses to
use. The function which deals with displaying the relations tabs,
when displaying a particular Object, is
DisplayBareRelations()
- class:Team
-
function DisplayBareRelations(WebPage $oPage, $bEditMode = false) { // We call the parent class otherwise all relations tab will be missing parent::DisplayBareRelations($oPage, $bEditMode); // If your new behavior should be limited to the read mode (or not) if (!$bEditMode) { // We assume the Team class as a 'persons_list' attribute $oToNotify = $this->Get('persons_list'); $aMailList = array(); while ($oContact = $oToNotify->Fetch()) { $aMailList[] = $oContact->Get('email'); } $sMailList = implode(', ', $aMailList); if ($sMailList != '') { // The oPage object contains multiple tabs // We want to put our link on a particular tab known by its label $sTabName = $oPage->FindTab('/^' . Dict::S('Class:Team/Attribute:persons_list') . '/'); // Set that Tab as the current one // If no Tab with that name exists, it creates a new one after the current tab $oPage->SetCurrentTab($sTabName); // Add an hyperlink at the end of that tab $sLink = "<br> <a href=\"mailto:?to={$sMailList}\">Open mailer</a>"; // As when writing on an oPage, it writes on the current tab $oPage->Add($sLink); } } }
-
the API iApplicationUIExtension using
OnDisplayRelations()
method, -
or with a new action menu
Display KnownErrors applicable to a Ticket
In this example, we will add a tab to the
UserRequest display. In this tab, we will display related
objects, but with a relation more complex than just a
LinkedSet attribute.
The Known Errors are not directly linked to a UserRequest in iTop
default Datamodel, but they are linked to FunctionalCI and
FunctionalCI are linked to Ticket, so following those two
relationships, we can propose on a UserRequest the Known Errors
which might be applicable to that ticket.
As in the above example, we will just write a PHP method to enrich the display of the UserRequest class.
- class:UserRequest
-
function DisplayBareRelations(WebPage $oPage, $bEditMode = false) { // Mandatory, to get the other tabs displayed as well parent::DisplayBareRelations($oPage, $bEditMode); // If the UserRequest is in Read mode // and the KnownError option has been selected at iTop setup if ((!$bEditMode) && (MetaModel::IsValidClass('KnownError'))) { //Search for known errors related to FunctionalCI // ...linked to current UserRequest $iTicketID = $this->GetKey(); // We create a Search (definition) with an OQL // Note {$iTicketID} in the OQL will be replaced by the true value $oSearch = DBObjectSearch::FromOQL(" SELECT KnownError AS ke JOIN lnkErrorToFunctionalCI AS l1 ON l1.error_id=ke.id JOIN FunctionalCI AS ci ON l1.functionalci_id=ci.id JOIN lnkFunctionalCIToTicket AS l2 ON l2.functionalci_id=ci.id WHERE l2.ticket_id={$iTicketID}"); // We get a set of Known Error objects, using the above Search $oKnownErrorSet = new CMDBObjectSet($oSearch); // Now that we have the Set we can count them $iNumberKE = $oKnownErrorSet->count(); // Here we have decided to always create a new Known Error tab // but you could decide to display the tab only if there are some Known Errors if ($iNumberKE > 0) { // here we use the standard iTop way to display tab with data inside $oPage->SetCurrentTab(Dict::S('Class:UserRequest:KnownErrorList') . " ({$iNumberKE})"); } else { // or without data inside with no brackets and no count $oPage->SetCurrentTab(Dict::S('Class:UserRequest:KnownErrorList')); } // We create a Block made of the Known Error in a 'list' mode // The Block just need a DBObjectSearch and not the Set itself // GetFilter() retrieve that Search from the Set $oBlock = new DisplayBlock($oKnownErrorSet->GetFilter(), 'list', false); // 'menu' says if the list will offer a menu // 'display_limit' says if we display in page mode or all objects at once $aExtraParam = array('menu' => true, 'display_limit' => false); // Display the block in the page with a Title (optional), and extra params $oBlock->Display($oPage, Dict::S('Class:UserRequest:KnownErrorList'), $aExtraParam); } }
AttributeLinkedSetIndirect
in 2.7.X and
before, the list cannot be filtered and can slow down
performance.Questions & Answers
Question: My object is not fully displayed, relations
tabs are missing?
Answer: Are you always calling
parent::DisplayBareRelations($oPage, $bEditMode);
in
your method?
Question: Tab title is
Class:UserRequest:KnownErrorList
, how can I fix
it?
Answer: You must define a dictionary
entry for Class:UserRequest:KnownErrorList
Copy data in clipboard
🚧 Rough example, need more work…
- class:Organization
-
function DisplayBareRelations(WebPage $oPage, $bEditMode = false) { parent::DisplayBareRelations($oPage, $bEditMode); if ((!$bEditMode) { $oPage->SetCurrentTab("Authorized users ($iCount)"); $oPage->table($aDisplayConfig, $aDisplayData); $oSearch = DBObjectSearch::FromOQL("SELECT Organization WHERE (id=:org_id OR managed_by_id=:org_id)"); $oSet = new DBObjectSet($oSearch, array('name' => true), array('org_id' => $this->GetKey())); $sOrgs =''; while ($aRow = $oSet->FetchAssoc()) { $oPerson = $aRow['Organization']; // If not the first one, add the | separator if ($sOrgs!='') $sOrgs = $sOrgs ."|"; $sOrgs = $sOrgs . "allowed_org_id:" . $oPerson->GetKey(); } $oPage->Add("<p><input id='MyOrgs'value='{$sOrgs}'/>"); $oPage->add_linked_script("//cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.4.0/clipboard.min.js"); $oPage->Add('<button class="button" id="copy-button" data-clipboard-target="#MyOrgs">Copy</button><p>'); $oPage->add_ready_script('new Clipboard("#copy-button");'); } }