Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

feat #964 Show error tooltip whenever there is an error #964

Closed
wants to merge 1 commit into from

3 participants

Srinath M divdavem Francesco Longo
Srinath M

This pull request allows error tooltip to appear as soon as there is an error while typing. For this we have introduced validation event 'onError'.

src/aria/widgets/CfgBeans.js
@@ -246,6 +246,10 @@ Aria.beanDefinitions({
$type : "json:Boolean",
$description : "Whether validation on input widgets is automatically called by default on blur."
},
+ "directOnErrorValidation" : {
+ $type : "json:Boolean",
+ $description : "Whether validation on input widgets is automatically called by default on keydown."
+ },
divdavem Collaborator

This property is not used in the widget, and is not mentioned in the spec. Please remove it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/aria/widgets/environment/WidgetSettingsCfgBeans.js
@@ -45,6 +45,11 @@ Aria.beanDefinitions({
$description : "Whether validation on input widgets is automatically called by default on blur.",
$default : true
},
+ "directOnErrorValidation" : {
+ $type : "json:Boolean",
+ $description : "Whether validation on input widgets is automatically called by default on keydown.",
+ $default : false
+ },
divdavem Collaborator

This property is not used in the widget, and is not mentioned in the spec. Please remove it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/aria/widgets/form/Input.js
@@ -364,7 +364,11 @@ Aria.classDefinition({
// environment
cfg.directOnBlurValidation = aria.widgets.environment.WidgetSettings.getWidgetSettings().directOnBlurValidation;
}
-
+ if (cfg.directOnErrorValidation == null) {
+ // the default value for directOnErrorValidation comes from the
+ // environment
+ cfg.directOnErrorValidation = aria.widgets.environment.WidgetSettings.getWidgetSettings().directOnErrorValidation;
+ }
divdavem Collaborator

directOnErrorValidation is not used in the widget, and is not mentioned in the spec. Please remove those lines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
divdavem divdavem commented on the diff
src/aria/widgets/form/MultiAutoComplete.js
((7 lines not shown))
event.preventDefault();
var report = this.controller.checkText(inputFieldValue, false);
this._reactToControllerReport(report);
this.setHelpText(false);
+ inputField.focus();
divdavem Collaborator

Why is this line needed?

This is to keep focus back to input (for a new suggestion) when user edits a suggestion, types freeText and press tab key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/aria/widgets/controllers/AutoCompleteController.js
@@ -372,6 +372,9 @@
} else {
if (!this.freeText && suggestionsAvailable && !hasSuggestions) {
report.ok = false;
+ var errorReport = this.checkText(nextValue);
+ this.widgetObj.changeProperty("formatErrorMessages", errorReport.errorMessages);
+ errorReport.$dispose();
divdavem Collaborator

The controller is not supposed to have a reference to the widget object. Any communication from the controller to the widget is supposed to be done through the report object.
In this method, we are already in the process of defining a report to be sent to the widget.
So, let's simply use the report which is already defined in order to pass the error messages to the widget.

So, I would replace those 3 lines with the following line:

report.errorMessages.push(this.res.errors["40020_WIDGET_AUTOCOMPLETE_VALIDATION"]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
...ia/widgets/controllers/MultiAutoCompleteController.js
@@ -296,6 +296,9 @@
} else {
if (!this.freeText && suggestionsAvailable && !hasSuggestions) {
report.ok = false;
+ var errorReport = this.checkText(nextValue);
+ this.widgetObj.changeProperty("formatErrorMessages", errorReport.errorMessages);
+ errorReport.$dispose();
divdavem Collaborator

Same remark as before:
The controller is not supposed to have a reference to the widget object. Any communication from the controller to the widget is supposed to be done through the report object.
In this method, we are already in the process of defining a report to be sent to the widget.
So, let's simply use the report which is already defined in order to pass the error messages to the widget.

So, I would replace those 3 lines with the following line:

report.errorMessages.push(this.res.errors["40020_WIDGET_AUTOCOMPLETE_VALIDATION"]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/aria/widgets/form/AutoComplete.js
@@ -59,6 +59,7 @@ Aria.classDefinition({
controllerInstance.maxlength = cfg.maxlength;
controllerInstance.expandButton = cfg.expandButton;
controllerInstance.selectionKeys = cfg.selectionKeys;
+ controllerInstance.widgetObj = this;
divdavem Collaborator

The controller is not supposed to have a reference to the widget object. Any communication from the controller to the widget is supposed to be done through a report object.
Please remove this line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/aria/widgets/form/MultiAutoComplete.js
@@ -37,6 +37,7 @@ Aria.classDefinition({
this._hideIconNames = ["dropdown"];
controller.maxOptions = cfg.maxOptions;
+ controller.widgetObj = this;
divdavem Collaborator

The controller is not supposed to have a reference to the widget object. Any communication from the controller to the widget is supposed to be done through a report object.
Please remove this line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/aria/widgets/form/TextInput.js
@@ -711,6 +711,14 @@ Aria.classDefinition({
|| propertyName === 'errorMessages') {
this._cfg[propertyName] = newValue;
this._reactToChange();
+ var cfg = this._cfg;
+ if (cfg && cfg.validationEvent === 'onError') {
divdavem Collaborator

According to the specifications, when validationEvent is set to "onError" the error tooltip should only appear when the widget has the focus.
So I would replace the previous line with:

if (cfg && cfg.validationEvent === 'onError' && (this._keepFocus || this._hasFocus)) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
divdavem
Collaborator

For my suggestions to work correctly, you will also need to move the code which sets formatErrorMessages from the checkValue method to the _reactToControllerReport method in TextInput.js.

To do that you could remove the following 3 lines from checkValue here (lines 439-441):

if (this._cfg.directOnBlurValidation) {
    this.changeProperty("formatErrorMessages", report.errorMessages);
}

and add the following 3 lines in _reactToControllerReport, just before the if (!delayedValidation) condition (line 515):

if (report.errorMessages.length && this._cfg.directOnBlurValidation) {
    this.changeProperty("formatErrorMessages", report.errorMessages);
}
Srinath M smadapathi referenced this pull request from a commit in smadapathi/ariatemplates
Srinath M smadapathi feat #964 Changes for Error tooltip on keydown 33b39a8
Srinath M smadapathi referenced this pull request from a commit in smadapathi/ariatemplates
Srinath M smadapathi feat #964 Changes for Error tooltip on keydown 9b9bea0
Francesco Longo flongo added this to the 1.4.16 milestone
divdavem divdavem was assigned by flongo
Srinath M smadapathi referenced this pull request from a commit in smadapathi/ariatemplates
Srinath M smadapathi feat #964 Changes for Error tooltip on keydown 05d7f53
Srinath M smadapathi referenced this pull request from a commit in smadapathi/ariatemplates
Srinath M smadapathi feat #964 Changes for Error tooltip on keydown d8a07c6
carlo-mr carlo-mr referenced this pull request from a commit in carlo-mr/ariatemplates
Srinath M smadapathi feat #964 Changes for Error tooltip on keydown
close #964
fdd1717
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 12, 2014
  1. Srinath M
This page is out of date. Refresh to see the latest.
2  src/aria/widgets/CfgBeans.js
View
@@ -256,7 +256,7 @@ Aria.beanDefinitions({
},
"validationEvent" : {
$type : "json:Enum",
- $enumValues : ["onFocus", "onBlur", "none"],
+ $enumValues : ["onFocus", "onBlur", "onError", "none"],
$default : "onFocus",
$description : "contains the event used to display the error tip"
},
1  src/aria/widgets/controllers/AutoCompleteController.js
View
@@ -372,6 +372,7 @@
} else {
if (!this.freeText && suggestionsAvailable && !hasSuggestions) {
report.ok = false;
+ report.errorMessages.push(this.res.errors["40020_WIDGET_AUTOCOMPLETE_VALIDATION"]);
} else {
report.ok = true;
}
3  src/aria/widgets/controllers/MultiAutoCompleteController.js
View
@@ -154,7 +154,7 @@
dataModel.value = null;
report.ok = true;
reportVal = null;
- } else if (value && !typeUtil.isString(value)) {
+ } else if (value && !typeUtil.isString(value) && dataModel.value !== null) {
if (this._checkWithSuggestionBean(value, this._resourcesHandler.SUGGESTION_BEAN)) {
var text = this._getLabelFromSuggestion(value);
dataModel.text = text;
@@ -296,6 +296,7 @@
} else {
if (!this.freeText && suggestionsAvailable && !hasSuggestions) {
report.ok = false;
+ report.errorMessages.push(this.res.errors["40020_WIDGET_AUTOCOMPLETE_VALIDATION"]);
} else {
report.ok = true;
}
1  src/aria/widgets/form/Input.js
View
@@ -364,7 +364,6 @@ Aria.classDefinition({
// environment
cfg.directOnBlurValidation = aria.widgets.environment.WidgetSettings.getWidgetSettings().directOnBlurValidation;
}
-
if (cfg.height > -1) {
this._inputMarkupHeight = cfg.height;
10 src/aria/widgets/form/MultiAutoComplete.js
View
@@ -20,7 +20,7 @@ Aria.classDefinition({
$classpath : "aria.widgets.form.MultiAutoComplete",
$extends : "aria.widgets.form.AutoComplete",
$dependencies : ["aria.widgets.controllers.MultiAutoCompleteController", "aria.utils.Event", "aria.utils.Dom",
- "aria.utils.Type", "aria.utils.Array", "aria.utils.Math"],
+ "aria.utils.Type", "aria.utils.Array", "aria.utils.Math", "aria.utils.String"],
$css : ["aria.widgets.form.MultiAutoCompleteStyle", "aria.widgets.form.list.ListStyle",
"aria.widgets.container.DivStyle"],
/**
@@ -85,7 +85,6 @@ Aria.classDefinition({
if (report && report.value !== null) {
this._addMultiselectValues(report, arg);
}
-
},
/**
@@ -269,13 +268,15 @@ Aria.classDefinition({
var inputField = this.getTextInputField();
var inputFieldValue = inputField.value;
var domUtil = aria.utils.Dom;
- if (tabPressed && inputFieldValue !== "") {
+ var stringUtil = aria.utils.String;
+ if (tabPressed && stringUtil.trim(inputFieldValue) !== "" && this.controller.freeText) {
event.preventDefault();
var report = this.controller.checkText(inputFieldValue, false);
this._reactToControllerReport(report);
this.setHelpText(false);
+ inputField.focus();
divdavem Collaborator

Why is this line needed?

This is to keep focus back to input (for a new suggestion) when user edits a suggestion, types freeText and press tab key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
- if (tabPressed && inputFieldValue === "" && inputField.nextSibling != null) {
+ if (tabPressed && stringUtil.trim(inputFieldValue) === "" && inputField.nextSibling != null) {
event.preventDefault();
this._makeInputFieldLastChild();
this.setHelpText(false);
@@ -292,7 +293,6 @@ Aria.classDefinition({
domUtil.removeElement(previousSiblingElement);
this._removeValues(previousSiblingLabel);
}
-
}
this.$DropDownTextInput._dom_onkeydown.call(this, event);
},
15 src/aria/widgets/form/TextInput.js
View
@@ -436,9 +436,6 @@ Aria.classDefinition({
if (!performCheckOnly) {
this.changeProperty("value", null);
this.changeProperty("invalidText", text);
- if (this._cfg.directOnBlurValidation) {
- this.changeProperty("formatErrorMessages", report.errorMessages);
- }
}
} else if (this._cfg.formatError === false && aria.utils.Type.isArray(this._cfg.formatErrorMessages)
&& this._cfg.formatErrorMessages.length) {
@@ -508,6 +505,9 @@ Aria.classDefinition({
}
}
+ if (report.errorMessages.length && this._cfg.directOnBlurValidation) {
+ this.changeProperty("formatErrorMessages", report.errorMessages);
+ }
// if the validation originated from a validation with delay we
// do not want to update the input text or
// value. The value will be set to 'undefined' though when the
@@ -711,6 +711,14 @@ Aria.classDefinition({
|| propertyName === 'errorMessages') {
this._cfg[propertyName] = newValue;
this._reactToChange();
+ var cfg = this._cfg;
+ if (cfg && cfg.validationEvent === 'onError' && (this._keepFocus || this._hasFocus)) {
+ if ((cfg.formatError && cfg.formatErrorMessages.length) || (cfg.error && cfg.errorMessages.length)) {
+ this._validationPopupShow();
+ } else {
+ this._validationPopupHide();
+ }
+ }
} else if (propertyName == "prefill") {
this.setPrefillText(true, newValue, true);
} else if (propertyName == "prefillError") {
@@ -812,7 +820,6 @@ Aria.classDefinition({
this.checkValue();
}
},
-
/**
* Internal method to handle the onkeyup event. This is called to set the value property in the data model
* through the setProperty method that also handles all other widgets bound to this value.
1  test/aria/widgets/form/autocomplete/AutoCompleteTestSuite.js
View
@@ -58,5 +58,6 @@ Aria.classDefinition({
this.addTests("test.aria.widgets.form.autocomplete.multiautocomplete.test7.MultiAutoError");
this.addTests("test.aria.widgets.form.autocomplete.multiautocomplete.test8.MultiAutoMaxOptions");
this.addTests("test.aria.widgets.form.autocomplete.multiautocomplete.test9.MultiAutoBackSpace");
+ this.addTests("test.aria.widgets.form.autocomplete.errorhandling.AutoComplete");
}
});
65 test/aria/widgets/form/autocomplete/errorhandling/AutoComplete.js
View
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 Amadeus s.a.s.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+Aria.classDefinition({
+ $classpath : "test.aria.widgets.form.autocomplete.errorhandling.AutoComplete",
+ $extends : "aria.jsunit.TemplateTestCase",
+ $prototype : {
+ /**
+ * This method is always the first entry point to a template test Start the test by focusing the first field.
+ * Initially give the field focus.
+ */
+ runTemplateTest : function () {
+ this.synEvent.click(this.getInputField("acDest"), {
+ fn : this.onAcFocused,
+ scope : this
+ });
+ },
+
+ /**
+ * Field should have focus, next trigger an exact match.
+ */
+ onAcFocused : function () {
+ this.synEvent.type(this.getInputField("acDest"), "z", {
+ fn : this.waitForType,
+ scope : this
+ });
+ },
+
+ /**
+ * Need to add a delay to allow the list to open with the returned suggestions including the exact match.
+ */
+ waitForType : function () {
+ this.waitFor({
+ condition : function () {
+ return (this.getWidgetInstance("acDest")._state == "normalErrorFocused");
+ },
+ callback : {
+ fn : this.checkErrorTooltip,
+ scope : this
+ }
+ });
+ },
+ /**
+ * Finalize the test, check the bound widgets value has been updated by a change to the data model when the
+ * enter key was triggered.
+ */
+ checkErrorTooltip : function () {
+ var acWidget = this.getWidgetInstance("acDest");
+ this.assertTrue(!!acWidget._onValidatePopup);
+ this.notifyTemplateTestEnd();
+ }
+ }
+});
45 test/aria/widgets/form/autocomplete/errorhandling/AutoCompleteTpl.tpl
View
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 Amadeus s.a.s.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{Template {
+ $classpath:"test.aria.widgets.form.autocomplete.errorhandling.AutoCompleteTpl",
+ $hasScript:true,
+ $width: {min: 500}
+}}
+
+ {var view_values = {
+ ac_air_value: null
+ }/}
+
+
+ {macro main()}
+ <h2>AutoComplete with LC resources handler</h2> <br />
+
+ {@aria:AutoComplete {
+ id: "acDest",
+ label:"Choose your destination: ",
+ labelPos:"left",
+ labelAlign:"right",
+ width:400,
+ block:false,
+ labelWidth:180,
+ validationEvent:'onError',
+ freeText:false,
+ resourcesHandler:_getCitiesHandler()
+ }/}
+
+ {/macro}
+
+{/Template}
41 test/aria/widgets/form/autocomplete/errorhandling/AutoCompleteTplScript.js
View
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013 Amadeus s.a.s.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+Aria.tplScriptDefinition({
+ $classpath : "test.aria.widgets.form.autocomplete.errorhandling.AutoCompleteTplScript",
+ $dependencies : ["aria.resources.handlers.LCResourcesHandler"],
+ $constructor : function () {
+ this._lcHandler = new aria.resources.handlers.LCResourcesHandler();
+ this._lcHandler.setSuggestions([{
+ label : 'Madrid',
+ code : 'MAD'
+ }, {
+ label : 'Rio de Janeiro',
+ code : 'RIO'
+ }, {
+ label : 'Miami',
+ code : 'MIA'
+ }]);
+ },
+ $destructor : function () {
+ this._lcHandler.$dispose();
+ this._lcHandler = null;
+ },
+ $prototype : {
+ _getCitiesHandler : function () {
+ return this._lcHandler;
+ }
+ }
+});
22 test/aria/widgets/form/autocomplete/multiautocomplete/test7/MultiAutoError.js
View
@@ -35,6 +35,7 @@ Aria.classDefinition({
* This method is always the first entry point to a template test Start the test by focusing the first field
*/
runTemplateTest : function () {
+
this.synEvent.click(this.getInputField("MultiAutoId"), {
fn : this.typeSomething,
scope : this
@@ -43,23 +44,28 @@ Aria.classDefinition({
typeSomething : function (evt, callback) {
// give it the time to open a drop down
- this.synEvent.type(this.getInputField("MultiAutoId"), "sdafwerew", {
- fn : this._wait,
+ this.synEvent.type(this.getInputField("MultiAutoId"), "az", {
+ fn : this._waitForType,
scope : this,
args : this._assertErrorState
});
},
- _wait : function (evt, callback) {
- aria.core.Timer.addCallback({
- fn : callback,
- scope : this,
- delay : 500
+ _waitForType : function () {
+ var acWidget = this.getWidgetInstance("MultiAutoId");
+ this.waitFor({
+ condition : function () {
+ return (acWidget._state == "normalErrorFocused");
+ },
+ callback : {
+ fn : this._assertErrorState,
+ scope : this
+ }
});
},
_assertErrorState : function () {
// test that the field is in error state
var acWidget = this.getWidgetInstance("MultiAutoId");
- this.assertTrue(acWidget._state == "normalErrorFocused", "The auto-complete should be in the normalErrorFocused state.");
+ this.assertTrue(!!acWidget._onValidatePopup);
this.notifyTemplateTestEnd();
}
}
5 test/aria/widgets/form/autocomplete/multiautocomplete/test7/MultiAutoErrorTpl.tpl
View
@@ -18,11 +18,11 @@
$hasScript:true
}}
-
+
{macro main()}
-
+
<h2>AutoComplete with Multi Options</h2>
<br />
{@aria:MultiAutoComplete{
@@ -30,6 +30,7 @@
helptext:"city",
id:"MultiAutoId",
labelPos:"left",
+ validationEvent:'onError',
labelAlign:"right",
width:400,
block:false,
Something went wrong with that request. Please try again.