diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index ac220dce1..085a6e6ce 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -1762,7 +1762,12 @@ EOF $sValidationSpan = ""; $sReloadSpan = ""; $sHelpText = htmlentities($oAttDef->GetHelpOnEdition(), ENT_QUOTES, 'UTF-8'); - $aEventsList = array(); + + // mandatory field control vars + $aEventsList = array(); // contains any native event (like change), plus 'validate' for the form submission + $sNullValue = $oAttDef->GetNullValue(); // used for the ValidateField() call in js/forms-json-utils.js + $sFieldToValidateId = $iId; // can be different than the displayed field (for example in TagSet) + switch ($oAttDef->GetEditClass()) { case 'Date': @@ -2139,9 +2144,19 @@ EOF $sJson = $oAttDef->GetJsonForWidget($value, $aArgs); $sEscapedJson = htmlentities($sJson, ENT_QUOTES, 'UTF-8'); $sSetInputName = "attr_{$sFormPrefix}{$sAttCode}"; + + // handle form validation + $aEventsList[] = 'change'; + $aEventsList[] = 'validate'; + $sNullValue = ''; + $sFieldToValidateId = $sFieldToValidateId.AttributeSet::EDITABLE_INPUT_ID_SUFFIX; + + // generate form HTML output + $sValidationSpan = ""; $sHTMLValue = '
'.$sValidationSpan.$sReloadSpan; - $sScript = "$('#$iId').set_widget();"; + $sScript = "$('#$iId').set_widget({inputWidgetIdSuffix: '".AttributeSet::EDITABLE_INPUT_ID_SUFFIX."'});"; $oPage->add_ready_script($sScript); + break; case 'String': @@ -2226,14 +2241,13 @@ EOF $sPattern = addslashes($oAttDef->GetValidationPattern()); //'^([0-9]+)$'; if (!empty($aEventsList)) { - $sNullValue = $oAttDef->GetNullValue(); if (!is_numeric($sNullValue)) { $sNullValue = "'$sNullValue'"; // Add quotes to turn this into a JS string if it's not a number } $sOriginalValue = ($iFlags & OPT_ATT_MUSTCHANGE) ? json_encode($value) : 'undefined'; - $oPage->add_ready_script("$('#$iId').bind('".implode(' ', - $aEventsList)."', function(evt, sFormId) { return ValidateField('$iId', '$sPattern', $bMandatory, sFormId, $sNullValue, $sOriginalValue) } );\n"); // Bind to a custom event: validate + $oPage->add_ready_script("$('#$sFieldToValidateId').bind('".implode(' ', + $aEventsList)."', function(evt, sFormId) { return ValidateField('$sFieldToValidateId', '$sPattern', $bMandatory, sFormId, $sNullValue, $sOriginalValue) } );\n"); // Bind to a custom event: validate } $aDependencies = MetaModel::GetDependentAttributes($sClass, $sAttCode); // List of attributes that depend on the current one diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 7e46743ed..180a9d996 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -8738,6 +8738,7 @@ class AttributePropertySet extends AttributeTable abstract class AttributeSet extends AttributeDBFieldVoid { const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW; + const EDITABLE_INPUT_ID_SUFFIX = '-setwidget-values'; // used client side, see js/jquery.itop-set-widget.js public function __construct($sCode, array $aParams) { diff --git a/js/forms-json-utils.js b/js/forms-json-utils.js index d46227957..0e0602119 100644 --- a/js/forms-json-utils.js +++ b/js/forms-json-utils.js @@ -147,6 +147,8 @@ function CheckFields(sFormId, bDisplayAlert) oFormErrors['input_'+sFormId] = null; // First 'input' with an error, to set the focus to it $('#'+sFormId+' :input').each( function() { + // this is synchronous ! + // each field should register this event to launch ValidateField() if needed validateEventResult = $(this).trigger('validate', sFormId); } ); @@ -210,6 +212,18 @@ function ReportFieldValidationStatus(sFieldId, sFormId, bValid, sExplain) } } +/** + * To be launched on each field from normal event (click, change, ...) and 'validate' event for form submission. + * Calls ReportFieldValidationStatus() to update global vars containing fields status + * @param sFieldId + * @param sPattern + * @param bMandatory + * @param sFormId + * @param nullValue + * @param originalValue + * @returns {boolean} + * @constructor + */ function ValidateField(sFieldId, sPattern, bMandatory, sFormId, nullValue, originalValue) { var bValid = true; diff --git a/js/jquery.itop-set-widget.js b/js/jquery.itop-set-widget.js index 27bf5bd44..145cf3fec 100644 --- a/js/jquery.itop-set-widget.js +++ b/js/jquery.itop-set-widget.js @@ -62,7 +62,10 @@ $.widget('itop.set_widget', { // default options - options: {isDebug: false}, + options: { + isDebug: false, + inputWidgetIdSuffix: "-setwidget-values" + }, PARENT_CSS_CLASS: "attribute-set", ITEM_CSS_CLASS: "attribute-set-item", @@ -123,7 +126,7 @@ $.widget('itop.set_widget', _generateSelectionWidget: function ($widgetElement) { var $parentElement = $widgetElement.parent(), isWidgetElementDisabled = $widgetElement.prop("disabled"), - inputId = $widgetElement.attr("id") + "-setwidget-values"; + inputId = $widgetElement.attr("id") + this.options.inputWidgetIdSuffix; $parentElement.append(""); var $inputWidget = $("#" + inputId);