mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 02:28:44 +02:00
N°803 - Allow display & edition of attributes on n:n relations on Portal
This commit is contained in:
@@ -2416,23 +2416,25 @@ class AttributeLinkedSet extends AttributeDefinition
|
||||
foreach ($aAttCodesToDisplay as $sAttCodeToDisplay) {
|
||||
$oAttDefToDisplay = MetaModel::GetAttributeDef($sTargetClass, $sAttCodeToDisplay);
|
||||
$aAttributesToDisplay[$sAttCodeToDisplay] = [
|
||||
'label' => $oAttDefToDisplay->GetLabel(),
|
||||
'mandatory' => !$oAttDefToDisplay->IsNullAllowed(),
|
||||
'att_code' => $sAttCodeToDisplay,
|
||||
'label' => $oAttDefToDisplay->GetLabel(),
|
||||
];
|
||||
}
|
||||
$oFormField->SetAttributesToDisplay($aAttributesToDisplay);
|
||||
|
||||
// Append lnk attributes (filtered from zlist)
|
||||
$aLnkAttDefToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($this->m_sHostClass, $this->m_sCode);
|
||||
$aLnkAttributesToDisplay = array();
|
||||
foreach ($aLnkAttDefToDisplay as $oLnkAttDefToDisplay) {
|
||||
$aLnkAttributesToDisplay[$oLnkAttDefToDisplay->GetCode()] = [
|
||||
'sortable' => false,
|
||||
'label' => $oLnkAttDefToDisplay->GetLabel(),
|
||||
'mandatory' => !$oLnkAttDefToDisplay->IsNullAllowed(),
|
||||
];
|
||||
if ($this->IsIndirect()) {
|
||||
$aLnkAttDefToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($this->m_sHostClass, $this->m_sCode);
|
||||
$aLnkAttributesToDisplay = array();
|
||||
foreach ($aLnkAttDefToDisplay as $oLnkAttDefToDisplay) {
|
||||
$aLnkAttributesToDisplay[$oLnkAttDefToDisplay->GetCode()] = [
|
||||
'att_code' => $oLnkAttDefToDisplay->GetCode(),
|
||||
'label' => $oLnkAttDefToDisplay->GetLabel(),
|
||||
'mandatory' => !$oLnkAttDefToDisplay->IsNullAllowed(),
|
||||
];
|
||||
}
|
||||
$oFormField->SetLnkAttributesToDisplay($aLnkAttributesToDisplay);
|
||||
}
|
||||
$oFormField->SetLnkAttributesToDisplay($aLnkAttributesToDisplay);
|
||||
|
||||
parent::MakeFormField($oObject, $oFormField);
|
||||
|
||||
@@ -3136,7 +3138,7 @@ class AttributeDecimal extends AttributeDBField
|
||||
$iPrecision = $this->Get('decimals');
|
||||
$iNbIntegerDigits = $iNbDigits - $iPrecision - 1; // -1 because the first digit is treated separately in the pattern below
|
||||
|
||||
return "^[-+]?[0-9]\d{0,$iNbIntegerDigits}(\.\d{0,$iPrecision})?$";
|
||||
return "^[\-\+]?[0-9]\d{0,$iNbIntegerDigits}(\.\d{0,$iPrecision})?$";
|
||||
}
|
||||
|
||||
public function GetBasicFilterOperators()
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1808,16 +1808,31 @@ table .group-actions .item-action-wrapper .panel-body > p:last-child{
|
||||
/**********************************************************/
|
||||
|
||||
/* Hide attributes label in link set edition, will be fixed during attributes refactoring */
|
||||
.form_linkedset_wrapper label {
|
||||
.form_linkedset_wrapper .form_field_label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form_linkedset_wrapper .form_field_control {
|
||||
width: 100%!important;
|
||||
}
|
||||
|
||||
/* Add mandatory field column label */
|
||||
.form_linkedset_wrapper .dataTables_scrollHead th.mandatory:after {
|
||||
content: "*";
|
||||
position: relative;
|
||||
left: 3px;
|
||||
color: #EA7D1E;
|
||||
color: $combodo-orange;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* Add style for invalid input */
|
||||
.form_linkedset_wrapper input:invalid {
|
||||
border-color: $state-danger-border;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
.form_linkedset_wrapper input:invalid:focus {
|
||||
border-color: darken($state-danger-border, 10);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px lighten($state-danger-border, 10);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px lighten($state-danger-border, 10);
|
||||
}
|
||||
|
||||
@@ -103,6 +103,12 @@ $(function()
|
||||
oEvent.preventDefault();
|
||||
var me = this;
|
||||
|
||||
// Prevent form submit if input in invalid state
|
||||
// @see Bug N°803 - Allow display & edition of attributes on n:n relations on Portal
|
||||
if($('input:invalid', this.element).length > 0){
|
||||
return;
|
||||
}
|
||||
|
||||
// EasterEgg : Vibrate on submit
|
||||
if(window.navigator.vibrate)
|
||||
{
|
||||
|
||||
@@ -1365,7 +1365,7 @@ class ObjectController extends BrickController
|
||||
$oFieldOutput = $oFieldRenderer->Render();
|
||||
$sValue = $oFieldOutput->GetHtml();
|
||||
}
|
||||
$aObjectData['attributes'][$sAttCode] = [
|
||||
$aObjectData['attributes']['lnk__'.$sAttCode] = [
|
||||
'att_code' => $sAttCode,
|
||||
'value' => $sValue,
|
||||
'css_inline' => $oFieldOutput->GetCss(),
|
||||
|
||||
@@ -861,8 +861,8 @@ class ObjectFormManager extends FormManager
|
||||
{
|
||||
$oAttDefToDisplay = MetaModel::GetAttributeDef($oField->GetTargetClass(), $sAttCodeToDisplay);
|
||||
$aAttributesToDisplay[$sAttCodeToDisplay] = [
|
||||
'label' => $oAttDefToDisplay->GetLabel(),
|
||||
'mandatory' => !$oAttDefToDisplay->IsNullAllowed(),
|
||||
'att_code' => $sAttCodeToDisplay,
|
||||
'label' => $oAttDefToDisplay->GetLabel(),
|
||||
];
|
||||
}
|
||||
$oField->SetAttributesToDisplay($aAttributesToDisplay);
|
||||
|
||||
@@ -53,16 +53,17 @@ class BsLinkedSetFieldRenderer extends BsFieldRenderer
|
||||
$sFieldMandatoryClass = ($this->oField->GetMandatory()) ? 'form_mandatory' : '';
|
||||
$sFieldDescriptionForHTMLTag = ($this->oField->HasDescription()) ? 'data-tooltip-content="'.utils::HtmlEntities($this->oField->GetDescription()).'"' : '';
|
||||
|
||||
// Merge lnk and remote class attributes to display
|
||||
$aAttributesToDisplay = array_merge($this->oField->GetLnkAttributesToDisplay(), $this->oField->GetAttributesToDisplay());
|
||||
// Retrieve link and remote attributes
|
||||
$aAttributesToDisplay = $this->oField->GetAttributesToDisplay();
|
||||
$aLnkAttributesToDisplay = $this->oField->GetLnkAttributesToDisplay();
|
||||
$iLinkAttributesToDisplayCount = count($this->oField->GetLnkAttributesToDisplay()) + 1;
|
||||
|
||||
// Vars to build the table
|
||||
$sAttributesToDisplayAsJson = json_encode($aAttributesToDisplay);
|
||||
$sLnkAttributesToDisplayAsJson = json_encode($aLnkAttributesToDisplay);
|
||||
$sAttCodesToDisplayAsJson = json_encode($this->oField->GetAttributesToDisplay(true));
|
||||
$sLnkAttCodesToDisplayAsJson = json_encode($this->oField->GetLnkAttributesToDisplay(true));
|
||||
|
||||
|
||||
$aItems = array();
|
||||
$aItemIds = array();
|
||||
$aAddedItemIds = array();
|
||||
@@ -161,6 +162,7 @@ EOF
|
||||
$('#{$sTableId} > tbody').html('<tr><td class="datatables_overlay" colspan="100">' + $('#page_overlay').html() + '</td></tr>');
|
||||
|
||||
// Prepares data for datatables
|
||||
var oLnkColumnProperties_{$this->oField->GetGlobalId()} = {$sLnkAttributesToDisplayAsJson};
|
||||
var oColumnProperties_{$this->oField->GetGlobalId()} = {$sAttributesToDisplayAsJson};
|
||||
var oRawDatas_{$this->oField->GetGlobalId()} = {$sItemsAsJson};
|
||||
var oTable_{$this->oField->GetGlobalId()};
|
||||
@@ -196,33 +198,68 @@ EOF
|
||||
});
|
||||
}
|
||||
|
||||
for(sKey in oColumnProperties_{$this->oField->GetGlobalId()})
|
||||
for(sKey in oLnkColumnProperties_{$this->oField->GetGlobalId()})
|
||||
{
|
||||
aColumnProperties = oColumnProperties_{$this->oField->GetGlobalId()}[sKey];
|
||||
aColumnProperties = oLnkColumnProperties_{$this->oField->GetGlobalId()}[sKey];
|
||||
|
||||
// Level main column
|
||||
aColumnsDefinition.push({
|
||||
"width": "auto",
|
||||
"searchable": true,
|
||||
"sortable": !aColumnProperties.sortable,
|
||||
"sortable": false,
|
||||
"title": aColumnProperties.label,
|
||||
"defaultContent": "",
|
||||
"type": "html",
|
||||
"data": "attributes."+sKey+".att_code",
|
||||
"data": "attributes.lnk__" + sKey,
|
||||
"className": aColumnProperties.mandatory ? 'mandatory' : '',
|
||||
"render": function(data, type, row){
|
||||
var cellElem;
|
||||
|
||||
|
||||
// Preparing the cell data
|
||||
if(row.attributes[data].url !== undefined)
|
||||
if(data.url !== undefined)
|
||||
{
|
||||
cellElem = $('<a></a>');
|
||||
cellElem.attr('href', row.attributes[data].url);
|
||||
cellElem.attr('href', data.url);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellElem = $('<span></span>');
|
||||
}
|
||||
cellElem.html('<span>' + row.attributes[data].value + '</span>');
|
||||
cellElem.html('<span>' + data.value + '</span>');
|
||||
|
||||
return cellElem.prop('outerHTML');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for(sKey in oColumnProperties_{$this->oField->GetGlobalId()})
|
||||
{
|
||||
aColumnProperties = oColumnProperties_{$this->oField->GetGlobalId()}[sKey];
|
||||
|
||||
// Level main column
|
||||
aColumnsDefinition.push({
|
||||
"width": "auto",
|
||||
"searchable": true,
|
||||
"sortable": true,
|
||||
"title": aColumnProperties.label,
|
||||
"defaultContent": "",
|
||||
"type": "html",
|
||||
"data": "attributes." + sKey,
|
||||
"className": aColumnProperties.mandatory ? 'mandatory' : '',
|
||||
"render": function(data, type, row){
|
||||
var cellElem;
|
||||
|
||||
// Preparing the cell data
|
||||
if(data.url !== undefined)
|
||||
{
|
||||
cellElem = $('<a></a>');
|
||||
cellElem.attr('href', data.url);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellElem = $('<span></span>');
|
||||
}
|
||||
cellElem.html('<span>' + data.value + '</span>');
|
||||
|
||||
return cellElem.prop('outerHTML');
|
||||
},
|
||||
@@ -445,9 +482,12 @@ JS
|
||||
oTable_{$this->oField->GetGlobalId()}.draw();
|
||||
|
||||
// Execute inline js for each attributes renderers
|
||||
for(key in oData.items[i].attributes){
|
||||
eval(oData.items[i].attributes[key].js_inline)
|
||||
}
|
||||
for(let i in oData.items)
|
||||
{
|
||||
for(let key in oData.items[i].attributes){
|
||||
eval(oData.items[i].attributes[key].js_inline)
|
||||
}
|
||||
}
|
||||
|
||||
// Updating input
|
||||
updateInputValue_{$this->oField->GetGlobalId()}();
|
||||
@@ -663,10 +703,10 @@ JS
|
||||
);
|
||||
|
||||
// Link attributes to display
|
||||
$this->PrepareItem($oItem, $this->oField->GetLinkedClass(), $this->oField->GetLnkAttributesToDisplay(true), true, $aItemProperties, $oOutput);
|
||||
$this->PrepareItem($oItem, $this->oField->GetLinkedClass(), $this->oField->GetLnkAttributesToDisplay(true), true, $aItemProperties, 'lnk__');
|
||||
|
||||
// Remote attributes to display
|
||||
$this->PrepareItem($oRemoteItem, $this->oField->GetTargetClass(), $this->oField->GetAttributesToDisplay(true), false, $aItemProperties, $oOutput);
|
||||
$this->PrepareItem($oRemoteItem, $this->oField->GetTargetClass(), $this->oField->GetAttributesToDisplay(true), false, $aItemProperties);
|
||||
|
||||
// Remap objects to avoid added item to be considered as current item when form validation isn't valid
|
||||
// and form reconstruct
|
||||
@@ -725,7 +765,7 @@ JS
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
protected function PrepareItem(DBObject $oItem, string $sClass, array $aAttributesCodesToDisplay, bool $bIsEditable, array &$aItemProperties, $oOutput)
|
||||
protected function PrepareItem(DBObject $oItem, string $sClass, array $aAttributesCodesToDisplay, bool $bIsEditable, array &$aItemProperties, string $sAttribueKeyPrefix = '')
|
||||
{
|
||||
// Iterate throw attributes...
|
||||
foreach ($aAttributesCodesToDisplay as $sAttCode) {
|
||||
@@ -780,7 +820,8 @@ JS
|
||||
}
|
||||
}
|
||||
|
||||
$aItemProperties['attributes'][$sAttCode] = $aAttProperties;
|
||||
$aItemProperties['attributes'][$sAttribueKeyPrefix.$sAttCode] = $aAttProperties;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,13 @@ namespace Combodo\iTop\Renderer\Bootstrap\FieldRenderer;
|
||||
use AttributeDate;
|
||||
use AttributeDateTime;
|
||||
use AttributeText;
|
||||
use Combodo\iTop\Form\Field\DateField;
|
||||
use Combodo\iTop\Form\Field\DateTimeField;
|
||||
use Combodo\iTop\Form\Field\Field;
|
||||
use Combodo\iTop\Form\Field\MultipleChoicesField;
|
||||
use Combodo\iTop\Form\Field\TextAreaField;
|
||||
use Combodo\iTop\Form\Validator\MandatoryValidator;
|
||||
use Combodo\iTop\Form\Validator\Validator;
|
||||
use Combodo\iTop\Renderer\RenderingOutput;
|
||||
use Dict;
|
||||
use InlineImage;
|
||||
@@ -63,57 +68,62 @@ class BsSimpleFieldRenderer extends BsFieldRenderer
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
// Opening container
|
||||
$oOutput->AddHtml('<div class="form-group form_group_small ' . $sFieldMandatoryClass . '">');
|
||||
$oOutput->AddHtml('<div class="form-group form_group_small '.$sFieldMandatoryClass.'">');
|
||||
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="' . $this->oField->GetGlobalId() . '" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
// Label
|
||||
$oOutput->AddHtml('<div class="form_field_label">');
|
||||
if ($this->oField->GetLabel() !== '') {
|
||||
$oOutput->AddHtml('<label for="'.$this->oField->GetGlobalId().'" class="control-label" '.$sFieldDescriptionForHTMLTag.'>')->AddHtml($this->oField->GetLabel(), true)->AddHtml('</label>');
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Help block
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
// - Value regarding the field type
|
||||
switch($sFieldClass) {
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
$oOutput->AddHtml('<div class="input-group date" id="datepicker_' . $this->oField->GetGlobalId() . '">');
|
||||
$oOutput->AddHtml('<input type="text" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetDisplayValue(), true)->AddHtml('" class="form-control" maxlength="255" />');
|
||||
$oOutput->AddHtml('<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
$sJSFormat = json_encode($this->oField->GetJSDateTimeFormat());
|
||||
$sLocale = Dict::S('Portal:Calendar-FirstDayOfWeek');
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
// Value
|
||||
$oOutput->AddHtml('<div class="form_field_control">');
|
||||
// - Help block
|
||||
$oOutput->AddHtml('<div class="help-block"></div>');
|
||||
|
||||
// Prepare input validations tags
|
||||
$sInputTags = $this->ComputeInputValidationTags($this->oField);
|
||||
|
||||
// - Value regarding the field type
|
||||
switch ($sFieldClass) {
|
||||
case 'Combodo\\iTop\\Form\\Field\\DateTimeField':
|
||||
$oOutput->AddHtml('<div class="input-group date" id="datepicker_'.$this->oField->GetGlobalId().'">');
|
||||
$oOutput->AddHtml('<input type="text" id="'.$this->oField->GetGlobalId().'" name="'.$this->oField->GetId().'" value="')->AddHtml($this->oField->GetDisplayValue(), true)->AddHtml('" class="form-control" maxlength="255" '.$sInputTags.'/>');
|
||||
$oOutput->AddHtml('<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>');
|
||||
$oOutput->AddHtml('</div>');
|
||||
$sJSFormat = json_encode($this->oField->GetJSDateTimeFormat());
|
||||
$sLocale = Dict::S('Portal:Calendar-FirstDayOfWeek');
|
||||
$oOutput->AddJs(
|
||||
<<<EOF
|
||||
$('#datepicker_{$this->oField->GetGlobalId()}').datetimepicker({format: $sJSFormat, locale: '$sLocale'});
|
||||
EOF
|
||||
);
|
||||
break;
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
$oOutput->AddHtml('<input type="password" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('" class="form-control" maxlength="255" autocomplete="off" />');
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\PasswordField':
|
||||
$oOutput->AddHtml('<input type="password" id="'.$this->oField->GetGlobalId().'" name="'.$this->oField->GetId().'" value="')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('" class="form-control" maxlength="255" autocomplete="off" />');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
$oOutput->AddHtml('<input type="text" id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" value="')->AddHtml($this->oField->GetCurrentValue(), true)->AddHtml('" class="form-control" maxlength="255" />');
|
||||
break;
|
||||
case 'Combodo\\iTop\\Form\\Field\\StringField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\UrlField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\EmailField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\PhoneField':
|
||||
$oOutput->AddHtml('<input type="text" id="'.$this->oField->GetGlobalId().'" name="'.$this->oField->GetId().'" value="')->AddHtml($this->oField->GetCurrentValue(),
|
||||
true)->AddHtml('" class="form-control" maxlength="255" '.$sInputTags.'/>');
|
||||
break;
|
||||
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
$oOutput->AddHtml('<select id="' . $this->oField->GetGlobalId() . '" name="' . $this->oField->GetId() . '" ' . ( ($this->oField->GetMultipleValuesEnabled()) ? 'multiple' : '' ) . ' class="form-control">');
|
||||
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)
|
||||
$sSelectedAtt = ($this->oField->GetCurrentValue() == $sChoice) ? 'selected' : '';
|
||||
$oOutput->AddHtml('<option value="' . $sChoice . '" ' . $sSelectedAtt . ' >')->AddHtml($sLabel)->AddHtml('</option>');
|
||||
}
|
||||
$oOutput->AddHtml('</select>');
|
||||
break;
|
||||
}
|
||||
case 'Combodo\\iTop\\Form\\Field\\SelectField':
|
||||
case 'Combodo\\iTop\\Form\\Field\\MultipleSelectField':
|
||||
$oOutput->AddHtml('<select id="'.$this->oField->GetGlobalId().'" name="'.$this->oField->GetId().'" '.(($this->oField->GetMultipleValuesEnabled()) ? 'multiple' : '').' class="form-control">');
|
||||
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)
|
||||
$sSelectedAtt = ($this->oField->GetCurrentValue() == $sChoice) ? 'selected' : '';
|
||||
$oOutput->AddHtml('<option value="'.$sChoice.'" '.$sSelectedAtt.' >')->AddHtml($sLabel)->AddHtml('</option>');
|
||||
}
|
||||
$oOutput->AddHtml('</select>');
|
||||
break;
|
||||
}
|
||||
$oOutput->AddHtml('</div>');
|
||||
|
||||
// Closing container
|
||||
@@ -725,4 +735,34 @@ JS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Combodo\iTop\Form\Field\Field $oField
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function ComputeInputValidationTags(Field $oField): string
|
||||
{
|
||||
// Result tags
|
||||
$sTags = '';
|
||||
|
||||
// Iterate throw validators...
|
||||
foreach ($oField->GetValidators() as $oValidator) {
|
||||
|
||||
// Validator
|
||||
if (get_class($oValidator) === Validator::class) {
|
||||
if (!($oField instanceof DateField || $oField instanceof DateTimeField)) { // unrecognized regular expression
|
||||
$sTags .= ' pattern="'.$oValidator->GetRegExp().'" ';
|
||||
}
|
||||
}
|
||||
|
||||
// Mandatory validator
|
||||
if ($oValidator instanceof MandatoryValidator) {
|
||||
$sTags .= ' required ';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $sTags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user