@@ -35,7 +35,8 @@ import {
3535  ValidatorType , 
3636  Experimental_DefaultFormStateBehavior , 
3737  Experimental_CustomMergeAllOf , 
38-   // FormValidation, 
38+   createErrorHandler , 
39+   unwrapErrorHandler , 
3940}  from  '@rjsf/utils' ; 
4041import  _forEach  from  'lodash/forEach' ; 
4142import  _get  from  'lodash/get' ; 
@@ -275,8 +276,6 @@ export default class Form<
275276   */ 
276277  formElement : RefObject < any > ; 
277278
278-   private  customValidationErrors : RJSFValidationError [ ]  =  [ ] ; 
279- 
280279  /** Constructs the `Form` from the `props`. Will setup the initial state from the props. It will also call the 
281280   * `onChange` handler if the initially provided `formData` is modified to add missing default values as part of the 
282281   * state construction. 
@@ -522,9 +521,21 @@ export default class Form<
522521    return  shouldRender ( this ,  nextProps ,  nextState ) ; 
523522  } 
524523
525-   // private customValidateCB = (formData: T | undefined, errors: FormValidation<T>, uiSchema?: UiSchema<T, S, F>): FormValidation<T> => { 
526-   //   const errorHandler = customValidate(newFormData, createErrorHandler<T>(newFormData), uiSchema); 
527-   // }; 
524+   /** Gets the previously raised customValidate errors. 
525+    * 
526+    * @returns  the previous customValidate errors 
527+    */ 
528+   private  getPreviousCustomValidateErrors  =  ( ) : ErrorSchema < T >  =>  { 
529+     const  {  customValidate,  uiSchema }  =  this . props ; 
530+     const  prevFormData  =  this . state . formData  as  T ; 
531+     let  customValidateErrors  =  { } ; 
532+     if  ( typeof  customValidate  ===  'function' )  { 
533+       const  errorHandler  =  customValidate ( prevFormData ,  createErrorHandler < T > ( prevFormData ) ,  uiSchema ) ; 
534+       const  userErrorSchema  =  unwrapErrorHandler < T > ( errorHandler ) ; 
535+       customValidateErrors  =  userErrorSchema ; 
536+     } 
537+     return  customValidateErrors ; 
538+   } ; 
528539
529540  /** Validates the `formData` against the `schema` using the `altSchemaUtils` (if provided otherwise it uses the 
530541   * `schemaUtils` in the state), returning the results. 
@@ -651,18 +662,39 @@ export default class Form<
651662    if  ( resolvedSchema ?. type  !==  'object'  &&  resolvedSchema ?. type  !==  'array' )  { 
652663      filteredErrors . __errors  =  schemaErrors . __errors ; 
653664    } 
665+ 
666+     const  prevCustomValidateErrors  =  this . getPreviousCustomValidateErrors ( ) ; 
667+     // Filtering out the previous raised customValidate errors so that they are cleared when no longer valid. 
668+     const  filterPreviousCustomErrors  =  ( errors : string [ ]  =  [ ] ,  prevCustomErrors : string [ ] )  =>  { 
669+       if  ( errors . length  ===  0 )  { 
670+         return  errors ; 
671+       } 
672+ 
673+       return  errors . filter ( ( error )  =>  { 
674+         return  ! prevCustomErrors . includes ( error ) ; 
675+       } ) ; 
676+     } ; 
677+ 
654678    // Removing undefined, null and empty errors. 
655-     const  filterNilOrEmptyErrors  =  ( errors : any ) : ErrorSchema < T >  =>  { 
679+     const  filterNilOrEmptyErrors  =  ( errors : any ,   previousCustomValidateErrors :  any   =   { } ) : ErrorSchema < T >  =>  { 
656680      _forEach ( errors ,  ( errorAtKey ,  errorKey : keyof  typeof  errors )  =>  { 
681+         const  prevCustomValidateErrorAtKey  =  previousCustomValidateErrors [ errorKey ] ; 
657682        if  ( _isNil ( errorAtKey ) )  { 
658683          delete  errors [ errorKey ] ; 
684+         }  else  if  ( 
685+           isObject ( errorAtKey )  && 
686+           isObject ( prevCustomValidateErrorAtKey )  && 
687+           Array . isArray ( prevCustomValidateErrorAtKey ?. __errors ) 
688+         )  { 
689+           // if previous customValidate error is an object and has __errors array, filter out the errors previous customValidate errors. 
690+           errors [ errorKey ]  =  filterPreviousCustomErrors ( errorAtKey . __errors ,  prevCustomValidateErrorAtKey . __errors ) ; 
659691        }  else  if  ( typeof  errorAtKey  ===  'object'  &&  ! Array . isArray ( errorAtKey . __errors ) )  { 
660-           filterNilOrEmptyErrors ( errorAtKey ) ; 
692+           filterNilOrEmptyErrors ( errorAtKey ,   previousCustomValidateErrors [ errorKey ] ) ; 
661693        } 
662694      } ) ; 
663695      return  errors ; 
664696    } ; 
665-     return  filterNilOrEmptyErrors ( filteredErrors ) ; 
697+     return  filterNilOrEmptyErrors ( filteredErrors ,   prevCustomValidateErrors ) ; 
666698  } 
667699
668700  /** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the 
@@ -710,12 +742,8 @@ export default class Form<
710742        errors  =  merged . errors ; 
711743      } 
712744      // Merging 'newErrorSchema' into 'errorSchema' to display the custom raised errors. 
713-       console . log ( 'newErrorSchema****' ,  newErrorSchema ) ; 
714745      if  ( newErrorSchema )  { 
715746        const  filteredErrors  =  this . filterErrorsBasedOnSchema ( newErrorSchema ,  retrievedSchema ,  newFormData ) ; 
716-         console . log ( 'filteredErrors' ,  filteredErrors ) ; 
717-         console . log ( 'newFormData' ,  newFormData ) ; 
718-         console . log ( 'filteredErrors formData' ,  formData ) ; 
719747        errorSchema  =  mergeObjects ( errorSchema ,  filteredErrors ,  'preventDuplicates' )  as  ErrorSchema < T > ; 
720748      } 
721749      state  =  { 
0 commit comments