diff --git a/sources/autoload.php b/sources/autoload.php index d28d9e331..3c770abb3 100644 --- a/sources/autoload.php +++ b/sources/autoload.php @@ -34,8 +34,8 @@ require_once APPROOT . 'sources/form/field/checkboxfield.class.inc.php'; require_once APPROOT . 'sources/form/field/radiofield.class.inc.php'; require_once APPROOT . 'sources/form/validator/validator.class.inc.php'; require_once APPROOT . 'sources/form/validator/mandatoryvalidator.class.inc.php'; -require_once APPROOT . 'sources/form/validator/notemptyvalidator.class.inc.php'; require_once APPROOT . 'sources/form/validator/integervalidator.class.inc.php'; +require_once APPROOT . 'sources/form/validator/notemptyextkeyvalidator.class.inc.php'; require_once APPROOT . 'sources/renderer/formrenderer.class.inc.php'; require_once APPROOT . 'sources/renderer/fieldrenderer.class.inc.php'; require_once APPROOT . 'sources/renderer/renderingoutput.class.inc.php'; diff --git a/sources/form/field/field.class.inc.php b/sources/form/field/field.class.inc.php index 91f46427e..4851cbe04 100644 --- a/sources/form/field/field.class.inc.php +++ b/sources/form/field/field.class.inc.php @@ -31,6 +31,7 @@ use \Combodo\iTop\Form\Validator\MandatoryValidator; abstract class Field { const DEFAULT_LABEL = ''; + const DEFAULT_HIDDEN = false; const DEFAULT_READ_ONLY = false; const DEFAULT_MANDATORY = false; const DEFAULT_VALID = true; @@ -39,6 +40,7 @@ abstract class Field protected $sGlobalId; protected $sFormPath; protected $sLabel; + protected $bHidden; protected $bReadOnly; protected $bMandatory; protected $aValidators; @@ -58,6 +60,7 @@ abstract class Field $this->sId = $sId; $this->sGlobalId = 'field_' . $sId . '_' . uniqid(); $this->sLabel = static::DEFAULT_LABEL; + $this->bHidden = static::DEFAULT_HIDDEN; $this->bReadOnly = static::DEFAULT_READ_ONLY; $this->bMandatory = static::DEFAULT_MANDATORY; $this->aValidators = array(); @@ -105,6 +108,15 @@ abstract class Field return $this->sLabel; } + /** + * + * @return boolean + */ + public function GetHidden() + { + return $this->bHidden; + } + /** * * @return boolean @@ -185,6 +197,17 @@ abstract class Field return $this; } + /** + * + * @param boolean $bHidden + * @return \Combodo\iTop\Form\Field\Field + */ + public function SetHidden($bHidden) + { + $this->bHidden = $bHidden; + return $this; + } + /** * * @param boolean $bReadOnly diff --git a/sources/form/field/textareafield.class.inc.php b/sources/form/field/textareafield.class.inc.php index cabf91240..84c2f41fc 100644 --- a/sources/form/field/textareafield.class.inc.php +++ b/sources/form/field/textareafield.class.inc.php @@ -19,6 +19,8 @@ namespace Combodo\iTop\Form\Field; +use \Closure; +use \DBObject; use \Combodo\iTop\Form\Field\TextField; /** @@ -28,5 +30,81 @@ use \Combodo\iTop\Form\Field\TextField; */ class TextAreaField extends TextField { + const ENUM_FORMAT_TEXT = 'text'; + const ENUM_FORMAT_HTML = 'html'; + const DEFAULT_FORMAT = 'html'; + + protected $sFormat; + protected $oObject; + protected $sTransactionId; + + public function __construct($sId, Closure $onFinalizeCallback = null, DBObject $oObject = null) + { + parent::__construct($sId, $onFinalizeCallback); + $this->sFormat = static::DEFAULT_FORMAT; + $this->oObject = $oObject; + $this->sTransactionId = null; + } + + /** + * + * @return string + */ + public function GetFormat() + { + return $this->sFormat; + } + + /** + * + * @param string $sFormat + * @return \Combodo\iTop\Form\Field\TextAreaField + */ + public function SetFormat($sFormat) + { + $this->sFormat = $sFormat; + return $this; + } + + /** + * + * @return DBObject + */ + public function GetObject() + { + return $this->oObject; + } + + /** + * + * @param DBObject $oObject + * @return \Combodo\iTop\Form\Field\TextAreaField + */ + public function SetObject(DBObject $oObject) + { + $this->oObject = $oObject; + return $this; + } + + /** + * Returns the transaction id for the field. This is usally used/setted when using a html format that allows upload of files/images + * + * @return string + */ + public function GetTransactionId() + { + return $this->sTransactionId; + } + + /** + * + * @param string $sTransactionId + * @return \Combodo\iTop\Form\Field\TextAreaField + */ + public function SetTransactionId($sTransactionId) + { + $this->sTransactionId = $sTransactionId; + return $this; + } } diff --git a/sources/form/form.class.inc.php b/sources/form/form.class.inc.php index f197d7623..0b1d88a65 100644 --- a/sources/form/form.class.inc.php +++ b/sources/form/form.class.inc.php @@ -31,6 +31,7 @@ use \Combodo\iTop\Form\Field\Field; class Form { protected $sId; + protected $sTransactionId; protected $aFields; protected $aDependencies; protected $bValid; @@ -44,6 +45,7 @@ class Form public function __construct($sId) { $this->sId = $sId; + $this->sTransactionId = null; $this->aFields = array(); $this->aDependencies = array(); $this->bValid = true; @@ -59,6 +61,26 @@ class Form return $this->sId; } + /** + * + * @return string + */ + public function GetTransactionId() + { + return $this->sTransactionId; + } + + /** + * + * @param string $sTransactionId + * @return \Combodo\iTop\Form\Form + */ + public function SetTransactionId($sTransactionId) + { + $this->sTransactionId = $sTransactionId; + return $this; + } + /** * * @return array diff --git a/sources/form/formmanager.class.inc.php b/sources/form/formmanager.class.inc.php index 863a5552e..12db9d27a 100644 --- a/sources/form/formmanager.class.inc.php +++ b/sources/form/formmanager.class.inc.php @@ -51,7 +51,11 @@ abstract class FormManager $oFormRenderer = new $sFormRendererClass(); $oFormRenderer->SetEndpoint($aJson['formrenderer_endpoint']); $oFormManager->SetRenderer($oFormRenderer); - + + $oFormManager->SetForm(new Form($aJson['id'])); + $oFormManager->GetForm()->SetTransactionId($aJson['transaction_id']); + $oFormManager->GetRenderer()->SetForm($oFormManager->GetForm()); + return $oFormManager; } @@ -123,6 +127,7 @@ abstract class FormManager // Overload in child class when needed return array( 'id' => $this->oForm->GetId(), + 'transaction_id' => $this->oForm->GetTransactionId(), 'formmanager_class' => $this->GetClass(), 'formrenderer_class' => get_class($this->GetRenderer()), 'formrenderer_endpoint' => $this->GetRenderer()->GetEndpoint() diff --git a/sources/form/validator/notemptyvalidator.class.inc.php b/sources/form/validator/notemptyvalidator.class.inc.php deleted file mode 100644 index dabb32d2b..000000000 --- a/sources/form/validator/notemptyvalidator.class.inc.php +++ /dev/null @@ -1,35 +0,0 @@ - - -namespace Combodo\iTop\Form\Validator; - -use \Combodo\iTop\Form\Validator\Validator; - -/** - * Description of NotEmptyValidator - * - * @author Guillaume Lajarige - */ -class NotEmptyValidator extends Validator -{ - const VALIDATOR_NAME = 'notempty'; - const DEFAULT_REGEXP = '.*\S.*'; - const DEFAULT_ERROR_MESSAGE = 'TOTR: MUST NOT BE EMPTY MESSAGE'; - -} diff --git a/sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php b/sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php index c8bbfbf1b..049e977fc 100644 --- a/sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php +++ b/sources/renderer/bootstrap/fieldrenderer/bssimplefieldrenderer.class.inc.php @@ -19,7 +19,10 @@ namespace Combodo\iTop\Renderer\Bootstrap\FieldRenderer; +use \utils; use \Dict; +use \UserRights; +use \InlineImage; use \Combodo\iTop\Renderer\FieldRenderer; use \Combodo\iTop\Renderer\RenderingOutput; @@ -41,10 +44,10 @@ class BsSimpleFieldRenderer extends FieldRenderer $oOutput = new RenderingOutput(); $sFieldClass = get_class($this->oField); $sFieldMandatoryClass = ($this->oField->GetMandatory()) ? 'form_mandatory' : ''; - + // TODO : Shouldn't we have a field type so we don't have to maintain FQN classname ? // Rendering field in edition mode - if (!$this->oField->GetReadOnly()) + if (!$this->oField->GetReadOnly() && !$this->oField->GetHidden()) { switch ($sFieldClass) { @@ -55,11 +58,13 @@ class BsSimpleFieldRenderer extends FieldRenderer $oOutput->AddHtml(''); } $oOutput->AddHtml('
'); - $oOutput->AddHtml(''); + $oOutput->AddHtml(''); $oOutput->AddHtml(''); break; case 'Combodo\\iTop\\Form\\Field\\TextAreaField': + $bRichEditor = ($this->oField->GetFormat() === 'html'); + $oOutput->AddHtml('
'); if ($this->oField->GetLabel() !== '') { @@ -68,6 +73,21 @@ class BsSimpleFieldRenderer extends FieldRenderer $oOutput->AddHtml('
'); $oOutput->AddHtml(''); $oOutput->AddHtml('
'); + // Some additional stuff if we are displaying it with a rich editor + if ($bRichEditor) + { + $sEditorLanguage = strtolower(trim(UserRights::GetUserLanguage())); + $oOutput->AddJs( +<<oField->GetGlobalId()}').addClass('htmlEditor'); + $('#{$this->oField->GetGlobalId()}').ckeditor(function(){}, {language: '$sEditorLanguage', contentsLanguage: '$sEditorLanguage'}); +EOF + ); + if (($this->oField->GetObject() !== null) && ($this->oField->GetTransactionId() !== null)) + { + $oOutput->AddJs(InlineImage::EnableCKEditorImageUpload($this->oField->GetObject(), utils::GetUploadTempId($this->oField->GetTransactionId()))); + } + } break; case 'Combodo\\iTop\\Form\\Field\\SelectField': @@ -116,11 +136,11 @@ class BsSimpleFieldRenderer extends FieldRenderer break; case 'Combodo\\iTop\\Form\\Field\\HiddenField': - $oOutput->AddHtml(''); + $oOutput->AddHtml(''); break; } } - // ... and in read-only mode + // ... and in read-only mode (or hidden) else { // ... specific rendering for fields with mulltiple values @@ -136,12 +156,16 @@ class BsSimpleFieldRenderer extends FieldRenderer case 'Combodo\\iTop\\Form\\Field\\StringField': case 'Combodo\\iTop\\Form\\Field\\TextAreaField': $oOutput->AddHtml('
'); - if ($this->oField->GetLabel() !== '') + // Showing label / value only if read-only but not hidden + if (!$this->oField->GetHidden()) { - $oOutput->AddHtml(''); + if ($this->oField->GetLabel() !== '') + { + $oOutput->AddHtml(''); + } + $oOutput->AddHtml('
' . htmlentities($this->oField->GetCurrentValue(), ENT_QUOTES, 'UTF-8') . '
'); } - $oOutput->AddHtml('
' . $this->oField->GetCurrentValue() . '
'); - $oOutput->AddHtml(''); + $oOutput->AddHtml(''); $oOutput->AddHtml('
'); break; @@ -151,11 +175,15 @@ class BsSimpleFieldRenderer extends FieldRenderer $sFieldValue = (isset($aFieldChoices[$this->oField->GetCurrentValue()])) ? $aFieldChoices[$this->oField->GetCurrentValue()] : Dict::S('UI:UndefinedObject'); $oOutput->AddHtml('
'); - if ($this->oField->GetLabel() !== '') + // Showing label / value only if read-only but not hidden + if (!$this->oField->GetHidden()) { - $oOutput->AddHtml(''); + if ($this->oField->GetLabel() !== '') + { + $oOutput->AddHtml(''); + } + $oOutput->AddHtml('
' . $sFieldValue . '
'); } - $oOutput->AddHtml('
' . $sFieldValue . '
'); $oOutput->AddHtml(''); $oOutput->AddHtml('
'); break; @@ -171,7 +199,7 @@ class BsSimpleFieldRenderer extends FieldRenderer case 'Combodo\\iTop\\Form\\Field\\SelectField': case 'Combodo\\iTop\\Form\\Field\\HiddenField': $oOutput->AddJs( - <<oField->GetGlobalId()}").off("change keyup").on("change keyup", function(){ var me = this; @@ -188,7 +216,7 @@ EOF case 'Combodo\\iTop\\Form\\Field\\RadioField': case 'Combodo\\iTop\\Form\\Field\\CheckboxField': $oOutput->AddJs( - <<oField->GetGlobalId()} input").off("change").on("change", function(){ var me = this; @@ -220,7 +248,6 @@ EOF switch ($sFieldClass) { case 'Combodo\\iTop\\Form\\Field\\StringField': - case 'Combodo\\iTop\\Form\\Field\\TextAreaField': case 'Combodo\\iTop\\Form\\Field\\SelectField': case 'Combodo\\iTop\\Form\\Field\\HiddenField': case 'Combodo\\iTop\\Form\\Field\\RadioField': @@ -228,6 +255,13 @@ EOF $oOutput->AddJs( <<AddJs( + <<sEndpoint = $sEndpoint; + return $this; } /** diff --git a/sources/renderer/formrenderer.class.inc.php b/sources/renderer/formrenderer.class.inc.php index b1d2295ab..6056dc2ad 100644 --- a/sources/renderer/formrenderer.class.inc.php +++ b/sources/renderer/formrenderer.class.inc.php @@ -184,16 +184,21 @@ abstract class FormRenderer } /** + * Returns an array of Output for the form fields. * + * @param array $aFieldIds An array of field ids. If specified, renders only those fields * @return array */ - public function Render($aRequestedFields = null) + public function Render($aFieldIds = null) { $this->InitOutputs(); foreach ($this->oForm->GetFields() as $oField) { - if ($aRequestedFields !== null && !in_array($oField->GetId(), $aRequestedFields)) continue; + if ($aFieldIds !== null && !in_array($oField->GetId(), $aFieldIds)) + { + continue; + } $this->aOutputs[$oField->GetId()] = $this->PrepareOutputForField($oField); }