*/ class ConsoleSimpleFieldRenderer extends FieldRenderer { public function Render() { $oOutput = parent::Render(); $sFieldClass = get_class($this->oField); if ($sFieldClass == 'Combodo\\iTop\\Form\\Field\\HiddenField') { $oOutput->AddHtml(''); } else { $oBlock = FieldUIBlockFactory::MakeStandard($this->oField->GetLabel()); $oBlock->SetAttLabel($this->oField->GetLabel()) ->AddDataAttribute("input-id",$this->oField->GetGlobalId()) ->AddDataAttribute("input-type",$sFieldClass); // Propagate data attribute from Field to UIBlock // Note: This might no longer be necessary after the upcoming attributes rework project foreach ($this->oField->GetMetadata() as $sMetadataKey => $sMetadataValue) { switch ($sMetadataKey) { // Important: Only some data attributes can be overloaded, this is done on purpose (eg. "input-type" set previously by an AttributeCustomFields) case 'attribute-code': case 'attribute-type': case 'input-type': if (utils::IsNotNullOrEmptyString($sMetadataValue)) { switch ($sMetadataKey) { case 'attribute-code': $oBlock->SetAttCode($sMetadataValue); break; case 'attribute-type': $oBlock->SetAttType($sMetadataValue ?? ''); break; case 'input-type': $oBlock->AddDataAttribute($sMetadataKey, $sMetadataValue ?? ''); break; } } break; default: if (false === $oBlock->HasDataAttribute($sMetadataKey)) { $oBlock->AddDataAttribute($sMetadataKey, $sMetadataValue ?? ''); } break; } } switch ($sFieldClass) { case 'Combodo\\iTop\\Form\\Field\\DateTimeField': $oValue = UIContentBlockUIBlockFactory::MakeStandard("",["form-field-content"]); $sDateTimeFormat = $this->oField->GetPHPDateTimeFormat(); $oFormat = new DateTimeFormat($sDateTimeFormat); $sPlaceHolder = $oFormat->ToPlaceholder(); if ($this->oField->GetReadOnly()) { $oValue->AddSubBlock(InputUIBlockFactory::MakeForHidden("",$this->oField->GetCurrentValue(),$this->oField->GetGlobalId())); $oValue->AddSubBlock(new Html($this->oField->GetCurrentValue())); } else { $oField = UIContentBlockUIBlockFactory::MakeStandard("", ["field_input_zone", "field_input_datetime", "ibo-input-field-wrapper", "ibo-input-datetime-wrapper"]); $oValue->AddSubBlock($oField); $oField->AddSubBlock(new Html('')); $oField->AddSubBlock(new Html('')); } $oBlock->AddSubBlock($oValue); break; case 'Combodo\\iTop\\Form\\Field\\LabelField': $oValue = UIContentBlockUIBlockFactory::MakeStandard("",[""]); $oBlock->AddSubBlock($oValue); $oValue->AddSubBlock(new Text($this->oField->GetCurrentValue())); $oValue->AddSubBlock(new Html('')); break; case 'Combodo\\iTop\\Form\\Field\\StringField': $oValue = UIContentBlockUIBlockFactory::MakeStandard("",["ibo-input-field-wrapper"]); if ($this->oField->GetReadOnly()) { $oValue->AddSubBlock(InputUIBlockFactory::MakeForHidden("",$this->oField->GetCurrentValue(),$this->oField->GetGlobalId())); $oValue->AddSubBlock(new Html($this->oField->GetCurrentValue())); } else { $oValue->AddSubBlock(InputUIBlockFactory::MakeStandard("text","", $this->oField->GetCurrentValue(),$this->oField->GetGlobalId())); $oValue->AddSubBlock(new Html('')); } $oBlock->AddSubBlock($oValue); break; case 'Combodo\\iTop\\Form\\Field\\TextAreaField': $oValue = UIContentBlockUIBlockFactory::MakeStandard("",["form-field-content", "ibo-input-field-wrapper"]); $bRichEditor = ($this->oField->GetFormat() === TextAreaField::ENUM_FORMAT_HTML); if ($this->oField->GetReadOnly()) { $oValue->AddSubBlock(UIContentBlockUIBlockFactory::MakeStandard())->AddSubBlock(HtmlFactory::MakeHtmlContent($this->oField->GetCurrentValue())); $oValue->AddSubBlock(InputUIBlockFactory::MakeForHidden("",$this->oField->GetCurrentValue(), $this->oField->GetGlobalId())); } else { $oText = new TextArea("",$this->oField->GetCurrentValue(),$this->oField->GetGlobalId(),40,8); $oText->AddCSSClasses(['ibo-input-field-wrapper', 'ibo-input']); $oValue->AddSubBlock($oText); // Some additional stuff if we are displaying it with a rich editor if ($bRichEditor) { $oText->AddCSSClass('ibo-input-richtext-placeholder'); $aConfig = utils::GetCkeditorPref(); $aConfig['extraPlugins'] = 'codesnippet'; $sJsConfig = json_encode($aConfig); foreach (WebResourcesHelper::GetJSFilesRelPathsForCKEditor() as $sJSFile) { $oOutput->AddJsFile($sJSFile); } $oOutput->AddJs( <<oField->GetGlobalId()}').addClass('htmlEditor'); $('#{$this->oField->GetGlobalId()}').ckeditor(function(){}, $sJsConfig); EOF ); if (($this->oField->GetObject() !== null) && ($this->oField->GetTransactionId() !== null)) { $oOutput->AddJs(InlineImage::EnableCKEditorImageUpload($this->oField->GetObject(), utils::GetUploadTempId($this->oField->GetTransactionId()))); } } $oValue->AddSubBlock(new Html('')); } $oBlock->AddSubBlock($oValue); break; case 'Combodo\\iTop\\Form\\Field\\SelectField': $oValue = UIContentBlockUIBlockFactory::MakeStandard("",["form-field-content","ibo-input-field-wrapper"]); if ($this->oField->GetReadOnly()) { $aChoices = $this->oField->GetChoices(); $sCurrentLabel = isset($aChoices[$this->oField->GetCurrentValue()]) ? $aChoices[$this->oField->GetCurrentValue()] : '' ; $oValue->AddSubBlock(InputUIBlockFactory::MakeForHidden("",$this->oField->GetCurrentValue(),$this->oField->GetGlobalId())); $oValue->AddSubBlock(new Html($sCurrentLabel)); } else { $oSelect = SelectUIBlockFactory::MakeForSelect("",$this->oField->GetGlobalId()); $oSelect->AddCSSClass('ibo-input-field-wrapper'); if ($this->oField->GetMultipleValuesEnabled()) { $oSelect->SetIsMultiple(true); } foreach ($this->oField->GetChoices() as $sChoice => $sLabel) { // Note : The test is a double equal on purpose as the type of the value received from the XHR is not always the same as the type of the allowed values. (eg : string vs int) $oSelect->AddOption(SelectOptionUIBlockFactory::MakeForSelectOption($sChoice,$sLabel, ($this->oField->GetCurrentValue() == $sChoice))); } $oValue->AddSubBlock($oSelect); $oValue->AddSubBlock(new Html('')); } $oBlock->AddSubBlock($oValue); break; case 'Combodo\\iTop\\Form\\Field\\RadioField': $oValue = UIContentBlockUIBlockFactory::MakeStandard("",["form-field-content"]); if ($this->oField->GetReadOnly()) { $aChoices = $this->oField->GetChoices(); $sCurrentLabel = isset($aChoices[$this->oField->GetCurrentValue()]) ? $aChoices[$this->oField->GetCurrentValue()] : '' ; $oValue->AddSubBlock(InputUIBlockFactory::MakeForHidden("",$this->oField->GetCurrentValue(),$this->oField->GetGlobalId())); $oValue->AddSubBlock(new Html($sCurrentLabel)); } else { $bVertical = true; $idx = 0; $bMandatory = $this->oField->GetMandatory(); $value = $this->oField->GetCurrentValue(); $sId = $this->oField->GetGlobalId(); $aChoices = $this->oField->GetChoices(); foreach ($aChoices as $sChoice => $sLabel) { if ((count($aChoices) == 1) && $bMandatory) { // When there is only once choice, select it by default $sSelected = 'checked'; $value = $sChoice; } else { $sSelected = ($value == $sChoice) ? 'checked' : ''; } $oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "radio_".$sId, $sChoice, "{$sId}_{$idx}", "radio"); $oRadio->GetInput()->SetIsChecked($sSelected); $oRadio->SetBeforeInput(false); $oRadio->GetInput()->AddCSSClass('ibo-input-checkbox'); $oValue->AddSubBlock($oRadio); if ($bVertical) { $oValue->AddSubBlock(new Html("
")); } $oOutput->AddJs( <<AddSubBlock(InputUIBlockFactory::MakeForHidden("",$value,$sId)); $oValue->AddSubBlock(new Html('')); } $oBlock->AddSubBlock($oValue); break; case 'Combodo\\iTop\\Form\\Field\\DurationField': $oValue = UIContentBlockUIBlockFactory::MakeStandard("",["form-field-content","ibo-input-field-wrapper"]); $value = $this->oField->GetCurrentValue(); if ($this->oField->GetReadOnly()) { $oValue->AddSubBlock(InputUIBlockFactory::MakeForHidden("",$value,$this->oField->GetGlobalId())); $oValue->AddSubBlock(new Html(AttributeDuration::FormatDuration($value))); } else { $sId = $this->oField->GetGlobalId(); $aVal = AttributeDuration::SplitDuration($value); $sDays = ""; $sHours = ""; $sMinutes = ""; $sSeconds = ""; $oTime = UIContentBlockUIBlockFactory::MakeStandard("",["pt-2"]); $oTime->AddSubBlock(new Html(Dict::Format('UI:DurationForm_Days_Hours_Minutes_Seconds', $sDays, $sHours, $sMinutes, $sSeconds))); $oValue->AddSubBlock($oTime); $oValue->AddSubBlock(InputUIBlockFactory::MakeForHidden("",$value,$sId)); $oOutput->AddJs("$('#{$sId}_d').on('keyup change', function(evt, sFormId) { return UpdateDuration('$sId'); });"); $oOutput->AddJs("$('#{$sId}_h').on('keyup change', function(evt, sFormId) { return UpdateDuration('$sId'); });"); $oOutput->AddJs("$('#{$sId}_m').on('keyup change', function(evt, sFormId) { return UpdateDuration('$sId'); });"); $oOutput->AddJs("$('#{$sId}_s').on('keyup change', function(evt, sFormId) { return UpdateDuration('$sId'); });"); $oOutput->AddJs("$('#{$sId}').on('update', function(evt, sFormId) { return ToggleDurationField('$sId'); });"); $oValue->AddSubBlock(new Html('')); } $oBlock->AddSubBlock($oValue); break; } $oOutput->AddHtml(BlockRenderer::RenderBlockTemplates($oBlock)); } switch ($sFieldClass) { case 'Combodo\\iTop\\Form\\Field\\DateTimeField': $sDateTimeFormat = $this->oField->GetPHPDateTimeFormat(); $sJSDaysMin = json_encode(array(Dict::S('DayOfWeek-Sunday-Min'), Dict::S('DayOfWeek-Monday-Min'), Dict::S('DayOfWeek-Tuesday-Min'), Dict::S('DayOfWeek-Wednesday-Min'), Dict::S('DayOfWeek-Thursday-Min'), Dict::S('DayOfWeek-Friday-Min'), Dict::S('DayOfWeek-Saturday-Min'))); $sJSMonthsShort = json_encode(array(Dict::S('Month-01-Short'), Dict::S('Month-02-Short'), Dict::S('Month-03-Short'), Dict::S('Month-04-Short'), Dict::S('Month-05-Short'), Dict::S('Month-06-Short'), Dict::S('Month-07-Short'), Dict::S('Month-08-Short'), Dict::S('Month-09-Short'), Dict::S('Month-10-Short'), Dict::S('Month-11-Short'), Dict::S('Month-12-Short'))); $iFirstDayOfWeek = (int) Dict::S('Calendar-FirstDayOfWeek'); $sJSDateFormat = json_encode(AttributeDate::GetFormat()->ToDatePicker()); $sTimeFormat = AttributeDateTime::GetFormat()->ToTimeFormat(); $oTimeFormat = new DateTimeFormat($sTimeFormat); $sJSTimeFormat = json_encode($oTimeFormat->ToDatePicker()); $sJSOk = json_encode(Dict::S('UI:Button:Ok')); if ($this->oField->IsDateOnly()) { $oOutput->AddJs( <<<\/i>", "dateFormat": $sJSDateFormat, "constrainInput":false, "changeMonth":true, "changeYear":true, "dayNamesMin":$sJSDaysMin, "monthNamesShort": $sJSMonthsShort, "firstDay":$iFirstDayOfWeek, "onSelect":function(a,b){ $("#{$this->oField->GetGlobalId()}").trigger("change");}, }).next("img").wrap(""); EOF ); } else { $oOutput->AddJs( <<<\/i>", dateFormat: $sJSDateFormat, constrainInput: false, changeMonth: true, changeYear: true, dayNamesMin: $sJSDaysMin, monthNamesShort: $sJSMonthsShort, firstDay: $iFirstDayOfWeek, // time picker options timeFormat: $sJSTimeFormat, controlType: 'select', closeText: $sJSOk }); EOF ); } $oOutput->AddJs( <<oField->GetGlobalId()}").off("change keyup").on("change keyup", function(){ var me = this; $(this).closest(".field_set").trigger("field_change", { id: $(me).attr("id"), name: $(me).closest(".form_field").attr("data-field-id"), value: $(me).val() }) .closest('.form_handler').trigger('value_change'); }); EOF ); break; break; case 'Combodo\\iTop\\Form\\Field\\StringField': case 'Combodo\\iTop\\Form\\Field\\TextAreaField': $oOutput->AddJs( <<oField->GetGlobalId()}").off("change keyup").on("change keyup", function(){ var me = this; $(this).closest(".field_set").trigger("field_change", { id: $(me).attr("id"), name: $(me).closest(".form_field").attr("data-field-id"), value: $(me).val() }) .closest('.form_handler').trigger('value_change'); }); EOF ); break; case 'Combodo\\iTop\\Form\\Field\\SelectField': $oOutput->AddJs( <<oField->GetGlobalId()}").selectize({ sortField: 'text', onChange: function(value){ var me = this.\$input; me.closest(".field_set").trigger("field_change", { id: me.attr("id"), name: me.closest(".form_field").attr("data-field-id"), value: me.val() }) .closest('.form_handler').trigger('value_change'); } }); EOF ); break; case 'Combodo\\iTop\\Form\\Field\\RadioField': case 'Combodo\\iTop\\Form\\Field\\DurationField': $oOutput->AddJs( <<oField->GetGlobalId()}").off("change").on("change", function(){ var me = this; $(this).closest(".field_set").trigger("field_change", { id: $(me).attr("id"), name: $(me).closest(".form_field").attr("data-field-id"), value: $(me).val() }) .closest('.form_handler').trigger('value_change'); }); EOF ); break; } // JS Form field widget construct $aValidators = array(); foreach ($this->oField->GetValidators() as $oValidator) { if (false === ($oValidator instanceof AbstractRegexpValidator)) { // no JS counterpart, so skipping ! continue; } $aValidators[$oValidator::GetName()] = array( 'reg_exp' => $oValidator->GetRegExp(), 'message' => Dict::S($oValidator->GetErrorMessage()), ); } $sValidators = json_encode($aValidators); $sFormFieldOptions = <<AddJs( <<AddJs( <<AddJs( <<