<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Data Driven Forms</title>
    <description>The latest articles on Forem by Data Driven Forms (@datadrivenforms).</description>
    <link>https://forem.com/datadrivenforms</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F333244%2F2b793a2e-81c0-4617-bf39-9574779d881f.jpg</url>
      <title>Forem: Data Driven Forms</title>
      <link>https://forem.com/datadrivenforms</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/datadrivenforms"/>
    <language>en</language>
    <item>
      <title>Introducing Material-UI component mapper for Data Driven Forms</title>
      <dc:creator>Data Driven Forms</dc:creator>
      <pubDate>Thu, 14 Jan 2021 09:18:42 +0000</pubDate>
      <link>https://forem.com/datadrivenforms/introducing-material-ui-component-mapper-for-data-driven-forms-13m5</link>
      <guid>https://forem.com/datadrivenforms/introducing-material-ui-component-mapper-for-data-driven-forms-13m5</guid>
      <description>&lt;p&gt;One of the most popular design system &lt;a href="https://github.com/mui-org/material-ui"&gt;Material-UI&lt;/a&gt; is integrated to Data Driven Forms to make building React forms as fast as possible with the least amount of boilerplate. Via Data Driven Forms &lt;a href="https://www.npmjs.com/package/@data-driven-forms/mui-component-mapper"&gt;mui-component-mapper&lt;/a&gt; users can start using Material React components to &lt;a href="https://medium.com/javascript-in-plain-english/data-driven-form-building-in-react-30768b49e625"&gt;write complex forms just in seconds&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Data Driven Forms
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://data-driven-forms.org/"&gt;Data Driven Forms&lt;/a&gt; is a &lt;a href="https://github.com/data-driven-forms/react-forms/"&gt;open source&lt;/a&gt; React library that uses a &lt;a href="https://medium.com/javascript-in-plain-english/data-driven-approach-to-forms-with-react-c69fd4ea7923"&gt;data driven approach&lt;/a&gt; for &lt;a href="https://medium.com/javascript-in-plain-english/data-driven-form-building-in-react-30768b49e625"&gt;building&lt;/a&gt; React forms. This approach is based on rendering JSON schemas as React forms with all needed functionality provided by the &lt;a href="https://data-driven-forms.org/components/renderer"&gt;renderer&lt;/a&gt;. It includes features such as &lt;a href="https://data-driven-forms.org/schema/introduction#validate"&gt;validation&lt;/a&gt;, &lt;a href="https://data-driven-forms.org/schema/introduction#condition"&gt;conditional fields&lt;/a&gt; and many more. It helps web developers to write forms much quicker, simpler and to achieve a consistency across the whole application.&lt;/p&gt;

&lt;h2&gt;
  
  
  About mappers
&lt;/h2&gt;

&lt;p&gt;A mapper is a set of components integrated with Data Driven Forms API. This set allows users to write forms without any need to implement their own components, so they can immediately write fully working forms with a wide range of features (displaying errors, wizard forms, etc.) You can also check the other mappers including components from &lt;a href="https://data-driven-forms.org/mappers/suir-component-mapper"&gt;Semantic UI React&lt;/a&gt;, &lt;a href="https://data-driven-forms.org/mappers/ant-component-mapper"&gt;Ant Design&lt;/a&gt; or &lt;a href="https://data-driven-forms.org/mappers/blueprint-component-mapper"&gt;BlueprintJS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;About Material-UI&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mui-org/material-ui"&gt;Material-UI&lt;/a&gt; with more than 61k stars is one of the most popular React libraries and it provides tens of flexible components for building all types of UIs following Google's &lt;a href="https://material.io/design"&gt;Material Design&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Provided features
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/introduction"&gt;Form state management, validation, conditions and much more&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/optimization"&gt;Treeshaking&lt;/a&gt;: select between CommonJS, ESM or UMD packages to achieve the minimal bundle size.&lt;/li&gt;
&lt;li&gt;  Typescript definitions for all components.&lt;/li&gt;
&lt;li&gt;  Additional components and additional props.&lt;/li&gt;
&lt;li&gt;  Wizard forms (see below.)&lt;/li&gt;
&lt;li&gt;  Dual list selector.&lt;/li&gt;
&lt;li&gt;  All inputs properly show errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Provided components
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/text-field?mapper=mui"&gt;TextField&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QKC1kQfv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/655/1%2AkzGHUknqiVtry7swdT0uOw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QKC1kQfv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/655/1%2AkzGHUknqiVtry7swdT0uOw.png" alt="Text input showing John as value. Enter name as label with a helper text."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/textarea?mapper=mui"&gt;Textarea&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DORnG7iv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/667/1%2Ai3uDaKMCfpVaMTyebFVcAg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DORnG7iv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/667/1%2Ai3uDaKMCfpVaMTyebFVcAg.gif" alt="Textarea description field that shows length of the value in helper text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Textarea using &lt;a href="https://data-driven-forms.org/schema/resolve-props"&gt;resolveProps&lt;/a&gt; to dynamically change the helper text&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/radio?mapper=mui"&gt;Radio&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8x3Tzqtd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/180/1%2AxL0e0ZJxGDl9SQJjWehsdA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8x3Tzqtd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/180/1%2AxL0e0ZJxGDl9SQJjWehsdA.png" alt="Radios, label: 'Do you like React? *' Radio 1: 'Yes' Radio 2: 'Of yourse, yeah'"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Checkboxes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/mappers/checkbox?mapper=mui"&gt;single&lt;/a&gt;/&lt;a href="https://data-driven-forms.org/mappers/checkbox-multiple?mapper=mui"&gt;multiple&lt;/a&gt; variant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OasE5ktz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/275/1%2A9NvbLTbh2Nvq2v58wr_u6A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OasE5ktz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/275/1%2A9NvbLTbh2Nvq2v58wr_u6A.png" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Single variant checkbox&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4C_-bo0W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/134/1%2AGZ5cTABvskG66BQZIqAnNQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4C_-bo0W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/134/1%2AGZ5cTABvskG66BQZIqAnNQ.png" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Multiple variant checkbox&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/date-picker?mapper=mui"&gt;DatePicker&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QHFYX12E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/667/1%2A5g5RxK3cCKcGCERlkX617Q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QHFYX12E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/667/1%2A5g5RxK3cCKcGCERlkX617Q.gif" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DatePicker&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/time-picker?mapper=mui"&gt;TimePicker&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rx3PPYOo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/667/1%2AM2DKESWhq5AoXtHJfeAFUw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rx3PPYOo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/667/1%2AM2DKESWhq5AoXtHJfeAFUw.gif" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TimePicker&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/switch?mapper=mui"&gt;Switch&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w930AkST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/243/1%2ABMsAHQLcVS9wUgTlEk80bw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w930AkST--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/243/1%2ABMsAHQLcVS9wUgTlEk80bw.gif" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A switch with on text and off text&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/select?mapper=mui"&gt;Select/Multiselect&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5i0s9aSI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/657/1%2AVFgBY2R4jmqCU1o5wLKl5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5i0s9aSI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/657/1%2AVFgBY2R4jmqCU1o5wLKl5g.png" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Single select&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r14qCwKW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/660/1%2AQxv9zfXn_FSJiTOqBMSb8Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r14qCwKW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/660/1%2AQxv9zfXn_FSJiTOqBMSb8Q.png" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Multi select&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/sub-form?mapper=mui"&gt;SubForm&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  allows to divide forms into sub groups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Li04MCds--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/659/1%2AsKSjySVFSjNjQ6uNrudEGg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Li04MCds--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/659/1%2AsKSjySVFSjNjQ6uNrudEGg.png" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A form splitted to two groups&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/plain-text?mapper=mui"&gt;PlainText&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uDcqcfnW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/163/1%2AHi5m2CI7xlkT7T95VIrkhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uDcqcfnW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/163/1%2AHi5m2CI7xlkT7T95VIrkhw.png" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Header and overline variants&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/slider?mapper=mui"&gt;Slider&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g5kaquLC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/597/1%2AfyRoMVAGXu7DeQJZ-PL4Ww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g5kaquLC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/597/1%2AfyRoMVAGXu7DeQJZ-PL4Ww.png" alt="Slider component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/tabs?mapper=mui"&gt;Tabs&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y9tYp8Pc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/333/1%2AqmG478KYCny3EYNKBo3qTQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y9tYp8Pc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/333/1%2AqmG478KYCny3EYNKBo3qTQ.gif" alt="Tabs component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/wizard?mapper=mui"&gt;Wizard&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  branching paths&lt;/li&gt;
&lt;li&gt;  submits only visited values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U2uUD5zR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/606/1%2AD3hpq4o0iyC2aDLUzF_3tg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U2uUD5zR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/606/1%2AD3hpq4o0iyC2aDLUzF_3tg.gif" alt="A wizard component, a GIF showing that users can branch their paths"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DualListSelect (custom component)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  allows to move options between two lists&lt;/li&gt;
&lt;li&gt;  filtering, sorting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fLudw9_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/944/1%2AbHLLMLsn6llGQfkq5I_yjQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fLudw9_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/944/1%2AbHLLMLsn6llGQfkq5I_yjQ.gif" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A dual list component lets users to move values between two lists&lt;/p&gt;

