/** * Get the HTML fragment corresponding to the ext key editing widget * @param WebPage $oP The web page used for all the output * @param Hash $aArgs Extra context arguments * @return string The HTML fragment to be inserted into the page */ public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true) { if (!is_null($bSearchMode)) { $this->bSearchMode = $bSearchMode; } $sTitle = addslashes($sTitle); $oPage->add_linked_script('../js/extkeywidget.js'); $oPage->add_linked_script('../js/forms-json-utils.js'); $bCreate = !$this->bSearchMode && !MetaModel::IsAbstract($this->sTargetClass) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation); $bExtensions = true; $sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm'); $sAttrFieldPrefix = $this->bSearchMode ? '' : 'attr_'; $sHTMLValue = "<span style=\"white-space:nowrap\">"; // no wrap $sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL()); if ($this->bSearchMode) { $sWizHelper = 'null'; $sWizHelperJSON = "''"; $sJSSearchMode = 'true'; } else { if (isset($aArgs['wizHelper'])) { $sWizHelper = $aArgs['wizHelper']; } else { $sWizHelper = 'oWizardHelper' . $sFormPrefix; } $sWizHelperJSON = $sWizHelper . '.UpdateWizardToJSON()'; $sJSSearchMode = 'false'; } if (is_null($oAllowedValues)) { throw new Exception('Implementation: null value for allowed values definition'); } elseif ($oAllowedValues->Count() < $iMaxComboLength) { // Discrete list of values, use a SELECT or RADIO buttons depending on the config switch ($sDisplayStyle) { case 'radio': case 'radio_horizontal': case 'radio_vertical': $sValidationField = "<span id=\"v_{$this->iId}\"></span>"; $sHTMLValue = ''; $bVertical = $sDisplayStyle != 'radio_horizontal'; $bExtensions = false; $oAllowedValues->Rewind(); $aAllowedValues = array(); while ($oObj = $oAllowedValues->Fetch()) { $aAllowedValues[$oObj->GetKey()] = $oObj->GetName(); } $sHTMLValue = $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", $bMandatory, $bVertical, $sValidationField); $aEventsList[] = 'change'; break; case 'select': case 'list': default: $sSelectMode = 'true'; $sHelpText = ''; //$this->oAttDef->GetHelpOnEdition(); if ($this->bSearchMode) { if ($bSearchMultiple) { $sHTMLValue = "<select class=\"multiselect\" multiple title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}[]\" id=\"{$this->iId}\">\n"; } else { $sHTMLValue = "<select title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"{$this->iId}\">\n"; $sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : Dict::S('UI:SearchValue:Any'); $sHTMLValue .= "<option value=\"\">{$sDisplayValue}</option>\n"; } } else { $sHTMLValue = "<select title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"{$this->iId}\">\n"; $sHTMLValue .= "<option value=\"\">" . Dict::S('UI:SelectOne') . "</option>\n"; } $oAllowedValues->Rewind(); while ($oObj = $oAllowedValues->Fetch()) { $key = $oObj->GetKey(); $display_value = $oObj->GetName(); if ($oAllowedValues->Count() == 1 && $bMandatory == 'true') { // When there is only once choice, select it by default $sSelected = ' selected'; } else { $sSelected = is_array($value) && in_array($key, $value) || $value == $key ? ' selected' : ''; } $sHTMLValue .= "<option value=\"{$key}\"{$sSelected}>{$display_value}</option>\n"; } $sHTMLValue .= "</select>\n"; if ($this->bSearchMode && $bSearchMultiple) { $aOptions = array('header' => true, 'checkAllText' => Dict::S('UI:SearchValue:CheckAll'), 'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'), 'noneSelectedText' => Dict::S('UI:SearchValue:Any'), 'selectedText' => Dict::S('UI:SearchValue:NbSelected'), 'selectedList' => 1); $sJSOptions = json_encode($aOptions); $oPage->add_ready_script("\$('.multiselect').multiselect({$sJSOptions});"); } $oPage->add_ready_script(<<<EOF \t\toACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '{$sFilter}', '{$sTitle}', true, {$sWizHelper}, '{$this->sAttCode}', {$sJSSearchMode}); \t\toACWidget_{$this->iId}.emptyHtml = "<div style=\\"background: #fff; border:0; text-align:center; vertical-align:middle;\\"><p>{$sMessage}</p></div>"; \t\t\$('#{$this->iId}').bind('update', function() { oACWidget_{$this->iId}.Update(); } ); \t\t\$('#{$this->iId}').bind('change', function() { \$(this).trigger('extkeychange') } ); EOF ); } // Switch } else { // Too many choices, use an autocomplete $sSelectMode = 'false'; // Check that the given value is allowed $oSearch = $oAllowedValues->GetFilter(); $oSearch->AddCondition('id', $value); $oSet = new DBObjectSet($oSearch); if ($oSet->Count() == 0) { $value = null; } if (is_null($value) || $value == 0) { $sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : ''; } else { $sDisplayValue = $this->GetObjectName($value); } $iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 3; //@@@ $this->oAttDef->GetMinAutoCompleteChars(); $iFieldSize = isset($aArgs['iFieldSize']) ? $aArgs['iFieldSize'] : 30; //@@@ $this->oAttDef->GetMaxSize(); // the input for the auto-complete $sHTMLValue = "<input count=\"" . $oAllowedValues->Count() . "\" type=\"text\" id=\"label_{$this->iId}\" size=\"{$iFieldSize}\" value=\"{$sDisplayValue}\"/> "; $sHTMLValue .= "<img id=\"mini_search_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_search.gif\" onClick=\"oACWidget_{$this->iId}.Search();\"/> "; // another hidden input to store & pass the object's Id $sHTMLValue .= "<input type=\"hidden\" id=\"{$this->iId}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"" . htmlentities($value, ENT_QUOTES, 'UTF-8') . "\" />\n"; $JSSearchMode = $this->bSearchMode ? 'true' : 'false'; // Scripts to start the autocomplete and bind some events to it $oPage->add_ready_script(<<<EOF \t\toACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '{$sFilter}', '{$sTitle}', false, {$sWizHelper}, '{$this->sAttCode}', {$sJSSearchMode}); \t\toACWidget_{$this->iId}.emptyHtml = "<div style=\\"background: #fff; border:0; text-align:center; vertical-align:middle;\\"><p>{$sMessage}</p></div>"; \t\t\$('#label_{$this->iId}').autocomplete(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', { scroll:true, minChars:{$iMinChars}, autoFill:false, matchContains:true, mustMatch: true, keyHolder:'#{$this->iId}', extraParams:{operation:'ac_extkey', sTargetClass:'{$this->sTargetClass}',sFilter:'{$sFilter}',bSearchMode:{$JSSearchMode}, json: function() { return {$sWizHelperJSON}; } }}); \t\t\$('#label_{$this->iId}').keyup(function() { if (\$(this).val() == '') { \$('#{$this->iId}').val(''); } } ); // Useful for search forms: empty value in the "label", means no value, immediatly ! \t\t\$('#label_{$this->iId}').result( function(event, data, formatted) { OnAutoComplete('{$this->iId}', event, data, formatted); } ); \t\t\$('#{$this->iId}').bind('update', function() { oACWidget_{$this->iId}.Update(); } ); \t\tif (\$('#ac_dlg_{$this->iId}').length == 0) \t\t{ \t\t\t\$('body').append('<div id="ac_dlg_{$this->iId}"></div>'); \t\t} EOF ); } if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) { $sHTMLValue .= "<img id=\"mini_tree_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_tree.gif\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"/> "; $oPage->add_ready_script(<<<EOF \t\t\tif (\$('#ac_tree_{$this->iId}').length == 0) \t\t\t{ \t\t\t\t\$('body').append('<div id="ac_tree_{$this->iId}"></div>'); \t\t\t}\t\t EOF ); } if ($bCreate && $bExtensions) { $sHTMLValue .= "<img id=\"mini_add_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_add.gif\" onClick=\"oACWidget_{$this->iId}.CreateObject();\"/> "; $oPage->add_ready_script(<<<EOF \t\tif (\$('#ajax_{$this->iId}').length == 0) \t\t{ \t\t\t\$('body').append('<div id="ajax_{$this->iId}"></div>'); \t\t} EOF ); } if ($sDisplayStyle == 'select' || $sDisplayStyle == 'list') { $sHTMLValue .= "<span id=\"v_{$this->iId}\"></span>"; } $sHTMLValue .= "</span>"; // end of no wrap return $sHTMLValue; }