Details
-
Type:
Improvement
-
Status: Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: EE-3.3.0.GA_P01
-
Fix Version/s: 4.0.BETA, EE-3.3.0.GA_P02, 4.0
-
Component/s: ACE-Components
-
Labels:None
-
Environment:All
-
Assignee Priority:P1
-
Salesforce Case Reference:
-
Affects:Documentation (User Guide, Ref. Guide, etc.), Compatibility/Configuration
Description
When validation has failed for an input field in the editable dataTable, clicking the revert button should put the invalid input back to its original state. This issue can be reproduced with our showcase app following these steps:
1) Select the pencil icon in the Options column for the row to edit
2) Modify the Weight (lbs) column with invalid data and click on checkmark to save, throws Invalid Exception as follows.
3) Click on the “x” to reject to revert back to original settings.
4) Click again on the pencil icon of the same row.
The invalid value is retained which should not be. At this moment the others rows can be edited but not able to save until the above row invalid data is corrected.
After clicking the revert button the output field shows the original value.
1) Select the pencil icon in the Options column for the row to edit
2) Modify the Weight (lbs) column with invalid data and click on checkmark to save, throws Invalid Exception as follows.
3) Click on the “x” to reject to revert back to original settings.
4) Click again on the pencil icon of the same row.
The invalid value is retained which should not be. At this moment the others rows can be edited but not able to save until the above row invalid data is corrected.
After clicking the revert button the output field shows the original value.
Committed fix to 4.0 trunk at revision 39907 and to 3.3. EE maintenance branch at revision 39908. The fix consists in adding an input reverting functionality to the cancel button of ace:rowEditor.
There was no real bug here. The 'x' button in ace:rowEditor wasn't a button for reverting the submitted values when editting a row. It's function was simply to cancel the row editting, which was accomplished by not executing any inputs in the request sent to the server when pressed. In fact, if you hover over that button, you'll see the tooltip reading 'Cancel Editing' and not 'Revert Editing', as specified by it's 'title' attribute.
However, if the values were already submitted by pressing the checkmark button, the cancel button didn't have the power of cancelling (reverting) what had been already submitted. Every input component is independent and goes through its own internal validation process, and this cancel button wasn't able to magically affect the internal state of all the input components in the row by simply cancelling the request, until now. That's a reason why we have the 'toggleOnInvalidEdit' attribute--to prevent exiting edit mode when there's a validation error, in order to give the user a chance to correct it.
Moreover, the normal behaviour of JSF input components is to render the 'submittedValue' (i.e. the invalid one) when validation fails. So, the invalid value wasn't supposed to be removed by simply hiding the input components when cancelling the row editing, since their 'rendered' attributes are not actually set to false, but they are simply skipped from rendering when not in edit mode.
Input reverting functionality was added to the decode() method of ace:rowEditor. The code retrieves all "input" facets from ace:cellEditor's in the row and goes through all EditableValueHolder instances and clears their submitted values and sets their valid flags to true. This causes the original, valid value to show when entering edit mode again after having cancelling the editing previously. This also allows other rows to be edited and submitted sucessfully, after reverting an invalid value. However, it's not possible to remove the FacesMessage associated with the initial failed validation. JSF simply doesn't provide a way to do that. The only way to remove it is to submit (and execute) again the input component that originally failed validation (now with a valid/original value).
An alternative, more practical solution that I found before implementing the fix above involves creating a special button at the app code level to revert the values of a row and submit them. It uses Javascript to locate each input component and reset its value to the original value used to render it. With this approach, the FacesMessage is also removed, since the inputs are submitted and executed, with their original values. For the showcase example, this approach would look like this and would be added to the last column, where ace:rowEditor is.