&lt;h2&gt;
  
  
  FieldArray (custom component)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  allows to dynamically add form fields into forms&lt;/li&gt;
&lt;li&gt;  i.e. registering multiple users at once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X6AXagwz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/618/1%2AyQBT2S5Zvyyu7-nM6JW-iw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X6AXagwz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/618/1%2AyQBT2S5Zvyyu7-nM6JW-iw.gif" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FieldArray component allows to add another fields into the form. In the GIF, you can see that this form is allowing to add more users to a users list and these users' groups can be then changed via using &lt;a href="https://data-driven-forms.org/schema/condition-schema"&gt;conditions&lt;/a&gt; to verify/not to verify the email.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://data-driven-forms.org/components/form-template"&gt;FormTemplate&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2-ct1ldc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/612/1%2AcFZMJWOQemFAMIYKZgeHXg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2-ct1ldc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/612/1%2AcFZMJWOQemFAMIYKZgeHXg.png" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FormTemplate component provides title, description and buttons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error example
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--El5qWe0f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/659/1%2AEYTaRZe1hCA8pFytjMEQWw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--El5qWe0f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/659/1%2AEYTaRZe1hCA8pFytjMEQWw.png" alt="Image for post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://data-driven-forms.org/schema/introduction#heading-validate"&gt;validate&lt;/a&gt; is it simple to set any kind of inline validation.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/carbon-component-mapper#installation"&gt;Installation&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;npm install --save @data-driven-forms/mui-component-mapper&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;yarn add @data-driven-forms/mui-component-mapper&lt;/p&gt;

&lt;p&gt;Material-UI components and icons have to be installed separately. Please follow their &lt;a href="https://material-ui.com/getting-started/installation/"&gt;guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more information, please reach &lt;a href="https://data-driven-forms.org/"&gt;the documentation page&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Contribution
&lt;/h1&gt;

&lt;p&gt;Data Driven Forms is an open source project, all community contributions are welcomed. If you encounter any issue, please let us know on &lt;a href="https://github.com/data-driven-forms/react-forms"&gt;GitHub&lt;/a&gt; issues page or open a PR. You can also follow the project on Twitter &lt;a href="https://twitter.com/DataDrivenForms"&gt;@DataDrivenForms&lt;/a&gt; or reach us on our &lt;a href="https://discord.gg/6sBw6WM"&gt;Discord server&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ddf</category>
      <category>react</category>
      <category>materialui</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Introducing Carbon component mapper for Data Driven Forms
</title>
      <dc:creator>Data Driven Forms</dc:creator>
      <pubDate>Thu, 17 Dec 2020 10:04:08 +0000</pubDate>
      <link>https://forem.com/datadrivenforms/introducing-carbon-component-mapper-for-data-driven-forms-1lip</link>
      <guid>https://forem.com/datadrivenforms/introducing-carbon-component-mapper-for-data-driven-forms-1lip</guid>
      <description>&lt;p&gt;The &lt;a href="https://data-driven-forms.org/" rel="noopener noreferrer"&gt;Data Driven Forms&lt;/a&gt; team released &lt;a href="https://data-driven-forms.org/mappers/carbon-component-mapper" rel="noopener noreferrer"&gt;Carbon component mapper&lt;/a&gt; that integrates IBM React Carbon components into Data Driven Forms.&lt;/p&gt;

