{
    "componentChunkName": "component---src-templates-doc-tsx",
    "path": "/docs/3.9.x/en/development/building-forms/",
    "result": {"data":{"navigation":{"nodes":[{"section":"Getting started","entries":[{"frontmatter":{"title":"Installation","subtitle":"Installation of scm-manager","partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/installation/"}},{"frontmatter":{"title":"First Startup","subtitle":"Administration User Creation","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/first-startup/"}},{"frontmatter":{"title":"Migrate from v1 to v3","subtitle":"How to use the Migration-Wizard","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/migrate-scm-manager-from-v1/"}},{"frontmatter":{"title":"Migrate from v2 to v3","subtitle":"Changes in the configuration","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/migrate-scm-manager-from-v2/"}},{"frontmatter":{"title":"Import existing repositories","subtitle":"How to import existing repositories into SCM-Manager","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/import/"}},{"frontmatter":{"title":"Frequently Asked Questions","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/faq/"}},{"frontmatter":{"title":"Known Issues","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/known-issues/"}}]},{"section":"User-oriented","entries":[{"frontmatter":{"title":"Repository","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/repo/"}},{"frontmatter":{"title":"User","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/user/"}},{"frontmatter":{"title":"Groups","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/group/"}},{"frontmatter":{"title":"Administration","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/admin/"}},{"frontmatter":{"title":"Profile","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/profile/"}},{"frontmatter":{"title":"Notifications","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/notification/"}},{"frontmatter":{"title":"CLI Client","subtitle":null,"partiallyActive":true},"fields":{"slug":"/docs/3.9.x/en/user/cli/"}},{"frontmatter":{"title":"Shortcuts","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/user/shortcuts/"}}]},{"section":"Administration","entries":[{"frontmatter":{"title":"Base Directory","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/basedirectory/"}},{"frontmatter":{"title":"Logging","subtitle":"Configuration and locations of SCM-Manager logging","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/logging/"}},{"frontmatter":{"title":"SCM-Server Configuration","subtitle":"Various configuration options for the SCM-Server","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/scm-server/"}},{"frontmatter":{"title":"Reverse Proxy","subtitle":"How to use SCM-Manager with common reverse proxies","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/reverse-proxies/"}},{"frontmatter":{"title":"Caching for Working Directories","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/administration/workdir_caching/"}}]},{"section":"Development","entries":[{"frontmatter":{"title":"Intellij IDEA Configuration","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/intellij-idea-configuration/"}},{"frontmatter":{"title":"Building SCM-Manager from Source","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/build-from-source/"}},{"frontmatter":{"title":"Architecture overview","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/architecture-overview/"}},{"frontmatter":{"title":"Common pitfall occurred while developing the SCM V2","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/ui-common-pitfall/"}},{"frontmatter":{"title":"Permission Concept","subtitle":"Fine-grained permission for SCM-Manager v2","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/permission-concept/"}},{"frontmatter":{"title":"Decision Table","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/decision-table/"}},{"frontmatter":{"title":"Error Handling","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/error-handling/"}},{"frontmatter":{"title":"Styleguide","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/styleguide/"}},{"frontmatter":{"title":"Testing Guide","subtitle":"Howto write tests for SCM-Manager","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/testing-guide/"}},{"frontmatter":{"title":"Integration Tests","subtitle":"How to run integration tests","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/integration-tests/"}},{"frontmatter":{"title":"UI-Extensions","subtitle":"How to extend the SCM-Manager UI with plugins","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/ui-extensions/"}},{"frontmatter":{"title":"I18n","subtitle":"Howto do internationalization","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/i18n/"}},{"frontmatter":{"title":"Building Forms","subtitle":"Howto build forms for SCM-Manager","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/building-forms/"}},{"frontmatter":{"title":"Javadoc","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/javadoc/"}},{"frontmatter":{"title":"CLI Guidelines","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/cli-guideline/"}},{"frontmatter":{"title":"Definition of Done","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/definition-of-done/"}},{"frontmatter":{"title":"DOD for UI development","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/ui-dod/"}}]},{"section":"Plugin Development","entries":[{"frontmatter":{"title":"Create a plugin","subtitle":"Create a new SCM-Manager plugin","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/create/"}},{"frontmatter":{"title":"Migrate a v1 plugin","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/migrate-plugin-from-v1/"}},{"frontmatter":{"title":"Extension Points","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/extension-points/"}},{"frontmatter":{"title":"i18n for Plugins","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/i18n-for-plugins/"}},{"frontmatter":{"title":"Plugin Descriptor","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/plugin-descriptor/"}},{"frontmatter":{"title":"SCM-Manager v2 Plugin Development","subtitle":null,"partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/plugin-development/"}},{"frontmatter":{"title":"Publish","subtitle":"Publish your Plugin","partiallyActive":null},"fields":{"slug":"/docs/3.9.x/en/development/plugins/publish/"}}]}]},"versions":{"group":[{"fieldValue":"1.0.x"},{"fieldValue":"1.x"},{"fieldValue":"2.0.x"},{"fieldValue":"2.1.x"},{"fieldValue":"2.10.x"},{"fieldValue":"2.11.x"},{"fieldValue":"2.12.x"},{"fieldValue":"2.13.x"},{"fieldValue":"2.14.x"},{"fieldValue":"2.15.x"},{"fieldValue":"2.16.x"},{"fieldValue":"2.17.x"},{"fieldValue":"2.18.x"},{"fieldValue":"2.19.x"},{"fieldValue":"2.2.x"},{"fieldValue":"2.20.x"},{"fieldValue":"2.21.x"},{"fieldValue":"2.22.x"},{"fieldValue":"2.23.x"},{"fieldValue":"2.24.x"},{"fieldValue":"2.25.x"},{"fieldValue":"2.26.x"},{"fieldValue":"2.27.x"},{"fieldValue":"2.28.x"},{"fieldValue":"2.29.x"},{"fieldValue":"2.3.x"},{"fieldValue":"2.30.x"},{"fieldValue":"2.31.x"},{"fieldValue":"2.32.x"},{"fieldValue":"2.33.x"},{"fieldValue":"2.34.x"},{"fieldValue":"2.35.x"},{"fieldValue":"2.36.x"},{"fieldValue":"2.37.x"},{"fieldValue":"2.38.x"},{"fieldValue":"2.39.x"},{"fieldValue":"2.4.x"},{"fieldValue":"2.40.x"},{"fieldValue":"2.41.x"},{"fieldValue":"2.42.x"},{"fieldValue":"2.43.x"},{"fieldValue":"2.44.x"},{"fieldValue":"2.45.x"},{"fieldValue":"2.46.x"},{"fieldValue":"2.47.x"},{"fieldValue":"2.48.x"},{"fieldValue":"2.5.x"},{"fieldValue":"2.6.x"},{"fieldValue":"2.7.x"},{"fieldValue":"2.8.x"},{"fieldValue":"2.9.x"},{"fieldValue":"3.0.x"},{"fieldValue":"3.1.x"},{"fieldValue":"3.10.x"},{"fieldValue":"3.11.x"},{"fieldValue":"3.2.x"},{"fieldValue":"3.3.x"},{"fieldValue":"3.4.x"},{"fieldValue":"3.5.x"},{"fieldValue":"3.6.x"},{"fieldValue":"3.7.x"},{"fieldValue":"3.8.x"},{"fieldValue":"3.9.x"}]},"languages":{"group":[{"fieldValue":"de"},{"fieldValue":"en"}]},"markdownRemark":{"html":"<p>Below we would like to explain how to write <a href=\"https://react-hook-form.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">React Hook Form</a> forms in an easy and fast way,\nwhy it makes sense to switch and what needs to be considered.</p>\n<h3 id=\"legacy-process\" style=\"position:relative;\"><a href=\"#legacy-process\" aria-label=\"legacy process permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Legacy Process</h3>\n<p>Previously, we passed our self-written form component into the Configuration component's render function.\nIn the form we defined a prop for each entry, plus an onChange handler that takes the value and writes it to a state.\nAdditionally, we added validation logic when a field changes.</p>\n<p>Especially in <a href=\"https://github.com/scm-manager/scm-ldap-plugin/blob/develop/src/main/js/LdapConfigurationForm.tsx#L65\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">old areas</a>, which were still built with class components, you should be very careful.</p>\n<p>A lot of boilerplate code was needed, errors were frequent, and typings were generally flawed.</p>\n<h3 id=\"standard-process\" style=\"position:relative;\"><a href=\"#standard-process\" aria-label=\"standard process permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Standard Process</h3>\n<p>React Hook Form will bring the <code class=\"language-text\">useForm</code> hook to validate your form with minimal re-render.\nThis contains a generic parameter which summarizes the possible input fields.</p>\n<p>The useForm hook returns an object with several properties:</p>\n<ul>\n<li><code class=\"language-text\">register</code> allows you to register an input or select element and apply validation rules to React Hook Form.</li>\n<li><code class=\"language-text\">formState</code> contains information about the form state. This can also specify <code class=\"language-text\">isValid</code>.</li>\n<li><code class=\"language-text\">handleSubmit</code> is called when you press the submit button and will receive the form data if form validation is successful.</li>\n<li><code class=\"language-text\">reset</code> reset either the entire form state or part of the form state.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"tsx\"><pre class=\"language-tsx\"><code class=\"language-tsx\"><span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">FC</span><span class=\"token punctuation\">,</span> useEffect <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">\"react\"</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// import hook from react-hook-form library</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useForm <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">\"react-hook-form\"</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> ReactHookForm<span class=\"token operator\">:</span> <span class=\"token function-variable function\">FC</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span>\n    register<span class=\"token punctuation\">,</span>\n    handleSubmit<span class=\"token punctuation\">,</span>\n    formState<span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> errors <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token generic-function\"><span class=\"token function\">useForm</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span>Name<span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>stored<span class=\"token punctuation\">,</span> setStored<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token generic-function\"><span class=\"token function\">useState</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span>Person<span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">onSubmit</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>person<span class=\"token operator\">:</span> Person<span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setStored</span><span class=\"token punctuation\">(</span>person<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>form</span> <span class=\"token attr-name\">onSubmit</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">handleSubmit</span><span class=\"token punctuation\">(</span>onSubmit<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">InputField</span></span> <span class=\"token attr-name\">label</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>First Name<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">autofocus</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">}</span></span> <span class=\"token spread\"><span class=\"token punctuation\">{</span><span class=\"token operator\">...</span><span class=\"token function\">register</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"firstName\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">InputField</span></span>\n        <span class=\"token attr-name\">label</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Last Name<span class=\"token punctuation\">\"</span></span>\n        <span class=\"token spread\"><span class=\"token punctuation\">{</span><span class=\"token operator\">...</span><span class=\"token function\">register</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"lastName\"</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> required<span class=\"token operator\">:</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span>\n        <span class=\"token attr-name\">validationError</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token operator\">!</span><span class=\"token operator\">!</span>errors<span class=\"token punctuation\">.</span>lastName<span class=\"token punctuation\">}</span></span>\n        <span class=\"token attr-name\">errorMessage</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token string\">\"Last name is required\"</span><span class=\"token punctuation\">}</span></span>\n      <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Level</span></span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>pt-2<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">right</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">SubmitButton</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Submit</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token class-name\">SubmitButton</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>form</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"building-configuration-forms\" style=\"position:relative;\"><a href=\"#building-configuration-forms\" aria-label=\"building configuration forms permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Building Configuration Forms</h3>\n<p><code class=\"language-text\">UseConfigLink</code> from <code class=\"language-text\">@scm-manager/ui-api</code> gets links via prop from binder and loads initial config asynchronously,\nalso specifies as reading part whether readOnly (no update link was set) and as writing part an update method.\nAs well as formProps for isLoading, isUpdating etc for ConfigurationForm.</p>\n<div class=\"gatsby-highlight\" data-language=\"tsx\"><pre class=\"language-tsx\"><code class=\"language-tsx\"><span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">FC</span><span class=\"token punctuation\">,</span> useEffect <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">\"react\"</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useForm <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">\"react-hook-form\"</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> GlobalConfig<span class=\"token operator\">:</span> <span class=\"token constant\">FC</span><span class=\"token operator\">&lt;</span>Props<span class=\"token operator\">></span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> link <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// formProps spread syntax returns prop for name, onBlur, onChange and ref and additionally attaches them to fields</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> initialConfiguration<span class=\"token punctuation\">,</span> update<span class=\"token punctuation\">,</span> isReadOnly<span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span>formProps <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token generic-function\"><span class=\"token function\">useConfigLink</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span>GlobalConfigurationDto<span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span>link<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> formState<span class=\"token punctuation\">,</span> handleSubmit<span class=\"token punctuation\">,</span> register<span class=\"token punctuation\">,</span> reset<span class=\"token punctuation\">,</span> control <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token generic-function\"><span class=\"token function\">useForm</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span>GlobalConfigurationDto<span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// mode onChange should be specified so that validation takes place immediately!</span>\n    mode<span class=\"token operator\">:</span> <span class=\"token string\">\"onChange\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>ConfigurationForm only takes care of the display of the component. All the logic now lives in the hook.</p>\n<p>Registering your own <code class=\"language-text\">onChange</code>-handler is not necessary anymore.\n<code class=\"language-text\">onSubmit</code> <code class=\"language-text\">handleSubmit</code>-function passes own submit function, which is called with filled form data type.</p>\n<p>In the <code class=\"language-text\">register</code>-function you can specify additional options for validation.\nFor example, <em>required, min, max, pattern</em>.</p>\n<div class=\"gatsby-highlight\" data-language=\"tsx\"><pre class=\"language-tsx\"><code class=\"language-tsx\"><span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">ConfigurationForm</span></span> <span class=\"token attr-name\">isValid</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>formState<span class=\"token punctuation\">.</span>isValid<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">isReadOnly</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>isReadOnly<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">onSubmit</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">handleSubmit</span><span class=\"token punctuation\">(</span>update<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span> <span class=\"token spread\"><span class=\"token punctuation\">{</span><span class=\"token operator\">...</span>formProps<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Title</span></span> <span class=\"token attr-name\">title</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">t</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"settings.title\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Checkbox</span></span>\n      <span class=\"token attr-name\">label</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">t</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fastForwardOnly.label\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span>\n      <span class=\"token attr-name\">helpText</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">t</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fastForwardOnly.helpText\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span>\n      <span class=\"token attr-name\">disabled</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>isReadOnly<span class=\"token punctuation\">}</span></span>\n      <span class=\"token spread\"><span class=\"token punctuation\">{</span><span class=\"token operator\">...</span><span class=\"token function\">register</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"fastForwardOnly\"</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> shouldUnregister<span class=\"token operator\">:</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span>\n    <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">InputField</span></span>\n      <span class=\"token attr-name\">label</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">t</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"branchesAndTagsPatterns.label\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span>\n      <span class=\"token attr-name\">helpText</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">t</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"branchesAndTagsPatterns.helpText\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span>\n      <span class=\"token attr-name\">disabled</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>isReadOnly<span class=\"token punctuation\">}</span></span>\n      <span class=\"token spread\"><span class=\"token punctuation\">{</span><span class=\"token operator\">...</span><span class=\"token function\">register</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"branchesAndTagsPatterns\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span>\n    <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">GpgVerificationControl</span></span> <span class=\"token attr-name\">control</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>control<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">isReadonly</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>isReadOnly<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n  </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token class-name\">ConfigurationForm</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h4 id=\"note-when-using-formstate\" style=\"position:relative;\"><a href=\"#note-when-using-formstate\" aria-label=\"note when using formstate permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Note when using <code class=\"language-text\">formState</code></h4>\n<p>Be sure to use as proxy to get objects out (not formState.isValid!), because you won't notice the render cycle otherwise.</p>\n<h4 id=\"set-to-initial-values\" style=\"position:relative;\"><a href=\"#set-to-initial-values\" aria-label=\"set to initial values permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set to initial values</h4>\n<p>In synchronous loading, a form can be set to an initial value using <code class=\"language-text\">defaultValue</code>.\nIn the asynchronous case, values for each field can be set separately by using <code class=\"language-text\">defaultValue={stored.fastForwardOnly}</code> or an entire form using <code class=\"language-text\">reset</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"tsx\"><pre class=\"language-tsx\"><code class=\"language-tsx\"><span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>initialConfiguration<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">reset</span><span class=\"token punctuation\">(</span>initialConfiguration<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>initialConfiguration<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"note-when-creating-new-components\" style=\"position:relative;\"><a href=\"#note-when-creating-new-components\" aria-label=\"note when creating new components permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Note when Creating new Components</h3>\n<ul>\n<li>If possible, pass all props.</li>\n<li>React Hook Form needs the following values for event to be recognized: name, onChange, onBlur, ref (reference to input element).</li>\n<li><code class=\"language-text\">FormFieldTypes</code> is not a base, but helps for backwards compatibility with old function types. When writing a new component omit old onChange!</li>\n<li>Since some components have other elements built around an input field, there is also the <code class=\"language-text\">forwardRef</code>. It creates a reference that can be passed to an inner element.</li>\n<li>Nested forms are a bit more complex to build and might need a wrapper.</li>\n<li>Validation rules are all based on the HTML standard and also allow for custom validation methods.</li>\n<li>Fields marked as <code class=\"language-text\">disabled</code> in SCM-Manager won't be included on submission. If you want to prevent interaction but need to submit the value of a form element, <code class=\"language-text\">readOnly</code> is the better choice.</li>\n</ul>\n<p>Some implementations:</p>\n<ul>\n<li><a href=\"https://github.com/scm-manager/scm-manager/blob/develop/scm-plugins/scm-git-plugin/src/main/js/GitGlobalConfiguration.tsx#L43\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Git Global Configuration</a></li>\n<li><a href=\"https://github.com/scm-manager/scm-repository-mirror-plugin/blob/develop/src/main/js/config/GlobalConfig.tsx#L37\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Repository Mirror Plugin Config</a></li>\n</ul>","description":"Below we would like to explain how to write React Hook Form forms in an easy and fast way,\nwhy it makes sense to switch and what needs to be considered. Legacy…","tableOfContents":"<ul>\n<li>\n<p><a href=\"#legacy-process\">Legacy Process</a></p>\n</li>\n<li>\n<p><a href=\"#standard-process\">Standard Process</a></p>\n</li>\n<li>\n<p><a href=\"#building-configuration-forms\">Building Configuration Forms</a></p>\n<ul>\n<li><a href=\"#note-when-using-formstate\">Note when using <code class=\"language-text\">formState</code></a></li>\n<li><a href=\"#set-to-initial-values\">Set to initial values</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#note-when-creating-new-components\">Note when Creating new Components</a></p>\n</li>\n</ul>","frontmatter":{"title":"Building Forms","subtitle":"Howto build forms for SCM-Manager","displayToc":false,"description":null,"keywords":null,"image":null}}},"pageContext":{"slug":"/docs/3.9.x/en/development/building-forms/","version":"3.9.x","latestVersion":"3.11.x","latestPageVersion":"3.11.x","language":"en","relativePath":"/development/building-forms/","canonicalPath":"/docs/latest/en/development/building-forms/","latestRootPath":"/docs/3.11.x/en/"}},
    "staticQueryHashes": ["1973669194","2742214048","2956773653","2957019495","698804963"]}