@@ -111,6 +111,7 @@ export type FormOptions<T extends ZodValidation<AnyZodObject>, M> = Partial<{
111111 } ) => MaybePromise < unknown | void > ;
112112 onUpdate : ( event : {
113113 form : Validation < UnwrapEffects < T > , M > ;
114+ formEl : HTMLFormElement ;
114115 cancel : ( ) => void ;
115116 } ) => MaybePromise < unknown | void > ;
116117 onUpdated : ( event : {
@@ -492,21 +493,6 @@ export function superForm<
492493 form : Validation < T2 , M > ,
493494 untaint : boolean
494495 ) {
495- let cancelled = false ;
496- const data = {
497- form,
498- cancel : ( ) => ( cancelled = true )
499- } ;
500-
501- for ( const event of formEvents . onUpdate ) {
502- await event ( data ) ;
503- }
504-
505- if ( cancelled ) {
506- if ( options . flashMessage ) cancelFlash ( options ) ;
507- return ;
508- }
509-
510496 if (
511497 form . valid &&
512498 options . resetForm &&
@@ -792,49 +778,45 @@ export function superForm<
792778 } ) ;
793779
794780 // Need to subscribe to catch page invalidation.
795- if ( options . applyAction ) {
796- Unsubscriptions_add (
797- page . subscribe ( async ( pageUpdate ) => {
798- function error ( type : string ) {
799- throw new SuperFormError (
800- `No form data found in ${ type } . Make sure you return { form } in form actions and load functions.`
801- ) ;
802- }
781+ Unsubscriptions_add (
782+ page . subscribe ( async ( pageUpdate ) => {
783+ if ( ! options . applyAction ) return ;
803784
804- const untaint =
805- pageUpdate . status >= 200 && pageUpdate . status < 300 ;
785+ function error ( type : string ) {
786+ throw new SuperFormError (
787+ `No form data found in ${ type } . Make sure you return { form } in form actions and load functions.`
788+ ) ;
789+ }
806790
807- if ( pageUpdate . form && typeof pageUpdate . form === 'object' ) {
808- const forms = Context_findValidationForms ( pageUpdate . form ) ;
809- if ( ! forms . length ) error ( '$page.form (ActionData)' ) ;
791+ const untaint = pageUpdate . status >= 200 && pageUpdate . status < 300 ;
810792
811- for ( const newForm of forms ) {
812- //console.log('🚀~ ActionData ~ newForm:', newForm.id );
813- if ( /*newForm === form ||*/ newForm . id !== _formId ) continue ;
793+ if ( pageUpdate . form && typeof pageUpdate . form === 'object' ) {
794+ const forms = Context_findValidationForms ( pageUpdate . form ) ;
795+ if ( ! forms . length ) error ( '$page. form (ActionData)' ) ;
814796
815- await Form_updateFromValidation (
816- newForm as Validation < T2 , M > ,
817- untaint
818- ) ;
819- }
820- } else if (
821- pageUpdate . data &&
822- typeof pageUpdate . data === 'object'
823- ) {
824- const forms = Context_findValidationForms ( pageUpdate . data ) ;
825-
826- // It's a page reload, redirect or error/failure,
827- // so don't trigger any events, just update the data.
828- for ( const newForm of forms ) {
829- //console.log('🚀 ~ PageData ~ newForm:', newForm.id);
830- if ( /*newForm === form ||*/ newForm . id !== _formId ) continue ;
831-
832- rebind ( newForm as Validation < T2 , M > , untaint ) ;
833- }
797+ for ( const newForm of forms ) {
798+ //console.log('🚀~ ActionData ~ newForm:', newForm.id);
799+ if ( /*newForm === form ||*/ newForm . id !== _formId ) continue ;
800+
801+ await Form_updateFromValidation (
802+ newForm as Validation < T2 , M > ,
803+ untaint
804+ ) ;
834805 }
835- } )
836- ) ;
837- }
806+ } else if ( pageUpdate . data && typeof pageUpdate . data === 'object' ) {
807+ const forms = Context_findValidationForms ( pageUpdate . data ) ;
808+
809+ // It's a page reload, redirect or error/failure,
810+ // so don't trigger any events, just update the data.
811+ for ( const newForm of forms ) {
812+ //console.log('🚀 ~ PageData ~ newForm:', newForm.id);
813+ if ( /*newForm === form ||*/ newForm . id !== _formId ) continue ;
814+
815+ rebind ( newForm as Validation < T2 , M > , untaint ) ;
816+ }
817+ }
818+ } )
819+ ) ;
838820 }
839821
840822 const Fields = Object . fromEntries (
@@ -938,7 +920,8 @@ export function superForm<
938920 Meta ,
939921 Constraints ,
940922 Tainted ,
941- LastChanges
923+ LastChanges ,
924+ Context_findValidationForms
942925 ) ;
943926 } ,
944927
@@ -1256,7 +1239,10 @@ function formEnhance<T extends AnyZodObject, M>(
12561239 meta : Readable < Entity < T > [ 'meta' ] | undefined > ,
12571240 constraints : Readable < Entity < T > [ 'constraints' ] > ,
12581241 tainted : Writable < TaintedFields < T > | undefined > ,
1259- lastChanges : Writable < string [ ] [ ] >
1242+ lastChanges : Writable < string [ ] [ ] > ,
1243+ Context_findValidationForms : (
1244+ data : Record < string , unknown >
1245+ ) => Validation < AnyZodObject > [ ]
12601246) {
12611247 // Now we know that we are upgraded, so we can enable the tainted form option.
12621248 enableTaintedForm ( ) ;
@@ -1728,60 +1714,89 @@ function formEnhance<T extends AnyZodObject, M>(
17281714 }
17291715
17301716 if ( ! cancelled ) {
1731- if ( result . type !== 'error' ) {
1732- if ( result . type === 'success' && options . invalidateAll ) {
1733- await invalidateAll ( ) ;
1717+ if (
1718+ ( result . type === 'success' || result . type == 'failure' ) &&
1719+ result . data
1720+ ) {
1721+ const forms = Context_findValidationForms ( result . data ) ;
1722+ if ( ! forms . length ) {
1723+ throw new SuperFormError (
1724+ 'No form data returned from ActionResult. Make sure you return { form } in the form actions.'
1725+ ) ;
17341726 }
17351727
1736- if ( options . applyAction ) {
1737- // This will trigger the page subscription in superForm,
1738- // which will in turn call Data_update.
1739- await applyAction ( result ) ;
1740- } else {
1741- // Call Data_update directly to trigger events
1742- await Data_update ( result ) ;
1728+ for ( const newForm of forms ) {
1729+ if ( newForm . id !== get ( id ) ) continue ;
1730+
1731+ const data = {
1732+ form : newForm as Validation < T > ,
1733+ formEl,
1734+ cancel : ( ) => ( cancelled = true )
1735+ } ;
1736+
1737+ for ( const event of formEvents . onUpdate ) {
1738+ await event ( data ) ;
1739+ }
17431740 }
1744- } else {
1745- // Error result
1746- if ( options . applyAction ) {
1747- if ( options . onError == 'apply' ) {
1741+ }
1742+
1743+ if ( ! cancelled ) {
1744+ if ( result . type !== 'error' ) {
1745+ if ( result . type === 'success' && options . invalidateAll ) {
1746+ await invalidateAll ( ) ;
1747+ }
1748+
1749+ if ( options . applyAction ) {
1750+ // This will trigger the page subscription in superForm,
1751+ // which will in turn call Data_update.
17481752 await applyAction ( result ) ;
17491753 } else {
1750- // Transform to failure, to avoid data loss
1751- await applyAction ( {
1752- type : 'failure' ,
1753- status : Math . floor ( result . status || 500 )
1754- } ) ;
1754+ // Call Data_update directly to trigger events
1755+ await Data_update ( result ) ;
1756+ }
1757+ } else {
1758+ // Error result
1759+ if ( options . applyAction ) {
1760+ if ( options . onError == 'apply' ) {
1761+ await applyAction ( result ) ;
1762+ } else {
1763+ // Transform to failure, to avoid data loss
1764+ await applyAction ( {
1765+ type : 'failure' ,
1766+ status : Math . floor ( result . status || 500 )
1767+ } ) ;
1768+ }
17551769 }
1756- }
17571770
1758- // Check if the error message should be replaced
1759- if ( options . onError !== 'apply' ) {
1760- // TODO: Omit 'apply' and undefined from the type
1761- // They are already filtered out, but type shouldn't be any.
1762- const data = { result, message } ;
1771+ // Check if the error message should be replaced
1772+ if ( options . onError !== 'apply' ) {
1773+ // TODO: Omit 'apply' and undefined from the type
1774+ // They are already filtered out, but type shouldn't be any.
1775+ const data = { result, message } ;
17631776
1764- for ( const event of formEvents . onError ) {
1765- if ( event !== 'apply' ) await event ( data ) ;
1777+ for ( const event of formEvents . onError ) {
1778+ if ( event !== 'apply' ) await event ( data ) ;
1779+ }
17661780 }
17671781 }
1768- }
17691782
1770- // Set flash message, which should be set in all cases, even
1771- // if we have redirected (which is the point of the flash message!)
1772- if ( options . flashMessage ) {
1773- if ( result . type == 'error' && options . flashMessage . onError ) {
1774- await options . flashMessage . onError ( {
1775- result,
1776- message : options . flashMessage . module . getFlash ( page )
1777- } ) ;
1778- } else if ( result . type != 'error' ) {
1779- await options . flashMessage . module . updateFlash ( page ) ;
1783+ // Set flash message, which should be set in all cases, even
1784+ // if we have redirected (which is the point of the flash message!)
1785+ if ( options . flashMessage ) {
1786+ if ( result . type == 'error' && options . flashMessage . onError ) {
1787+ await options . flashMessage . onError ( {
1788+ result,
1789+ message : options . flashMessage . module . getFlash ( page )
1790+ } ) ;
1791+ } else if ( result . type != 'error' ) {
1792+ await options . flashMessage . module . updateFlash ( page ) ;
1793+ }
17801794 }
17811795 }
1782- } else {
1783- // Cancelled
1784- if ( options . flashMessage ) cancelFlash ( options ) ;
1796+ }
1797+
1798+ if ( cancelled && options . flashMessage ) {
1799+ cancelFlash ( options ) ;
17851800 }
17861801
17871802 htmlForm . completed ( cancelled ) ;
0 commit comments