&lt;h4&gt;
  
  
  About Data Driven Forms
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://data-driven-forms.org/" rel="noopener noreferrer"&gt;Data Driven Forms&lt;/a&gt; is a &lt;a href="https://github.com/data-driven-forms/react-forms/" rel="noopener noreferrer"&gt;open source&lt;/a&gt; React library that uses a &lt;a href="https://dev.to/datadrivenforms/simple-data-driven-way-for-building-react-forms-1nip"&gt;data driven approach&lt;/a&gt; for &lt;a href="https://dev.to/datadrivenforms/data-driven-react-forms-building-in-multiple-design-systems-5d41"&gt;building&lt;/a&gt; React forms. This approach is based on rendering JSON schemas as React forms with all needed functionality provided by the &lt;a href="https://data-driven-forms.org/components/renderer" rel="noopener noreferrer"&gt;renderer&lt;/a&gt;. It includes features such as &lt;a href="https://data-driven-forms.org/schema/introduction#validate" rel="noopener noreferrer"&gt;validation&lt;/a&gt;, &lt;a href="https://data-driven-forms.org/schema/introduction#condition" rel="noopener noreferrer"&gt;conditional fields&lt;/a&gt; and many more. It helps web developers to write forms much quicker, simpler and to achieve a consistency across the whole application.&lt;/p&gt;

&lt;h4&gt;
  
  
  About mappers
&lt;/h4&gt;

&lt;p&gt;A mapper is a set of components integrated with Data Driven Forms API. This set allows users to write forms without any need to implement their own components, so they can immediately write fully working forms with a wide range of features (displaying errors, wizard forms, etc.) You can also check the other mappers including components from &lt;a href="https://data-driven-forms.org/mappers/suir-component-mapper" rel="noopener noreferrer"&gt;Semantic UI React&lt;/a&gt;, &lt;a href="https://data-driven-forms.org/mappers/ant-component-mapper" rel="noopener noreferrer"&gt;Ant Design&lt;/a&gt; or &lt;a href="https://data-driven-forms.org/mappers/blueprint-component-mapper" rel="noopener noreferrer"&gt;BlueprintJS&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  About Carbon Design System
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://www.carbondesignsystem.com/" rel="noopener noreferrer"&gt;Carbon Design System&lt;/a&gt; is a set of patterns, rules and components for building modern web applications. This system is fully open sourced and maintained by IBM.&lt;/p&gt;

&lt;h4&gt;
  
  
  Provided features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/introduction" rel="noopener noreferrer"&gt;Form state management, validation, conditions and much more&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/optimization" rel="noopener noreferrer"&gt;&lt;strong&gt;Treeshaking&lt;/strong&gt;&lt;/a&gt;: select between CommonJS, ESM or UMD packages to achieve the minimal bundle size.&lt;/li&gt;
