From 9dfb8940cded684f3bc7195697394b2efa0a01af Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Fri, 11 Sep 2009 06:01:32 +0000 Subject: [PATCH] Added the validation of mandatory form fields before submitting the creation / modification / clone forms. SVN:trunk[140] --- application/cmdbabstract.class.inc.php | 61 +++++++++++++++++++++----- application/uiwizard.class.inc.php | 2 +- core/attributedef.class.inc.php | 1 + css/light-grey.css | 3 ++ js/forms-json-utils.js | 43 +++++++++++++++++- pages/UI.php | 15 ++++++- 6 files changed, 108 insertions(+), 17 deletions(-) diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 42e06bc0b..75e0bfc78 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -596,7 +596,7 @@ abstract class cmdbAbstractObject extends CMDBObject return $sHtml; } - public static function GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value = '', $sDisplayValue = '', $iId = '', $sNameSuffix = '') + public static function GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $value = '', $sDisplayValue = '', $iId = '', $sNameSuffix = '', $iFlags = 0) { static $iInputId = 0; if (!empty($iId)) @@ -607,20 +607,29 @@ abstract class cmdbAbstractObject extends CMDBObject { $iInputId++; } + if (!$oAttDef->IsExternalField()) { + $aCSSClasses = array(); + if ( (!$oAttDef->IsNullAllowed()) || ($iFlags & OPT_ATT_MANDATORY)) + { + $aCSSClasses[] = 'mandatory'; + } + $sCSSClasses = self::GetCSSClasses($aCSSClasses); switch($oAttDef->GetEditClass()) { case 'Date': - $sHTMLValue = ""; + $aCSSClasses[] = 'date-pick'; + $sCSSClasses = self::GetCSSClasses($aCSSClasses); + $sHTMLValue = ""; break; case 'Password': - $sHTMLValue = ""; + $sHTMLValue = ""; break; case 'Text': - $sHTMLValue = ""; + $sHTMLValue = ""; break; case 'List': @@ -637,13 +646,13 @@ abstract class cmdbAbstractObject extends CMDBObject //Enum field or external key, display a combo if (count($aAllowedValues) == 0) { - $sHTMLValue = ""; + $sHTMLValue = ""; } else if (count($aAllowedValues) > 50) { // too many choices, use an autocomplete // The input for the auto complete - $sHTMLValue = ""; + $sHTMLValue = ""; // another hidden input to store & pass the object's Id $sHTMLValue .= "\n"; $oPage->add_ready_script("\$('#label_$iInputId').autocomplete('./ajax.render.php', { minChars:3, onItemSelect:selectItem, onFindValue:findValue, formatItem:formatItem, autoFill:true, keyHolder:'#$iInputId', extraParams:{operation:'autocomplete', sclass:'$sClass',attCode:'".$sAttCode."'}});"); @@ -651,7 +660,8 @@ abstract class cmdbAbstractObject extends CMDBObject else { // Few choices, use a normal 'select' - $sHTMLValue = "\n"; + $sHTMLValue .= "\n"; foreach($aAllowedValues as $key => $display_value) { $sSelected = ($value == $key) ? ' selected' : ''; @@ -662,7 +672,7 @@ abstract class cmdbAbstractObject extends CMDBObject } else { - $sHTMLValue = ""; + $sHTMLValue = ""; } break; } @@ -672,11 +682,13 @@ abstract class cmdbAbstractObject extends CMDBObject public function DisplayModifyForm(web_page $oPage) { + static $iFormId = 0; + $iFormId++; $oAppContext = new ApplicationContext(); $sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this)); $iKey = $this->GetKey(); $aDetails = array(); - $oPage->add("
\n"); + $oPage->add("\n"); foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode=>$oAttDef) { if ('finalclass' == $sAttCode) // finalclass is a reserved word, hardcoded ! @@ -707,7 +719,7 @@ abstract class cmdbAbstractObject extends CMDBObject { $sValue = $this->Get($sAttCode); $sDisplayValue = $this->GetDisplayValue($sAttCode); - $sHTMLValue = self::GetFormElementForField($oPage, get_class($this), $sAttCode, $oAttDef, $sValue, $sDisplayValue); + $sHTMLValue = self::GetFormElementForField($oPage, get_class($this), $sAttCode, $oAttDef, $sValue, $sDisplayValue, '', '', $iFlags); } $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue); } @@ -726,11 +738,24 @@ abstract class cmdbAbstractObject extends CMDBObject public static function DisplayCreationForm(web_page $oPage, $sClass, $oObjectToClone = null) { + static $iCreationFormId = 0; + + $iCreationFormId++; $oAppContext = new ApplicationContext(); $aDetails = array(); $sOperation = ($oObjectToClone == null) ? 'apply_new' : 'apply_clone'; $sStateAttCode = MetaModel::GetStateAttributeCode(get_class($oObjectToClone)); - $oPage->add("\n"); + $oPage->add("\n"); + $aStates = MetaModel::EnumStates($sClass); + if ($oObjectToClone == null) + { + $sTargetState = MetaModel::GetDefaultState($sClass); + } + else + { + $sTargetState = $oObjectToClone->GetState(); + } + foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode=>$oAttDef) { if ('finalclass' == $sAttCode) // finalclass is a reserved word, hardcoded ! @@ -747,7 +772,9 @@ abstract class cmdbAbstractObject extends CMDBObject { $sValue = ($oObjectToClone == null) ? '' : $oObjectToClone->Get($sAttCode); $sDisplayValue = ($oObjectToClone == null) ? '' : $oObjectToClone->GetDisplayValue($sAttCode); - $sHTMLValue = self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue); + $iOptions = isset($aStates[$sTargetState]['attribute_list'][$sAttCode]) ? $aStates[$sTargetState]['attribute_list'][$sAttCode] : 0; + + $sHTMLValue = self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, '', '', $iOptions); $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue); } } @@ -764,5 +791,15 @@ abstract class cmdbAbstractObject extends CMDBObject $oPage->add("\n"); $oPage->add("
\n"); } + + protected static function GetCSSClasses($aCSSClasses) + { + $sCSSClasses = ''; + if (!empty($aCSSClasses)) + { + $sCSSClasses = ' class="'.implode(' ', $aCSSClasses).'" '; + } + return $sCSSClasses; + } } ?> diff --git a/application/uiwizard.class.inc.php b/application/uiwizard.class.inc.php index 9ef29b340..886b8fd39 100644 --- a/application/uiwizard.class.inc.php +++ b/application/uiwizard.class.inc.php @@ -56,7 +56,7 @@ class UIWizard $sFieldFlag = ($iOptions & (OPT_ATT_MANDATORY | OPT_ATT_MUSTCHANGE)) ? ' *' : ''; $oDefaultValuesSet = $oAttDef->GetDefaultValue(); // @@@ TO DO: get the object's current value if the object exists - $sHTMLValue = cmdbAbstractObject::GetFormElementForField($this->m_oPage, $this->m_sClass, $sAttCode, $oAttDef, $oDefaultValuesSet, '', "att_$iMaxInputId"); + $sHTMLValue = cmdbAbstractObject::GetFormElementForField($this->m_oPage, $this->m_sClass, $sAttCode, $oAttDef, $oDefaultValuesSet, '', "att_$iMaxInputId", '', $iOptions); $aFieldsMap[$iMaxInputId] = $sAttCode; $aDetails[] = array('label' => $oAttDef->GetLabel().$sFieldFlag, 'value' => "
$sHTMLValue
"); if ($oAttDef->GetValuesDef() != null) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index cc96f0204..42d4c5bca 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -107,6 +107,7 @@ abstract class AttributeDefinition public function IsExternalKey($iType = EXTKEY_RELATIVE) {return false;} public function IsExternalField() {return false;} public function IsWritable() {return false;} + public function IsNullAllowed() {return true;} public function GetCode() {return $this->m_sCode;} public function GetLabel() {return $this->Get("label");} public function GetDescription() {return $this->Get("description");} diff --git a/css/light-grey.css b/css/light-grey.css index 4778c40c7..994bf7a3b 100644 --- a/css/light-grey.css +++ b/css/light-grey.css @@ -660,3 +660,6 @@ div.HRDrawer { nopadding-right: 1em; margin-top: 0; } +.mandatory { + border: 1px solid #f00; +} diff --git a/js/forms-json-utils.js b/js/forms-json-utils.js index 8488a111e..1c6b5b1e3 100644 --- a/js/forms-json-utils.js +++ b/js/forms-json-utils.js @@ -57,8 +57,11 @@ function ReloadObjectFromServer(sJSON) function GoToStep(iCurrentStep, iNextStep) { var oCurrentStep = document.getElementById('wizStep'+iCurrentStep); - oCurrentStep.style.display = 'none'; - ActivateStep(iNextStep); + if (CheckMandatoryFields('wizStep'+iCurrentStep)) + { + oCurrentStep.style.display = 'none'; + ActivateStep(iNextStep); + } } function ActivateStep(iTargetStep) @@ -104,3 +107,39 @@ function AjaxGetDefaultValue(oObj, sClass, sAttCode, iFieldId) ); } } + +function CheckMandatoryFields(sFormId) +{ + $('#'+sFormId+' :submit').attr('disable', 'disabled'); + $('#'+sFormId+' :button[type=submit]').attr('disable', 'disabled'); + firstErrorId = ''; + + var iErrorsCount = 0; + $('#'+sFormId+' :input.mandatory').each( function() { + if (( this.value == '') || (this.value == 0)) + { + this.style.background = '#fcc'; + iErrorsCount++; + if (iErrorsCount == 1) + { + firstErrorId = this.id; + } + } + else + { + this.style.background = '#fff'; + } + } + ); + if(iErrorsCount > 0) + { + alert('Please fill-in all mandatory fields before continuing.'); + $('#'+sFormId+' :submit').attr('disable', ''); + $('#'+sFormId+' :button[type=submit]').attr('disable', ''); + if (firstErrorId != '') + { + $('#'+firstErrorId).focus(); + } + } + return(iErrorsCount == 0); +} diff --git a/pages/UI.php b/pages/UI.php index 36b1b6b25..b854e357f 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -278,9 +278,20 @@ switch($operation) $bIsReadAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_READ, $oSet) == UR_ALLOWED_YES); if( ($oObjToClone != null) && ($bIsModifiedAllowed) && ($bIsReadAllowed)) { + $oP->add_linked_script("../js/json.js"); + $oP->add_linked_script("../js/forms-json-utils.js"); + $oP->add_linked_script("../js/wizardhelper.js"); + $oP->add_linked_script("../js/wizard.utils.js"); + $oP->add_linked_script("../js/linkswidget.js"); + $oP->add_linked_script("../js/jquery.blockUI.js"); $oP->set_title("iTop - ".$oObjToClone->GetName()." - $sClassLabel clone"); - $oP->add("

".$oObjToClone->GetName()." - $sClassLabel clone

\n"); + $oP->add("
\n"); + $oP->add("

Clone of $sClassLabel: ".$oObjToClone->GetName()."

\n"); + $oP->add("
\n"); + + $oP->add("
\n"); cmdbAbstractObject::DisplayCreationForm($oP, $sClass, $oObjToClone); + $oP->add("
\n"); } else { @@ -611,7 +622,7 @@ switch($operation) { $aAttributesDef = MetaModel::ListAttributeDefs($sClass); $oAttDef = $aAttributesDef[$sAttCode]; - $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $oObj->Get($sAttCode), $oObj->GetDisplayValue($sAttCode)); + $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $oObj->Get($sAttCode), $oObj->GetDisplayValue($sAttCode), '', '', $iExpectCode); $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sHTMLValue); } }