[{"data":1,"prerenderedAt":437},["ShallowReactive",2],{"content-\u002Fdocs\u002Fsubmitting\u002Fhandle-submit":3},{"id":4,"title":5,"body":6,"description":419,"extension":420,"meta":421,"metaRows":422,"navigation":431,"path":432,"seo":433,"source":434,"stem":435,"__hash__":436},"docs\u002Fdocs\u002Fsubmitting\u002Fhandle-submit.md","handleSubmit",{"type":7,"value":8,"toc":412},"minimark",[9,16,27,30,46,51,56,159,169,173,176,220,240,244,296,306,310,368,376,380,408],[10,11,13],"h1",{"id":12},"handlesubmit",[14,15,5],"code",{},[17,18,19],"blockquote",{},[20,21,22,23,26],"p",{},"A submit handler that waits for validation, hands you parsed values, and routes rejections through ",[14,24,25],{},"onError",".",[28,29],"docs-meta-table",{},[20,31,32,33,35,36,39,40,45],{},"Submit the form without checking the terms box to watch the ",[14,34,25],{}," path fire: focus pulls to the broken field and the rejection alert lands. Check the box, fill the email, submit again to see ",[14,37,38],{},"onSubmit"," receive the parsed values. The ",[41,42,44],"a",{"href":43},"#the-dispatch-contract","dispatch contract"," section traces every step between the click and the callback.",[47,48],"docs-demo",{"label":49,"slug":50},"handleSubmit Demo","handle-submit",[52,53,55],"h2",{"id":54},"signature","Signature",[57,58,63],"pre",{"className":59,"code":60,"language":61,"meta":62,"style":62},"language-ts shiki shiki-themes github-light github-dark","const submit = form.handleSubmit(\n  async (values) => {\n    \u002F* onSubmit *\u002F\n  },\n  (errors) => {\n    \u002F* onError, optional *\u002F\n  }\n)\n","ts","",[14,64,65,91,113,120,126,141,147,153],{"__ignoreMap":62},[66,67,70,74,78,81,85,88],"span",{"class":68,"line":69},"line",1,[66,71,73],{"class":72},"szBVR","const",[66,75,77],{"class":76},"sj4cs"," submit",[66,79,80],{"class":72}," =",[66,82,84],{"class":83},"sVt8B"," form.",[66,86,5],{"class":87},"sScJk",[66,89,90],{"class":83},"(\n",[66,92,94,97,100,104,107,110],{"class":68,"line":93},2,[66,95,96],{"class":72},"  async",[66,98,99],{"class":83}," (",[66,101,103],{"class":102},"s4XuR","values",[66,105,106],{"class":83},") ",[66,108,109],{"class":72},"=>",[66,111,112],{"class":83}," {\n",[66,114,116],{"class":68,"line":115},3,[66,117,119],{"class":118},"sJ8bj","    \u002F* onSubmit *\u002F\n",[66,121,123],{"class":68,"line":122},4,[66,124,125],{"class":83},"  },\n",[66,127,129,132,135,137,139],{"class":68,"line":128},5,[66,130,131],{"class":83},"  (",[66,133,134],{"class":102},"errors",[66,136,106],{"class":83},[66,138,109],{"class":72},[66,140,112],{"class":83},[66,142,144],{"class":68,"line":143},6,[66,145,146],{"class":118},"    \u002F* onError, optional *\u002F\n",[66,148,150],{"class":68,"line":149},7,[66,151,152],{"class":83},"  }\n",[66,154,156],{"class":68,"line":155},8,[66,157,158],{"class":83},")\n",[20,160,161,162,165,166,26],{},"The return value is a function ready for ",[14,163,164],{},"\u003Cform @submit.prevent>",". Call signature: ",[14,167,168],{},"(event?: Event) => Promise\u003Cvoid>",[52,170,172],{"id":171},"the-dispatch-contract","The dispatch contract",[20,174,175],{},"When the returned handler fires:",[177,178,179,191,194,197,213],"ol",{},[180,181,182,183,186,187,190],"li",{},"The form's submit count increments. ",[14,184,185],{},"form.meta.submissionAttempts"," lifts; the default ",[14,188,189],{},"getDisplayState"," heuristic starts surfacing errors for every field.",[180,192,193],{},"Sync validation runs across every active path.",[180,195,196],{},"Async refinements are awaited.",[180,198,199,200,203,204,208,209,212],{},"If every refinement passes, ",[14,201,202],{},"onSubmit(values)"," is called with the ",[205,206,207],"strong",{},"parsed"," Zod output: ",[14,210,211],{},".transform","-aware, fully typed.",[180,214,215,216,219],{},"If anything fails, focus pulls to the first invalid field and ",[14,217,218],{},"onError(errors)"," fires (when supplied).",[20,221,222,223,225,226,229,230,233,234,236,237,239],{},"While step 4 is awaiting your ",[14,224,38],{}," callback, ",[14,227,228],{},"form.meta.submitting"," is ",[14,231,232],{},"true",". It flips back when the callback resolves or rejects (",[14,235,5],{}," catches and surfaces errors through ",[14,238,25],{},").",[52,241,243],{"id":242},"without-onerror","Without onError",[57,245,247],{"className":59,"code":246,"language":61,"meta":62,"style":62},"const submit = form.handleSubmit(async (values) => {\n  await api.signup(values)\n})\n",[14,248,249,277,291],{"__ignoreMap":62},[66,250,251,253,255,257,259,261,264,267,269,271,273,275],{"class":68,"line":69},[66,252,73],{"class":72},[66,254,77],{"class":76},[66,256,80],{"class":72},[66,258,84],{"class":83},[66,260,5],{"class":87},[66,262,263],{"class":83},"(",[66,265,266],{"class":72},"async",[66,268,99],{"class":83},[66,270,103],{"class":102},[66,272,106],{"class":83},[66,274,109],{"class":72},[66,276,112],{"class":83},[66,278,279,282,285,288],{"class":68,"line":93},[66,280,281],{"class":72},"  await",[66,283,284],{"class":83}," api.",[66,286,287],{"class":87},"signup",[66,289,290],{"class":83},"(values)\n",[66,292,293],{"class":68,"line":115},[66,294,295],{"class":83},"})\n",[20,297,298,299,301,302,305],{},"Skip ",[14,300,25],{}," when the default behavior (focus the first invalid field) is enough. Validation errors still surface through ",[14,303,304],{},"form.errors.\u003Cpath>","; the optional callback is for cross-field UI behavior like a toast or a console log.",[52,307,309],{"id":308},"submission-state","Submission state",[57,311,315],{"className":312,"code":313,"language":314,"meta":62,"style":62},"language-vue shiki shiki-themes github-light github-dark","\u003Cbutton :disabled=\"form.meta.submitting\" type=\"submit\">\n  {{ form.meta.submitting ? 'Saving…' : 'Save' }}\n\u003C\u002Fbutton>\n","vue",[14,316,317,354,359],{"__ignoreMap":62},[66,318,319,322,326,329,332,335,339,341,343,346,348,351],{"class":68,"line":69},[66,320,321],{"class":83},"\u003C",[66,323,325],{"class":324},"s9eBZ","button",[66,327,328],{"class":83}," :",[66,330,331],{"class":87},"disabled",[66,333,334],{"class":83},"=",[66,336,338],{"class":337},"sZZnC","\"",[66,340,228],{"class":83},[66,342,338],{"class":337},[66,344,345],{"class":87}," type",[66,347,334],{"class":83},[66,349,350],{"class":337},"\"submit\"",[66,352,353],{"class":83},">\n",[66,355,356],{"class":68,"line":93},[66,357,358],{"class":83},"  {{ form.meta.submitting ? 'Saving…' : 'Save' }}\n",[66,360,361,364,366],{"class":68,"line":115},[66,362,363],{"class":83},"\u003C\u002F",[66,365,325],{"class":324},[66,367,353],{"class":83},[20,369,370,372,373,375],{},[14,371,228],{}," is the reactive flag while the ",[14,374,38],{}," callback runs.",[52,377,379],{"id":378},"where-to-next","Where to next",[381,382,383,391,398],"ul",{},[180,384,385,390],{},[41,386,388],{"href":387},"\u002Fdocs\u002Freading-the-form\u002Ferrors",[14,389,134],{},": the per-path error reads.",[180,392,393,397],{},[41,394,396],{"href":395},"\u002Fdocs\u002Fvalidation\u002Fwhen-validation-runs","When validation runs",": the timing knob.",[180,399,400,404,405,407],{},[41,401,403],{"href":402},"\u002Fdocs\u002Fvalidation\u002Fshowing-errors","Display state and showing errors",": the ",[14,406,189],{}," predicate.",[409,410,411],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":62,"searchDepth":93,"depth":93,"links":413},[414,415,416,417,418],{"id":54,"depth":93,"text":55},{"id":171,"depth":93,"text":172},{"id":242,"depth":93,"text":243},{"id":308,"depth":93,"text":309},{"id":378,"depth":93,"text":379},"handleSubmit wraps a submit callback in Attaform's validation gate. Values reach onSubmit only after every async refinement has settled, with focus pulled to the first invalid field if not.","md",{},[423,426,428],{"label":424,"value":425},"Category","Return method",{"label":55,"value":427,"kind":14},"handleSubmit(onSubmit, onError?)",{"label":429,"value":430,"kind":14},"Returns","(event?) => Promise\u003Cvoid>",true,"\u002Fdocs\u002Fsubmitting\u002Fhandle-submit",{"title":5,"description":419},null,"docs\u002Fsubmitting\u002Fhandle-submit","R3MGVBEYX-HRM3Sj8DbirC7aeJpCBCB-f-viEE6lYCo",1780949760555]