&lt;li&gt;  Typescript definitions.&lt;/li&gt;
&lt;li&gt;  Additional components and additional props:&lt;/li&gt;
&lt;li&gt;  all components supports helperText,&lt;/li&gt;
&lt;li&gt;  all components display error texts.&lt;/li&gt;
&lt;li&gt;  Wizard forms (see below.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Provided components
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/text-field?mapper=carbon" rel="noopener noreferrer"&gt;TextField&lt;/a&gt; (TextInput)
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AaeiI4ZKdTxk19huoR7HJqQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AaeiI4ZKdTxk19huoR7HJqQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/textarea?mapper=carbon" rel="noopener noreferrer"&gt;Textarea&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2Aet8y9eNK-NN5dnVzBR9isQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2Aet8y9eNK-NN5dnVzBR9isQ.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/radio?mapper=carbon" rel="noopener noreferrer"&gt;Radio&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AFjGxEmwvAjPFhd2PoPYuiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AFjGxEmwvAjPFhd2PoPYuiw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Checkboxes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/mappers/checkboxmapper=carbon" rel="noopener noreferrer"&gt;single&lt;/a&gt;/&lt;a href="https://data-driven-forms.org/mappers/checkbox-multiple?mapper=carbon" rel="noopener noreferrer"&gt;multiple&lt;/a&gt; variant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AEj8DGYCoVERrzFImsIZNNQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AEj8DGYCoVERrzFImsIZNNQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Multiple variant&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A_zr83y64UfbmWzOfe4WlqA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A_zr83y64UfbmWzOfe4WlqA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Single variant&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/date-picker?mapper=carbon" rel="noopener noreferrer"&gt;DatePicker&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AHiY-c_Acf-KxOIHzs84BQA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AHiY-c_Acf-KxOIHzs84BQA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/time-picker?mapper=carbon" rel="noopener noreferrer"&gt;TimePicker&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  including AM/PM and timezone selectors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AhugY9yhfYcj2-Pi76lQmkA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AhugY9yhfYcj2-Pi76lQmkA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/switch?mapper=carbon" rel="noopener noreferrer"&gt;Switch&lt;/a&gt; (Toggle)
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ASiwr8QCt1gV0JQEr0NNC5g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ASiwr8QCt1gV0JQEr0NNC5g.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/select?mapper=carbon" rel="noopener noreferrer"&gt;Select&lt;/a&gt;/&lt;a href="https://data-driven-forms.org/mappers/select?mapper=carbon" rel="noopener noreferrer"&gt;Multiselect&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  allows to lazy load initial data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AkC8lhPv7Kq3dnGIPBiNTcA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AkC8lhPv7Kq3dnGIPBiNTcA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Single select&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AUtTjLTZOQxPUz6g-bJpqcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AUtTjLTZOQxPUz6g-bJpqcw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Multiple select&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/sub-form?mapper=carbon" rel="noopener noreferrer"&gt;SubForm&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  allows to divide forms into sub groups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AvoJD1jOfZYhKATg2i7BILQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AvoJD1jOfZYhKATg2i7BILQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/plain-text?mapper=carbon" rel="noopener noreferrer"&gt;PlainText&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  allows to render any text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AAL6iB3bDma6PyC7aD4EJQQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AAL6iB3bDma6PyC7aD4EJQQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/slider?mapper=carbon" rel="noopener noreferrer"&gt;Slider&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AfTXp6qOtdVFd482q-zZ7vw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AfTXp6qOtdVFd482q-zZ7vw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/tabs?mapper=carbon" rel="noopener noreferrer"&gt;Tabs&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2Au3DMGMfZek8H6RptGTmpxg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2Au3DMGMfZek8H6RptGTmpxg.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/wizard?mapper=carbon" rel="noopener noreferrer"&gt;Wizard&lt;/a&gt; (custom component)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  branching paths&lt;/li&gt;
&lt;li&gt;  interactive navigation&lt;/li&gt;
&lt;li&gt;  submits only visited values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AY3S8wKYyu3Yg5pG1EDpw1Q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AY3S8wKYyu3Yg5pG1EDpw1Q.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/dual-list-select?mapper=carbon" rel="noopener noreferrer"&gt;DualListSelect&lt;/a&gt; (custom componet)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  allows to move options between two lists&lt;/li&gt;
&lt;li&gt;  filtering, sorting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AkbYtpRv4nacqKTzRzBYVFw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AkbYtpRv4nacqKTzRzBYVFw.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/field-array?mapper=carbon" rel="noopener noreferrer"&gt;FieldArray&lt;/a&gt; (custom component)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  allows to dynamically add form fields into forms&lt;/li&gt;
&lt;li&gt;  i.e. registering multiple users at once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A9Jz8lIRCIRHErSmf471_TA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A9Jz8lIRCIRHErSmf471_TA.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/components/form-template" rel="noopener noreferrer"&gt;FormTemplate&lt;/a&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  the form (spacing, buttons) is designed according Carbon's guidelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AHJn6Nc3GN1yOdWWOey-taw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AHJn6Nc3GN1yOdWWOey-taw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://data-driven-forms.org/mappers/carbon-component-mapper#installation" rel="noopener noreferrer"&gt;Installation&lt;/a&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; @data-driven-forms/carbon-component-mapper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @data-driven-forms/carbon-component-mapper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information, please reach &lt;a href="https://data-driven-forms.org/" rel="noopener noreferrer"&gt;the documentation page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contribution
&lt;/h3&gt;

&lt;p&gt;Data Driven Forms is an open source project, all community contributions are welcomed. If you encounter any issue, please let us know on &lt;a href="https://github.com/data-driven-forms/react-forms" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; issues page or open a PR. You can also follow the project on Twitter &lt;a href="https://twitter.com/DataDrivenForms" rel="noopener noreferrer"&gt;@DataDrivenForms&lt;/a&gt; or reach us on our &lt;a href="https://discord.gg/6sBw6WM" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>forms</category>
      <category>carbon</category>
    </item>
    <item>
      <title>Data Driven React forms building in multiple design systems</title>
      <dc:creator>Data Driven Forms</dc:creator>
      <pubDate>Mon, 29 Jun 2020 12:37:49 +0000</pubDate>
      <link>https://forem.com/datadrivenforms/data-driven-react-forms-building-in-multiple-design-systems-5d41</link>
      <guid>https://forem.com/datadrivenforms/data-driven-react-forms-building-in-multiple-design-systems-5d41</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JDuH6r_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/44ul19pjjsi1qle55l19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JDuH6r_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/44ul19pjjsi1qle55l19.png" alt="Available design systems"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally published &lt;a href="https://medium.com/javascript-in-plain-english/data-driven-form-building-in-react-30768b49e625"&gt;here&lt;/a&gt;. Original author: Richard Všianský&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Design system&lt;/em&gt; is a very powerful buzzword of today's application development. Each tech company is trying to achieve consistency and simple developer experience by incorporating one of them into all their applications.&lt;/p&gt;

&lt;p&gt;Additionally, many of them are open-sourced and publicly available. To illustrate it we can mention IBM's &lt;a href="https://www.carbondesignsystem.com/"&gt;Carbon&lt;/a&gt;, Google's &lt;a href="https://material.io/design"&gt;Material&lt;/a&gt;, or Red Hat's &lt;a href="https://www.patternfly.org/v4/"&gt;PatternFly&lt;/a&gt;. These libraries are customizable and easy to use with many predefined components, so even small projects can use them to make their own development easier, cheaper, and faster without sacrificing a custom identity.&lt;/p&gt;

&lt;p&gt;However, choosing the right one is particularly hard when there are so many of them. Because of that, it's a great idea to start with a simple prototype but doing it shouldn't take so much time. One tool helping with that is &lt;a href="https://data-driven-forms.org/"&gt;Data Driven Forms&lt;/a&gt; (&lt;em&gt;DDF&lt;/em&gt;), a React library for rendering and managing forms using a &lt;a href="https://dev.to/datadrivenforms/simple-data-driven-way-for-building-react-forms-1nip"&gt;data driven approach&lt;/a&gt;. This approach takes JSON data and changes them into fully functional forms. Complex forms can be 'coded' in minutes without any actual code knowledge.&lt;/p&gt;

&lt;h1&gt;
  
  
  Use case --- creating a form schema
&lt;/h1&gt;

&lt;p&gt;Let's imagine a simple case to implement: a registration form. According to our &lt;em&gt;fictional&lt;/em&gt; product management, the form consists of several elements users have to enter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Nickname&lt;/li&gt;
&lt;li&gt;  Email&lt;/li&gt;
&lt;li&gt;  Password&lt;/li&gt;
&lt;li&gt;  Confirm Password&lt;/li&gt;
&lt;li&gt;  Terms confirmation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can start directly with defining a Data Driven Forms schema according to its &lt;a href="https://data-driven-forms.org/renderer/renderer-api#schema"&gt;definition&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The schema is an object containing one required attribute: fields. An array of form fields. Each of these are defined by objects having just &lt;a href="https://data-driven-forms.org/renderer/component-api#commonpropsforallformfields"&gt;two required attributes&lt;/a&gt;: name and component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;additionalAttributes&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Both of them are string values defining what their names exactly suggests. Component depends on a used set of components, but in libraries provided by Data Driven Forms we can find &lt;a href="https://data-driven-forms.org/renderer/component-api"&gt;all basic form components&lt;/a&gt; under keys such as &lt;code&gt;text-field, select, checkbox, radio, textarea, ...&lt;/code&gt;. These components then implement their custom attributes, most of them are shared: &lt;code&gt;label, helperText, options, ...&lt;/code&gt; . In React, attributes correspond to component props.&lt;/p&gt;

&lt;p&gt;So, let's transform our elements to fields definitions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Nickname
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nickname&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, this is clearly not enough to satisfy (&lt;em&gt;also fictional&lt;/em&gt;) UX requirements. There is no label and validation --- with a configuration like this, it's just a single HTML input element. Luckily, in Data Driven Forms fixing that is really simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nickname&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nick name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are introduced two new attributes: label and validate. &lt;a href="https://data-driven-forms.org/renderer/validators"&gt;Validate&lt;/a&gt; is an array of validators --- objects or functions. Data Driven Forms provide basic validation covering most cases (length, patterns), but it can be also customized by providing &lt;a href="https://data-driven-forms.org/renderer/validators#customfunction"&gt;a function&lt;/a&gt; (&lt;a href="https://data-driven-forms.org/renderer/validators#asyncvalidator"&gt;async functions&lt;/a&gt; are also supported!) or using &lt;a href="https://data-driven-forms.org/renderer/validators#customvalidatormapper"&gt;validatorMapper&lt;/a&gt; to define custom types. These custom types can be then used in string-based objects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://data-driven-forms.org/renderer/validators#requiredvalidator"&gt;required validator&lt;/a&gt; is one of the implemented validators by the library, so we can use it immediately. (We could add another attribute to the field: isRequired, a boolean value that appends a required mark to the field. However, all inputs are required in our form, so it's better to put a single note to the beginning of the form. We will do it later.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jL-UQ9yQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/684/1%2AGuiFh7SMmIOv3aVBpSsrPA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jL-UQ9yQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/684/1%2AGuiFh7SMmIOv3aVBpSsrPA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The difference between isRequired. (Material UI design)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can use the knowledge obtained in the previous paragraph to write the same object for the email, but the email has an additional format limitation. We will use &lt;a href="https://data-driven-forms.org/renderer/validators#patternvalidators"&gt;pattern validation&lt;/a&gt; type to enforce it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;,{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pattern&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,}$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Not valid email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZW9hQI7D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/354/1%2AjYPuUZ6rJs0E8VBlMODwqA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZW9hQI7D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/354/1%2AjYPuUZ6rJs0E8VBlMODwqA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Validation triggered on the email field. (Semantic UI design)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Password
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
   &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;min-length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;helperText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password has to be at least 6 chars long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A new validator type is used: &lt;code&gt;min-length&lt;/code&gt; makes sure that the value will have a length of 6 or more. &lt;code&gt;type: 'password'&lt;/code&gt; is a standard HTML input element type, that shows the value as dots. &lt;code&gt;helperText&lt;/code&gt; renders additional information to the field, its position and look depends on the used design library.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c28kvj-o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/367/1%2Am7nK78EVMkRqOhE5RnglOg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c28kvj-o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/367/1%2Am7nK78EVMkRqOhE5RnglOg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The password field with helperText and password type. (BlueprintJS design)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Confirm Password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's do a twist here: there is a requirement that the password confirmation field will appear only if users enter some password to the field above. From the UX viewpoint, it does not make much sense, but it will nicely show another feature of Data Driven Forms: &lt;a href="https://data-driven-forms.org/renderer/condition"&gt;conditional fields&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confirm-password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Confirm your password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Data Driven Forms provides several types of conditions --- one of them is &lt;a href="https://data-driven-forms.org/renderer/condition#isnotempty"&gt;isNotEmpty&lt;/a&gt;. Using this type we can make sure that users have to enter the password first. DDF also allows to nest conditions (&lt;em&gt;AND, OR, NOT&lt;/em&gt;), so all combinations are possible.&lt;/p&gt;

&lt;p&gt;However, we are still missing to check if the confirmation is the same as the password. As said earlier, we can do it via providing a function in the validate array or adding a custom type to in &lt;code&gt;validatorMapper&lt;/code&gt;. We will use the second option, because we need to access all values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validatorMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;same-password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;allValues&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;allValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password do not match&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that the validator is a function returning a function (&lt;em&gt;high-order function&lt;/em&gt;.) This construct allow to cache results or pass additional arguments from the schema. We will use this object as a prop later. Now, we can use this type in the validate array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;same-password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that we can remove the required validator as it's already checked in the initial password field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ICWCUGud--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/382/1%2Aw7D9vLQlgzU_ia7siU0nfQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ICWCUGud--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/382/1%2Aw7D9vLQlgzU_ia7siU0nfQ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cross-field validation and conditional field. (PatternFly 4 design)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Terms confirmation
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;terms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I agree with our business terms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Changing the component is simple --- just replace the component string. Everything else works still the same.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VeJ7k3qn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/367/1%2Arz5ftX8KVaH3s02dYgah-w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VeJ7k3qn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/367/1%2Arz5ftX8KVaH3s02dYgah-w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Checkbox component. (PatternFly 3 design)&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Final schema
&lt;/h1&gt;

&lt;p&gt;Now, we can put all the fields together in the final schema with adding a title and description:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Registration form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;All fields are required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nickname&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nick name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;}]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pattern&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,}$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Not valid email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;min-length&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;helperText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password has to be at least 6 chars long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confirm-password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;same-password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Confirm your password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;terms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I agree with our business terms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;}]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In just few minutes, we have written a fully functional and human readable form with many advanced features.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, let's make it work in our React project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using of Data Driven Forms
&lt;/h1&gt;

&lt;p&gt;The first thing we have to do is to install &lt;a href="https://www.npmjs.com/package/@data-driven-forms/react-form-renderer"&gt;r&lt;/a&gt;eact-form-renderer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save @data-driven-forms/react-form-renderer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @data-driven-forms/react-form-renderer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is the core of the Data Driven Forms library. The renderer is the component responsible for converting the schema into React components and it provides all the features we mentioned in this article.&lt;/p&gt;

&lt;p&gt;After we install it, we can import it into our project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FormRenderer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@data-driven-forms/react-form-renderer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// if you want to treeshake the component&lt;/span&gt;
&lt;span class="c1"&gt;// import FormRenderer from '@data-driven-forms/react-form-renderer/dist/cjs/form-renderer';&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// defined earlier&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validatorMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// defined earlier, not required&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FormRenderer&lt;/span&gt;
      &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formApi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;FormTemplate&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;FormTemplate&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;componentMapper&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;componentMapper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;validatorMapper&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;validatorMapper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="c1"&gt;// not required*&lt;/span&gt;
   &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
 &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;onSubmit is a submit function. Typically it would be a function making a request to API endpoint. schema is the object we created in the previous chapter. However, two props are still missing: FormTemplate and componentMapper. This is the point of this article: these two props define components the form uses. &lt;a href="https://data-driven-forms.org/renderer/component-mapping"&gt;componentMapper&lt;/a&gt; includes components we are using in the schema: &lt;em&gt;text-field&lt;/em&gt;, &lt;em&gt;checkbox&lt;/em&gt;, etc. &lt;a href="https://data-driven-forms.org/renderer/form-template"&gt;FormTemplate&lt;/a&gt; wraps the form, renders buttons, show a title.&lt;/p&gt;

&lt;p&gt;We can implement our own components and templates, but Data Driven Forms offers multiple prepared libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/mappers/mui-component-mapper"&gt;Material UI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/mappers/blueprint-component-mapper"&gt;BlueprintJS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/mappers/suir-component-mapper"&gt;Semantic UI React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/mappers/pf3-component-mapper"&gt;PatternFly 3&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://data-driven-forms.org/mappers/pf4-component-mapper"&gt;PatternFly 4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XTeT_HuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1072/1%2AX0Z0pkKN906OnA1GAsgXnA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XTeT_HuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1072/1%2AX0Z0pkKN906OnA1GAsgXnA.png" alt="Available Data Driven Forms mappers library"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Available Data Driven Forms mappers libraries.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We call these libraries 'mappers' because they map Data Driven Forms attributes and features to libraries' props. For example, &lt;code&gt;label&lt;/code&gt; attribute from the schema is mapped to &lt;code&gt;FormLabel&lt;/code&gt; Material UI component.&lt;/p&gt;

&lt;p&gt;Using of these mappers is as simple as it can be. Install them, import them and use them in the renderer component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FormRenderer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@data-driven-forms/react-form-renderer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;componentMapper&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@data-driven-forms/mui-component-mapper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// you can also treeshake whatever component you need&lt;/span&gt;
&lt;span class="c1"&gt;// import FormTemplate from '@data-driven-forms/mui-component-mapper/dist/cjs/form-template';&lt;/span&gt;
&lt;span class="c1"&gt;// import TextField from '@data-driven-forms/mui-component-mapper/dist/cjs/text-field';&lt;/span&gt;
&lt;span class="c1"&gt;// import Checkbox from '@data-driven-forms/mui-component-mapper/dist/cjs/checkbox';&lt;/span&gt;
&lt;span class="c1"&gt;// const componentMapper = { 'text-field': TextField, checkbox: Checkbox }&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// defined earlier&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validatorMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// defined earlier&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FormRenderer&lt;/span&gt;
      &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formApi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;FormTemplate&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;FormTemplate&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;componentMapper&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;componentMapper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;validatorMapper&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;validatorMapper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
 &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Because all mappers' APIs are the same, we can quickly switch between them and choose the one we like the most.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, we have to still install components libraries and their styles separately. The Data Driven Forms documentation page provides links leading to each library's installation guide or you can use examples below as starter points. Be aware that some libraries overwrites global styles, so be sure that you include only one of them at one time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Material UI form
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D-hbP__6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/509/1%2Ac7Z2bGAFI1jESirWRSwy1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D-hbP__6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/509/1%2Ac7Z2bGAFI1jESirWRSwy1A.png" alt="Material UI React form showcase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/wttpqn"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  BlueprintJS form
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nath3BfH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/537/1%2AE5m9vjxAR3AtP9SQM3CsYw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nath3BfH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/537/1%2AE5m9vjxAR3AtP9SQM3CsYw.png" alt="BlueprintJS React form showcase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/e9przu"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantic UI form
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G5aaKdwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/588/1%2AeV1lH0CjKLwNMnbZR_xkIg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G5aaKdwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/588/1%2AeV1lH0CjKLwNMnbZR_xkIg.png" alt="Semantic UI React form showcase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/feb5xg"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  PatternFly 4 form
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N-hNmoel--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/516/1%2AS7msByYdcgMq23TVn0x16A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N-hNmoel--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/516/1%2AS7msByYdcgMq23TVn0x16A.png" alt="Patternfly 4 React form showcase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/eydxlw"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  PatternFly 3 form
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ajkb6QKz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/545/1%2ABjxklo5C-ZMUrH_Z1nNvQQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ajkb6QKz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/545/1%2ABjxklo5C-ZMUrH_Z1nNvQQ.png" alt="PatternFly 3 React form showcase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/zdpmfp"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Using Data Driven Forms we wrote common code defining the schema of form and everything else is provided by the library. We can run all these projects and take a look at how the libraries differ from each other. All these forms are fully functional, so during prototyping, we can code the whole form and switch the design library anytime we need to.&lt;/p&gt;

&lt;p&gt;Also, it's simple to customize each part of the form --- if you don't like the headers or buttons, just switch them in FormTemplate. Or you can replace the whole components, add your custom ones, and much more.&lt;/p&gt;

&lt;p&gt;In addition, there are more complex components like &lt;a href="https://data-driven-forms.org/component-example/wizard"&gt;Wizard&lt;/a&gt; or &lt;a href="https://data-driven-forms.org/component-example/select"&gt;Select&lt;/a&gt; --- writing them from scratch can take hours, using them in Data Driven Forms is just as simple as using &lt;em&gt;text-field&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UBiSFGq2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/1018/1%2ALXCEAwj7QKKNPXgAAlI2SQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UBiSFGq2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/1018/1%2ALXCEAwj7QKKNPXgAAlI2SQ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A &lt;a href="https://data-driven-forms.org/component-example/dual-list-select"&gt;dual list select&lt;/a&gt; component provided by Data Driven Forms. (Material UI design)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you want to use different or custom components/design library, Data Driven Forms provides a &lt;a href="https://data-driven-forms.org/renderer/development-setup#generatingamappertemplate"&gt;simple command line&lt;/a&gt; that generates the structure of the whole package, it can even add TypeScript definitions. Just run&lt;code&gt;yarn generate-template&lt;/code&gt; inside a root folder of &lt;a href="https://github.com/data-driven-forms/react-forms"&gt;DDF repository&lt;/a&gt; and interactive CLI will guide you. Next time, we will take look at this command and making a custom mapper.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The &lt;/em&gt;&lt;a href="https://data-driven-forms.org/"&gt;&lt;em&gt;Data Driven Forms&lt;/em&gt;&lt;/a&gt;&lt;em&gt; project is fully open-sourced on &lt;/em&gt;&lt;a href="https://github.com/data-driven-forms/react-forms"&gt;&lt;em&gt;GitHub&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. If you find this project interesting, please join our community. We are opened to all contributions and we deeply appreciate each star we get. There is also an official twitter account &lt;/em&gt;&lt;a href="https://twitter.com/DataDrivenForms"&gt;&lt;em&gt;@DataDrivenForms&lt;/em&gt;&lt;/a&gt;&lt;em&gt; you can follow to get all the latest news.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>forms</category>
      <category>design</category>
    </item>
    <item>
      <title>Simple data-driven way for building React forms</title>
      <dc:creator>Data Driven Forms</dc:creator>
      <pubDate>Mon, 10 Feb 2020 12:01:01 +0000</pubDate>
      <link>https://forem.com/datadrivenforms/simple-data-driven-way-for-building-react-forms-1nip</link>
      <guid>https://forem.com/datadrivenforms/simple-data-driven-way-for-building-react-forms-1nip</guid>
      <description>&lt;p&gt;A brief introduction how easy can be building React forms using data-driven approach!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1280%2F1%2AU4aFxcK-cNsKCuhLkY0MGA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1280%2F1%2AU4aFxcK-cNsKCuhLkY0MGA.jpeg"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image by &lt;a href="https://pixabay.com/illustrations/analytics-information-innovation-3088958/" rel="noopener noreferrer"&gt;xresch&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally published at &lt;a href="https://medium.com/javascript-in-plain-english/data-driven-approach-to-forms-with-react-c69fd4ea7923" rel="noopener noreferrer"&gt;https://medium.com/javascript-in-plain-english/data-driven-approach-to-forms-with-react-c69fd4ea7923&lt;/a&gt; Origin author: Richard Všianský&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Forms are undoubtedly the most basic interaction pattern between a user and a web server. From the first login to the last order confirmation, all these actions are still handled by a few HTML elements as inputs or buttons. With this high importance and the emerging power of JavaScript, forms are becoming more and more complex. Asynchronous validation and submit, dynamic elements, touch-based controls, complex multi-searchable dropdowns supporting different localization configurations and many more advanced features are slowly but surely replacing simple static HTML pages.&lt;/p&gt;

&lt;p&gt;But how to handle these endless changes in large projects? One of them,&lt;a href="https://www.manageiq.org/" rel="noopener noreferrer"&gt; ManageIQ&lt;/a&gt;, an open-source tool to manage clouds, which has been in development since 2006 to the present, includes over one hundred forms. And all are different: a majority of the forms were written in the old fashioned way of providing dynamic features by Ruby on Rails and a few are using AngularJS. However, since the technology is still moving forward and ManageIQ decided to switch to&lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt; ReactJS&lt;/a&gt;, the team had to come up with a solution to make future development easier, more maintainable and testable.&lt;/p&gt;



&lt;p&gt;First, the team looked at React libraries, which can handle forms. And there are plenty of them:&lt;a href="https://github.com/jaredpalmer/formik" rel="noopener noreferrer"&gt; Formik&lt;/a&gt;,&lt;a href="https://redux-form.com/8.2.2/" rel="noopener noreferrer"&gt; ReduxForm&lt;/a&gt;,&lt;a href="https://final-form.org/" rel="noopener noreferrer"&gt; Final Form&lt;/a&gt; and many others. The issue was solved and provided all the needed features. These libraries are advanced and they provide everything that a developer needs. However, the developer still has to write HTML markups (despite it being in the form of JSX) and needs to use a lot of JavaScript/React code to bring all of these features to life. So, nothing is actually solved, as the troubles will emerge in the future, when the team decides to switch to another technology (&lt;em&gt;maybe Svelte? *wink&lt;/em&gt;*)&lt;/p&gt;

&lt;p&gt;There were many discussions about how to deal with it, but ultimately, a data driven approach was chosen as the solution. What does it actually mean? Because you have read the title, you probably have some idea, but essentially it means that instead of writing HTML markup and JavaScript code, simple data is written with no dependency on the technology used. We can also call it a declarative way to write forms. Same as in the declarative paradigm, a programmer does not need to specify how to build the form, but only what the user should see and how it should behave. Everything else is done by magic. (Not truly by magic, but by a lot of code... don't worry, we will get there.)&lt;/p&gt;

&lt;p&gt;Sounds simple? It really is. Let me give you an example. Let's imagine we need to build a simple login page with a login name and a password. (Right now, it doesn't matter which library we choose.) First we are going to write it in a standard way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"login"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your login name&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your login&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still simple, right? And it still is. However, when a user clicks on a button without entering any information, they want to see which inputs are required.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"login"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your login name&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This field is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This field is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your login&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great. All developers are happy and users too... but no, instead of showing simple text, the UX team decided to show a modal component with a warning triangle icon. Let's change the markup again... kidding, I hope you have already gotten the picture. Under normal circumstances, each change, even if it is just a small one, can be painful with a lot of code changing. It's manageable --- in a small project it's perfectly okay, but how about in a project with hundreds of forms? No, no way. Even if you end up in a situation where you are using a small number of reusable components, this approach will not enable you to use different technologies and all forms will have to be built from scratch when you decide to change it.&lt;/p&gt;

&lt;p&gt;Let's look at how we would deal with this form in a format we are using in our React library,&lt;a href="https://data-driven-forms.org/" rel="noopener noreferrer"&gt; Data Driven Forms&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your login name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we are converting the HTML data into JSON, we just copy its attributes to the right keys. And most of these keys are the same. The name attribute becomes name, the type is type and the label is label. The component is the name of a component from a mapper (more about it later.) Keys are simple and self-explanatory. You don't have to know anything about HTML or React and you are still able to write your own complex forms...&lt;/p&gt;

&lt;p&gt;... oh no, we have forgotten to add the required warnings! Let's fix it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your login name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required-validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required-validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And what about the triangle-modal stuff? Well, we don't need to change anything in the form at all. But let's wait until we get to the implementation for that. It's still time to talk about the advantages of this approach and what it brings to us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F792%2F1%2Am3ptQF-vlwLK6h5HgBlObg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F792%2F1%2Am3ptQF-vlwLK6h5HgBlObg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PatternFly 4 visualization of the form using the schema. You can test it yourself &lt;a href="https://data-driven-forms.org/live-editor" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You have already seen that it is simple to code, is easily readable and changes can happen by the help of CTRL-F, CTRL-V with no hesitation. Also, as the name suggests, you can keep this data in a database, so a web development team and those cool dudes who work on the newest iOS application can share it and use it across different programming languages and technologies. And we don't need to talk about upgradeability anymore. Data is just data, no matter which version of React you use and no matter what format or where you decide to keep it.&lt;/p&gt;

&lt;p&gt;Awesome, isn't it? Of course, there are some flaws that are difficult to handle by only storing information in JSON. (But not impossible!) For example, for each submit action we are still using a separate coded function, as each submit action is different. But if your team has designed its API well, you can store the API endpoint in the schema too and use it in a generic way. Using complex text components can cause another issue, because it is not possible to store React components in JSON in a database. However, even here you can still use some text format (such as markdown) and then convert the text into components you need.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F587%2F1%2AqLL3IoIeY4K71EyIacBMCQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F587%2F1%2AqLL3IoIeY4K71EyIacBMCQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Data Driven Forms is a React library used to change your data into React forms.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Data Driven Forms
&lt;/h1&gt;

&lt;p&gt;Now, it is time to move into a more specific example of using the data driven approach. In the text above I mentioned our custom open source library,&lt;a href="https://data-driven-forms.org/" rel="noopener noreferrer"&gt; Data Driven Forms&lt;/a&gt;. It is a React module that basically handles all features you could want from a standard web form. This is possible with the help of another mentioned library,&lt;a href="https://final-form.org/" rel="noopener noreferrer"&gt; Final Form&lt;/a&gt;. Final Form completely handles the form state, validation and all essential stuff. If you are more interested, keep its documentation page open in another tab and continue reading!&lt;/p&gt;

&lt;p&gt;Data Driven Forms consists of two separate components: a form renderer and a mapper. The form renderer is all provided by the Data Driven Forms and its responsibility is to parse the data into the form using Final Form and provide all the functionality, so all forms behave the same. The mapper is a different story, you can easily create your &lt;a href="https://data-driven-forms.org/renderer/component-mapping" rel="noopener noreferrer"&gt;own&lt;/a&gt; or you can use one of three mappers provided by the Data Driven Forms teams:&lt;a href="https://www.patternfly.org/v3/" rel="noopener noreferrer"&gt; PatternFly 3&lt;/a&gt;,&lt;a href="https://www.patternfly.org/v4/" rel="noopener noreferrer"&gt; PatternFly 4&lt;/a&gt; and&lt;a href="https://material-ui.com/" rel="noopener noreferrer"&gt; Material-UI&lt;/a&gt;. The mapper is what the name suggests. It is a set of components which maps the provided functionality (through passed props) to React components. Nothing more, nothing less. And each mapper includes components by design libraries you see in their names.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1284%2F1%2Aiy8iK7aJWTV23tlgqP8EbQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1284%2F1%2Aiy8iK7aJWTV23tlgqP8EbQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Same data, different mapper (from the left: PatternFly 4, PatternFly 3, Material-UI)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's return to our previous example to remind us of how the data looks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your login name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required-validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;required-validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's take a look at how to use this schema in Data Driven Forms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FormRenderer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[@data](http://twitter.com/data)-driven-forms/react-form-renderer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;formFieldsMapper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;layoutMapper&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@data-driven-forms/mui-component-mapper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FormRenderer&lt;/span&gt;
    &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;formFieldsMapper&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formFieldsMapper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;layoutMapper&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;layoutMapper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, what is happening here?&lt;a href="https://www.npmjs.com/package/@data-driven-forms/react-form-renderer" rel="noopener noreferrer"&gt; FormRenderer&lt;/a&gt; is the component, which converts your data into the form. There are only four required&lt;a href="https://data-driven-forms.org/renderer/renderer-api#requiredprops" rel="noopener noreferrer"&gt; props&lt;/a&gt;: schema is the JSON data with specific format, formFieldsMapper is a set of components which creates the form elements and has access to the form state with an ability to change it, layoutMapper is a set of a few specific components like a form wrapper or a button, which cannot be rendered in the form from the data and cannot change the form. Both of these mappers are bundled together. The last prop is an onSubmit, which is just a function, that is called after pressing Enter in the form or pressing the Submit button. There are many more&lt;a href="https://data-driven-forms.org/renderer/renderer-api#optionalprops" rel="noopener noreferrer"&gt; props&lt;/a&gt; you can use, which allow more customization (onReset, onCancel, ...)&lt;/p&gt;

&lt;p&gt;It cannot be simpler. You wrote a form you can immediately use. That's all. End of story.&lt;/p&gt;

&lt;p&gt;Wait. Have you already written a lot of forms with a lot of custom components? Well, that's a perfect time to write your custom mapper. Below, you can see a basic example with only one component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TextField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;touched&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;touched&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;formFieldsMapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's untangle it together. The component is just the basic React component you know and you love. You can notice it gets all attributes from the schema, such as name, type or label. However, there are two new props:&lt;a href="https://data-driven-forms.org/renderer/field-provider#input" rel="noopener noreferrer"&gt; input&lt;/a&gt; and&lt;a href="https://data-driven-forms.org/renderer/field-provider#meta" rel="noopener noreferrer"&gt; meta&lt;/a&gt;. These props are provided by the form renderer and they are the most important props obtained by the mapper: meta is an object, which includes various metadata about the field: dirty, pristine, modified, etc. and input is an object providing value and methods to change the form state. If you are wondering where the validate attribute goes, the answer is simple --- the validation is completely handled by the form renderer and components do not need to know about it.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/practical-maxwell-7zcsq"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1245%2F1%2AUVfSyKyohTAZ9iXsW7nk-A.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1245%2F1%2AUVfSyKyohTAZ9iXsW7nk-A.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A wizard form created using the PatternFly 4 mapper. Different steps for each source type are defined in the JSON schema. It's easy to add new steps, remove old ones or add a completely new wizard branch. All wizard features (jumping back, switching steps, ...) are controlled by the mapper, so there is no need to implement anything in the form itself.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Done. End of another story. But in reality, it is more complex; there are more&lt;a href="https://data-driven-forms.org/renderer/component-api" rel="noopener noreferrer"&gt; components&lt;/a&gt; to cover and more&lt;a href="https://github.com/data-driven-forms/react-forms" rel="noopener noreferrer"&gt; features&lt;/a&gt; to implement. This article serves as an introduction to the world of the data driven approach. I have shown you its main advantages and how simple it can be to build a form using data. Meanwhile, I kept features such as&lt;a href="https://data-driven-forms.org/component-example/wizard?mapper=pf4" rel="noopener noreferrer"&gt; Wizard&lt;/a&gt; forms,&lt;a href="https://data-driven-forms.org/renderer/validators#asyncvalidator" rel="noopener noreferrer"&gt; asynchronous validation&lt;/a&gt;,&lt;a href="https://final-form.org/docs/final-form/field-names" rel="noopener noreferrer"&gt; nested names&lt;/a&gt; and many more in secret. If you want to discover these, please check out&lt;a href="https://github.com/data-driven-forms/react-forms" rel="noopener noreferrer"&gt; our community&lt;/a&gt; on GitHub or visit our&lt;a href="https://data-driven-forms.org/" rel="noopener noreferrer"&gt; documentation page&lt;/a&gt;, where you can get all the information you need to start.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>database</category>
    </item>
  </channel>
</rss>
