<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ forms - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ forms - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:30:18 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/forms/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Automate Form UX Audits: Errors, Hints, and Keyboard Flows ]]>
                </title>
                <description>
                    <![CDATA[ Forms are often the gatekeepers to conversions on a site or application. Abandoned carts, partially signed-up users, and users who stop engaging with your app are often thanks to friction with forms.  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/automate-form-ux-audits-handbook/</link>
                <guid isPermaLink="false">69bc38cfb238fd45a3231433</guid>
                
                    <category>
                        <![CDATA[ UX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UIUX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oleh Romanyuk ]]>
                </dc:creator>
                <pubDate>Thu, 19 Mar 2026 17:56:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/5bf2b730-1a9f-46e9-9809-b63926589f00.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Forms are often the gatekeepers to conversions on a site or application. Abandoned carts, partially signed-up users, and users who stop engaging with your app are often thanks to friction with forms.</p>
<p>People will also abandon a site when they don’t understand an error message, can’t navigate through fields easily, or can’t get the help they need right away.</p>
<p>This guide will show you how to create automated systems that detect these issues before your users do. Together, we'll write code that systematically checks your forms so you don’t have to go through each field by hand in the hopes of finding problems.</p>
<p>Here's what we'll build together:</p>
<ul>
<li><p>Scripts that confirm your error messages are helpful and specific rather than generic and annoying.</p>
</li>
<li><p>Automated checks that guarantee the hint text appears in the appropriate location and at the appropriate time.</p>
</li>
<li><p>Tests to ensure keyboard users can navigate your forms without becoming lost or stuck.</p>
</li>
<li><p>A comprehensive audit system that performs these checks automatically and provides you with a list of fixes ranked in order of priority.</p>
</li>
<li><p>Integration with your development process so that each time you make a code change, these checks are performed.</p>
</li>
</ul>
<p>By the end of this handbook, you'll know how to:</p>
<ul>
<li><p>Configure automated audits for any application form.</p>
</li>
<li><p>Verify error messages against accessibility guidelines and usability best practices.</p>
</li>
<li><p>Make sure the hint text aids users rather than confounds them.</p>
</li>
<li><p>Verify that all users can finish your forms by testing the keyboard navigation.</p>
</li>
<li><p>Link audit findings to actual business metrics, such as conversion rates.</p>
</li>
<li><p>As part of your deployment procedure, run these audits automatically.</p>
</li>
</ul>
<p>You can run the functional JavaScript code in each section right away. Because the examples use vanilla JavaScript, they can be used with any framework, including React, Vue, Angular, or simply HTML. Although you don't have to be an expert, you should be able to follow along with JavaScript to get this most out of this guide.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ol>
<li><p><a href="#heading-why-should-you-automate-form-audits-in-the-first-place">Why Should You Automate Form Audits in the First Place?</a></p>
</li>
<li><p><a href="#heading-how-to-define-concise-objectives-and-scope">How to Define Concise Objectives and Scope</a></p>
</li>
<li><p><a href="#heading-how-to-scope-audit-boundaries">How to Scope Audit Boundaries</a></p>
</li>
<li><p><a href="#heading-how-to-incorporate-heuristic-evaluation-and-quantitative-data">How to Incorporate Heuristic Evaluation and Quantitative Data</a></p>
</li>
<li><p><a href="#heading-how-to-define-automated-test-cases-for-form-components">How to Define Automated Test Cases for Form Components</a></p>
</li>
<li><p><a href="#heading-how-to-consistently-confirm-keyboard-navigation-flows">How to Consistently Confirm Keyboard Navigation Flows</a></p>
</li>
<li><p><a href="#heading-aiinformed-navigation-pattern-detection">AI-Informed Navigation Pattern Detection</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-why-should-you-automate-form-audits-in-the-first-place">Why Should You Automate Form Audits in the First Place?</h2>
<p>Manual testing will typically find easy problems. But it may miss the systematic issues with forms across your entire application. You know the type of errors I’m talking about – those that don’t state incorrect values, missing keyboard support for fields, or hints that don’t have a clear place for help based on static design.</p>
<p>Research on user experience design shows that an effective UX can be strategically built, refined, or designed by using continuous feedback loops (Source: <a href="https://www.researchgate.net/publication/382804453_Assessment_of_User_Experience_UX_Design_Trends_in_Mobile_Applications">Okonkwo, Research Gate</a>). Automated audits are a good way of putting this into practice, as they can help you find issues at scale before you release your product.</p>
<p>The key advantage here is coverage. You can prepare form UX audit basics so you and your teammates can check every form field, validation rule, and keyboard interaction in a systematic way.</p>
<h3 id="heading-key-form-components-to-audit"><strong>Key Form Components to Audit</strong></h3>
<p>Before we create our roadmap for the UX audit, let’s talk about the three main elements of forms that typically have issues:</p>
<ul>
<li><p><strong>Error states</strong> indicate what went wrong, as well as how to fix it. The clearer they are, the better: the confusion of generic messages like "Invalid input" frustrates users. In contrast, specific feedback like "Email must contain @ symbol" is specific enough to help them get things completed.</p>
</li>
<li><p><strong>Hint text</strong> helps prevent errors before users can input anything. Proactive guidance like "Password must contain 8+ characters" provides realistic expectations. Placing hint text in the right location and conveying its message at the appropriate time also determines how useful the hint text will be.</p>
</li>
<li><p><strong>Keyboard flows</strong> distinguish accessible forms from broken forms. Tab order, focus order, and keyboard shortcuts dictate whether a user can complete their form without a mouse.</p>
</li>
</ul>
<p>To guide you through the audit workflow for each component, we’ll focus on three user flows: a sign-up form, checkout, and a contact form. All of these affect the conversion rate of a product’s users. And each of these elements maps to multiple metrics you can track.</p>
<p>We’ll use Nielsen Norman Group's 10 usability heuristics (Source: <a href="https://www.nngroup.com/articles/ten-usability-heuristics/">Jakob Nielsen, NNgroup</a>) as a foundation while incorporating any data indicators. These heuristics are:</p>
<ul>
<li><p><strong>System status visibility</strong>: Users should always be aware of what's going on thanks to prompt feedback</p>
</li>
<li><p><strong>System and real-world match</strong>: Use the user's language instead of technical terms</p>
</li>
<li><p><strong>User freedom and control</strong>: Enable users to quickly correct errors</p>
</li>
<li><p><strong>Consistency and standards</strong>: Adhere to platform norms so users don't have to question whether various terms or behaviors have the same meaning.</p>
</li>
<li><p><strong>Error prevention</strong>: Design to stop issues before they start</p>
</li>
<li><p><strong>Recognition rather than recall</strong>: Show options rather than making users memorize details.</p>
</li>
<li><p><strong>Flexibility and efficiency of use</strong>: Provide shortcuts for experienced users while keeping things simple for beginners.</p>
</li>
<li><p><strong>Aesthetic and minimalist design</strong>: Don't clutter interfaces with irrelevant information.</p>
</li>
<li><p><strong>Help users recognize, diagnose, and recover from errors</strong>: Error messages should clearly explain the problem and suggest a solution.</p>
</li>
<li><p><strong>Help and documentation</strong>: Provide easy-to-search help when needed.</p>
</li>
</ul>
<p>For form audits, we'll focus especially on heuristics #5 (error prevention through hint text), #6 (making requirements visible), and #9 (clear error recovery). These directly affect whether users can complete forms successfully.</p>
<p>There’s one more important thing to note before we proceed. For each component, you’ll want to identify what tests you can automate as part of your test case. For each form component, start building checks programmatically for several criteria:</p>
<ul>
<li><p><strong>Accessibility</strong> – for contrast ratios, ARIA labels, and focus indicators.</p>
</li>
<li><p><strong>Performance</strong> – for the time it takes to validate fields and render error messages.</p>
</li>
<li><p><strong>Visual consistency</strong> – for error state styling, hint text patterns, and keyboard focus.</p>
</li>
</ul>
<p>We’ll prioritize fixes with a high impact that will help prevent users from abandoning a form. Also, each audit will produce actionable information along with a line of code, acceptance criteria, and example code for fixes.</p>
<p>Now, let’s start building our form UX audit workflow.</p>
<h2 id="heading-how-to-define-concise-objectives-and-scope">How to Define Concise Objectives and Scope</h2>
<p>Before you even put your fingers to the keyboard, you'll want to determine what exactly you’re measuring and for what purpose. There’s a golden rule: ambiguous statements will yield ambiguous results. Having specific objectives linked to user behavior and business metrics is what creates actionable audits.</p>
<h3 id="heading-identifying-form-types-and-objectives">Identifying Form Types and Objectives</h3>
<p>First, you need to know what form you’re going to audit. Let’s start by mapping the three forms that have the greatest direct impact on the success of your application and defining the nuances and objectives of each one.</p>
<h4 id="heading-1-a-signup-forms-key-goal-is-user-acquisition">1. A signup form’s key goal is user acquisition.</h4>
<p>Every friction point - like poorly defined password requirements, vague expectations for email formats, and a lack of field labels - means a user will likely abandon the signup process. Your audit must identify these user flows.</p>
<h4 id="heading-2-checkout-forms-are-aimed-at-bringing-revenue">2. Checkout forms are aimed at bringing revenue</h4>
<p>User engagement improves significantly when applications use user-centered design principles – shocking, right? (Source: <a href="https://www.researchgate.net/publication/382804453_Assessment_of_User_Experience_UX_Design_Trends_in_Mobile_Applications">Okonkwo, ResearchGate</a>). In checkout flows, this means that error messages appear inline, hints show requirements before a user can type, and keyboard navigation follows the expected tab order from shipping to payment fields.</p>
<h4 id="heading-3-contact-forms-have-the-objective-of-establishing-communication">3. Contact forms have the objective of establishing communication</h4>
<p>Often, devs pay less attention to contact forms than to transactional forms. But contact forms are crucial for proposal requests, customer support requests, collaboration requests, and so on. A broken contact form can mean lost business.</p>
<p>Now that you’ve identified the type of form and its key objective, let’s do something equally important: link these high-level objectives to specific, measurable metrics.</p>
<h3 id="heading-connecting-objectives-and-metrics-to-track">Connecting Objectives and Metrics to Track</h3>
<p>Every objective for the audit maps to a set of measurements. Here’s how to build this continuum:</p>
<h4 id="heading-error-message-metrics">Error message metrics</h4>
<p>Your audit should evaluate whether error messages fulfill three criteria:</p>
<ol>
<li><p>Specificity (Does the message indicate what the problem is?),</p>
</li>
<li><p>Timing (In what context will the user see the error?), and</p>
</li>
<li><p>Actionable (Does the message explain what the user should do to recover?).</p>
</li>
</ol>
<p>For example, "password too weak" does not provide actionable information and isn’t specific enough, while "Password must have at least one uppercase character, one number, and one special character" is highly actionable and provides clear information on what the user needs to do.</p>
<p><strong>You can measure this by tracking two things:</strong> what percentage of your error messages mention the specific field name, and how many errors show up immediately when users leave a field versus only appearing after they hit submit.</p>
<h4 id="heading-hints-can-reduce-user-errors-before-they-occur-your-audit-should-validate">Hints can reduce user errors before they occur. Your audit should validate:</h4>
<ul>
<li><p>Whether a hint’s positioning is proactive (for instance, is the hint text located before users engage the provided input field?).</p>
</li>
<li><p>Visual proximity (Is the hint text next to the input field?).</p>
</li>
<li><p>Accessibility (for example, are the hints connected to the fields programmatically using aria-describedby?)</p>
</li>
</ul>
<p>The latter is especially important, as screen readers require explicit connections to announce hints at the correct time. You’ll want to measure these using metrics like the time to display a hint (immediate vs delayed) and the number of ARIA-associated hint elements.</p>
<h4 id="heading-keyboard-flow-metrics-are-also-directly-connected-to-accessibility">Keyboard flow metrics are also directly connected to accessibility</h4>
<p>Your audit should define if there is a correct order logic. Do fields follow the visual layout? When the tabindex jumps around sporadically across the screen, users lose context.</p>
<p>It should also determine if the focus visibility is the current field and if that’s clearly indicated. When the focus is invisible or subtle, you end up making your users guess where they are.</p>
<p>Keyboard shortcuts let users submit forms, clear fields, or jump between sections without touching their mouse. Everyone benefits from this, not just people using screen readers or other assistive technology.</p>
<p>You will want to measure these with the tabindex sequence alignment to the visual layout, focus indicator contrast ratios, and by defining if there are keyboard shortcuts for submitting, clearing, and moving about the forms.</p>
<p>Now that you have outlined the key metrics and principles applicable to the form you’re auditing, it’s time to define the specific area you want to focus on.</p>
<h2 id="heading-how-to-scope-audit-boundaries">How to Scope Audit Boundaries</h2>
<p>You’ll need to define exactly what forms and fields your audit will cover. You’ll want to start small in order to build working automations and then slowly expand.</p>
<h3 id="heading-setting-the-initial-scope">Setting the Initial Scope</h3>
<p>You should start with forms in your application’s critical user paths. We’ll use the below JavaScript snippet as an example. Paste this configuration object into your audit automation tool or script:</p>
<pre><code class="language-python">const auditScope = {
  signupForm: {
    url: '/signup',
    fields: ['email', 'password', 'confirmPassword'],
    priority: 'critical'
  },
  checkoutForm: {
    url: '/checkout',
    fields: ['cardNumber', 'expiryDate', 'cvv', 'billingZip'],
    priority: 'critical'
  },
  contactForm: {
    url: '/contact',
    fields: ['name', 'email', 'subject', 'message'],
    priority: 'high'
  }
};
</code></pre>
<p>In the code above, the auditScope object lists critical forms (signup, checkout, and contact forms), specifies their URLs along with important fields to check (such as email, password, cardNumber), and lists their priority level. This helps the auditing system see what resources to prioritize.</p>
<p>The priority property allows your audit system to prioritize high-impact forms first when protocol limits the resources available. Such a method prevents your system from being overwhelmed with too broad a scope.</p>
<h3 id="heading-setting-the-audit-execution-plan">Setting the Audit Execution Plan</h3>
<p>Your objectives dictate how the audit system will act. After you have defined the scope, you can divide the workflow into several definite phases.</p>
<ul>
<li><p><strong>Phase 1:</strong> Static analysis will address the structure of the HTML document and verify the ARIA attributes, tab indices, and markup patterns for semantic use. This can discover structural issues that require no user interaction.</p>
</li>
<li><p><strong>Phase 2:</strong> Dynamic testing simulates user interactions to identify the occurrence of errors, when hints are displayed, and when a keyboard user would navigate to which elements. This can identify runtime problems that were not revealed through static analysis.</p>
</li>
<li><p><strong>Phase 3:</strong> Visual verification measures spacing, contrast ratios, or positioning of elements, but using visually computed styles. This allows us to examine the visual design in relation to meeting either UX or UI objectives.</p>
</li>
</ul>
<p>Each phase will result in findings that continually tie back to your defined objectives. In the case of a failed check, the audit report will show which objective contributed to the finding, the current state of the component, the target states, and recommendations for the solution.</p>
<h3 id="heading-field-level-objectives">Field-level objectives</h3>
<p>For each field, you should tell the script or the automated tool what the audit is actually checking. Each check is a specific automated test. When the audit is executed, every check is confirmed for every field, and failures are noted.</p>
<p>For instance, in the following snippet, for each field we provide (like "email" or "password"), we list three categories of checks: errorChecks, hintChecks, and keyboardChecks. When you link this object to your audit automation system (for example, UI testing frameworks, accessibility checkers), your audit automation system runs all these tests on every field. It will report any test failures so you can see which part of the input is broken or missing.</p>
<pre><code class="language-python">const fieldObjectives = {
  email: {
    errorChecks: [
      'hasInlineValidation',
      'errorMessageSpecific',
      'showsValidFormatExample'
    ],
    hintChecks: [
      'hintVisibleBeforeInteraction',
      'hintExplainsFormat',
      'hintAccessible'
    ],
    keyboardChecks: [
      'tabOrderCorrect',
      'focusVisible',
      'supportsAutocomplete'
    ]
  },
  password: {
    errorChecks: [
      'hasInlineValidation',
      'listsAllRequirements',
      'showsProgressIndicator'
    ],
    hintChecks: [
      'hintListsRequirements',
      'hintVisibleBeforeTyping',
      'hintPersistsDuringTyping'
    ],
    keyboardChecks: [
      'tabOrderCorrect',
      'focusVisible',
      'supportsPasswordManagers'
    ]
  }
};
</code></pre>
<p>This leads to a very granular, consistent, and repeatable test of important user input components so you can validate usability, accessibility, and correctness of the form.</p>
<h3 id="heading-linking-objectives-to-business-kpis">Linking Objectives to Business KPIs</h3>
<p>The findings of the audit should link back to business impact. Let’s look at how our objectives map to key performance indicators.</p>
<p>The impact on conversion rate should be direct and specific. For instance, improved error messages directly impact the form completion rate:</p>
<ul>
<li><p><strong>Baseline</strong>. The current abandonment rate for forms.</p>
</li>
<li><p><strong>Target</strong>. Decrease abandonment by 15% due to clear error messages.</p>
</li>
<li><p><strong>Audit validation.</strong> 100% of error messages are clear and specific.</p>
</li>
</ul>
<p>Reducing support tickets is another priority. In this case, better hint text provides less confusion:</p>
<ul>
<li><p><strong>Baseline</strong>. Volume of support requests related to forms currently.</p>
</li>
<li><p><strong>Target</strong>. Decrease the number of support tickets by 25%.</p>
</li>
<li><p><strong>Audit validation.</strong> 100% of complex fields have proactive hints.</p>
</li>
</ul>
<p>Accessibility compliance is another important goal. Keyboard navigation has a direct impact on the legal compliance and reach of a wider base of users. The example of the KPIs here can be the following:</p>
<ul>
<li><p><strong>Baseline</strong>. Current level of WCAG conformance.</p>
</li>
<li><p><strong>Target</strong>. All forms to be WCAG 2.1 AA compliant.</p>
</li>
<li><p><strong>Audit validation.</strong> 100% of fields work with a keyboard only.</p>
</li>
</ul>
<p>After you create such measurable criteria for success, you should actually give them as thresholds to your system. Here’s an example of how you can provide defined measures for passing and failing for the automated audit:</p>
<pre><code class="language-python">const auditThresholds = {
  errorMessages: {
    specificityScore: 0.9,  // 90% must include field-specific details
    inlineValidationPercentage: 1.0,  // 100% must show inline errors
    actionabilityScore: 0.85  // 85% must include fix instructions
  },
  hintText: {
    proactiveDisplayPercentage: 1.0,  // 100% must appear before interaction
    proximityMaxPixels: 8,  // Hints must be within 8px of fields
    ariaAssociationPercentage: 1.0  // 100% must have aria-describedby
  },
  keyboardFlow: {
    tabOrderCorrectnessScore: 1.0,  // 100% must follow visual layout
    focusContrastRatio: 3.0,  // Minimum 3:1 contrast for focus indicators
    shortcutCoveragePercentage: 0.8  // 80% of actions must have shortcuts
  }
};
</code></pre>
<p>As you can see, under errorMessages, the specificityScore of 0.9 states that 90% of error messages must include details specific to each field. Also, within the hintText directions, the proactiveDisplayPercentage of 1.0 demands that the hints appear before the user starts typing, not after, for the test to be passed.</p>
<h3 id="heading-the-5cs-framework-for-audit-documentation">The 5Cs Framework for Audit Documentation</h3>
<p>When you document your audit results, use the 5Cs framework to make sure your reports are actually useful:</p>
<ul>
<li><p><strong>Coverage</strong>: Which forms and fields did you test? Be specific about the scope.</p>
</li>
<li><p><strong>Completion</strong>: Did you run all the planned checks? Note any that were skipped and why.</p>
</li>
<li><p><strong>Consistency</strong>: Do your results use the same format and terminology throughout? This makes reports easier to scan.</p>
</li>
<li><p><strong>Clarity</strong>: Can a developer read the failure report and know exactly what to fix? Include the current state, expected state, and code examples.</p>
</li>
<li><p><strong>Correctness</strong>: Are your checks testing the right things? Validate that failures match real user problems, not just technical violations.</p>
</li>
</ul>
<p>This framework helps both designers and developers understand audit results and take action quickly.</p>
<h2 id="heading-how-to-incorporate-heuristic-evaluation-and-quantitative-data">How to Incorporate Heuristic Evaluation and Quantitative Data</h2>
<p>Once you've established objectives, you’ll want to base your audit on the usability principles and behavior patterns of users. This combination of established usability heuristics along with quantitative data can help you verify that your automated checks are surfacing issues that users actually experience – and not fictional edge cases (Source: <a href="https://www.nngroup.com/articles/ten-usability-heuristics/">Jakob Nielsen, NNgroup</a>).</p>
<p>The best way to do this is to map the issues to the common standard of the Web Content Accessibility Guidelines and use that as the basis for your audit (Source: <a href="https://www.w3.org/TR/WCAG21/">WCAG 2.1, W3C Recommendation</a>). For every identified problem, identify the WCAG success criteria that the issue violates. This will give you clear requirements that you can use as an automated check and that should be commonly understood by everyone working on the audits.</p>
<p>In the automated script, you can use the following code to map these guidelines:</p>
<pre><code class="language-python">const wcagMapping = {
  errorIdentification: {
    criterion: '3.3.1',
    level: 'A',
    requirement: 'Error messages must identify the item in error',
    testFunction: 'checkErrorIdentification'
  },
  errorSuggestion: {
    criterion: '3.3.3',
    level: 'AA',
    requirement: 'Error messages must provide suggestions for correction',
    testFunction: 'checkErrorSuggestions'
  },
  labelInName: {
    criterion: '2.5.3',
    level: 'A',
    requirement: 'Accessible name must contain visible label text',
    testFunction: 'checkLabelInName'
  },
  focusOrder: {
    criterion: '2.4.3',
    level: 'A',
    requirement: 'Focus order must preserve meaning and operability',
    testFunction: 'checkFocusOrder'
  }
};
</code></pre>
<p>If any part of the form violates WCAG 3.3.1 – perhaps it doesn’t identify the field when it provides an error – your audit report can document it as follows:</p>
<p>"The error message displayed on the email field said 'Invalid input' but didn’t identify the requirement it didn't meet. WCAG 3.3.1 states that the error must identify the field with the error (potential fix: 'Email must have an @ symbol'). 3.3.1 is the mapped criteria."</p>
<p>Nielsen's heuristics tell you what good usability looks like. But tools like Google Analytics and Hotjar show you what users actually do on your forms. When you combine both – usability principles and real user behavior data – you make better decisions about which problems to fix first.</p>
<p>Research shows this combined approach catches more real issues than either method alone (Sources: <a href="https://www.researchgate.net/publication/334385231_User_Experience_Evaluation_Using_Mouse_Tracking_and_Artificial_Intelligence">Souza and others, IEEE Access</a>). Use both types of data to prioritize what your automated audits should check.</p>
<h3 id="heading-define-binary-passfail-criteria">Define Binary Pass/Fail Criteria</h3>
<p>Automation requires clear results. Your audit must document whether a component passed or failed its WCAG criteria. The process must yield binary results – yes/no, positive/negative.</p>
<p>For instance, the following code incorporates a definite, binary audit check to verify whether a form field is compliant with WCAG 3.3.1 criteria for error identification (Source: <a href="https://www.w3.org/TR/WCAG21/">WCAG 2.1, W3C Recommendation</a>):</p>
<pre><code class="language-python">function checkErrorIdentification(field) {
  const errorElement = field.querySelector('[role="alert"], .error-message');
  
  if (!errorElement) {
    return {
      pass: false,
      wcag: '3.3.1',
      severity: 'critical',
      message: `Field "${field.name}" lacks error message element`,
      fix: 'Add aria-describedby pointing to error container'
    };
  }
  
  const errorText = errorElement.textContent.trim();
  const hasFieldReference = errorText.toLowerCase().includes(field.name.toLowerCase()) 
    || errorText.toLowerCase().includes(field.labels[0]?.textContent.toLowerCase());
  
  if (!hasFieldReference) {
    return {
      pass: false,
      wcag: '3.3.1',
      severity: 'major',
      message: `Error message "${errorText}" doesn't identify field`,
      fix: `Include field name in error: "\({field.labels[0]?.textContent} \){errorText}"`
    };
  }
  
  return { pass: true, wcag: '3.3.1' };
}
</code></pre>
<p>The error message identified the error, and each component definitively passes or fails the criterion. There’s no room for interpretation or doubt.</p>
<h3 id="heading-standardize-error-messages-and-hint-messages">Standardize Error Messages and Hint Messages</h3>
<p>Keep in mind that automated functions require familiarity and consistency. You can create centralized repositories with libraries of accepted usage patterns and approval that developers can refer to, and your tests can check that your forms are using standardized messages.</p>
<p>For example, in the following snippet, the errorLibrary object provides a single source of truth for every acceptable error message your application will display for specific fields. For each field, there are appropriately defined message strings for common validation issues (like empty, invalid, duplicate). Similarly, the hintLibrary object provides a single source of truth for every hint text that prefaces user input.</p>
<pre><code class="language-python">const errorLibrary = {
  email: {
    empty: 'Email address is required',
    invalid: 'Email must include @ symbol and domain (example: user@domain.com)',
    duplicate: 'This email is already registered. Try signing in instead.'
  },
  password: {
    empty: 'Password is required',
    tooShort: 'Password must be at least 8 characters',
    missingUppercase: 'Password must include at least one uppercase letter',
    missingNumber: 'Password must include at least one number',
    missingSpecial: 'Password must include at least one special character (!@#$%^&amp;*)'
  }
};

const hintLibrary = {
  email: 'Enter your email address (example: name@company.com)',
  password: 'Create a password with 8+ characters, including uppercase, number, and special character',
  phone: 'Enter 10-digit phone number without dashes (example: 5551234567)'
};
</code></pre>
<p>By having a single source of these patterns, you won’t run the risk of writing duplicate or misaligned messages in different areas across the app, increasing maintainability.</p>
<h3 id="heading-utilize-definite-aria-identifiers">Utilize Definite ARIA Identifiers</h3>
<p>If you use consistent ARIA attributes, you can automate checks. As an example, in the following snippet, we explicitly define which ARIA attributes connect error messages, hints, and fields. The auditARIAImplementation function checks whether each field has an accessible label (either an HTML element or an aria-label attribute) to meet WCAG 1.3.1. Without it, users will likely find it hard to identify the purpose of the input.</p>
<pre><code class="language-python">function auditARIAImplementation(field) {
  const checks = {
    hasLabel: !!field.labels?.length || !!field.getAttribute('aria-label'),
    hasDescription: !!field.getAttribute('aria-describedby'),
    hasErrorMessage: !!field.getAttribute('aria-errormessage'),
    hasRequired: field.hasAttribute('required') || field.getAttribute('aria-required') === 'true'
  };
  
  const failures = [];
  
  if (!checks.hasLabel) {
    failures.push({
      wcag: '1.3.1',
      message: `Field "${field.name}" lacks accessible label`,
      fix: 'Add &lt;label&gt; element or aria-label attribute'
    });
  }
  
  if (!checks.hasDescription) {
    failures.push({
      wcag: '3.3.2',
      message: `Field "${field.name}" lacks hint text association`,
      fix: 'Add aria-describedby pointing to hint element ID'
    });
  }
  
  if (field.dataset.validatable &amp;&amp; !checks.hasErrorMessage) {
    failures.push({
      wcag: '3.3.1',
      message: `Validatable field "${field.name}" lacks aria-errormessage`,
      fix: 'Add aria-errormessage attribute pointing to error container ID'
    });
  }
  
  return {
    pass: failures.length === 0,
    failures
  };
}
</code></pre>
<p>This function checks for specific ARIA-tied patterns that your design system prescribes. The great thing is that you can check the code in CI/CD pipelines to maintain implementation standards.</p>
<p>The next section will help you identify specific automated test cases for errors, hints, and keyboard flows.</p>
<h2 id="heading-how-to-define-automated-test-cases-for-form-components">How to Define Automated Test Cases for Form Components</h2>
<p>Now that you've established a baseline with WCAG standards, heuristics, and user data, you can create specific automated test cases. Each test case targets a measurable quality for the error messages, hint text, or keyboard navigation functionality of each form component. The following sections will provide concrete ways to automate these checks for each form component.</p>
<h3 id="heading-automated-error-message-checks">Automated Error Message Checks</h3>
<p>Error messages are crucial conversion points. Your automated checks should ensure that each error message meets the specificity, timing, and actionability criteria. Every error message must convey what exactly has gone wrong. Generic error messages don’t pass this quality check.</p>
<p>For automation, your checks can provide insight as to whether the error message references the specific construction of the field. For instance, in the following snippet, the method verifies that every error message that appears in a form serves to pinpoint the input problem, not use a vague general expression.</p>
<pre><code class="language-python">function auditErrorSpecificity(formId) {
  const form = document.getElementById(formId);
  const fields = form.querySelectorAll('input, textarea, select');
  const failures = [];
  
  fields.forEach(field =&gt; {
    const errorElement = document.querySelector(`[aria-describedby="${field.id}-error"]`);
    if (errorElement) {
      const errorText = errorElement.textContent.toLowerCase();
      const genericTerms = ['invalid', 'error', 'wrong', 'incorrect'];
      const isGeneric = genericTerms.some(term =&gt; 
        errorText.includes(term) &amp;&amp; errorText.split(' ').length &lt; 4
      );
      
      if (isGeneric) {
        failures.push({
          field: field.id,
          message: errorText,
          issue: 'Generic error message lacks specificity',
          wcag: '3.3.1 Error Identification'
        });
      }
    }
  });
  
  return failures;
}
</code></pre>
<p>It looks through field-specific error messages and flags any that use common generic terms in a short, vague message, as ambiguous messages don’t serve the purposes of WCAG 3.3.1 since they don’t provide an actionable correction for user input (Source: <a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/minimize-error-identified.html">WCAG 3.3.1, WC3</a>).</p>
<h3 id="heading-validation-timing-of-inline-messages">Validation Timing of Inline Messages</h3>
<p>Error messages should show the message when the user leaves the field and not just at submission. Research demonstrates that even just the timing of the feedback alone significantly disrupts user performance. Your automation should check whether errors are displayed inline (Source: <a href="https://www.researchgate.net/publication/282715275_Soft_Keyboard_UX_Evaluation_An_Eye_Tracking_Study">Al-Khalifa and others, ResearchGate</a>).</p>
<p>This code verifies that error messages appear immediately when a user leaves a required input field on blur, as opposed to only showing errors after submitting the entire form.</p>
<pre><code class="language-python">function auditErrorTiming(formId) {
  const form = document.getElementById(formId);
  const fields = form.querySelectorAll('input[required], textarea[required]');
  const failures = [];
  
  fields.forEach(field =&gt; {
    let hasBlurValidation = false;
    let hasInputValidation = false;
    
    // Check for blur event listeners
    const blurListeners = getEventListeners(field).blur || [];
    hasBlurValidation = blurListeners.length &gt; 0;
    
    // Check for input event listeners
    const inputListeners = getEventListeners(field).input || [];
    hasInputValidation = inputListeners.length &gt; 0;
    
    if (!hasBlurValidation &amp;&amp; !hasInputValidation) {
      failures.push({
        field: field.id,
        issue: 'No inline validation detected',
        recommendation: 'Add blur or input event validation',
        wcag: '3.3.1 Error Identification'
      });
    }
  });
  
  return failures;
}
</code></pre>
<p>This audit verifies that an event handler which runs against an inline validator is in place for blur and input events on input fields. It also checks that it flags any that fail to have these interactions as a failure under the WCAG 3.3.1 Error Identification guideline (Source: <a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/minimize-error-identified.html">WCAG 3.3.1, WC3</a>).</p>
<h3 id="heading-confirm-actionable-recovery-guidance">Confirm Actionable Recovery Guidance</h3>
<p>Error messages must clarify how to recover from any faults or issues. "Password too weak" fails the user. In contrast, the error message "Password must be 8+ characters, contain at least 1 upper case letter, and one numeric character" gives the user enough information to make the proper adjustment.</p>
<p>Let’s take an example of some code that audits password fields to ensure that the error message includes specific actionable recovery instructions outlining character types or character length and clearly guides users on how to correct input errors (Source: <a href="https://www.w3.org/WAI/WCAG21/Understanding/error-suggestion.html">WCAG 3.3.3, WC3</a>).</p>
<pre><code class="language-python">function auditErrorActionability(formId) {
  const form = document.getElementById(formId);
  const failures = [];
  const passwordFields = form.querySelectorAll('input[type="password"]');
  
  passwordFields.forEach(field =&gt; {
    const errorElement = document.getElementById(`${field.id}-error`);
    if (errorElement) {
      const errorText = errorElement.textContent;
      const hasSpecificRequirements = /\d+/.test(errorText) || 
        /uppercase|lowercase|special|character|digit/.test(errorText.toLowerCase());
      
      if (!hasSpecificRequirements) {
        failures.push({
          field: field.id,
          message: errorText,
          issue: 'Error lacks specific recovery guidance',
          wcag: '3.3.3 Error Suggestion'
        });
      }
    }
  });
  
  return failures;
}
</code></pre>
<p>If the error message doesn’t contain these characters or meet the length requirement, the function will flag the instance as a failure with a corresponding WCAG reference.</p>
<h3 id="heading-automated-rich-hint-text-auditing">Automated Rich Hint Text Auditing</h3>
<p>Rich text hints help prevent errors (and hopefully the need for an error message). Research suggests that users who are given proactive guidance improve form completion by up to 23% (Source: <a href="https://www.researchgate.net/publication/382804453_Assessment_of_User_Experience_UX_Design_Trends_in_Mobile_Applications">Okonkwo, ResearchGate</a>). Your automation should confirm that the right hints appear at the right time, in the right places, with appropriate accessible information and presentation.</p>
<p>This function audits form fields to ensure that hint text is seen before the user interacts with the form, helping avoid user errors while filling out the form.</p>
<pre><code class="language-python">function auditHintTiming(formId) {
  const form = document.getElementById(formId);
  const complexFields = form.querySelectorAll('input[type="password"], input[pattern]');
  const failures = [];
  
  complexFields.forEach(field =&gt; {
    const hintElement = document.querySelector(`[id="${field.getAttribute('aria-describedby')}"]`);
    
    if (!hintElement) {
      failures.push({
        field: field.id,
        issue: 'Complex field missing proactive hint text',
        wcag: '3.3.2 Labels or Instructions'
      });
    } else {
      // Check if hint is visible before interaction
      const computedStyle = window.getComputedStyle(hintElement);
      const isVisible = computedStyle.display !== 'none' &amp;&amp; 
        computedStyle.visibility !== 'hidden';
      
      if (!isVisible) {
        failures.push({
          field: field.id,
          issue: 'Hint text hidden until interaction',
          wcag: '3.3.2 Labels or Instructions'
        });
      }
    }
  });
  
  return failures;
}
</code></pre>
<p>If the hint doesn't exist or doesn’t show until after the user interacts with the form, the function will flag it as a failure to satisfy WCAG 3.3.2 Labels or Instructions for a generally consistent and user-friendly form design (Source: <a href="https://www.w3.org/WAI/WCAG21/Understanding/labels-or-instructions.html">WCAG 3.3.3, WC3</a>).</p>
<h2 id="heading-how-to-consistently-confirm-keyboard-navigation-flows">How to Consistently Confirm Keyboard Navigation Flows</h2>
<p>Keyboard accessibility is required for WCAG compliance, and you can automate most of the testing with code. When people can't use your forms with just a keyboard, they often give up and leave. This directly hurts your conversion rates.</p>
<p>When you document how keyboard navigation should work, you can write automated tests to check if it actually works that way.</p>
<h3 id="heading-outlining-the-interactions">Outlining the Interactions</h3>
<p>Your audit should document expected keyboard interactions for each component. If there's a modal dialog, note that Tab will cycle through the elements within the modal, Escape closes the modal, and the focus returns to the element that opened the modal.</p>
<p>For forms, note that Tab advances through the fields in visual order, Shift+Tab will go back, and Enter will submit the form from the submit button only.</p>
<p>You should document these flows in a data-driven way. A structured format with columns for "Component," "Keystroke," "Expected Action," and "Relevant WCAG" will make both human review and automated parsing much easier:</p>
<pre><code class="language-python">const keyboardPatterns = {
  'modal-dialog': {
    tab: 'Focus next element within modal',
    shiftTab: 'Focus previous element within modal',
    escape: 'Close modal and return focus',
    wcag: '2.1.1 Keyboard, 2.4.3 Focus Order'
  },
  'form-field': {
    tab: 'Move to next field in visual order',
    shiftTab: 'Move to previous field',
    enter: 'Submit only from submit button',
    wcag: '2.1.1 Keyboard, 2.4.3 Focus Order'
  },
  'dropdown-select': {
    space: 'Open dropdown menu',
    arrowDown: 'Navigate to next option',
    arrowUp: 'Navigate to previous option',
    enter: 'Select current option',
    escape: 'Close dropdown without selection',
    wcag: '2.1.1 Keyboard, 4.1.2 Name, Role, Value'
  }
};
</code></pre>
<p>This code aligns these patterns with WCAG guidelines 2.1.1 (Keyboard Accessibility), 2.4.3 (Focus Order), and 4.1.2 (Name, Role, Value) to support users who rely on keyboard inputs (Source: <a href="https://www.w3.org/WAI/WCAG21/Understanding/">WCAG Understanding Docs, WC3</a>).</p>
<h3 id="heading-automated-tab-order-validation">Automated Tab Order Validation</h3>
<p>Tab order should follow the visual layout of the page. When focus jumps around randomly, users get lost. The code below checks that focus moves through fields in the order people expect – top to bottom, left to right. It catches cases where focus skips around even when the tabindex values look correct.</p>
<pre><code class="language-python">function auditTabOrder(formId) {
  const form = document.getElementById(formId);
  const focusableElements = form.querySelectorAll(
    'input, select, textarea, button, a[href], [tabindex]:not([tabindex="-1"])'
  );
  const failures = [];
  
  const elements = Array.from(focusableElements).map(el =&gt; ({
    element: el,
    position: el.getBoundingClientRect(),
    tabindex: parseInt(el.getAttribute('tabindex')) || 0
  }));
  
  for (let i = 1; i &lt; elements.length; i++) {
    const prev = elements[i - 1];
    const curr = elements[i];
    
    // Check if tab order follows visual top-to-bottom, left-to-right
    const visuallyBefore = prev.position.top &lt; curr.position.top || 
      (prev.position.top === curr.position.top &amp;&amp; prev.position.left &lt; curr.position.left);
    
    if (!visuallyBefore &amp;&amp; prev.tabindex === curr.tabindex) {
      failures.push({
        field: curr.element.id,
        issue: 'Tab order does not match visual layout',
        wcag: '2.4.3 Focus Order'
      });
    }
  }
  
  return failures;
}
</code></pre>
<p>In essence, the audit identifies failures to adhere to WCAG 2.4.3 Focus Order while preserving context and the ability to interact with keyboard users as they interact with form fields (Source: <a href="https://www.w3.org/WAI/WCAG21/Understanding/focus-order.html">WCAG 2.4.3, WC3</a>).</p>
<h3 id="heading-verify-focus-visibility">Verify Focus Visibility</h3>
<p>Focus indicators need to be clearly identifiable. According to research, visible focus indicators improved typing and reduced errors significantly (Source: <a href="https://www.researchgate.net/publication/392950031_Enhancing_User_Experience_of_Virtual_Keyboard_Through_Collaborative_and_Speed-Adaptive_Auditory-Vibrotactile_Feedback">Liu and others, ResearchGate</a>).</p>
<p>For instance, focus styles can include an outline, border, or shadow, but they must have enough contrast against the background (at least 3:1) to satisfy WCAG 2.4.7 Focus Visible and 1.4.11 Non-text Contrast (Source: <a href="https://www.w3.org/WAI/WCAG21/Understanding/">WCAG Understanding Docs, WC3</a>). Consider the following example:</p>
<pre><code class="language-python">function auditFocusVisibility(formId) {
  const form = document.getElementById(formId);
  const focusableElements = form.querySelectorAll('input, select, textarea, button');
  const failures = [];
  
  focusableElements.forEach(element =&gt; {
    element.focus();
    const computedStyle = window.getComputedStyle(element);
    
    // Check for visible focus indicator
    const hasOutline = computedStyle.outline !== 'none' &amp;&amp; 
      computedStyle.outlineWidth !== '0px';
    const hasBorder = computedStyle.borderStyle !== 'none';
    const hasBoxShadow = computedStyle.boxShadow !== 'none';
    
    // Check contrast ratio for focus indicator
    const outlineColor = computedStyle.outlineColor;
    const backgroundColor = computedStyle.backgroundColor;
    const contrastRatio = calculateContrastRatio(outlineColor, backgroundColor);
    
    if (!hasOutline &amp;&amp; !hasBorder &amp;&amp; !hasBoxShadow) {
      failures.push({
        field: element.id,
        issue: 'No visible focus indicator',
        wcag: '2.4.7 Focus Visible'
      });
    } else if (contrastRatio &lt; 3) {
      failures.push({
        field: element.id,
        contrastRatio: contrastRatio.toFixed(2),
        issue: 'Focus indicator contrast ratio below 3:1',
        wcag: '1.4.11 Non-text Contrast'
      });
    }
  });
  
  return failures;
}
</code></pre>
<p>Good focus styling helps keyboard users see where they are on the page. This code checks that focus indicators are visible and have enough contrast against the background so users can tell which field they're currently in.</p>
<h3 id="heading-using-automated-testing-tools">Using Automated Testing Tools</h3>
<p>To speed up and automate audits even more efficiently, you can use tools such as <a href="https://developer.chrome.com/docs/lighthouse/overview">Google Lighthouse</a>, <a href="https://chromewebstore.google.com/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd">axe-core</a>, and <a href="https://www.cypress.io/">Cypress</a>. You can also combine these tools to be even more powerful – for example, using axe-core in conjunction with Cypress is the most comprehensive test suite I can suggest.</p>
<p>Here is a workflow you can follow:</p>
<pre><code class="language-python">async function runAccessibilityAudit(formId) {
  const form = document.getElementById(formId);
  const results = await axe.run(form, {
    rules: {
      'label': { enabled: true },
      'aria-required-attr': { enabled: true },
      'aria-valid-attr-value': { enabled: true },
      'keyboard-navigation': { enabled: true },
      'focus-order-semantics': { enabled: true }
    }
  });
  
  const violations = results.violations.map(violation =&gt; ({
    rule: violation.id,
    impact: violation.impact,
    description: violation.description,
    wcag: violation.tags.filter(tag =&gt; tag.startsWith('wcag')),
    elements: violation.nodes.map(node =&gt; node.target)
  }));
  
  return violations;
}
</code></pre>
<p>When you document keyboard patterns and automate the checks, you make sure everyone can complete your forms – whether they use a mouse, keyboard, or screen reader. Run these checks in your CI/CD pipeline to catch problems before they go live.</p>
<h2 id="heading-ai-informed-navigation-pattern-detection">AI-Informed Navigation Pattern Detection</h2>
<p>Machine learning models can help identify strange keyboard navigation sequences that signal potential usability challenges. Combining mouse tracking with artificial intelligence can give you insights into user behavior that aren't possible using traditional strategies (Sources: <a href="https://www.researchgate.net/publication/334385231_User_Experience_Evaluation_Using_Mouse_Tracking_and_Artificial_Intelligence">Souza and others, IEEE Access</a>).</p>
<p>The logic could similarly be applied to keyboard navigation studies, as AI models can be trained on typical successful navigation patterns to signal when users are struggling in their keyboard flows.</p>
<h3 id="heading-pattern-detection-for-navigation-using-ai">Pattern Detection for Navigation Using AI</h3>
<p>AI tools can assess keyboard navigation to find non-compliant actions during testing. For instance, through machine learning, the code sample below captures, evaluates, and categorizes unusual or problematic keyboard navigation behavior on web forms and detects unique keyboard navigation or k-action sequences that are likely indicative of usability concerns.</p>
<pre><code class="language-python">async function detectNavigationAnomalies(formId) {
  const navigationData = captureKeyboardSequence(formId);
  const features = extractNavigationFeatures(navigationData);
  
  // Use machine learning to classify navigation patterns
  const model = await loadTrainedModel('keyboard-anomaly-detection');
  const predictions = await model.predict(features);
  
  const anomalies = predictions.filter(p =&gt; p.confidence &gt; 0.8).map(p =&gt; ({
    sequence: p.keystrokes,
    anomalyType: p.classification,
    severity: p.confidence,
    recommendation: generateRecommendation(p.classification)
  }));
  
  return anomalies;
}

function extractNavigationFeatures(data) {
  return {
    tabSequenceLength: data.tabs.length,
    backtrackCount: countBacktracks(data.tabs),
    focusTrapIndicators: detectFocusTraps(data),
    averageTimePerElement: calculateAverageTime(data),
    sequenceDeviation: measureSequenceDeviation(data)
  };
}
</code></pre>
<p>The code structure captures the user's keyboard navigation actions on specified forms using <code>captureKeyboardSequence(formId)</code>, which means that the user has entered keystrokes, such as tabbing and focusing between fields.</p>
<p>Using <code>extractNavigationFeatures(data)</code>, the code processes the Raw keyboard navigation sequence by calculating metrics. Lastly, the code loads a previously-trained ML model and provides the extracted features to the model to be classified into their respective categories along with a confidence score.</p>
<p>Any keyboard navigation anomalies detected with a confidence score of 0.8 or higher will be filtered. The detected keystroke sequences, type of anomaly, severity, and specific suggestions will be included in the final results report for later review by the user.</p>
<h3 id="heading-fuzzy-logic-paradigm-for-navigation-performance-scoring">Fuzzy Logic Paradigm for Navigation-Performance Scoring</h3>
<p>Collaborative feedback systems can help improve the virtual keyboard user experience. Fuzzy logic lets you combine multiple measurements – like focus visibility and tab order – into a single score that better reflects the actual user experience. (Source: <a href="https://www.researchgate.net/publication/392950031_Enhancing_User_Experience_of_Virtual_Keyboard_Through_Collaborative_and_Speed-Adaptive_Auditory-Vibrotactile_Feedback">Liu and others, ResearchGate</a>).</p>
<p>For example, the following code creates a fuzzy inference system that evaluates two inputs: Focus Visibility and Tab Order Logic. These two inputs are evaluated using fuzzy logic and associated rules to arrive at a single score representing the total efficiency of keyboard navigation for a given application.</p>
<pre><code class="language-python">function createKeyboardNavigationFuzzySystem() {
  // Define fuzzy variables
  const focusVisibility = new FuzzyVariable('focusVisibility', 0, 100);
  focusVisibility.addTerm('poor', new TriangularMF(0, 0, 40));
  focusVisibility.addTerm('adequate', new TriangularMF(30, 50, 70));
  focusVisibility.addTerm('excellent', new TriangularMF(60, 100, 100));
  
  const tabOrderLogic = new FuzzyVariable('tabOrderLogic', 0, 100);
  tabOrderLogic.addTerm('confusing', new TriangularMF(0, 0, 40));
  tabOrderLogic.addTerm('acceptable', new TriangularMF(30, 50, 70));
  tabOrderLogic.addTerm('intuitive', new TriangularMF(60, 100, 100));
  
  const navigationEfficiency = new FuzzyVariable('navigationEfficiency', 0, 100);
  navigationEfficiency.addTerm('inefficient', new TriangularMF(0, 0, 40));
  navigationEfficiency.addTerm('moderate', new TriangularMF(30, 50, 70));
  navigationEfficiency.addTerm('efficient', new TriangularMF(60, 100, 100));
  
  // Define fuzzy rules
  const rules = [
    'IF focusVisibility IS excellent AND tabOrderLogic IS intuitive THEN navigationEfficiency IS efficient',
    'IF focusVisibility IS poor OR tabOrderLogic IS confusing THEN navigationEfficiency IS inefficient',
    'IF focusVisibility IS adequate AND tabOrderLogic IS acceptable THEN navigationEfficiency IS moderate'
  ];
  
  return new FuzzyInferenceSystem([focusVisibility, tabOrderLogic], navigationEfficiency, rules);
}
</code></pre>
<p>The resulting score is meant to be more representative of a user’s experience with the keyboard navigation system than other existing methods of measuring user satisfaction. This fuzzy inference system assesses keyboard navigation quality based on multiple dimensions at the same time, yielding scores in a similar range to user-reported satisfaction measurements (Source: <a href="https://www.researchgate.net/publication/392950031_Enhancing_User_Experience_of_Virtual_Keyboard_Through_Collaborative_and_Speed-Adaptive_Auditory-Vibrotactile_Feedback">Liu and others, ResearchGate</a>).</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article has given you the tools and resources you’ll need to automate a UX audit of your app’s forms – from the initial setup through continuous integration.</p>
<p>You’ve learned:</p>
<ul>
<li><p>Three essential components of forms and the importance of addressing each component systematically.</p>
</li>
<li><p>How to link objectives directly with business KPIs and user outcomes.</p>
</li>
<li><p>How to set up automated testing for the specificity of errors, the timing of validation, and the direction for the next actionable step after an error.</p>
</li>
<li><p>How to review the hint text on your forms: proactive display, proximity to the field it assists, and accessibility.</p>
</li>
<li><p>How to validate keyboard navigation through verification of tab order, testing focus visibility, and using ARIA tags.</p>
</li>
<li><p>How to incorporate WCAG criteria into your automated tests and to incorporate Nielsen's 10 Heuristics.</p>
</li>
<li><p>How to prepare documentation for the handoff between Design and Development, using the "5Cs": Coverage, Completion, Consistency, Clarity, and Correctness.</p>
</li>
</ul>
<p><strong>Next steps:</strong></p>
<ul>
<li><p>Begin with a single high-impact form in your application (signup or checkout) and run the basic automated checks on error messages and keyboard flows.</p>
</li>
<li><p>Integrate one or two audit functions into your existing test suite to see how they surface issues you might have missed manually.</p>
</li>
<li><p>Create a centralized error and hint message library for your most critical forms to ensure consistency.</p>
</li>
<li><p>Gradually expand your audit coverage to additional forms and fields as you refine your automation approach.</p>
</li>
<li><p>Add these checks to your CI/CD pipeline so they run automatically on every pull request, catching regressions before they reach users.</p>
</li>
<li><p>Experiment with AI-powered anomaly detection for keyboard navigation patterns once your foundational audits are stable.</p>
</li>
</ul>
<p>Most importantly, remember that form UX optimization is an ongoing practice, not a one-time fix. Start with the forms that directly impact your conversion metrics, validate that your automated checks catch real user problems, and expand your coverage systematically. Your goal should be to build a reliable system that continuously protects your users from friction.</p>
<h3 id="heading-about-the-author">About the author</h3>
<p>Hope you enjoyed the article and found it helpful. I’ve been a contributor to freeCodeCamp for more than 8 years, and to make this piece more precise and detailed, I used some expert help.</p>
<p>I sincerely thank skilled designers from <a href="https://coaxsoft.com/">COAX Software</a> for the UX and accessibility guidelines, and the developers who provided the audit automation code snippets (who both wished to stay anonymous). The company has a deep expertise in <a href="https://coaxsoft.com/services/ux-audit-services">UI/UX design</a>.</p>
<p>To find out more about me and read more content on tech and digital, visit <a href="https://www.linkedin.com/in/oleg-romanyuk/">https://www.linkedin.com/in/oleg-romanyuk/</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Validate Forms in React and React Native Using Yup and Formik ]]>
                </title>
                <description>
                    <![CDATA[ Validation is a key part of development, regardless of what programming language you’re writing. Developers should always be validating user input, API parameters, and retrieved values. One of the most common elements where you’ll need to apply user ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-how-to-validate-user-input/</link>
                <guid isPermaLink="false">66bb889bc32849d18c5cdca7</guid>
                
                    <category>
                        <![CDATA[ Form validations ]]>
                    </category>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Grant Riordan ]]>
                </dc:creator>
                <pubDate>Mon, 24 Jun 2024 19:51:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/06/1080_Template.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Validation is a key part of development, regardless of what programming language you’re writing. Developers should always be validating user input, API parameters, and retrieved values.</p>
<p>One of the most common elements where you’ll need to apply user input validation is via a form. This could be a user sign up form, a contact us form, or a simple questionnaire.</p>
<h2 id="heading-outcomes-of-the-tutorial">Outcomes of the Tutorial</h2>
<p>By the end of this article , you will be able to:</p>
<ul>
<li>Understand common issues with form validation.</li>
<li>How to utilise the Yup schema validation library alongside the Formik form library.</li>
<li>How to build a form in React with full validation (same principles apply for React Native, with different component syntax).</li>
</ul>
<h2 id="heading-contents">Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-validation">What is Validation</a>?</li>
<li><a class="post-section-overview" href="#heading-the-object-to-be-validated">The Object to Be Validated</a></li>
<li><a class="post-section-overview" href="#heading-introducing-yup-and-formik">Introducing Yup and Formik</a></li>
<li><a class="post-section-overview" href="#heading-how-to-add-validation-to-a-form">How to Add Validation to a Form</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-what-is-validation">What is Validation?</h2>
<p>Validation is defined as:</p>
<blockquote>
<p><em>the action of checking or proving the validity or accuracy of something.</em></p>
</blockquote>
<p>But what does that mean in computer speak? This could be a multitude of things, but the premise still stands. You could be validating a variable value or an object against a pre-determined set of rules or regulations.</p>
<p>Examples of validation rules could be:</p>
<ul>
<li>Password must be at least 8 characters and contain a special character.</li>
<li>Username must be unique.</li>
<li>Date of birth must be received as a string, in a particular format, for example ISO8601</li>
</ul>
<p>Let’s use the example of a user registration form on a website. </p>
<h2 id="heading-the-object-to-be-validated">The Object to Be Validated</h2>
<p>The form will comprise of several inputs to form a <code>UserRegistration</code> object. Like so‌:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">interface</span> UserRegistration {
  firstName: <span class="hljs-built_in">string</span>;
  surname: <span class="hljs-built_in">string</span>;
  email: <span class="hljs-built_in">string</span>;
  dob: <span class="hljs-built_in">string</span>;
}
</code></pre>
<p>Above is an interface (contract) for a <code>UserRegistration</code> object. It simply defines some key user information which needs to be collected, with all values being a <code>string</code> value.</p>
<p>While languages like TypeScript are useful for ensuring that we pass the correct types to functions throughout our application, they do not inherently validate the actual content or values within those types. TypeScript guarantees that a variable is of a specific type, such as a string or a number, but it does not verify if the content of that string or number meets specific criteria or constraints.</p>
<h3 id="heading-what-if-we-didnt-validate-the-values">What If We Didn't Validate the Values?</h3>
<p>Ok, before we move onto how to validate, let's look at what could happen if we don't validate.</p>
<p>Without validation, a user could input the following values:</p>
<p><strong>Firstname</strong>: 1231301‌<br>‌<strong>Surname</strong>: Hello##test_101‌<br>‌<strong>Email</strong>: user_123@@email.to@.com‌<br>‌<strong>DoB</strong>: 10+12+1909</p>
<p>These values may <strong>seem</strong> perfectly acceptable, and your front end might allow them to be submitted without any issues. And the API will likely accept these values initially. </p>
<p>But when the API attempts to parse these values (converting) during the request processing, it will encounter errors and fail to process the request correctly.</p>
<p>There are several negative consequences to this approach:</p>
<ol>
<li><strong>Increased Server Load</strong>: The front end is making multiple invalid requests to the server, which unnecessarily strains the server. This extra load could have been avoided.</li>
<li><strong>Potentially Higher Costs</strong>: The cost of handling these invalid requests can increase significantly, depending on your hosting plan and server configuration. Each invalid request consumes server resources that could be used more efficiently.</li>
<li><strong>Poor User Experience (UX)</strong>: Users will likely become frustrated if they repeatedly enter details, submit the form, and then receive error messages indicating that their inputs are invalid. This can lead to a negative perception of the application.</li>
</ol>
<p>To mitigate these issues and reduce the number of invalid requests, we can implement 'client-side validation' to ensure that the data meets the required criteria before sending the API request.</p>
<h2 id="heading-introducing-yup-and-formik">Introducing Yup and Formik</h2>
<p>Yup and Formik are both libraries which you can add to any React or React Native application via npm or yarn.</p>
<p>Yup is a schema building library that allows you to build schemas for validation at runtime. It has a plethora of extension functions which can set rulesets, transform values, and return validation messages right out the box.</p>
<p>Let's take a look at an example of a Yup schema for our user form:‌</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> Yup <span class="hljs-keyword">from</span> <span class="hljs-string">'yup'</span>;

<span class="hljs-comment">// If using Typescript, you can utilise a wrapper function to enforce strict typing</span>

<span class="hljs-keyword">const</span> createYupSchema = &lt;T <span class="hljs-keyword">extends</span> <span class="hljs-built_in">object</span>&gt;(schema: Yup.ObjectSchema&lt;T&gt;): Yup.ObjectSchema&lt;T&gt; =&gt; schema;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> userFormSchema = createYupSchema&lt;UserInput&gt;(
  Yup.object().shape({
    firstname: Yup.string().required(<span class="hljs-string">'First name is required'</span>),
    surname: Yup.string().required(<span class="hljs-string">'Surname is required'</span>),
    email: Yup.string().email(<span class="hljs-string">'Invalid email format'</span>).required(<span class="hljs-string">'Email is required'</span>),
    dob: Yup.string().required(<span class="hljs-string">'Date of Birth is required'</span>),
  })
);

<span class="hljs-comment">// JS Version</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> validationSchema = Yup.object({
  firstname: Yup.string().required(<span class="hljs-string">'First name is required'</span>),

  surname: Yup.string().required(<span class="hljs-string">'Surname is required'</span>),
  email: Yup.string().email(<span class="hljs-string">'Invalid email format'</span>).required(<span class="hljs-string">'Email is required'</span>),
  dob: Yup.date().required(<span class="hljs-string">'Date of Birth is required'</span>)
});
</code></pre>
<p>We're creating a Yup object (schema) which contains all of our Keys for our UserInput interface.</p>
<h3 id="heading-schema-parts">Schema Parts:</h3>
<ul>
<li>key: the key which will be used later for the name of our element (as we're using TypeScript, this needs to match the object key name).</li>
<li>ruleset: for all keys, apply a ruleset. A ruleset must start with a typing declaration, that is <code>Yup.string()</code> or <code>Yup.number()</code> and so on. You can then chain your other validation functions. </li>
</ul>
<p>Using TypeScript ensures that we match the schema type to our interface types.</p>
<p>For example, if we try and do this:</p>
<pre><code class="lang-ts">firstname: Yup.date().required();
</code></pre>
<p>it will throw a TypeScript error complaining that <code>firstname</code> cannot be validated as if it was a date, as the type of firstname is a <code>string</code>.</p>
<h3 id="heading-how-to-add-validation-to-a-form">How to Add Validation to a Form</h3>
<p>This is where our Formik library comes in and makes things much easier than validating a form and implementing error handling manually.</p>
<p>Formik is a library which encapsulates a <code>&lt;Form/&gt;</code> component. It allows us to create richer forms in React and React Native, giving us access to features like form state, error handling, validation, and processing of form submissions much more efficiently.</p>
<p>You can access a pre-built version of a UserForm utilising Yup, Formik, and React (Vite) at my GitHub <a target="_blank" href="https://github.com/grant-dot-dev/fcc-yup-schema-validation">here</a>. Simply clone the GitHub repository and follow the README.md instructions. ‌</p>
<pre><code class="lang-tsx">&lt;Formik
        initialValues={initialValues}
        validationSchema={userFormSchema}
        onSubmit={onSubmit}
      &gt;
        {({ isValid, dirty, isSubmitting }) =&gt; (
          &lt;Form&gt;
            &lt;div className="form-control"&gt;
              &lt;label htmlFor="firstName"&gt;First Name&lt;/label&gt;
              &lt;Field type="text" id="firstName" name="firstName" /&gt;
              &lt;ErrorMessage name="firstName" component="div" className="error" /&gt;
            &lt;/div&gt;

            &lt;div className="form-control"&gt;
              &lt;label htmlFor="surname"&gt;Surname&lt;/label&gt;
              &lt;Field type="text" id="surname" name="surname" /&gt;
              &lt;ErrorMessage name="surname" component="div" className="error" /&gt;
            &lt;/div&gt;

            &lt;div className="form-control"&gt;
              &lt;label htmlFor="email"&gt;Email&lt;/label&gt;
              &lt;Field type="email" id="email" name="email" /&gt;
              &lt;ErrorMessage name="email" component="div" className="error" /&gt;
            &lt;/div&gt;

            &lt;div className="form-control"&gt;
              &lt;label htmlFor="dob"&gt;Date of Birth&lt;/label&gt;
              &lt;Field type="date" id="dob" name="dob" /&gt;
              &lt;ErrorMessage name="dob" component="div" className="error" /&gt;
            &lt;/div&gt;

            &lt;button type="submit" disabled={isSubmitting || !isValid}&gt;Submit&lt;/button&gt;
          &lt;/Form&gt;
        )}
      &lt;/Formik&gt;
</code></pre>
<p>In this code, we've utilsed the <code>&lt;Formik/&gt;</code> library component, which wraps around our standard <code>&lt;Form/&gt;</code>  element. We pass the following properties to the component:</p>
<ul>
<li><code>**initialValues**</code> – these are the required initial values of your form (that is when the form renders what values your inputs will have).‌ </li>
<li><strong><code>validationSchema</code> –</strong> this is probably the most important for this tutorial. Bear in mind this is an optional property, as it's not needed to utilise the <code>&lt;Formik/&gt;</code> component, but for any validation it is. ‌<br>‌‌<br>‌We're going to import our <code>userFormSchema</code> we created in the previous step. This is going to tell the form, when validating inputs within this form utilise these schemas. ‌</li>
<li><strong><code>onSubmit</code></strong> – a straightforward function to run on clicking your button / submitting the form. The values of the form will automatically be passed to this function.‌</li>
</ul>
<p>You can wrap the form within a "render prop" function also to utilise some of the exposed props from Formik within your form. You can learn about render props more <a target="_blank" href="https://legacy.reactjs.org/docs/render-props.html">here</a>.</p>
<pre><code class="lang-tsx">{({ isValid, isSubmitting }) =&gt; (
</code></pre>
<p><strong>Note:</strong> This is not required if you don't want to utilise any of the underlying Formik properties within the form itself. You can simply remove and place your opening <code>&lt;Form&gt;</code> tag in its place. ‌<br>‌‌<br>‌But using this render prop allows you to access properties exposed from the Formik component within your <code>&lt;Form/&gt;</code> element. You can see that we are utilising the<code>isValid</code> and <code>isSubmitting</code> properties to control the state of our submit button.</p>
<p>Continuing on with analyzing the code:</p>
<ul>
<li><code>**isValid**</code> – a boolean value which Formik controls based on our schema validation result.</li>
<li><code>**isSubmitting**</code> – A boolean flag indicating if a form is mid-submission. This flag is very useful when wanting to disable a button, to prevent multiple clicks meaning multiple submissions of the form.</li>
</ul>
<p>We can use these values to control the enablement of the submit button like so:</p>
<pre><code class="lang-tsx">&lt;button type="submit" disabled={isSubmitting || !isValid}&gt;Submit&lt;/button&gt;
</code></pre>
<h3 id="heading-input-fields">Input Fields</h3>
<p>It's important to note that when using Formik and Yup, in order for the validation to work, the names of the input fields need to match the Yup schema keys exactly (case sensitive) – otherwise the validation rules won't be registered.</p>
<p><strong>Example:‌</strong></p>
<pre><code class="lang-tsx">&lt;Field type="email" id="email" name="email" /&gt;
&lt;ErrorMessage name="email" component="div" className="error" /&gt;
</code></pre>
<p>We've defined this field is to be used for an email input, and given it the matching <code>name</code> of "email" to our a userFormSchema definition.</p>
<p>Underneath, we code our Formik <code>&lt;ErrorMessage/&gt;</code> component, again passing in the name of '<em>email'</em>, matching our schema. Using the name property we are able to link our input, error message, and validation schemas all together. </p>
<p>If there are any issues with validating the input field, the error message will show any defined error messages – otherwise it will fallback to a default message, e.g "<em>firstname is a required field</em>". This can be less user friendly, so I'd recommend always passing a custom message.</p>
<p>You'll also notice, that when we lose focus or when typing (after first validation has run), it will automatically run validation again. You can overwrite this functionality by setting the <code>validateOnBlur</code> and the <code>validateOnChange</code> flags (true / false).</p>
<p>As an example, it will look like this in its error state.:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-100.png" alt="Image: Invalid Formik form showing error state" width="600" height="400" loading="lazy">
<em>Image: Invalid Formik form showing error state</em></p>
<p>‌Once we've entered values for all inputs, and our validation has passed (you can see the submit button is now enabled), we can submit.‌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-95.png" alt="Image: Valid Formik form showing valid state" width="600" height="400" loading="lazy">
<em></em></p><div id="ember289" class="miw-100 tc bn form-text bg-transparent pr8 pl8 ember-view" data-kg-has-link-toolbar="true" data-koenig-dnd-disabled="true"><div class="koenig-basic-html-input__editor-wrappper"><div class="koenig-basic-html-input__editor __mobiledoc-editor" data-gramm="false" data-kg="editor" data-kg-allow-clickthrough="" data-placeholder="Type caption for image (optional)"><p><em>Image: Valid User form with enabled submit button</em></p></div></div></div><p></p>
<h3 id="heading-further-validation-and-formik-features">Further Validation and Formik Features‌</h3>
<p>You've now seen how easy Yup and Formik can make creating a form. It has full validation and even error handling, meaning you can have a fully functioning user friendly form built in just a few minutes.</p>
<p>But what if you want to add more complex validation to a much larger / complicated form? Well, let's look at an example:</p>
<p>Let's say we want to validate that the date of birth provided ensures that the user is over the age of 18. We will also add a password field, which will have rules of:</p>
<ul>
<li>minimum of 6 letters</li>
<li>contain a number</li>
<li>contain a special character</li>
</ul>
<h4 id="heading-dob-extra-requirements">DoB Extra Requirements</h4>
<p>We can do this by chaining the <code>test()</code> function onto the <code>string()</code> function of the dob object within our schema.</p>
<p>The <code>test()</code> function allows us to test against custom logic. Update the <code>dob</code> parameter within the userFormSchema to the following:‌</p>
<pre><code class="lang-ts">dob: Yup.string()
      .required(<span class="hljs-string">'Date of Birth is required'</span>)
      .test(<span class="hljs-string">'is-older-than-18'</span>, <span class="hljs-string">'You must be at least 18 years old'</span>, <span class="hljs-function">(<span class="hljs-params">value</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (!value) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;

        <span class="hljs-comment">// try to parse the value to date</span>
        <span class="hljs-keyword">const</span> parsedDate = parse(value, <span class="hljs-string">'yyyy-MM-dd'</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>());
        <span class="hljs-keyword">if</span> (!isValid(parsedDate)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;

        <span class="hljs-keyword">const</span> today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
        <span class="hljs-keyword">const</span> eighteenYearsAgo = subYears(today, <span class="hljs-number">18</span>);

        <span class="hljs-comment">// check if date provided is before or the same as 18 years ago.</span>
        <span class="hljs-keyword">return</span> parsedDate &lt;= eighteenYearsAgo;
      })
</code></pre>
<p>We now get the following error when trying to submit a date that is less than 18 years ago. ‌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/image-99.png" alt="Image showing Invalid date input field due to failed date validation" width="600" height="400" loading="lazy">
<em>Image: Invalid input field due to failed date validation</em></p>
<h4 id="heading-password-validation">Password Validation</h4>
<p>For the password field validation, we can do something like this:‌</p>
<pre><code class="lang-ts">password: Yup.string()
    .required(<span class="hljs-string">'This field is required'</span>)
    .min(<span class="hljs-number">6</span>, <span class="hljs-string">'Must be at least 6 characters'</span>)
    .matches(<span class="hljs-regexp">/[!@#$%^&amp;*(),.?":{}|&lt;&gt;]/</span>, <span class="hljs-string">'Must contain at least one special character'</span>)
    .matches(<span class="hljs-regexp">/\d/</span>, <span class="hljs-string">'Must contain at least one number'</span>);
</code></pre>
<p>Here we use the <code>matches()</code> function, passing in a regular expression to assert against. You could combine these cases into one regular expression, but the benefit of keeping them separate is it allows you to pinpoint which validation rule is failing. It also allows for a more granular error message and maintenance should the rules change in the future.</p>
<h3 id="heading-other-useful-methods">Other Useful Methods:</h3>
<ul>
<li><code>length()</code> – asserts the length of the string / number</li>
<li><code>positive()</code> – asserts the number type is a positive number</li>
<li><code>email()</code> – asserts that it is a valid email address</li>
<li><code>url()</code>  – asserts that it is a valid URL </li>
<li><code>min()</code> / <code>max()</code> – asserts that the number is at least 'x' and less than 'y'</li>
<li><code>ensure()</code> – transforms <code>undefined</code> and <code>null</code> values to an empty string along with setting the <code>default</code> to an empty string.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As you can see, the possibilities with Yup are vast. Then combine this with the Formik library, and you can have rich, efficient, and easy to use forms. </p>
<p>This ease of use makes it so much quicker to get a form up and running on your web or mobile application, allowing you to focus on user experience, design, and business logic. </p>
<p>As always feel free to reach and discuss this article with me on <a target="_blank" href="https://x.com/grantdotdev">Twitter</a>, and don't forget to drop me a follow to hear about future articles and dev tips.   </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Client-Side Form Handling with JavaScript – Explained with Example Code ]]>
                </title>
                <description>
                    <![CDATA[ HTML forms are essential components of most websites and web apps. They enable interaction between users and those websites, and are a key concept for web developers to understand.  This comprehensive guide covers various aspects of HTML forms, from ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/form-validation-in-javascript/</link>
                <guid isPermaLink="false">66c72185783c8978e5e7647a</guid>
                
                    <category>
                        <![CDATA[ Form validations ]]>
                    </category>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Samyak Jain ]]>
                </dc:creator>
                <pubDate>Fri, 08 Mar 2024 21:10:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/form-handling-in-javascript.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>HTML forms are essential components of most websites and web apps. They enable interaction between users and those websites, and are a key concept for web developers to understand. </p>
<p>This comprehensive guide covers various aspects of HTML forms, from how to create and structure forms to JavaScript interaction and form validation. </p>
<p>Understanding how to work with forms programmatically allows you to validate and capture user input, handle submissions, and enhance the overall user experience. </p>
<p>By following the examples and best practices provided in this guide, you'll be equipped with the knowledge necessary to build robust web forms that enhance user experience and facilitate seamless data collection and submission. </p>
<p>Whether you're a beginner or an experienced developer, this guide serves as a valuable resource for understanding and implementing HTML forms effectively in your web projects. </p>
<h3 id="heading-prerequisites"><strong>Prerequisites:</strong></h3>
<p>A basic understanding of JavaScript fundamentals is recommended to fully comprehend the concepts discussed in this tutorial. Familiarity with HTML forms will also be beneficial for understanding and applying the material covered.</p>
<p>If you're new to JavaScript, it's recommended to acquaint yourself with variables, data types, functions, loops, and basic DOM manipulation techniques before diving into this tutorial. This foundational knowledge will facilitate a smoother learning experience as we explore more advanced topics related to form handling in JavaScript.</p>
<p>Starting Note: For your convenience, all the examples and code discussed here can be accessed on <a target="_blank" href="https://github.com/theSamyak/FCC-Blog-CodeArchive/tree/main/Client-Side%20Form%20Handling%20with%20JavaScript">GitHub</a>.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ol>
<li><a class="post-section-overview" href="#heading-understanding-html-forms">Understanding HTML Forms</a><br>– <a class="post-section-overview" href="#heading-introduction-to-html-form-elements">Introduction to HTML form elements</a><br>– <a class="post-section-overview" href="#heading-javascript-and-form-handling">JavaScript and Form Handling</a><br>– <a class="post-section-overview" href="#accessing-form-fields">Accessing Form Fields</a><br>– <a class="post-section-overview" href="#heading-lets-see-an-example-registration-form">Example: Registration Form</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-radio-buttons">How to Create Radio Buttons</a><br>– <a class="post-section-overview" href="#javascript-to-handle-radio-button-selection">JavaScript to Handle Radio Button Selection</a><br>– <a class="post-section-overview" href="#heading-radio-button-change-event">Radio Button Change Event</a></li>
<li><a class="post-section-overview" href="#heading-checkboxes">Checkboxes</a><br>– <a class="post-section-overview" href="#heading-how-to-check-if-a-checkbox-is-checked">How to Check if a Checkbox is Checked</a><br>– <a class="post-section-overview" href="#heading-how-to-get-checkbox-values">How to Get Checkbox Values</a><br>– <a class="post-section-overview" href="#heading-how-to-handle-multiple-checkboxes">How to Handle Multiple Checkboxes</a><br>– <a class="post-section-overview" href="#heading-how-to-check-uncheck-all-checkboxes">How to Check / Uncheck All Checkboxes</a><br>– <a class="post-section-overview" href="#heading-how-to-dynamically-generate-checkboxes">How to Dynamically Generate CheckBoxes</a></li>
<li><a class="post-section-overview" href="#select-element">Select Element</a><br>– <a class="post-section-overview" href="#how-to-interact-with-a-select-element">How to Interact with a Select Element</a><br>– <a class="post-section-overview" href="#heading-how-to-access-options-with-javascript">How to Access Options with JavaScript</a><br>– <a class="post-section-overview" href="#how-to-handle-multiple-selections">How to Handle Multiple Selections</a><br>– <a class="post-section-overview" href="#lets-see-an-example-task-manager-adding-and-removing-tasks">Example: Task Manager</a></li>
<li><a class="post-section-overview" href="#heading-difference-between-change-and-input-event">Difference Between Change and Input Event</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<p>Before we start, here's something to note:</p>
<p>This is a follow up blog on this <a target="_blank" href="https://www.freecodecamp.org/news/javascript-in-the-browser-dom-and-events/">DOM and Events Handbook</a> and not cover server-side communication/server-side form handling in this blog as it involves advanced topics such as AJAX (Asynchronous JavaScript and XML), Promises, error handling, and handling asynchronous operations in JavaScript.</p>
<p>In this tutorial, we'll instead focuses on how to work with various form elements including radio buttons, checkboxes, and select elements, as well as dynamically generating and interacting with them using JavaScript. </p>
<p>Delving into server-side communication would extend beyond the scope of this article, which aims to provide a comprehensive understanding of DOM manipulation and event handling within the context of form elements.</p>
<h2 id="heading-understanding-html-forms">Understanding HTML Forms</h2>
<p>HTML forms are fundamental elements used for collecting and submitting user data on the web. They enable interaction between users and websites by allowing users to input information, make selections, and submit data to servers for processing.</p>
<h4 id="heading-introduction-to-html-form-elements">Introduction to HTML Form Elements</h4>
<p>HTML forms are created using the <code>&lt;form&gt;</code> element, which acts as a container for various input elements. Common form elements include text fields, checkboxes, radio buttons, dropdown menus, and buttons.</p>
<p>To reference a form in JS, you can use DOM methods like <code>getElementById()</code> or <code>document.forms</code>. <code>document.forms</code> returns a collection of forms, and you can access a specific form using an index, name, or id.    </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'signup'</span>);
<span class="hljs-keyword">const</span> firstForm = <span class="hljs-built_in">document</span>.forms[<span class="hljs-number">0</span>]; <span class="hljs-comment">// accessing first form</span>
<span class="hljs-keyword">const</span> formByName = <span class="hljs-built_in">document</span>.forms[<span class="hljs-string">'formName'</span>]; <span class="hljs-comment">// accessing form by name</span>
<span class="hljs-keyword">const</span> formById = <span class="hljs-built_in">document</span>.forms[<span class="hljs-string">'formId'</span>]; <span class="hljs-comment">// accessing form by id</span>
</code></pre>
<p>Let's see a basic example of an HTML form:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"username"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"password"</span>&gt;</span>Password:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Submit"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>In this example, we have a form with two input fields for username and password, along with a submit button.</p>
<h3 id="heading-form-structure-and-attributes">Form Structure and Attributes</h3>
<p>HTML forms can have various attributes that control their behavior and appearance. Some common attributes include:</p>
<ul>
<li><strong>action:</strong> Specifies the URL where the form data should be submitted.</li>
<li><strong>method:</strong> Specifies the HTTP method used to send form data (<code>post</code> or <code>get</code>).</li>
<li><strong>target</strong>: Specifies where to display the response after form submission (for example, <code>_self</code>, <code>_blank</code>, <code>_parent</code>, <code>_top</code>).</li>
<li><strong>name</strong>: Assigns a name to the form for identification purposes.</li>
</ul>
<p>Here's an example of a form with action, method, and target attributes:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/submit-form"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"POST"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"myForm"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Form elements go here --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<h3 id="heading-javascript-and-form-handling">JavaScript and Form Handling</h3>
<p>JavaScript uses the <code>HTMLFormElement</code> object to represent a form. This object has properties corresponding to the HTML attributes <code>action</code> and <code>method</code>.</p>
<p>Methods like <code>submit()</code> and <code>reset()</code> are used for submitting and resetting forms.</p>
<pre><code class="lang-html">const form = document.getElementById('signup');
form.action; // returns the action attribute
form.method; // returns the method attribute
form.submit(); // submits the form
</code></pre>
<p>JavaScript provides Event Handlers to add interactivity to HTML forms. By leveraging these events, you can execute custom scripts in response to user actions within the form:</p>
<p><strong>Submit Event</strong>: A form typically has a submit button, which when clicked, sends the form data to the server. This is achieved using an <code>&lt;input&gt;</code> or <code>&lt;button&gt;</code> element with <code>type="submit"</code>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Sign Up"</span>&gt;</span>
// or
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Sign Up<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>To attach an event listener to the submit event, you use the <code>addEventListener()</code> method. Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'signup'</span>);
form.addEventListener(<span class="hljs-string">'submit'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    <span class="hljs-comment">// Custom validation and submission logic here</span>
});
</code></pre>
<p>In many cases, you may want to intercept the default form submission behavior and execute custom logic before allowing the form to be submitted to the server. You can use <code>preventDefault()</code> for this. Example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'signup'</span>);
form.addEventListener(<span class="hljs-string">'submit'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    event.preventDefault(); <span class="hljs-comment">// Prevents the default form submission</span>
    <span class="hljs-comment">// Custom validation and submission logic here</span>
});
</code></pre>
<p>Without <code>event.preventDefault()</code>, any custom validation and submission logic would still execute within the event listener, but the default form submission behavior would not be prevented.</p>
<p><strong>Reset Event</strong>: The <code>reset</code> event is triggered when the form is reset using a reset button or programmatically. We use <code>reset()</code> method to clear all form fields and reset them to their default values.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'form'</span>).addEventListener(<span class="hljs-string">'reset'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
    <span class="hljs-comment">// Custom form reset logic here</span>
});
</code></pre>
<h3 id="heading-how-to-access-form-fields">How to Access Form Fields</h3>
<p>You can access form fields using DOM methods like <code>getElementsByName()</code>, <code>getElementById()</code>, <code>querySelector()</code>, and so on</p>
<p>The <code>form.elements</code> property stores a collection of form elements. You can access these Elements by index, id, or name. Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'signup'</span>);
<span class="hljs-keyword">const</span> nameField = form.elements[<span class="hljs-string">'name'</span>]; <span class="hljs-comment">// accessing element by name</span>
<span class="hljs-keyword">const</span> emailField = form.elements[<span class="hljs-string">'email'</span>]; <span class="hljs-comment">// accessing element by name</span>
<span class="hljs-keyword">const</span> firstElement = form.elements[<span class="hljs-number">0</span>]; <span class="hljs-comment">// accessing first element by index no.</span>
</code></pre>
<p>Once you've accessed a form field, you can use the <code>value</code> property to access its value. Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> nameValue = nameField.value;
<span class="hljs-keyword">const</span> emailValue = emailFieldByName.value;
</code></pre>
<h3 id="heading-form-validation">Form Validation</h3>
<p>Form validation is an essential aspect of web development that ensures the data submitted by users is accurate and meets specified criteria before being processed by the server. Common validations include checking for empty fields, valid email formats, and so on.</p>
<h4 id="heading-html-form-validation">HTML Form Validation</h4>
<p>HTML5 provides built-in form validation through various attributes:</p>
<ul>
<li><strong>required</strong>: Specifies that a field must be filled out.</li>
<li><strong>pattern</strong>: Specifies a regular expression pattern that the input value must match.</li>
<li><strong>min</strong> and <strong>max</strong>: Specify the minimum and maximum values for an input field.</li>
<li><strong>maxlength</strong> and <strong>minlength</strong>: Specify the maximum and minimum length of the input</li>
<li><strong>type</strong>: Specifies the type of input expected (for example, email, number, date).</li>
</ul>
<p>Here's an example of HTML form validation using these attributes:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"username"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">required</span> <span class="hljs-attr">minlength</span>=<span class="hljs-string">"3"</span> <span class="hljs-attr">maxlength</span>=<span class="hljs-string">"15"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">required</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"age"</span>&gt;</span>Age:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"age"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"age"</span> <span class="hljs-attr">min</span>=<span class="hljs-string">"18"</span> <span class="hljs-attr">max</span>=<span class="hljs-string">"99"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Submit"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<h4 id="heading-javascript-form-validation">JavaScript Form Validation</h4>
<p>JavaScript allows developers to perform more sophisticated validation logic beyond what HTML attributes offer. Event listeners can be attached to form elements to handle validation dynamically. </p>
<p>Here's a basic example of JavaScript form validation:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'form'</span>);

form.addEventListener(<span class="hljs-string">'submit'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault(); <span class="hljs-comment">// Prevent form submission</span>

    <span class="hljs-comment">// Perform custom validation logic</span>
    <span class="hljs-keyword">const</span> email = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'email'</span>).value;
    <span class="hljs-keyword">const</span> password = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'password'</span>).value;

    <span class="hljs-keyword">if</span> (!emailIsValid(email)) {
        alert(<span class="hljs-string">'Please enter a valid email address.'</span>);
        <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">if</span> (password.length &lt; <span class="hljs-number">6</span>) {
        alert(<span class="hljs-string">'Password must be at least 6 characters long.'</span>);
        <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// If validation passes, submit the form</span>
    form.submit();
});

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">emailIsValid</span>(<span class="hljs-params">email</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-regexp">/^[^\s@]+@[^\s@]+\.[^\s@]+$/</span>.test(email);
}
</code></pre>
<p>In this example, the JavaScript function <code>emailIsValid()</code> uses a regular expression to validate the email format. The <code>submit</code> event listener prevents the form from being submitted if the validation fails, and custom error messages are displayed to the user.</p>
<h3 id="heading-lets-see-an-example-registration-form">Let's See an Example: Registration Form</h3>
<p>Now, let's combine all the concepts we've covered into a complete example of a Registration form with client-side validation using JavaScript:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>User Registration<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"registrationForm"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"username"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"password"</span>&gt;</span>Password:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Register"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"errorMessages"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p><strong>HTML Structure</strong>: We have a simple registration form with fields for username, email, password, and a submit button. There's also a container div (<code>errorMessages</code>) to display validation error messages.</p>
<p>Now let's write JavaScript code to handle form submission and perform client-side validation:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> registrationForm = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"registrationForm"</span>);
<span class="hljs-keyword">const</span> errorMessages = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"errorMessages"</span>);

registrationForm.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
  event.preventDefault();

  <span class="hljs-keyword">const</span> { username, email, password } = registrationForm.elements;

  errorMessages.innerHTML = <span class="hljs-string">""</span>;

  <span class="hljs-keyword">if</span> (!username.value.trim()) {
    displayError(<span class="hljs-string">"Username is required."</span>);
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-keyword">if</span> (!email.value.trim() || !isValidEmail(email.value)) {
    displayError(<span class="hljs-string">"Please enter a valid email address."</span>);
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-keyword">if</span> (!password.value.trim() || !isStrongPassword(password.value)) {
    displayError(
      <span class="hljs-string">"Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one digit, and one special character."</span>
    );
    <span class="hljs-keyword">return</span>;
  }

  alert(<span class="hljs-string">"Registration successful!"</span>);
  registrationForm.reset();
});

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">displayError</span>(<span class="hljs-params">message</span>) </span>{
  errorMessages.innerHTML += <span class="hljs-string">`&lt;div class="error"&gt;<span class="hljs-subst">${message}</span>&lt;/div&gt;`</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isValidEmail</span>(<span class="hljs-params">email</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-regexp">/^[^\s@]+@[^\s@]+\.[^\s@]+$/</span>.test(email);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isStrongPassword</span>(<span class="hljs-params">password</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-regexp">/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&amp;*]).{8,}$/</span>.test(password);
}
</code></pre>
<p><strong>JavaScript Handling</strong>: We select the form and the error message container using <code>getElementById</code>. We attach an event listener to the form's submit event. When the form is submitted, we prevent its default behavior using <code>event.preventDefault()</code> to handle form submission manually.</p>
<p><strong>Form Validation</strong>: We retrieve the values of username, email, and password.</p>
<p>We perform basic validation: Username must not be empty, Email must be in a valid format, Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one digit, and one special character.</p>
<p><strong>Error Handling</strong>: If any validation fails, we display the corresponding error message. Error messages are displayed in the <code>errorMessages</code> div.</p>
<p><strong>Form Reset</strong>: Upon successful registration (in this case, a simple alert), we reset the form using <code>registrationForm.reset()</code></p>
<p>Currently, the code uses an <code>alert</code> to indicate successful registration. In a real scenario, you might want to implement an AJAX call to submit the data to a server for processing and handle the response accordingly But that's not what we're going to discuss, as mentioned at the start of this tutorial.</p>
<p>Overall this example covers form creation, form handling with JavaScript, form validation using regular expressions, and dynamic custom error message display, demonstrating a basic user registration form with client-side validation.</p>
<h2 id="heading-radio-buttons">Radio Buttons</h2>
<p>Radio buttons are a common form element used to select one option from a set of options. In JavaScript, you can manipulate radio buttons to retrieve user selections and perform actions based on those selections.</p>
<h3 id="heading-how-to-create-radio-buttons">How to Create Radio Buttons</h3>
<p>You can use radio buttons you want users to select only one option from a set of choices. In HTML, you can create radio buttons using the <code>&lt;input&gt;</code> element with the <code>type</code> attribute set to "radio". A group of radio buttons with the same <code>name</code> attribute forms a radio group. </p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"languageForm"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Select your favorite programming language:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"JavaScript"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"js"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"js"</span>&gt;</span>JavaScript<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Python"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"python"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"python"</span>&gt;</span>Python<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Java"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"java"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"java"</span>&gt;</span>Java<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-comment">&lt;!-- More language options can be added here --&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>You use the <code>id</code> and <code>for</code> attributes for accessibility, linking the label to the corresponding radio button.</p>
<h3 id="heading-how-to-retreive-the-selected-radio-button-value">How to Retreive the Selected Radio Button Value</h3>
<p>Now, let's discuss how to retrieve the value of the selected radio button using JavaScript.</p>
<pre><code class="lang-html">    <span class="hljs-comment">&lt;!-- HTML --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn"</span>&gt;</span>Show Selected Language<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"output"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#btn"</span>);
      <span class="hljs-keyword">const</span> radioButtons = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'input[name="language"]'</span>);
      <span class="hljs-keyword">const</span> output = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"output"</span>);

      btn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">let</span> selectedLanguage;
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> radioButton <span class="hljs-keyword">of</span> radioButtons) {
          <span class="hljs-keyword">if</span> (radioButton.checked) {
            selectedLanguage = radioButton.value;
            <span class="hljs-keyword">break</span>;
          }
        }
        <span class="hljs-comment">// Displaying the output:</span>
        output.innerText = selectedLanguage
          ? <span class="hljs-string">`You selected <span class="hljs-subst">${selectedLanguage}</span>`</span>
          : <span class="hljs-string">`You haven't selected any language`</span>;
      });
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Here's how this the code works: the JavaScript code initializes by selecting the button, radio buttons, and output elements from the HTML document. We add a click event listener to the button element. When the button is clicked, the function inside the event listener is executed.</p>
<p>Inside the click event listener, we iterate over all radio buttons in the <code>radioButtons</code> collection. We check if a radio button is checked using its <code>checked</code> property. If a radio button is checked, we assign its value to the <code>selectedLanguage</code> variable and exit the loop using <code>break</code>.</p>
<p>We update the content of the output element (<code>&lt;p&gt;</code> tag with id <code>output</code>) based on whether a language is selected. If a language is selected (<code>selectedLanguage</code> is truthy), we display a message indicating the selected language. Otherwise, we prompt the user to select a language.</p>
<h3 id="heading-radio-button-change-event">Radio Button Change Event</h3>
<p>When a radio button is checked or unchecked, it fires a <code>change</code> event. You can listen to this event using <code>addEventListener()</code>. Inside the event handler, you can access the checked state and value of the radio button using <code>this.checked</code> and <code>this.value</code>.</p>
<pre><code class="lang-javascript">radioButton.addEventListener(<span class="hljs-string">'change'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">e</span>) </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.checked) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.value);
  }
});
</code></pre>
<h3 id="heading-how-to-dynamically-generate-radio-buttons">How to Dynamically Generate Radio Buttons</h3>
<p>Now, let's explore how to dynamically generate radio buttons using JavaScript. This is useful when you want to create radio button options dynamically based on certain criteria or data.</p>
<p>Suppose we have an array of languages, and we want to dynamically generate radio buttons for each language option:</p>
<pre><code class="lang-javascript">&lt;!DOCTYPE html&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"languages"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">const</span> languageOptions = [<span class="hljs-string">"Python"</span>, <span class="hljs-string">"Javascript"</span>, <span class="hljs-string">"C++"</span>, <span class="hljs-string">"Java"</span>];

      <span class="hljs-comment">// Generate the radio buttons</span>
      <span class="hljs-keyword">const</span> languages = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#languages"</span>);
      languages.innerHTML = languageOptions.map(<span class="hljs-function">(<span class="hljs-params">language</span>) =&gt;</span> <span class="hljs-string">`
          &lt;div&gt;
              &lt;input type="radio" name="language" value="<span class="hljs-subst">${language}</span>" id="<span class="hljs-subst">${language}</span>"&gt;
              &lt;label for="<span class="hljs-subst">${language}</span>"&gt;<span class="hljs-subst">${language}</span>&lt;/label&gt;
          &lt;/div&gt;`</span>).join(<span class="hljs-string">' '</span>);
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
</code></pre>
<p>It dynamically generates radio buttons based on the <code>languageOptions</code> array and inserts them into the container element (<code>&lt;div id="languages"&gt;&lt;/div&gt;</code>). Each radio button has a unique ID and value corresponding to the language name, and the labels are associated with their respective radio buttons using the <code>for</code> attribute.</p>
<p>After dynamically generating the radio buttons, Now let's add <code>change</code> event listeners to them to handle changes in selection.</p>
<pre><code class="lang-javascript">    &lt;!-- HTML --&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"languages"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"languageOutput"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> <span class="hljs-comment">// we create this one to fetch our selected language output</span>

    &lt;!-- Generate the radio buttons --&gt;

<span class="hljs-comment">// Attaching Change Event Listeners</span>
<span class="hljs-keyword">const</span> radioButtons = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'input[name="language"]'</span>);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> radioButton <span class="hljs-keyword">of</span> radioButtons) {
    radioButton.addEventListener(<span class="hljs-string">'change'</span>, showSelectedlanguage);
}        

<span class="hljs-comment">// Handling the Change Event</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showSelectedlanguage</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.checked) {
        <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#languageOutput'</span>).innerText = <span class="hljs-string">`You selected <span class="hljs-subst">${<span class="hljs-built_in">this</span>.value}</span>`</span>;
    }
}
</code></pre>
<p>Here's what's happening:</p>
<ul>
<li>We select all radio buttons with the <code>name</code> attribute set to <code>"language"</code>.</li>
<li>We use a <code>for...of</code> loop to iterate over each radio button and add a <code>change</code> event listener to each radio button. This listener listens for changes in the state of the radio buttons, i.e., when a radio button is selected or deselected.</li>
<li>We define a function named <code>showSelectedLanguage</code> to handle the change event triggered by selecting a radio button. </li>
<li>Inside the <code>showSelectedLanguage</code> function, we first check if the current radio button (<code>this</code>) is checked using the <code>checked</code> property. If the radio button is checked, we update the text content of an element with the id <code>languageOutput</code> using <code>document.querySelector('#languageOutput')</code>. This element serves as a placeholder to display the selected language.</li>
</ul>
<p>This setup ensures that dynamically generated radio buttons have <code>change</code> event listeners attached to them, allowing for dynamic handling of user selections.</p>
<h2 id="heading-checkboxes">Checkboxes</h2>
<h3 id="heading-how-to-create-an-html-checkbox">How to Create an HTML Checkbox</h3>
<p>Let's first create a checkbox using the <code>&lt;input&gt;</code> element and type attribute set to "checkbox". let's associate it with label for better accessibility.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"agree"</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"agree"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"agree"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"yes"</span>&gt;</span> I agree to the terms
<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-check-if-a-checkbox-is-checked">How to Check if a Checkbox is Checked</h3>
<p>A checkbox in HTML can exist in two states: checked and unchecked. And we can determine which is active using <code>checked</code> property. If it's <code>true</code>, the checkbox is checked – otherwise, it's unchecked. Example:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"agree"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"agree"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"agree"</span>&gt;</span> I agree to the terms
    <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
        <span class="hljs-keyword">const</span> checkbox = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'agree'</span>);
        <span class="hljs-built_in">console</span>.log(checkbox.checked);
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-get-checkbox-values">How to Get Checkbox Values</h3>
<p>In HTML forms, when a checkbox is checked and the form is submitted, the browser includes the checkbox in the form data with its <code>name</code> attribute as the key and the <code>value</code> attribute (if specified) as the value. But if the checkbox is unchecked, it's not included in the form data at all.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"agree"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"agree"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"agree"</span>&gt;</span> I agree to the terms
<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn"</span>&gt;</span>Show Value<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">const</span> checkbox = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#agree'</span>);
    <span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#btn'</span>);
    btn.onclick = <span class="hljs-function">() =&gt;</span> {
       alert(checkbox.value);
    };
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>So basically the point is: When a checkbox is checked and included in form submissions, the browser defaults to sending <code>'on'</code> as the value if no <code>value</code> attribute is explicitly defined for the checkbox input element. To accurately handle the checked state of a checkbox using JavaScript, use the <code>checked</code> property instead of relying solely on the <code>value</code> attribute.</p>
<h3 id="heading-how-to-handle-multiple-checkboxes">How to Handle Multiple Checkboxes</h3>
<p>Sometimes, you may need to work with multiple checkboxes with the same name and you want to retrieve the values of the selected checkboxes. Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Select your preferred languages:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"l1"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"C++"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"l1"</span> /&gt;</span>C++
    <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"l2"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Python"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"l2"</span> /&gt;</span>Python
    <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"l3"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Java"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"l3"</span> /&gt;</span>Java
    <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn"</span>&gt;</span>Get Selected Languages<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#btn"</span>);
      btn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">const</span> checkboxes = <span class="hljs-built_in">document</span>.querySelectorAll(
          <span class="hljs-string">'input[name="language"]:checked'</span>
        );
        <span class="hljs-keyword">const</span> selectedLanguages = <span class="hljs-built_in">Array</span>.from(checkboxes).map(
          <span class="hljs-function">(<span class="hljs-params">checkbox</span>) =&gt;</span> checkbox.value
        );
        alert(<span class="hljs-string">"Selected Languages: "</span> + selectedLanguages.join(<span class="hljs-string">", "</span>));
      });
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In this example, we have checkboxes for selecting preferred programming languages.</p>
<ul>
<li>When the button is clicked, it triggers an event listener. Inside the event listener, we select all checkboxes with the name attribute "language" that are checked.</li>
<li>We then convert the NodeList returned by <code>querySelectorAll()</code> into an array using <code>Array.from()</code>.</li>
<li>Finally, we map over the array to retrieve the values of selected checkboxes and display them using <code>alert()</code>.</li>
</ul>
<h3 id="heading-how-to-check-uncheck-all-checkboxes">How to Check / Uncheck All Checkboxes</h3>
<p>Now, let's create a functionality to check or uncheck all checkboxes at once:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn"</span>&gt;</span>Check / Uncheck All<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Select your preferred languages:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"l1"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"C++"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"l1"</span> /&gt;</span>C++
    <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"l2"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Python"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"l2"</span> /&gt;</span>Python
    <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"l3"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"language"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Java"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"l3"</span> /&gt;</span>Java
    <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Javascript code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// function to check or uncheck all checkboxes</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">check</span>(<span class="hljs-params">checked = true</span>) </span>{
  <span class="hljs-keyword">const</span> checkboxes = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'input[name="language"]'</span>);

  <span class="hljs-comment">// Iterate through each checkbox</span>
  checkboxes.forEach(<span class="hljs-function">(<span class="hljs-params">checkbox</span>) =&gt;</span> {
    <span class="hljs-comment">// Set the checked property of each checkbox to the value of the 'checked' parameter</span>
    checkbox.checked = checked;
  });
}

<span class="hljs-comment">// function to check all checkboxes and change button behavior to uncheck all</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkAll</span>(<span class="hljs-params"></span>) </span>{
  check();
  <span class="hljs-built_in">this</span>.onclick = uncheckAll;
}

<span class="hljs-comment">// function to uncheck all checkboxes and change button behavior to check all</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">uncheckAll</span>(<span class="hljs-params"></span>) </span>{
  check(<span class="hljs-literal">false</span>);
  <span class="hljs-built_in">this</span>.onclick = checkAll;
}

<span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#btn"</span>);

btn.onclick = checkAll;
</code></pre>
<p>In this example, we have a button labeled "Check / Uncheck All".</p>
<ul>
<li>When the button is first clicked, it's intended to check all the checkboxes. Therefore, the <code>checkAll</code> function is assigned to handle this action (<code>const btn = document.querySelector("#btn");</code>).</li>
<li>If the button is clicked again, it unchecks all checkboxes. We define functions <code>check()</code>, <code>checkAll()</code>, and <code>uncheckAll()</code> to handle the checking and unchecking of checkboxes.</li>
<li>We assign <code>checkAll()</code> to the button's <code>onclick</code> event initially, and then switch between <code>checkAll()</code> and <code>uncheckAll()</code> based on the current state of the checkboxes.</li>
</ul>
<p>Alternate approach could be:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkAll</span>(<span class="hljs-params">checked = true</span>) </span>{
  <span class="hljs-keyword">const</span> checkboxes = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'input[name="language"]'</span>);
  checkboxes.forEach(<span class="hljs-function">(<span class="hljs-params">checkbox</span>) =&gt;</span> {
    checkbox.checked = checked;
  });
}

<span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#btn"</span>);

btn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Find the first checkbox with the name attribute set to 'language'</span>
  <span class="hljs-keyword">const</span> firstCheckbox = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'input[name="language"]'</span>);
  <span class="hljs-comment">// Check if the first checkbox is checked</span>
  <span class="hljs-keyword">const</span> isChecked = firstCheckbox.checked;
  <span class="hljs-comment">// Call the checkAll function with the opposite state of the first checkbox</span>
  checkAll(!isChecked);
});
</code></pre>
<p>Here, we select the first checkbox with the name "language" to determine its current checked state. Then, we call <code>checkAll()</code> with the opposite state.</p>
<h3 id="heading-how-to-dynamically-generate-checkboxes">How to Dynamically Generate CheckBoxes</h3>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"languages"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">const</span> languageOptions = [<span class="hljs-string">"Python"</span>, <span class="hljs-string">"Javascript"</span>, <span class="hljs-string">"C++"</span>, <span class="hljs-string">"Java"</span>];

      <span class="hljs-comment">// Generate the checkboxes</span>
      <span class="hljs-keyword">const</span> html = languageOptions
        .map(
          <span class="hljs-function">(<span class="hljs-params">language</span>) =&gt;</span> <span class="hljs-string">`&lt;label for="language-<span class="hljs-subst">${language}</span>"&gt;
                &lt;input type="checkbox" name="language" id="language-<span class="hljs-subst">${language}</span>" value="<span class="hljs-subst">${language}</span>"&gt; <span class="hljs-subst">${language}</span>
            &lt;/label&gt;`</span>
        )
        .join(<span class="hljs-string">" "</span>);
      <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#languages"</span>).innerHTML = html;
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Here's how it works:</p>
<ul>
<li>We define an array <code>languageOptions</code> containing language names.</li>
<li>We use the <code>map()</code> method to iterate through the <code>languageOptions</code> array and generate an array of HTML strings for each language.</li>
<li>Each HTML string comprises a <code>label</code> element associated with an <code>input</code> checkbox. The <code>input</code> checkbox includes appropriate attributes such as <code>type</code>, <code>name</code>, <code>id</code>, and <code>value</code>, dynamically derived from the language name.</li>
<li>We join the array of HTML strings into a single string using <code>join(' ')</code>.</li>
<li>Finally, we set the <code>innerHTML</code> property of the root <code>&lt;div&gt;</code> element with the id <code>languages</code> to the generated HTML string, thereby rendering checkboxes for each programming language.</li>
</ul>
<h2 id="heading-select-element">Select Element:</h2>
<p>The <code>&lt;select&gt;</code> element in HTML provides a dropdown list of options for users to choose from. It allows for single or multiple selections. Example:</p>
<pre><code class="lang-javascript">&lt;select id=<span class="hljs-string">"cities"</span>&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"JAI"</span>&gt;</span>Jaipur<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"DEL"</span>&gt;</span>New Delhi<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"UDR"</span>&gt;</span>Udaipur<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"MUM"</span>&gt;</span>Mumbai<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span></span>
&lt;/select&gt;
</code></pre>
<p>By default, a <code>&lt;select&gt;</code> element allows for a single selection. To enable multiple selections, add the <code>multiple</code> attribute. </p>
<pre><code class="lang-javascript">&lt;select id=<span class="hljs-string">"cities"</span> multiple&gt;
</code></pre>
<p>Users can now select multiple fruits by holding down the Ctrl (or Cmd on Mac) key while clicking.</p>
<h3 id="heading-how-to-interact-with-a-select-element">How to Interact with a Select Element:</h3>
<p>To interact with a <code>&lt;select&gt;</code> element using JavaScript, we use the <code>HTMLSelectElement</code> type, which provides useful properties like <code>selectedIndex</code> and <code>value</code>. Example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">const</span> selectElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'cities'</span>);
<span class="hljs-built_in">console</span>.log(selectElement.selectedIndex); <span class="hljs-comment">// Returns the index of the selected option</span>
<span class="hljs-built_in">console</span>.log(selectElement.value); <span class="hljs-comment">// Returns the value of the selected option</span>
<span class="hljs-built_in">console</span>.log(selectElement.multiple); <span class="hljs-comment">// Returns true if multiple selections are allowed</span>
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>JavaScript allows you to handle events on the <code>&lt;select&gt;</code> element, such as when a user selects an option. Example:</p>
<pre><code class="lang-javascript">&lt;button id=<span class="hljs-string">"btn"</span>&gt;Get Selected City&lt;/button&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#btn"</span>);
      <span class="hljs-keyword">const</span> selectElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"cities"</span>);
      btn.onclick = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
        event.preventDefault();
        <span class="hljs-keyword">const</span> selectedCity =
          selectElement.options[selectElement.selectedIndex].text;
        alert(<span class="hljs-string">`Selected city: <span class="hljs-subst">${selectedCity}</span>, 
        Index: <span class="hljs-subst">${selectElement.selectedIndex}</span>`</span>);
      };
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<p><strong>Using the <code>value</code> property:</strong> The <code>value</code> property represents the value of the selected option. Let's understand it with example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"cities"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span>&gt;</span>Jaipur<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"DEL"</span>&gt;</span>New Delhi<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"UDR"</span>&gt;</span>Udaipur<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">option</span>&gt;</span>Mumbai<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#btn"</span>);
<span class="hljs-keyword">const</span> selectElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#cities"</span>);

btn.onclick = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    event.preventDefault();
    alert(selectElement.value);
};
</code></pre>
<ul>
<li>If "Jaipur" is selected, this means we have an empty string since the value attribute is empty in our Html.</li>
<li>If an option lacks a value attribute, the select box's value property becomes the text of the selected option. Example: if "Mumbai" is selected, the value property is "Mumbai".</li>
<li>If multiple options are selected, the <code>value</code> property of the select box is derived from the first selected option based on the previous rules.</li>
</ul>
<h3 id="heading-how-to-access-options-with-javascript">How to Access Options with JavaScript</h3>
<p>The <code>HTMLOptionElement</code> type represents individual <code>&lt;option&gt;</code> elements within a <code>&lt;select&gt;</code> element in JavaScript. It provides properties like <code>index</code>, <code>selected</code>, <code>text</code>, and <code>value</code> to access information about each option. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> selectElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'cities'</span>);
<span class="hljs-keyword">const</span> secondOptionText = selectElement.options[<span class="hljs-number">1</span>].text; <span class="hljs-comment">// Accessing text of the second option</span>
<span class="hljs-keyword">const</span> secondOptionValue = selectElement.options[<span class="hljs-number">1</span>].value; <span class="hljs-comment">// Accessing value of the second option</span>
</code></pre>
<h3 id="heading-how-to-handle-multiple-selections">How to Handle Multiple Selections:</h3>
<p>When a <code>&lt;select&gt;</code> element allows multiple selections, you can iterate through its options to find which ones are selected and retrieve their text values. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> selectElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'cities'</span>);
<span class="hljs-keyword">const</span> selectedOptions = <span class="hljs-built_in">Array</span>.from(selectElement.options).filter(<span class="hljs-function"><span class="hljs-params">option</span> =&gt;</span> option.selected);
<span class="hljs-keyword">const</span> selectedValues = selectedOptions.map(<span class="hljs-function"><span class="hljs-params">option</span> =&gt;</span> option.text);
</code></pre>
<p>The output will be an array containing text of selected options. We can use <code>option.value</code> to get an array of values instead. Example:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"cities"</span> <span class="hljs-attr">multiple</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"JAI"</span>&gt;</span>Jaipur<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"DEL"</span>&gt;</span>New Delhi<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"UDR"</span>&gt;</span>Udaipur<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"MUM"</span>&gt;</span>Mumbai<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn"</span>&gt;</span>Get Selected Cities<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#btn"</span>);
      <span class="hljs-keyword">const</span> selectElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#cities"</span>);

      btn.onclick = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
        event.preventDefault();
        <span class="hljs-keyword">const</span> selectedOptions = <span class="hljs-built_in">Array</span>.from(selectElement.options)
          .filter(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span> option.selected)
          .map(<span class="hljs-function">(<span class="hljs-params">option</span>) =&gt;</span> option.text);
        alert(<span class="hljs-string">"Selected City: "</span> + selectedOptions.join(<span class="hljs-string">", "</span>));
      };
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<ul>
<li>When the button is clicked, the script collects the selected options by filtering the options based on the <code>selected</code> property. It then maps over the selected options to retrieve their text content.</li>
<li>Finally, it displays the selected languages in an alert message.</li>
</ul>
<h3 id="heading-lets-see-an-example-task-manager-adding-and-removing-tasks">Let's See an Example: Task Manager (Adding and Removing Tasks)</h3>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
    <span class="hljs-selector-id">#container</span> {
      <span class="hljs-attribute">max-width</span>: <span class="hljs-number">540px</span>;
      <span class="hljs-attribute">margin</span>: <span class="hljs-number">50px</span> auto;
    }

    <span class="hljs-selector-tag">form</span> {
      <span class="hljs-attribute">display</span>: flex;
      <span class="hljs-attribute">flex-direction</span>: column;
    }
  </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"task"</span>&gt;</span>Task:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
          <span class="hljs-attr">id</span>=<span class="hljs-string">"task"</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter a task"</span>
          <span class="hljs-attr">autocomplete</span>=<span class="hljs-string">"off"</span>
        /&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btnAdd"</span>&gt;</span>Add Task<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"taskList"</span>&gt;</span>Task List:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"taskList"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"taskList"</span> <span class="hljs-attr">multiple</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btnRemove"</span>&gt;</span>Remove Selected Tasks<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>This HTML structure includes input fields for entering task descriptions, buttons for adding and removing tasks, and a <code>&lt;select&gt;</code> element to display the list of tasks. We added a little css for clarity. Let's see Javascript code now:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> btnAdd = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#btnAdd'</span>);
<span class="hljs-keyword">const</span> btnRemove = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#btnRemove'</span>);
<span class="hljs-keyword">const</span> taskList = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#taskList'</span>);
<span class="hljs-keyword">const</span> taskInput = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'#task'</span>);

btnAdd.onclick = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    e.preventDefault();

    <span class="hljs-comment">// Validate the task input</span>
    <span class="hljs-keyword">if</span> (taskInput.value.trim() === <span class="hljs-string">''</span>) {
        alert(<span class="hljs-string">'Please enter a task description.'</span>);
        <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Create a new task option</span>
    <span class="hljs-keyword">const</span> option = <span class="hljs-keyword">new</span> Option(taskInput.value, taskInput.value);
    taskList.add(option, <span class="hljs-literal">undefined</span>);

    <span class="hljs-comment">// Reset the task input</span>
    taskInput.value = <span class="hljs-string">''</span>;
    taskInput.focus();
};

btnRemove.onclick = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    e.preventDefault();

    <span class="hljs-comment">// Save the selected tasks</span>
    <span class="hljs-keyword">let</span> selectedTasks = [];

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; taskList.options.length; i++) {
        selectedTasks[i] = taskList.options[i].selected;
    }

    <span class="hljs-comment">// Remove selected tasks</span>
    <span class="hljs-keyword">let</span> index = taskList.options.length;
    <span class="hljs-keyword">while</span> (index--) {
        <span class="hljs-keyword">if</span> (selectedTasks[index]) {
            taskList.remove(index);
        }
    }
};
</code></pre>
<p>Explaination: we select the necessary elements from the HTML and attach event listeners to the "Add Task" and "Remove Selected Tasks" buttons. When the "Add Task" button is clicked, we create a new task option based on the input field value and add it to the <code>&lt;select&gt;</code> element. When the "Remove Selected Tasks" button is clicked, we remove the selected tasks from the <code>&lt;select&gt;</code> element.</p>
<h2 id="heading-difference-between-change-and-input-event">Difference Between Change and Input Event</h2>
<p>The input event in JavaScript is triggered whenever the value of an input, <code>&lt;select&gt;</code>, or <code>&lt;textarea&gt;</code> element changes. Unlike the change event, which waits for a value to be committed (for example, when an input loses focus), the input event fires continuously as the value changes. The input event basically provides a way to respond to user input in real-time. Example: </p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"userInput"</span>&gt;</span>Enter Your Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"userInput"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Your name"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Your name is: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"displayName"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript">&lt;script&gt;
    <span class="hljs-keyword">const</span> userInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'userInput'</span>);
    <span class="hljs-keyword">const</span> Name = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'displayName'</span>);

    userInput.addEventListener(<span class="hljs-string">'input'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
        Name.textContent = userInput.value || <span class="hljs-string">'Guest!'</span>;
    });
&lt;/script&gt;
</code></pre>
<ul>
<li>This JavaScript code selects the input field with the ID "userInput" and the span element with the ID "displayName".</li>
<li>An event listener is attached to the input event of the userInput field.</li>
<li>When the input event is triggered (for example, when typing in the input field), the event handler updates the text content of the <code>displayName</code> span dynamically to reflect the entered name, or it displays "Anonymous" if the input field is empty.</li>
<li>Now, if you change 'input' to 'change' here <code>userInput.addEventListener('input', function()</code> like this: <code>userInput.addEventListener('change', function()</code>, the event listener will be triggered only when the input field loses focus after a value has been entered (as opposed to continuously while the value is being changed in real-time).</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>By understanding the fundamentals of HTML form elements, attributes, and events, you can create dynamic and user-friendly web forms that enhance the user experience. </p>
<p>JavaScript plays a crucial role in handling form submissions, validating user input, and providing real-time feedback to users.</p>
<p>Through practical examples and detailed explanations, in this guide you've learned about working with radio buttons, checkboxes, select elements, and handling multiple selections. </p>
<p>Keep exploring and experimenting with the concepts presented here to create robust and intuitive forms for your web applications.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use HTML Forms – HTML Form Basics ]]>
                </title>
                <description>
                    <![CDATA[ By Kelechukwu Isaac Awoke HTML forms are used to get information from users. They are widely used in webpages or apps for surveys or registration processes.  HTML form basics include the common HTML elements, tags, attributes, concepts, or best pract... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-html-forms/</link>
                <guid isPermaLink="false">66d45f63264384a65d5a954a</guid>
                
                    <category>
                        <![CDATA[ Form validations ]]>
                    </category>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 06 Mar 2024 10:37:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/glenn-carstens-peters-RLw-UC03Gwc-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Kelechukwu Isaac Awoke</p>
<p>HTML forms are used to get information from users. They are widely used in webpages or apps for surveys or registration processes. </p>
<p>HTML form basics include the common HTML elements, tags, attributes, concepts, or best practices required for you to create good HTML forms. The collected data is sent to a server for processing.</p>
<ul>
<li><a class="post-section-overview" href="#heading-basic-structure-of-html-form">Basic Structure of HTML Form</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-html-form-elements">How to Use HTML Form Elements</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-html-element">How to Use the HTML  Element</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-html-element">How to Use the HTML  Element</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-html">How to Use the HTML </a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-html-element">How to Use the HTML  Element</a></li>
<li><a class="post-section-overview" href="#heading-form-validation">Form Validation</a></li>
<li><a class="post-section-overview" href="#heading-importance-of-form-validation">Importance of Form Validation</a></li>
<li><a class="post-section-overview" href="#heading-types-of-form-validation">Types of Form Validation</a></li>
<li><a class="post-section-overview" href="#heading-common-validation-techniques">Common Validation Techniques</a></li>
<li><a class="post-section-overview" href="#heading-form-submission-and-methods">Form Submission and Methods</a></li>
<li><a class="post-section-overview" href="#heading-how-to-style-html-forms">How to Style HTML Forms</a></li>
<li><a class="post-section-overview" href="#heading-best-practices-and-accessibility">Best Practices and Accessibility</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-basic-structure-of-html-form">Basic Structure of HTML Form</h2>
<p>You can use the <code>&lt;form&gt;</code> element to create an HTML form</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"submit_form"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">" post"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">" name"</span> <span class="hljs-attr">required</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">required</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p> The HTML <code>&lt;form&gt;</code> element is a container for several HTML form elements. The <code>&lt;form&gt;</code> element can contain the following:</p>
<ul>
<li><code>&lt;input&gt;</code></li>
<li><code>&lt;label&gt;</code></li>
<li><code>&lt;select&gt;</code></li>
<li><code>&lt;textarea&gt;</code></li>
<li><code>&lt;button&gt;</code></li>
<li><code>&lt;fieldset&gt;</code></li>
<li><code>&lt;legend&gt;</code></li>
<li><code>&lt;datalist&gt;</code></li>
<li><code>&lt;output&gt;</code></li>
<li><code>&lt;option&gt;</code></li>
<li><code>&lt;optgroup&gt;</code></li>
</ul>
<h2 id="heading-how-to-use-html-form-elements">How to Use HTML Form Elements</h2>
<p>In this section, you'll learn how to use some of the HTML form elements.</p>
<h3 id="heading-how-to-use-the-html-element">How to Use the HTML  Element</h3>
<p>The <code>&lt;input&gt;</code> element is the most commonly used form element. The type of information an <code>&lt;input&gt;</code> element can hold depends on the <code>&lt;type&gt;</code> attribute. </p>
<p>The <code>&lt;input&gt;</code>  element can only accept a particular type of data assigned to it using the <code>&lt;type&gt;</code>  attribute.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span>
        <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your username"</span>
        <span class="hljs-attr">required</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span>
        <span class="hljs-attr">id</span>=<span class="hljs-string">"security"</span>
        <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your password"</span>
        <span class="hljs-attr">required</span>
      /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your email"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"subscribe"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"yes"</span> /&gt;</span> Subscribe to the
      newsletter <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"gender"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"male"</span> /&gt;</span> Male
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"radio"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"gender"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"female"</span> /&gt;</span> Female
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"submit"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p> The following are the different  <code>&lt;type&gt;</code> attributes that can be assigned to an <code>&lt;input&gt;</code> element:</p>
<ul>
<li><code>&lt;input type="text"&gt;</code>: Allows the user to type in text.</li>
<li><code>&lt;input type="email"&gt;</code>: The user input must follow an email format.</li>
<li><code>&lt;input type="password"&gt;</code> : Accepts password from the user. The passwords are masked, usually displayed as asterisks (*) or dots, to protect the privacy of the input.</li>
<li><code>&lt;input type="checkbox"&gt;</code>: The user can select none or many of the displayed checkboxes. Checkboxes can be checked or unchecked.</li>
<li><code>&lt;input type="radio"&gt;</code>: Allows the user to select only one from the multiple-choice radio buttons.</li>
<li><code>&lt;input type="submit"&gt;</code>: Enables the user to submit the form.</li>
</ul>
<p>The following are other possible attributes found in the input element:</p>
<ul>
<li><code>&lt;input name=" "&gt;</code> : Assigns the input field a name. The assigned name identifies the input data when the form is submitted.</li>
<li><code>&lt;input id=" "&gt;</code>: The identifier creates a unique id for the input field. It is usually associated with CSS for styling and JavaScript for other manipulations.</li>
<li><code>&lt;input value=" "&gt;</code>: Used to set the initial value for the input field. The default initial value gives the user an idea of the information required.</li>
<li><code>&lt;input placeholder=" "&gt;</code>: A faint pseudo value set to the input field that disappears once the user starts typing. Gives a hint on what data to enter, similar to the value attribute.</li>
<li><code>&lt;input required&gt;</code>: Requires that the input field must be filled out before submission. Gives an error message when not filled out.</li>
<li><code>&lt;input disabled&gt;</code>: As the name implies, this prevents the user from interacting with the input field. Disables the input field from accepting input. With this attribute, the input field becomes unclickable.</li>
<li><code>&lt;input readonly&gt;</code>: The user can only read the initially set value but can't change it. Unlike the disabled attribute, the input field is clickable but can't be modified.</li>
</ul>
<p>Note that the <code>&lt;input&gt;</code> element doesn't contain a <code>for</code> attribute.</p>
<h3 id="heading-how-to-use-the-html-element-1">How to Use the HTML  Element</h3>
<p>The label element associates text with a form input, checkbox, or radio button.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">" "</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"user"</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>The label element describes the information required in the text field.</p>
<p>The label element is important for accessibility, this makes it easier for screen-reader users to navigate the form. The assistive technologies read the label loud to users.</p>
<p>Clicking on the label focuses the corresponding input field when the <code>for</code> attribute of the label element corresponds with the id attribute of the input element, making it more convenient for users to interact with the form.</p>
<p>Label improves the overall usage of the form, providing context and guidance.</p>
<p>The following are the commonly used attributes for the <code>label</code> element:</p>
<ul>
<li><code>&lt;label for=" "&gt;&lt;/label&gt;</code>: Associates the label with the corresponding form element, usually an input element. The value of the <code>for</code> attribute is always the same as the id value of the associated form element, usually the input element.</li>
<li>id attribute <code>&lt;label id=" "&gt;&lt;/label&gt;</code>: Gives the label a unique identifier. The value is set to the same value with the <code>for</code> attribute of the corresponding form element, usually an input element. Used for selecting the label for styling in CSS or other manipulations in JavaScript.</li>
</ul>
<h3 id="heading-how-to-use-the-html">How to Use the HTML </h3>
<p>A multi-line text input field, allows users to write longer text or paragraphs. The <code>rows</code> and <code>cols</code> attributes control the initial size of the textarea box. </p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"testimony"</span>&gt;</span>Testimony:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"testimony"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"testimony"</span> <span class="hljs-attr">cols</span>=<span class="hljs-string">"30"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"10"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>The <code>rows</code> attribute controls the height (vertical size) of the textarea box, determining the number of visible lines while the <code>cols</code> attribute controls the width (horizontal size), specifying the number of visible characters per line. </p>
<p>Note, that the <code>textarea</code> box can <em>wrap</em> to fit the entered text within its defined width.</p>
<p>Unlike the single-line input field, the <code>textarea</code> element does not have a <code>maxlength</code> attribute or <code>value</code> attribute. The content is placed within the opening and closing tags. </p>
<p>For accessibility, it's a good practice to associate label or context with the <code>textarea</code> element to assist users who use screen-readers or other assistive technologies.</p>
<h4 id="heading-how-to-use-the-html-element-2">How to Use the HTML  Element</h4>
<p>The <code>&lt;select&gt;</code> element creates a drop-down list, that allows users to select one or multiple options from the listed choices.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"numbers"</span>&gt;</span>Choose a favorite number:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"numbers"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"numbers"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"5"</span> <span class="hljs-attr">multiple</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">""</span> <span class="hljs-attr">disabled</span> <span class="hljs-attr">selected</span>&gt;</span>Select a number<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"one"</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"two"</span>&gt;</span>2<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"three"</span>&gt;</span>3<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"four"</span>&gt;</span>4<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"five"</span>&gt;</span>5<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"six"</span>&gt;</span>6<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"seven"</span>&gt;</span>7<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"eight"</span>&gt;</span>8<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"nine"</span>&gt;</span>9<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"ten"</span>&gt;</span>10<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>The <code>&lt;option&gt;</code> element is contained within the <code>&lt;select&gt;</code> element. The <code>&lt;option&gt;</code> element holds the items to be selected. Each <code>&lt;option&gt;</code> represents one item in the drop-down list.</p>
<p>Each <code>&lt;option&gt;</code> element is expected to have a <code>&lt;value=" "&gt;</code> attribute, which holds the value to be submitted when the form containing the <code>&lt;select&gt;</code> element is submitted. If the <code>&lt;value=" "&gt;</code> attribute is omitted, the text content of the <code>&lt;option&gt;</code> element becomes the value to be submitted instead.</p>
<p>The <code>&lt;name=" "&gt;</code> attribute identifies the select control on the server side when the form is submitted. The <code>&lt;name=" "&gt;</code> is important for processing the form data on the server. </p>
<p>You can select one of the options as the default selection by including the <code>&lt;selected&gt;</code> attribute in the <code>&lt;option&gt;</code> element. If no option is selected, then the first option in the list will be selected by default.</p>
<p>The <code>&lt;size=" "&gt;</code> attribute sets the number of options you can see at once in the drop-down by setting the <code>&lt;size=" "&gt;</code> attribute on the <code>&lt;select&gt;</code>. Note that other options are seen as you scroll down. </p>
<p>Including the <code>&lt;disabled&gt;</code> attribute on the <code>&lt;select&gt;</code> element, disables the select option and prevents the users from selecting any option. The select option becomes unclickable. </p>
<p>Also, multiple options can be selected by including <code>&lt;multiple&gt;</code> attribute on the <code>&lt;select&gt;</code> element. You can hold the <code>Ctrl</code> (or Command on Mac) key to select multiple options.</p>
<p>Understanding the <code>&lt;select&gt;</code> element and using the necessary attributes can make your form convenient for users to select different options and for easy processing of the <code>&lt;select&gt;</code> element on the server side.</p>
<h2 id="heading-form-validation">Form Validation</h2>
<p>Simply put, this is the process of checking whether the data entered in the form is correct, complete, and meets the specified format.</p>
<h3 id="heading-importance-of-form-validation">Importance of Form Validation</h3>
<ul>
<li><strong>Data Accuracy:</strong>  Prevents submission of incorrect or incomplete data.</li>
<li><strong>Security:</strong> Checks the data to prevent incorrect or malicious data from being submitted, thereby reducing harmful attacks or data breaches. </li>
<li><strong>User Experience:</strong>  Makes filling out the forms less stressful by giving a quick error message if the user is entering the wrong data. Also, it can be used to suggest the expected format. </li>
<li><strong>Efficiency:</strong> Form validation before submission saves time and resources. Reduces unnecessary requests to the server, improving the overall performance of your application.</li>
</ul>
<h3 id="heading-types-of-form-validation">Types of Form Validation</h3>
<ol>
<li><strong>Client-Side Validation:</strong> The user's browser performs the checks before submission. How does the browser validate forms? Browsers use JavaScript, CSS, or HTML attributes to validate forms. The advantage of client-side validation is the quick error message the user receives when data is incorrect or incomplete. The response is quick and doesn't require validation from the server side. One of the disadvantages is that client-side validation can be bypassed by an experienced user. </li>
<li><strong>Server-Side Validation:</strong> The server checks the form data after submission. Server-side validation is more robust and secure. Performs double verification, and validates form data again, even if the client-side validation fails or is bypassed. The server-side validation is commonly done by using scripting languages like PHP or ASP.NET. </li>
</ol>
<p>Note that you can use either of the two or a combination of both.    </p>
<h3 id="heading-common-validation-techniques">Common Validation Techniques</h3>
<p>These are common HTML attributes that help you decide the pattern of form validation.</p>
<h4 id="heading-length-limits">Length Limits</h4>
<p>You can use the <code>maxlength</code> attribute to set the maximum number of characters an input field can hold.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Username"</span> <span class="hljs-attr">maxlength</span>=<span class="hljs-string">"20"</span> <span class="hljs-attr">required</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<h4 id="heading-required-fields">Required Fields</h4>
<p>Requires that certain input fields are filled before the form is submitted. The <code>&lt;required&gt;</code> attribute is used to perform this technique. An error message is displayed when the required field is not filled by the user. </p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Username"</span> <span class="hljs-attr">required</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Email"</span> <span class="hljs-attr">required</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<h4 id="heading-data-format">Data Format</h4>
<p>Ensures the data entered by the user follows the required format. The <code>&lt;input type="email"&gt;</code> type attribute set to email will require the user to enter the correct email format (for example: me@example.com) before form submission. </p>
<p>The same thing happens if the type attribute is set to number <code>&lt;input type="number"&gt;</code>, the user can only put data from 0-9.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Email"</span> <span class="hljs-attr">required</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<h4 id="heading-password-strength">Password Strength</h4>
<p>The <code>&lt;pattern=""&gt;</code> attribute is used to specify password complexity such as minimum length, and the inclusion of uppercase or lowercase letters, numbers, and special characters. </p>
<p>The <code>&lt;title=""&gt;</code> attribute displays the error message when the user hovers over the input field or when the entered password does not match the specified password format. The higher the password complexity, the higher the user account is protected from unauthorized access.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Password"</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">"(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,}"</span> <span class="hljs-attr">title</span>=<span class="hljs-string">"Password must contain at least one number, one uppercase letter, one lowercase letter, and at least 8 or more characters"</span> <span class="hljs-attr">required</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<h4 id="heading-numeric-values">Numeric values</h4>
<p>You can set the range of numeric values to be entered by the user by using the <code>min</code> and <code>max</code> attributes. For example, to check if a user is within the specified age range:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"age"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"age"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Age"</span> <span class="hljs-attr">min</span>=<span class="hljs-string">"18"</span> <span class="hljs-attr">max</span>=<span class="hljs-string">"100"</span> <span class="hljs-attr">required</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>Having a good form validation practice helps to create forms with accurate data and reduces vulnerability to malicious attacks. </p>
<h2 id="heading-form-submission-and-methods">Form Submission and Methods</h2>
<p>When the submit button is clicked after filling out a form, your information is sent to the server for processing. This is called form submission. </p>
<h3 id="heading-methods-of-form-submission">Methods of Form Submission</h3>
<p>Form data is sent to the server using the <code>method</code> attribute. There are two commonly used methods:</p>
<h4 id="heading-get-method">GET Method</h4>
<p>With the <code>get</code> method <code>&lt;method="get"&gt;</code>, the form data is sent using the URL in the browser's address bar to the server. </p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"http://example.com"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"get"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Submit"</span> /&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>Using the above code sample, when the user enters a name (let's say the user's name is KC) in the input field named ''name'', and clicks the submit button, the form data will be sent to the server in the URL like this: "http://example.com?name=KC". </p>
<p>The GET method is not safe, as it is commonly used for sending small amounts of data that is not sensitive.  </p>
<h4 id="heading-post-method">POST Method</h4>
<p>The post method attribute <code>&lt;method=post&gt;</code> sends the form data in the body of the HTTP request to the server, rather than in the URL.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"http://example.com"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"get"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Submit"</span> /&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>Using the same code sample above, the POST method will send the form data to the server like this: "https://example.com/submit.php". </p>
<p>You'd should notice that the POST request does not contain the form data in the URL but rather points to the server-side script (submit.php) that will process the form data. </p>
<p>The sent form data is not visible. The POST request is used to submit sensitive information, like passwords, since the data is not visible in the URL, but rather sent in the HTTP body request.</p>
<h2 id="heading-how-to-style-html-forms">How to Style HTML Forms</h2>
<p>HTML forms can be styled using CSS, just like any other HTML element. You can do the following with CSS to match the design of your website:</p>
<ul>
<li><strong>Selectors</strong>: CSS selectors such as element selectors, class selectors, or ID selectors can be used to select specific elements in the HTML code for styling.</li>
<li><strong>Typography</strong>: Typography can be used to set the font-family, adjust the size, font-weight, and color of the text within the form element to enhance readability. </li>
<li><strong>Box Model</strong>: With the knowledge of CSS properties like padding, border, and margin, which affect the spacing and layout, you can style HTML elements.</li>
<li><strong>Colors and Backgrounds</strong>: The color of your text or background can be styled using the CSS properties like color and background-color (or background-image) respectively. </li>
<li><strong>Responsiveness</strong>: With media queries, you can make your form responsive and adapt to different screen sizes and devices. </li>
<li><strong>Layout</strong>: You can control the layout of a form to make it user-friendly with CSS properties like display, float, and positioning.</li>
</ul>
<h2 id="heading-best-practices-and-accessibility">Best Practices and Accessibility</h2>
<p>Like every other HTML document, ensure your form complies with web standards and is accessible to people with disabilities. For best practices and accessibility, take note of the following:</p>
<h3 id="heading-structures-and-semantics">Structures and Semantics</h3>
<ul>
<li>Always use proper semantic HTML elements (like  <code>&lt;form&gt;</code>, <code>&lt;input&gt;</code>, <code>&lt;label&gt;</code>, and so on) to structure not just forms but every other HTML document.</li>
<li>Nest elements properly and associate labels to their respective input field. </li>
<li>Make sure your input fields have the appropriate type attributes.</li>
</ul>
<h3 id="heading-error-handling-and-validation">Error Handling and Validation</h3>
<ul>
<li>Combine both client-side and server-side validation to avoid incorrect or incomplete data submission.</li>
<li>Use the appropriate attribute to display error messages when form submission fails or validation errors occur. </li>
</ul>
<h3 id="heading-responsive-design">Responsive Design</h3>
<ul>
<li>Your forms should be responsive and adapt to various screen sizes and devices.</li>
<li>Use CSS media queries to adjust your form layouts and styles based on the viewport size.</li>
</ul>
<h3 id="heading-design-and-contrast">Design and Contrast</h3>
<ul>
<li>Use fonts and colors that are easy to see.</li>
<li>The color contrast between text and background should ensure readability, especially for users with low vision. </li>
</ul>
<h3 id="heading-aria-roles-and-attributes">ARIA Roles and Attributes</h3>
<ul>
<li>ARIA (Accessible Rich Internet Application) roles and attributes improve accessibility for screen-reader users or other assistive technologies.</li>
<li>ARIA attributes ( <code>aria-labelledby</code>, <code>aria-describedby</code>, and <code>aria-invalid</code>) provide additional context and feedback for form elements.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Creating good HTML forms that meet web standards improve user interaction and experience on your website. By following the best practices and accessibility, developers can create forms that are user-friendly, and effective in collecting data from users. </p>
<p>You can learn more about HTML forms and responsive web design using <a target="_blank" href="https://www.freecodecamp.org/learn/2022/responsive-web-design/">freeCodeCamp's Responsive Web Design Certification</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Validate Forms with Zod and React-Hook-Form ]]>
                </title>
                <description>
                    <![CDATA[ Forms allow you to collect user data on your websites and apps. And validation is essential to guarantee type safety and the proper format for collected data. You can perform validation on both the client and server side of the application.  This is ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-form-validation-zod-react-hook-form/</link>
                <guid isPermaLink="false">66bb580c0da5b03e481107d0</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ zod ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Gift Uhiene ]]>
                </dc:creator>
                <pubDate>Wed, 17 Jan 2024 21:58:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Frame-7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Forms allow you to collect user data on your websites and apps. And validation is essential to guarantee type safety and the proper format for collected data. You can perform validation on both the client and server side of the application. </p>
<p>This is where Zod and React-Hook-Form come in as a dynamic duo, ready to take your forms to the next level.</p>
<p><a target="_blank" href="https://zod.dev/">Zod</a> is a validation library that provides a concise and expressive syntax for defining data schemas, making it an excellent choice for validating form data. </p>
<p>On the other hand, <a target="_blank" href="https://react-hook-form.com/">React-Hook-Form</a> is a lightweight form library for React that embraces uncontrolled components and simplifies form-building with its intuitive hooks-based API.</p>
<p>In this tutorial, you will learn how to build a type-safe form using React-Hook-Form for form management and Zod for both client-side and server-side validation.</p>
<h3 id="heading-heres-what-well-cover">Here's what we'll cover:</h3>
<ol>
<li><a class="post-section-overview" href="#heading-getting-started">Getting Started</a></li>
<li><a class="post-section-overview" href="#heading-how-to-define-form-types">How to Define Form Types</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-form-with-react-hook-form">How to Create a Form with react-hook-form</a></li>
<li><a class="post-section-overview" href="#heading-how-to-integrate-zod-for-schema-validation">How to Integrate Zod for Schema Validation</a></li>
<li><a class="post-section-overview" href="#heading-how-to-handle-server-side-errors">How to Handle Server-Side Errors</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-getting-started">Getting Started</h2>
<p>To get started, clone the starter boilerplate for the project. Open up your terminal and run this command:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> --branch starter https://github.com/Giftea/zod-rhf-fcc.git
</code></pre>
<p>You can find the final version on GitHub <a target="_blank" href="https://github.com/Giftea/zod-rhf-fcc">here</a>.</p>
<p>Once you've got the boilerplate on your local machine, run the following commands to install dependencies and start the project:</p>
<pre><code class="lang-bash">npm install
npm run dev
</code></pre>
<p>Point your browser to <a target="_blank" href="http://localhost:3000">http://localhost:3000</a>, and you'll be greeted by the starting page of our project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-16-at-15.21.10.png" alt="Image" width="600" height="400" loading="lazy">
<em>localhost</em></p>
<h2 id="heading-how-to-define-form-types">How to Define Form Types</h2>
<p>The <code>/types.ts</code> file will contain the types and schemas related to our form fields and their validation. Update the <code>/types.ts</code> file with the code below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { FieldError, UseFormRegister } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-hook-form"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> FormData = {
    email: <span class="hljs-built_in">string</span>;
    githubUrl: <span class="hljs-built_in">string</span>;
    yearsOfExperience: <span class="hljs-built_in">number</span>;
    password: <span class="hljs-built_in">string</span>;
    confirmPassword: <span class="hljs-built_in">string</span>;
  };

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> FormFieldProps = {
    <span class="hljs-keyword">type</span>: <span class="hljs-built_in">string</span>;
    placeholder: <span class="hljs-built_in">string</span>;
    name: ValidFieldNames;
    register: UseFormRegister&lt;FormData&gt;;
    error: FieldError | <span class="hljs-literal">undefined</span>;
    valueAsNumber?: <span class="hljs-built_in">boolean</span>;
  };


  <span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> ValidFieldNames =
  | <span class="hljs-string">"email"</span>
  | <span class="hljs-string">"githubUrl"</span>
  | <span class="hljs-string">"yearsOfExperience"</span>
  | <span class="hljs-string">"password"</span>
  | <span class="hljs-string">"confirmPassword"</span>;
</code></pre>
<p><code>FormData</code> represents the structure of the data expected in the form.</p>
<p><code>FormFieldProps</code> defines the properties expected by the form field component (which we will build later on). It includes:</p>
<ul>
<li><code>type</code>: The type of the input field (for example, text, password).</li>
<li><code>placeholder</code>: Placeholder text for the input field.</li>
<li><code>name</code>: The name of the field, which corresponds to one of the valid field names defined in the <code>ValidFieldNames</code> type.</li>
<li><code>register</code>: A function from <code>react-hook-form</code> (<code>UseFormRegister&lt;FormData&gt;</code>) used to register the input field with the form.</li>
<li><code>error</code>: Represents any validation error associated with the field. It can be <code>undefined</code> if there are no errors.</li>
<li><code>valueAsNumber</code> (optional): A boolean flag indicating whether the field value should be treated as a number. Defaults to <code>undefined</code>.</li>
</ul>
<p><code>ValidFieldNames</code> is a union type that enumerates the valid field names for the form. These correspond to the fields defined in the <code>FormData</code> type.</p>
<h2 id="heading-how-to-create-a-form-with-react-hook-form">How to Create a Form with React-Hook-Form</h2>
<p>Now that we have defined the types for the form, let's create a reusable form field component and the form component.</p>
<h3 id="heading-create-a-reusable-form-field-component">Create a Reusable Form Field Component</h3>
<p>Let's create a reusable <code>FormField</code> component that handles rendering an input element, registering it with the form using <code>react-hook-form</code>, and displaying a validation error message when necessary.</p>
<p>Head on to the <code>/app/components/FormField.tsx</code> file and update the component:</p>
<pre><code class="lang-tsx">import { FormFieldProps } from "@/types";

const FormField: React.FC&lt;FormFieldProps&gt; = ({
  type,
  placeholder,
  name,
  register,
  error,
  valueAsNumber,
}) =&gt; (
  &lt;&gt;
    &lt;input
      type={type}
      placeholder={placeholder}
      {...register(name, { valueAsNumber })}
    /&gt;
    {error &amp;&amp; &lt;span className="error-message"&gt;{error.message}&lt;/span&gt;}
  &lt;/&gt;
);
export default FormField;
</code></pre>
<h4 id="heading-imports">Imports:</h4>
<ul>
<li>The component imports the <code>FormFieldProps</code> type from the <code>@/types</code> module. This type contains the expected properties for a form field, such as <code>type</code>, <code>placeholder</code>, <code>name</code>, <code>register</code>, <code>error</code>, and <code>valueAsNumber</code>.</li>
</ul>
<h4 id="heading-input-element">Input Element:</h4>
<ul>
<li>The component renders an <code>&lt;input&gt;</code> element with attributes set based on the provided props (<code>type</code>, <code>placeholder</code>, <code>name</code>). </li>
<li>The <code>...register(name, { valueAsNumber })</code> syntax is used to register the input field with the form, enabling form state management.</li>
</ul>
<h4 id="heading-error-handling">Error Handling:</h4>
<ul>
<li>If there is a validation error, a <code>&lt;span&gt;</code> element is rendered, displaying the error message.</li>
</ul>
<h3 id="heading-create-the-form-component">Create the Form Component</h3>
<p>The <code>Form</code> component will utilize the <code>react-hook-form</code> library to manage the form state. It modularizes form fields by using our reusable <code>FormField</code> component.</p>
<p>Navigate to <code>app/components/Form.tsx</code> and update it with the code below:</p>
<pre><code class="lang-tsx">import { useForm } from "react-hook-form";
import { FormData } from "@/types";
import FormField from "./FormField";

function Form() {
  const {
    register,
    handleSubmit,
    formState: { errors },
    setError,
  } = useForm&lt;FormData&gt;();

  const onSubmit = async (data: FormData) =&gt; {
      console.log("SUCCESS", data);
  }

  return (
      &lt;form onSubmit={handleSubmit(onSubmit)}&gt;
        &lt;div className="grid col-auto"&gt;
          &lt;h1 className="text-3xl font-bold mb-4"&gt;
            Zod &amp; React-Hook-Form
          &lt;/h1&gt;
          &lt;FormField
            type="email"
            placeholder="Email"
            name="email"
            register={register}
            error={errors.email}
          /&gt;

          &lt;FormField
            type="text"
            placeholder="GitHub URL"
            name="githubUrl"
            register={register}
            error={errors.githubUrl}
          /&gt;

          &lt;FormField
            type="number"
            placeholder="Years of Experience (1 - 10)"
            name="yearsOfExperience"
            register={register}
            error={errors.yearsOfExperience}
            valueAsNumber
          /&gt;

          &lt;FormField
            type="password"
            placeholder="Password"
            name="password"
            register={register}
            error={errors.password}
          /&gt;

          &lt;FormField
            type="password"
            placeholder="Confirm Password"
            name="confirmPassword"
            register={register}
            error={errors.confirmPassword}
          /&gt;
          &lt;button type="submit" className="submit-button"&gt;
            Submit
          &lt;/button&gt;
        &lt;/div&gt;
      &lt;/form&gt;
  );
}

export default Form;
</code></pre>
<h4 id="heading-imports-1">Imports:</h4>
<ul>
<li>The <code>useForm</code> hook provides functionality for managing form state and validation.</li>
<li><code>FormData</code> represents the structure of the form data.</li>
<li><code>FormField</code> is our reusable form field component.</li>
</ul>
<h4 id="heading-form-component">Form Component:</h4>
<ul>
<li>Form-related functions and state variables are destructured from the <code>useForm</code> hook, which is explicitly typed with <code>FormData</code> to define the shape of the form data.</li>
<li>Within the form, the <code>FormField</code> components are rendered for different input fields such as email, GitHub URL, years of experience, password, and confirm password.</li>
</ul>
<h4 id="heading-run-code">Run Code:</h4>
<p>Import the <code>Form</code> component into <code>/app/page.tsx</code> file:</p>
<pre><code class="lang-tsx">"use client";
import Form from "./components/Form";

function Home() {

  return (
    &lt;main className="flex min-h-screen flex-col items-center justify-between p-24"&gt;
     &lt;Form /&gt;
    &lt;/main&gt;
  );
}

export default Home;
</code></pre>
<p>Visit <a target="_blank" href="http://localhost:3000/">http://localhost:3000/</a> to view the form:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-11-at-11.40.22.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="http://localhost:3000/">http://localhost:3000/</a></em></p>
<p>In summary, our <code>Form</code> component is a basic form structure that uses the <code>react-hook-form</code> library for state management and employs a reusable <code>FormField</code> component to handle the rendering and validation of individual form fields. </p>
<h2 id="heading-how-to-integrate-zod-for-schema-validation">How to Integrate Zod for Schema Validation</h2>
<p>Zod stands out as a schema declaration and validation library, with TypeScript as its primary focus. The term "schema" encompasses various data types, ranging from strings, numbers, and booleans to more complex objects.</p>
<h3 id="heading-define-a-form-schema-with-zod">Define a Form Schema with Zod</h3>
<p>Let's create a TypeScript-backed form schema using Zod for our form structure.</p>
<p>Head to your <code>/types.ts</code> file, add the new imports, and create a user schema with the code below:</p>
<pre><code class="lang-ts"> <span class="hljs-keyword">import</span> { z, ZodType } <span class="hljs-keyword">from</span> <span class="hljs-string">"zod"</span>; <span class="hljs-comment">// Add new import</span>

 <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> UserSchema: ZodType&lt;FormData&gt; = z
  .object({
    email: z.string().email(),
    githubUrl: z
      .string()
      .url()
      .includes(<span class="hljs-string">"github.com"</span>, { message: <span class="hljs-string">"Invalid GitHub URL"</span> }),
    yearsOfExperience: z
      .number({
        required_error: <span class="hljs-string">"required field"</span>,
        invalid_type_error: <span class="hljs-string">"Years of Experience is required"</span>,
      })
      .min(<span class="hljs-number">1</span>)
      .max(<span class="hljs-number">10</span>),
    password: z
      .string()
      .min(<span class="hljs-number">8</span>, { message: <span class="hljs-string">"Password is too short"</span> })
      .max(<span class="hljs-number">20</span>, { message: <span class="hljs-string">"Password is too long"</span> }),
    confirmPassword: z.string(),
  })
  .refine(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> data.password === data.confirmPassword, {
    message: <span class="hljs-string">"Passwords do not match"</span>,
    path: [<span class="hljs-string">"confirmPassword"</span>], <span class="hljs-comment">// path of error</span>
  });
</code></pre>
<h4 id="heading-imports-2">Imports:</h4>
<ul>
<li><code>z</code> is an instance of the Zod object. </li>
<li><code>ZodType</code> is a generic type that represents a Zod schema type for a specific data structure.</li>
</ul>
<h4 id="heading-user-schema">User Schema:</h4>
<ul>
<li><code>export const UserSchema: ZodType&lt;FormData&gt; = ...</code>: The <code>UserSchema</code> represents a Zod type that corresponds to the structure defined by the <code>FormData</code> type.</li>
<li><code>z.object({...})</code>: This part defines an object schema using Zod. The object has several fields, each with its own validation rules.</li>
<li>Inside the object, each field is defined with its own validation rules using Zod methods like <code>z.string()</code>, <code>z.url()</code>, <code>z.number()</code>, and <code>z.min()</code>. Optional custom error messages are provided for some of the fields.</li>
<li><code>z.refine((data) =&gt; data.password === data.confirmPassword, { /* ... */ });</code>: Adds a refinement to the schema to check if the <code>password</code> and <code>confirmPassword</code> fields match. If not, a custom error message is provided, and the error is associated with the <code>confirmPassword</code> field.</li>
</ul>
<h3 id="heading-how-to-integrate-zod-with-react-hook-form-for-validation">How to Integrate Zod with React-Hook-Form for validation</h3>
<p>Now that we've set up the Zod schema for the form, let's integrate it with our existing Form component. To do this, we'll use <code>zodResolver</code> from the <code>[@hookform](https://www.npmjs.com/package/@hookform/resolvers)</code> library.</p>
<p><code>zodResolver</code> is a resolver function that integrates the Zod schema validation with the form validation process. </p>
<p>Head over to the <code>app/components/Form.tsx</code> file and update it with the code below:</p>
<pre><code class="lang-tsx">// Update imports
import { FormData, UserSchema } from "@/types";
import { zodResolver } from "@hookform/resolvers/zod";

function Form() {
  const {
    register,
    handleSubmit,
    formState: { errors },
    setError,
  } = useForm&lt;FormData&gt;({
    resolver: zodResolver(UserSchema), // Apply the zodResolver
  });

{/* Existing Code...*/}

}
</code></pre>
<p>If you try submitting the form with empty input fields, you will see error messages on the browser.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-11-at-20.38.03.png" alt="Image" width="600" height="400" loading="lazy">
<em>Error Messages - http://localhost:3000/</em></p>
<p>Additionally, our custom error messages, such as prompting users to provide a valid GitHub URL and checking if the passwords match, are demonstrated in the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-11-at-20.59.18.png" alt="Image" width="600" height="400" loading="lazy">
<em>Custom Error Messages - http://localhost:3000/</em></p>
<h2 id="heading-how-to-handle-server-side-errors">How to Handle Server-Side Errors</h2>
<p>When creating forms, data integrity and type safety are very important, given that submitted data goes to the website's server. This leads us to the significance of handling server-side errors — an extra security measure to make sure data from the client is accurate and non-malicious.</p>
<h3 id="heading-how-to-implement-server-side-validation">How to Implement Server-Side Validation</h3>
<p>To implement server-side validation, we will leverage Next.js' backend capabilities to build a simple server. This server will receive and validate the data submitted through our form.</p>
<p>Navigate to <code>app/api/form/route.ts</code> and include the code below:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { UserSchema } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/types"</span>;
<span class="hljs-keyword">import</span> { NextResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next/server"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">POST</span>(<span class="hljs-params">request: Request</span>) </span>{
  <span class="hljs-comment">// Retrieve the JSON data from the request body</span>
  <span class="hljs-keyword">const</span> body = <span class="hljs-keyword">await</span> request.json();

  <span class="hljs-comment">// Use Zod to validate the received data against the UserSchema</span>
  <span class="hljs-keyword">const</span> result = UserSchema.safeParse(body);

  <span class="hljs-comment">// Check if the validation is successful</span>
  <span class="hljs-keyword">if</span> (result.success) {
    <span class="hljs-keyword">return</span> NextResponse.json({ success: <span class="hljs-literal">true</span> });
  }

  <span class="hljs-comment">// If validation errors, map them into an object</span>
  <span class="hljs-keyword">const</span> serverErrors = <span class="hljs-built_in">Object</span>.fromEntries(
    result.error?.issues?.map(<span class="hljs-function">(<span class="hljs-params">issue</span>) =&gt;</span> [issue.path[<span class="hljs-number">0</span>], issue.message]) || []
  );

  <span class="hljs-comment">// Respond with a JSON object containing the validation errors</span>
  <span class="hljs-keyword">return</span> NextResponse.json({ errors: serverErrors });
}
</code></pre>
<h4 id="heading-imports-3">Imports:</h4>
<ul>
<li>The <code>UserSchema</code> we defined earlier is imported.</li>
<li><code>NextResponse</code> from the <code>next/server</code> module, which allows us to craft server responses in a Next.js environment.</li>
</ul>
<h4 id="heading-post-function">POST Function:</h4>
<ul>
<li><code>const body = await request.json()</code>: Retrieves the JSON data from the request body and stores it in the <code>body</code> variable.</li>
<li><code>const result = UserSchema.safeParse(body)</code>: Utilizes the <code>safeParse</code> method provided by Zod to validate the received data against the <code>UserSchema</code>. The result contains information about whether the validation was successful and, if not, details about the validation issues.</li>
<li><code>if (result.success) { return NextResponse.json({ success: true }); }</code>: If the validation is successful, a JSON response with <code>{ success: true }</code> is sent.</li>
<li><code>const serverErrors = Object.fromEntries(/* ... */)</code>: If there are validation errors, the code maps them into an object with field names and corresponding error messages.</li>
<li><code>return NextResponse.json({ errors: serverErrors })</code>: Responds with a JSON object containing the validation errors.</li>
</ul>
<p>In your terminal, stop running the project and run <code>npm run dev</code> again to restart the server.</p>
<h3 id="heading-how-to-integrate-server-side-validation">How to Integrate Server-Side Validation</h3>
<p>To integrate the server-side validation, we have to update the <code>onSubmit</code> function in the Form component.</p>
<p>Head over to the <code>/app/components/Form.tsx</code> file and update the imports and <code>onSubmit</code> function:</p>
<pre><code class="lang-tsx">// Update import
import { FormData, UserSchema, ValidFieldNames } from "@/types";  
import axios from "axios";

function Form() {
{/* Existing Code... */}

  const onSubmit = async (data: FormData) =&gt; {
    try {
      const response = await axios.post("/api/form", data); // Make a POST request
      const { errors = {} } = response.data; // Destructure the 'errors' property from the response data

      // Define a mapping between server-side field names and their corresponding client-side names
      const fieldErrorMapping: Record&lt;string, ValidFieldNames&gt; = {
        email: "email",
        githubUrl: "githubUrl",
        yearsOfExperience: "yearsOfExperience",
        password: "password",
        confirmPassword: "confirmPassword",
      };

      // Find the first field with an error in the response data
      const fieldWithError = Object.keys(fieldErrorMapping).find(
        (field) =&gt; errors[field]
      );

      // If a field with an error is found, update the form error state using setError
      if (fieldWithError) {
        // Use the ValidFieldNames type to ensure the correct field names
        setError(fieldErrorMapping[fieldWithError], {
          type: "server",
          message: errors[fieldWithError],
        });
      }
    } catch (error) {
      alert("Submitting form failed!");
    }
  };
{/* Existing Code... */}
}
</code></pre>
<ul>
<li><code>axios</code> is used to make a POST request to the server endpoint <code>/api/form</code> with the form data.</li>
<li>The <code>errors</code> object is extracted from the response data.</li>
<li>A mapping (<code>fieldErrorMapping</code>) between field names and their corresponding <code>ValidFieldNames</code> is defined.</li>
<li>It then checks if there are any errors related to form fields by iterating over the <code>fieldErrorMapping</code> and finding the first field with an error.</li>
<li>If a field with an error is found, the <code>setError</code> function from <code>react-hook-form</code> is used to set an error for the corresponding field. The error type is marked as "server," and the error message comes from the server response.</li>
<li>If there's an error in the entire try block, it catches the error and displays an alert: "Submitting form failed!"</li>
</ul>
<p>Now, to test if we can receive errors from the server, we'll deliberately send improperly formatted data to the server. In your <code>onSubmit</code> function, replace the <code>data</code> object with the incorrect data in the code block below:</p>
<pre><code class="lang-tsx">
{/* Existing Code...*/}
  const onSubmit = async (data: FormData) =&gt; {

    try {
      // Update data sent in axios with incorrect data
      const response = await axios.post("/api/form", {
        email: "Not an email",
        githubUrl: "Not a URL",
        yearsOfExperience: "Hello",
        password: 1234,
        confirmPassword: 1234,
      }); // Make a POST request

{/* Existing Code...*/}
}
</code></pre>
<p>Fill the form in the browser normally and submit the form. </p>
<p>Inspect the "Network" tab within the browser's developer tools. You'll find error messages coming directly from the server, as demonstrated in the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-2024-01-12-at-10.21.47.png" alt="Image" width="600" height="400" loading="lazy">
<em>Server errors - http://localhost:3000/</em></p>
<p>If you're not getting any response from your server, remember to stop running your project in your terminal and run <code>npm run dev</code> again to re-start the server.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, we built a form with React-Hook-Form and validated it with Zod. With Zod, we explored schema validation, customized error messages, and server-side errors. The integration of React-Hook-Form and Zod presents a powerful, developer-friendly solution to creating resilient forms.</p>
<p>You can reach out to me on <a target="_blank" href="https://twitter.com/dev_giftea">Twitter</a> if you have any questions.</p>
<p>You can check out the <a target="_blank" href="https://github.com/Giftea/zod-rhf-fcc">source code</a> and the deployed <a target="_blank" href="https://zod-rhf-fcc.vercel.app/">app</a>.</p>
<h3 id="heading-resources">Resources:</h3>
<ul>
<li><a target="_blank" href="https://zod.dev/">Zod Documentation</a></li>
<li><a target="_blank" href="https://zod.dev/ERROR_HANDLING?id=error-handling-in-zod">Zod Error Handling</a></li>
<li><a target="_blank" href="https://react-hook-form.com/get-started">React-Hook-Form Documentation</a></li>
<li><a target="_blank" href="https://www.npmjs.com/package/@hookform/resolvers">Hookform Resolvers</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Error-Free HTML Forms ]]>
                </title>
                <description>
                    <![CDATA[ After taking some coding courses, I decided that it was time to put my knowledge to good use and do a coding project.  Like most newbies, I went to Google to find some inspiration. As I scrolled through the internet, I stumbled upon Skillcrush’s list... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-error-free-html-forms/</link>
                <guid isPermaLink="false">66b904fe941d2f900bad52b6</guid>
                
                    <category>
                        <![CDATA[ error ]]>
                    </category>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Christine Belzie ]]>
                </dc:creator>
                <pubDate>Mon, 17 Jul 2023 18:47:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/FCC-Blog-Cover-4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>After taking some coding courses, I decided that it was time to put my knowledge to good use and do a coding project. </p>
<p>Like most newbies, I went to Google to find some inspiration. As I scrolled through the internet, I stumbled upon <a target="_blank" href="https://skillcrush.com/blog/html-css-projects/">Skillcrush’s list of HTML and CSS projects for beginners</a>. </p>
<p>Number 5 piqued my interest, so I googled some images on how HTML forms should look. I thought “Oh I can do this. This looks easy!” But this project turned out to be a bit harder than I thought. </p>
<p>In this article, I will show you three things I have learned in surviving, I mean making HTML forms error-free. Let’s get started! 😀</p>
<h2 id="heading-tip-1-make-sure-the-labels-and-inputs-match">Tip #1: Make Sure the Labels and Inputs Match.</h2>
<p>When I first started creating HTML forms, I would often use the following methods for creating email input fields:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"text"</span>&gt;</span> Your Email<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"text"</span>&gt;</span>
</code></pre>
<p>I would often use <code>text</code> as the label and id's attribute because I thought it was the correct method. </p>
<p>This all changed when I started using <a target="_blank" href="https://wave.webaim.org/extension/">WAVE’s accessibility checker</a> to learn how to make my code more accessible. When I ran my form through the checker, it pointed out that the email input did not have a properly associated label, and that can cause screen readers to have difficulty presenting it to users with disabilities.</p>
<p>So, I googled a few sources and found <a target="_blank" href="https://css-tricks.com/html-inputs-and-labels-a-love-story/">”HTML Inputs and Labels: A Love Story” by Amber Wilson</a>. Through reading this article, I learned that it’s best to use specific names in the <code>id</code> attribute. </p>
<p>With a new feeling of confidence, I started using this approach. Here’s an example:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/CB_ID2/embed/MWPPmBG" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>In the code snippet above, I used <code>email</code> as the label and input’s <code>id</code> attribute. When I ran it through the accessibility checker, there were no red Xs.  </p>
<p>While this victory was sweet, I wanted to learn more ways to ensure that labels and inputs were accessible. So I went to Google and found this <a target="_blank" href="https://www.w3schools.com/html/html_forms_attributes.asp">HTML Forms attributes article</a>. Through reading, I learned that you can add other attributes like <code>placeholder</code>, which demonstrates how the user should present their contact information.  </p>
<p>Through these experiences, I realized that creating harmonious labels and inputs for a form is like constructing a sandwich. You want to make sure that your flavors work well together and use the best features of your oven (or whatever appliance you use) to make your sandwich nice and toasty. </p>
<p>Now before we start getting hungry, let’s move on to my next tip. :) </p>
<h2 id="heading-tip-2-be-more-semantic-when-creating-a-button"><strong>Tip #2:  Be More Semantic When Creating a Button</strong></h2>
<p>Formatting your form’s buttons is crucial to the efficiency of your HTML form. Buttons are the main way that your user’s information is sent to your desired destination. </p>
<p>When I first started creating HTML forms, I used to create buttons like this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>
</code></pre>
<p>Like the labels and inputs, I would get a red x on WAVE’s accessibility checker. In the results, it mentioned that a <code>value</code> attribute was missing, which makes it difficult for the screen reader to detect the button. </p>
<p>With that in mind, I decided to do what most beginners do when creating this feature: </p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span> Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>When I ran the code in the WAVE accessibility checker again, it passed a few tests. But something inside me told me that my previous solution was ok too and that I just needed to find a way to add a <code>value</code> attribute to it.  </p>
<p>With a new thirst for knowledge, I went to Google and found this <a target="_blank" href="https://www.w3.org/WAI/tutorials/forms/labels/#labeling-buttons">article on how to create accessible form components</a>. In the section about buttons, they recommend using the following methods to make this element semantic:   </p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"Submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Submit"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"Submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>When I ran the first snippet into the accessibility checker, I received no red Xs. The same result occurred when I ran the second code snippet through the accessibility checker.  </p>
<p>At first, I didn't know which one to pick because both approaches made the form accessible. But something inside me told to go with what I truly wanted. So, I took a deep breath and chose the following code line:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/CB_ID2/embed/Rwedeme" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>I decided to go with the second code snippet because it's more explicitly labeled, which makes it easier for screen readers to scan. It's also easier to remember, and is the method that I often use for creating buttons. </p>
<p>Think of it as deciding to go with the brand of bread you’ve always used for your sandwiches instead of picking a different one. As cliché as this saying sounds, sometimes simplicity is best.  </p>
<p>Before you start getting hungry again, there is just one more suggestion for making your HTML forms error-free.</p>
<h2 id="heading-tip-3-pick-the-best-css-framework-based-on-your-needs"><strong>Tip #3:  Pick the Best CSS Framework Based on Your Needs</strong></h2>
<p>When I first started creating the style for my forms, I used to force myself to use CSS frameworks like Flexbox. At the time, my feelings of imposter syndrome were at an all-time high due to seeing other people creating great forms with those frameworks. I felt that if I started using them too, I would get those same designs. </p>
<p>At first, I was happy with using Flexbox as it made things like centering content easier as shown in the snippet below:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/CB_ID2/embed/mdzoQrg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>Unfortunately, I still wasn't satisfied in the end. I found that the design did not come to fruition as I envisioned.  </p>
<p>To combat this feeling, I went to Google to find something to help me solve my dilemma. When I was about to give up, I stumbled upon the article, <a target="_blank" href="https://blog.logrocket.com/how-to-style-forms-with-css-a-beginners-guide/">“How to style forms with CSS: A beginner’s guide” by Supun Kavinda</a>.</p>
<p>My heart leaped with joy when it pointed out that you can use vanilla CSS to create beautiful designs. For example, to make the texts’ input fields look more presentable, I could do this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=text]</span>{
<span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
}
</code></pre>
<p>With newfound confidence, I gave vanilla CSS another chance, and I can honestly say I was so happy with this decision. Here’s the final result:</p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/CB_ID2/embed/NWOOQXQ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p>I wanted to keep my design simple, so I used basic elements like <code>text-align</code>  property to center my form's content. </p>
<p>If I had to pick something that exemplifies this experience, it would be like a sandwich cut into two triangle slices. Simple yet effective.  </p>
<p>Overall, sometimes, it’s best to go back to the basics before moving on to something more challenging. </p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>There it is folks, my three tips on how to make your HTML forms error-free. </p>
<p>I know creating HTML forms can be frightening in the beginning. But with these tips, confidence, and some imagination, you can HTML forms that wow your viewers. Now go forth and be great! :)   </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Simple HTML and PHP Form ]]>
                </title>
                <description>
                    <![CDATA[ If you have a website, it's only a matter of time before you feel the irrepressible urge to gather information about your site's users.  The most direct way to do that is to ask them some questions. And, in the HTML world, the best tool for recording... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/creating-html-forms/</link>
                <guid isPermaLink="false">66b995c87bb37b73c3f3c4d7</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ David Clinton ]]>
                </dc:creator>
                <pubDate>Tue, 20 Jun 2023 22:17:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/pexels-john-petalcurin-2115257.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you have a website, it's only a matter of time before you feel the irrepressible urge to gather information about your site's users. </p>
<p>The most direct way to do that is to ask them some questions. And, in the HTML world, the best tool for recording the answers to those questions is the simple HTML form. </p>
<p>In this guide, I'm going to show you how that's done using basic HTML and just a dash of PHP.</p>
<p>As you'll soon see, the HTML you'll need to present a form is, in fact, pretty straightforward. But that'll only solve half of your problem. </p>
<p>A form will prompt users to enter whatever information you're asking for. But, if we leave it there, nothing will actually happen when they hit the Submit button. And that's because we don't have anything running on our server to collect and process that information.</p>
<p>Building the back end that'll integrate your form with a database engine or an associated application can get really complicated and is way beyond our scope here. But, once we understand the HTML form here, I <em>will</em> show you how you can add some PHP code to handle the code in a basic way.</p>
<p>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>. If you'd like, you can follow the video version here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/nRWn917ZZ60" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-how-to-prepare-your-linux-server-environment">How to Prepare Your Linux Server Environment</h2>
<p>I'm running a Linux virtual container that's got both PHP and the Apache HTTPD server installed. You can install those packages on an Ubuntu machine this way:</p>
<pre><code class="lang-bash">$ sudo apt install apache2 php
</code></pre>
<p>I'll start by navigating to the web root directory which is <code>/var/www/html</code>. The <code>ls</code> command will list all the files in the directory. </p>
<pre><code>$ pwd
/<span class="hljs-keyword">var</span>/www/html
$ ls
form.html    index.html    submit.php
</code></pre><p>That <code>index.html</code> file is the default place holder that's created when Apache is installed. I would replace that with my own home page file if this website was a real project.</p>
<h2 id="heading-how-to-create-an-html-form">How to Create an HTML Form</h2>
<p>For now, though, I'll let you see what's inside that <code>form.html</code> file:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Example Form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Example Form<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"submit.php"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">required</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">required</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"message"</span>&gt;</span>Message:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"5"</span> <span class="hljs-attr">cols</span>=<span class="hljs-string">"30"</span> <span class="hljs-attr">required</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Submit"</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>We start with the standard tags and then some <code>&lt;h1&gt;</code> text for a title. But then we open a <code>&lt;form&gt;</code> tag where the <code>action</code> points to a file called <code>submit.php</code> and the <code>method</code> specifies <code>post</code>. "Post" means that any text that's been entered into the form will be posted – or sent – to the <code>submit.php</code> file once the form is submitted.</p>
<p>The <code>&lt;input&gt;</code> tag down at the bottom of the code right before we close out the <code>&lt;form&gt;</code> uses the <code>submit</code> type to send our data. </p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Submit"</span>&gt;</span>
</code></pre>
<p>The <code>Submit</code> value attribute is there to print the word "Submit" on the button we'll see on the form. That'll make figuring out how to use the form easier for users.</p>
<p>Now the code used by the form itself is broken down into three pairs of lines:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">required</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">required</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"message"</span>&gt;</span>Message:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">"5"</span> <span class="hljs-attr">cols</span>=<span class="hljs-string">"30"</span> <span class="hljs-attr">required</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
</code></pre>
<p>The first line here is a <code>&lt;label&gt;</code> tag that prints the word "Name:" on the first entry field. The accompanying <code>&lt;input&gt;</code> tag has a <code>type</code> attribute of "text", an <code>id</code> attribute of "name" and is a <code>required</code> field. That means the form submission won't be successful unless this field has a value.</p>
<p>The next pair does the same thing for an email address. But as we see from the <code>type</code> attribute, this field expects the input to conform to the properties of a valid email address. This field is also <code>required</code>.</p>
<p>The final pair – "Message" – takes a <code>&lt;textarea&gt;</code> tag and has a maximum number of rows and columns specified. This field, as you might expect, allows free-form text, but only up to a maximum number of characters.</p>
<p>That's our code. Let's see what it looks like in a browser. First, though, you'll need to get the container's public IP address. </p>
<p>There are a few ways to do that, but the one that involves the fewest keystrokes is to run <code>ip a</code> inside the container. </p>
<pre><code class="lang-bash">$ ip a
[...]
12: eth0@if13: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:81:57:1b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.3.216/24 metric 100 brd 10.0.3.255 scope global dynamic eth0
       valid_lft 3154sec preferred_lft 3154sec
    inet6 fd42:e265:3791:64f9:216:3eff:fe81:571b/64 scope global mngtmpaddr noprefixroute 
[...]
</code></pre>
<p>The IP I got was <code>10.0.3.216</code>. Just add <code>form.html</code> to the value you got and pop it into your browser URL bar and the site will load. This is, by the way, a local NAT IP, so it won't be accessible outside of my home network.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/form_html.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Feel free to type something into the Name, Email, and Message fields, but there's no point hitting the Submit button just yet. That's because, without some PHP magic, nothing will happen. And I haven't shown you that PHP yet.</p>
<h2 id="heading-how-to-write-a-php-script-to-capture-user-inputs">How to Write a PHP Script to Capture User Inputs</h2>
<p>PHP, by the way, is a web-friendly scripting language that's a popular choice for adding programmed functionality to web pages. In fact, you can even incorporate PHP code directly into your HTML code. But here's how it'll look on its own, in a file called <code>submit.php</code>:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">if</span> ($_SERVER[<span class="hljs-string">"REQUEST_METHOD"</span>] == <span class="hljs-string">"POST"</span>) {
    <span class="hljs-comment">// Retrieve form data</span>
    $name = $_POST[<span class="hljs-string">"name"</span>];
    $email = $_POST[<span class="hljs-string">"email"</span>];
    $message = $_POST[<span class="hljs-string">"message"</span>];

    <span class="hljs-comment">// Display the submitted data</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"Name: "</span> . $name . <span class="hljs-string">"&lt;br&gt;"</span>;
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"Email: "</span> . $email . <span class="hljs-string">"&lt;br&gt;"</span>;
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"Message: "</span> . $message . <span class="hljs-string">"&lt;br&gt;"</span>;
}
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>Remember how our HTML <code>post</code> method sent the form data to this file? Well here's what PHP is going to do with it. The <code>if</code> block looks for posted data and then organizes it by field: name, email, and message. Normally, you'd probably send that data along to a database but, for simplicity, this code will just print it back to the page to prove that we actually had it.</p>
<p>Let's see what that'll look like. I click the Submit button and the form is replaced by the text I'd entered. Nothing spectacular, but it does nicely illustrate how forms work with PHP.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/results.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>With this simple code, you're now able to create your own HTML forms that collect and process user input. </p>
<p>Your next step will be to connect with a back end database so you can save and manipulate that data. For for now, enjoy this accomplishment!</p>
<p><em>This article comes from <a target="_blank" href="https://www.udemy.com/course/complete-lpi-web-development-essentials-exam-study-guide/?referralCode=C92570BCBB38302A9257">my Complete LPI Web Development Essentials Study Guide course</a>.</em> <em>And there's much more technology goodness available at <a target="_blank" href="https://bootstrap-it.com/">bootstrap-it.com</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build React Forms with Formik ]]>
                </title>
                <description>
                    <![CDATA[ By Popoola Temitope Form building in React can be complex and time-consuming, requiring state management, validation, and error handling.  To simplify this process, the Formik library provides an intuitive solution for building forms in React. Formik... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-react-forms-with-formik-library/</link>
                <guid isPermaLink="false">66d46089f855545810e934ab</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 20 Mar 2023 16:56:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/Group-1--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Popoola Temitope</p>
<p>Form building in <a target="_blank" href="https://reactjs.org/"><code>React</code></a> can be complex and time-consuming, requiring state management, validation, and error handling. </p>
<p>To simplify this process, the <a target="_blank" href="https://formik.org/"><code>Formik</code></a> library provides an intuitive solution for building forms in React. Formik has a straightforward API and built-in validation, making collecting and manipulating input data in React applications easy.</p>
<h1 id="heading-what-is-formik">What is Formik?</h1>
<p><code>[Formik](https://formik.org/)</code> is a popular open-source library for building and processing form data in React applications. It provides many utility components and functions that make handling form data in a React application more enjoyable.</p>
<p>Traditional form-management method in React requires creating a universal or single <strong><code>useState()</code></strong> hook for each form field, adding an event listener to each field, and triggering a method to update them individually. </p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Infuriating traditional react form management method</span>

<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">InputForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [input1, setInput1] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [input2, setInput2] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">const</span> handleInputChange = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { name, value } = event.target;
    <span class="hljs-keyword">if</span> (name === <span class="hljs-string">"input1"</span>) {
      setInput1(value);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (name === <span class="hljs-string">"input2"</span>) {
      setInput2(value);
    }
  };

  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
   <span class="hljs-comment">// . . .</span>
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"input1"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{input1}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleInputChange}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"input2"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{input2}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleInputChange}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> InputForm;
</code></pre>
<p>On the other hand, Formik handles all of these tedious operations for us under the hood. We only need to import its provided components – our form data are readily available.</p>
<pre><code class="lang-javascript">&lt;Formik
  onSubmit={<span class="hljs-function">(<span class="hljs-params">formData</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(formData);
  }}
&gt;
  {<span class="hljs-function">(<span class="hljs-params">{ isSubmitting }</span>) =&gt;</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Form</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Field</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"fullname"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter fullname"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Field</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter address"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Form</span>&gt;</span></span>
  )}
&lt;/Formik&gt;;
</code></pre>
<p>In addition to helping us handle form data, Formik provides some other mechanisms that let us validate form fields, track form submission state, and handle errors.</p>
<p>This tutorial will show you how to use Formik in a React app by creating a simple registration form.</p>
<h1 id="heading-how-to-install-formik">How to Install Formik</h1>
<p>To start with Formik, let's create a new React app using the below command:</p>
<pre><code class="lang-bash">npx create-react-app my-app
<span class="hljs-built_in">cd</span> my-app
npm start
</code></pre>
<p>Once we have our React app set up, we can install Formik with the following command:</p>
<pre><code class="lang-bash">npm install formik --save
</code></pre>
<p>Once we've installed Formik, we can import its components and utilize them in our application.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Formik, Form, Field, ErrorMessage } <span class="hljs-keyword">from</span> <span class="hljs-string">'formik'</span>;
</code></pre>
<p>In the above import code, we have the following:</p>
<ul>
<li>The <code>Form</code> component wraps all the form fields and provides essential context for using Formik's tools. This includes managing the form's state, handling validation, and submitting the form.</li>
<li><code>Field</code> is a component provided by Formik that represents a form field. We can use this component to render an input, select, or other form elements. It automatically handles the state of the field, such as its value and validation.</li>
<li><code>ErrorMessage</code> is a component provided by Formik that renders an error message for a specific field. We can use this component to display validation errors for a field. This is especially helpful for displaying form errors in a user-friendly way.</li>
</ul>
<h1 id="heading-how-to-create-a-form-with-formik">How to Create a Form with Formik</h1>
<p>We can create a form input by wrapping the form and its fields inside the Formik component. The code below is an example of creating form input using Formik:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { Formik, Form, Field, ErrorMessage } <span class="hljs-keyword">from</span> <span class="hljs-string">"formik"</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
 <span class="hljs-keyword">return</span> (
   <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">center</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Register a new account<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">Formik</span>&gt;</span>
         {({ isSubmitting }) =&gt; (
           <span class="hljs-tag">&lt;<span class="hljs-name">Form</span>&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">Field</span>
               <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
               <span class="hljs-attr">name</span>=<span class="hljs-string">"fullname"</span>
               <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your fullname"</span>
             /&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">ErrorMessage</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"fullname"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">"div"</span> /&gt;</span>

             <span class="hljs-tag">&lt;<span class="hljs-name">Field</span>
               <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>
               <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span>
               <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter email address"</span>
             /&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">ErrorMessage</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">"div"</span> /&gt;</span>

             <span class="hljs-tag">&lt;<span class="hljs-name">Field</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span> /&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">ErrorMessage</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">"div"</span> /&gt;</span>

             <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{isSubmitting}</span>&gt;</span>
               Submit
             <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
           <span class="hljs-tag">&lt;/<span class="hljs-name">Form</span>&gt;</span>
         )}
       <span class="hljs-tag">&lt;/<span class="hljs-name">Formik</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">center</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
 );
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>In the above code, the Formik component wraps the form and provides utilities like form validation and submission handling. The <code>Field</code> component defines each form input, such as <code>fullname</code>, <code>email</code>, and <code>password</code>, while the <code>ErrorMessage</code> component displays validation errors for each field.</p>
<p>The <code>isSubmitting</code> prop is passed to the render prop function, which is used to disable the submit button while the form is submitted.</p>
<p>Next, we must set the field's initial values by passing the <code>initialValues</code> prop. We can set the initial values for fullname, email, and password using the code below:</p>
<pre><code class="lang-javascript">&lt;Formik initialValues={{ <span class="hljs-attr">fullname</span>: <span class="hljs-string">""</span>, <span class="hljs-attr">email</span>: <span class="hljs-string">""</span>, <span class="hljs-attr">password</span>: <span class="hljs-string">""</span> }}&gt;
</code></pre>
<h2 id="heading-form-validation-with-formik">Form Validation with Formik</h2>
<p>When creating forms, it's essential to validate input data to prevent errors and provide an interactive user experience. The code below shows how to validate form input data using Formik.</p>
<pre><code class="lang-javascript">&lt;Formik
         initialValues={{ <span class="hljs-attr">fullname</span>: <span class="hljs-string">""</span>, <span class="hljs-attr">email</span>: <span class="hljs-string">""</span>, <span class="hljs-attr">password</span>: <span class="hljs-string">""</span> }}
         validate={<span class="hljs-function">(<span class="hljs-params">values</span>) =&gt;</span> {
           <span class="hljs-keyword">const</span> errors = {};
           <span class="hljs-keyword">if</span> (!values.fullname) {
             errors.fullname = <span class="hljs-string">"Required"</span>;
           }

           <span class="hljs-keyword">if</span> (!values.email) {
             errors.email = <span class="hljs-string">"Required"</span>;
           } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (
             !<span class="hljs-regexp">/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i</span>.test(values.email)
           ) {
             errors.email = <span class="hljs-string">"Invalid email address"</span>;
           }
           <span class="hljs-keyword">if</span> (!values.password) {
             errors.password = <span class="hljs-string">"Required"</span>;
           }
           <span class="hljs-keyword">return</span> errors;
         }}
       &gt;
</code></pre>
<p>In the code above, we use the validate prop to define a validation function that will be called whenever the user interacts with the form. This function takes the current values of the form fields as a parameter and returns an object that specifies any errors in the form data.</p>
<h2 id="heading-form-submission-with-formik">Form Submission With Formik</h2>
<p>Formik uses an <code>onSubmit</code> function to handle form data whenever the submit button gets clicked. It first validates the data using the validation function. </p>
<p>To process a form using the <code>onSubmit</code> function, add the following code to the Formik component:</p>
<pre><code class="lang-javascript"> &lt;Formik
   initialValues={{ <span class="hljs-attr">fullname</span>: <span class="hljs-string">""</span>, <span class="hljs-attr">email</span>: <span class="hljs-string">""</span>, <span class="hljs-attr">password</span>: <span class="hljs-string">""</span> }}
   <span class="hljs-comment">// . . .</span>
   onSubmit={<span class="hljs-function">(<span class="hljs-params">values, { setSubmitting }</span>) =&gt;</span> {
     <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
       alert(<span class="hljs-built_in">JSON</span>.stringify(values, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>));
       setSubmitting(<span class="hljs-literal">false</span>);
     }, <span class="hljs-number">400</span>);
   }}
&gt;
</code></pre>
<p>From the code above, the onSubmit function is called when the form is submitted and uses the <code>setSubmitting</code> function to update the Formik component's state during the submission process.</p>
<p>Here is the output of the form we created using Formik:</p>
<p><img src="https://lh6.googleusercontent.com/mhfCqUCehriSWJPKlD55nkuULYzndQOcNC43HsP5PxrfAsc6Cn42CF13uExK3li8gXiFevXpxD_tHe93DrXAgce_hGBO8RCHL1etkjcUGFJfP1VkN1wYceb6F_vywGL9BUG_TwGKU9daQ2O0x12eIcs" alt="Image" width="762" height="530" loading="lazy"></p>
<h1 id="heading-conclusion">Conclusion</h1>
<p><code>Formik</code> is a React library that makes building forms easy and intuitive, especially when creating complex forms or trying to save time during development.</p>
<p>In this tutorial, we learned how to use Formik to create and manage form states in React applications. <a target="_blank" href="https://formik.org/docs/overview">If you want to learn more about Formik, you can check out their official documentation</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Forms in React ]]>
                </title>
                <description>
                    <![CDATA[ Forms play an essential role in modern web applications. They enable users to share information, complete tasks and provide feedback.  Without forms, many of the tasks that we take for granted on the web, such as logging in, signing up, or making pur... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-forms-in-react/</link>
                <guid isPermaLink="false">66bd904edc6141cf21aaada4</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Boateng Dickson ]]>
                </dc:creator>
                <pubDate>Fri, 10 Mar 2023 17:43:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/pexels-rodnae-productions-7821577.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Forms play an essential role in modern web applications. They enable users to share information, complete tasks and provide feedback. </p>
<p>Without forms, many of the tasks that we take for granted on the web, such as logging in, signing up, or making purchases, would not be possible.</p>
<p>As such, learning how to create effective and user-friendly forms is essential for developers looking to build engaging and interactive web applications.</p>
<p>With its extensive collection of built-in hooks, React provides several features and techniques for creating and managing forms, including state management, event handling, and form validation.</p>
<p>The purpose of this guide is to provide a comprehensive and in-depth look at creating forms in React. </p>
<h2 id="heading-getting-started">Getting Started...</h2>
<p>In React, there are two ways of handling form data:</p>
<ul>
<li><strong>Controlled Components:</strong> In this approach, form data is handled by React through the use of hooks such as the <code>useState</code> hook.</li>
<li><strong>Uncontrolled Components:</strong> Form data is handled by the Document Object Model (DOM) rather than by React. The DOM maintains the state of form data and updates it based on user input.</li>
</ul>
<p>To better understand the difference between controlled and uncontrolled components, consider there are two ways of riding a bike.</p>
<p>In the first approach, you let the bike take control. You sit on the bike and let it decide the direction and speed. You might try to make it go in a certain direction by leaning your body, but ultimately, the bike decides where to go.</p>
<p>This is similar to uncontrolled components in React. You place a form element in the component, and the DOM takes control of it. The DOM decides the state of the input element and updates it based on a user's input.</p>
<p>In the second approach, you take control of the bike. You hold the handlebars and pedal, and you decide where to go and how fast to ride. You can easily slow down or speed up as needed.</p>
<p>This is similar to controlled components where a React component takes control of the form data, and maintains the state of form elements. The component decides when and how to update the state, and it re-renders itself based on the state changes.</p>
<p>In the upcoming sections, we will expound upon the distinction between controlled and uncontrolled components and provide practical examples to illustrate how each operates.</p>
<h2 id="heading-controlled-components-in-react">Controlled Components in React</h2>
<p>In React, a controlled component is a component where form elements derive their value from a React state.</p>
<p>When a component is controlled, the value of form elements is stored in a state, and any changes made to the value are immediately reflected in the state.</p>
<p>To create a controlled component, you need to use the <code>value</code> prop to set the value of form elements and the <code>onChange</code> event to handle changes made to the value.</p>
<p>The <code>value</code> prop sets the initial value of a form element, while the <code>onChange</code> event is triggered whenever the value of a form element changes. Inside the <code>onChange</code> event, you need to update the state with the new value using a state update function.</p>
<p>Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {useState} <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span>  <span class="hljs-title">ControlledComponent</span>(<span class="hljs-params"></span>)  </span>{
    <span class="hljs-keyword">const</span>  [inputValue, setInputValue] =  useState(<span class="hljs-string">''</span>);

    <span class="hljs-keyword">const</span>  handleChange = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
        setInputValue(event.target.value);
    };

<span class="hljs-keyword">return</span>  (
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Input Value:
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span>  <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>  <span class="hljs-attr">value</span>=<span class="hljs-string">{inputValue}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Input Value: {inputValue}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)};
</code></pre>
<p>In this example:</p>
<p>The <code>useState</code> hook defines a state variable (inputValue) and a state update function (setInputValue).</p>
<p>The <code>value</code> prop sets the initial value of the input element to the value of <code>inputValue</code>.</p>
<p>Also, the <code>onChange</code> event handles changes made to the input value. The <code>handleChange</code> function updates the <code>inputValue</code> state with the new value of the input element, and the updated value is immediately reflected in the state and displayed on the screen.</p>
<p><img src="https://i.imgur.com/N77Ohpv.gif" width="700" height="300" alt="N77Ohpv" loading="lazy"></p>
<p>As the user types into the input field, the <code>handleChange</code> function updates the state variable using the "setInputValue" function. The component is then re-rendered, and the input field's <code>value</code> attribute is updated to reflect the new value of <code>inputValue</code>.</p>
<p>The value of the input field and the text displayed below it are always in sync, making it a controlled component.</p>
<h3 id="heading-how-to-handle-dropdowns-and-checkboxes-in-controlled-components">How to handle dropdowns and checkboxes in Controlled Components</h3>
<p>Just like with input elements, the value of a dropdown can be set by using the <code>value</code> prop in conjunction with the <code>onChange</code> event handler to update the state of the component.</p>
<p>For example, to handle a dropdown menu, you can define the initial value of the dropdown menu within the state of the component, then update the state when the value of the dropdown changes:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Dropdown</span>(<span class="hljs-params"></span>)  </span>{
    <span class="hljs-keyword">const</span> [selectedOption, setSelectedOption] = useState(<span class="hljs-string">"option1"</span>);

    <span class="hljs-keyword">const</span>  handleDropdownChange = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
        setSelectedOption(event.target.value);
    };

<span class="hljs-keyword">return</span>  (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
            Select an option:
                <span class="hljs-tag">&lt;<span class="hljs-name">select</span>  <span class="hljs-attr">value</span>=<span class="hljs-string">{selectedOption}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleDropdownChange}</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">option</span>  <span class="hljs-attr">value</span>=<span class="hljs-string">"option1"</span>&gt;</span>Option 1<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">option</span>  <span class="hljs-attr">value</span>=<span class="hljs-string">"option2"</span>&gt;</span>Option 2<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">option</span>  <span class="hljs-attr">value</span>=<span class="hljs-string">"option3"</span>&gt;</span>Option 3<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Selected option: {selectedOption}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
}
</code></pre>
<p><img src="https://i.imgur.com/5cjbAeO.gif" width="700" height="300" alt="5cjbAeO" loading="lazy"></p>
<p>Similarly, you can handle checkboxes by setting the <code>checked</code> prop of the checkbox input element based on the state of a component, and then updating the state when a checkbox is clicked.</p>
<p>Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Checkbox</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [isChecked, setIsChecked] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    setIsChecked(event.target.checked);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"color"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"color"</span> <span class="hljs-attr">checked</span>=<span class="hljs-string">{isChecked}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}/</span>&gt;</span>
        Blue
      <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

      {isChecked &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Blue is selected!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Checkbox;
</code></pre>
<p>In this example, we have defined a state variable <code>isChecked</code> to keep track of whether the checkbox is checked or not. When the checkbox is clicked, the <code>handleChange</code> function is called, and it updates the <code>isChecked</code> state variable to a new value (true or false.).</p>
<p>The <code>isChecked</code> variable controls the <code>checked</code> attribute of the checkbox input and conditionally renders a message indicating that the checkbox is selected.</p>
<p><img src="https://i.imgur.com/81zMRzO.gif" width="700" height="300" alt="81zMRzO" loading="lazy"></p>
<h3 id="heading-how-to-handle-multiple-form-fields">How to handle multiple form fields</h3>
<p>When working with forms in React, it's common to have several form elements, such as text inputs, checkboxes, radio buttons, and others. </p>
<p>To manage the state of these form elements, you can define the values for the input fields as an object using a single state variable and update each respective state variable using the <code>onChange</code> event.</p>
<p>As an example, suppose you wish to create a form with the following fields:</p>
<ul>
<li>Text input for the user's name</li>
<li>An email field for the user's email</li>
<li>A textarea field for the user's message</li>
</ul>
<p>Here's how you could handle these fields:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Multiple</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [formData, setFormData] = useState({<span class="hljs-attr">name</span>: <span class="hljs-string">""</span>,<span class="hljs-attr">email</span>: <span class="hljs-string">""</span>,<span class="hljs-attr">message</span>: <span class="hljs-string">""</span>});

  <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { name, value } = event.target;
    setFormData(<span class="hljs-function">(<span class="hljs-params">prevFormData</span>) =&gt;</span> ({ ...prevFormData, [name]: value }));
  };

  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
    event.preventDefault();
    alert(<span class="hljs-string">`Name: <span class="hljs-subst">${formData.name}</span>, Email: <span class="hljs-subst">${formData.email}</span>, Message: <span class="hljs-subst">${formData.message}</span>`</span>
    );
};

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"name"</span>&gt;</span>Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{formData.name}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}/</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{formData.email}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}/</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"message"</span>&gt;</span>Message:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{formData.message}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}/</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}
</code></pre>
<p><img src="https://i.imgur.com/4ln01Wq.gif" width="900" height="450" alt="4ln01Wq" loading="lazy"></p>
<p>In the example code:</p>
<p>The <code>useState</code> hook defines a state object named <code>formData</code> that contains three properties: <code>name</code>, <code>email</code>, and <code>message</code>, each initialized to an empty string.</p>
<p>The <code>handleChange</code> function is called whenever a user types in one of the form fields. It extracts the <code>name</code> and <code>value</code> of the form field that has changed using the <code>event.target</code> object and then updates the <code>formData</code> state variable using the <code>setFormData</code> function.</p>
<p>The <code>setFormData</code> function uses the spread operator (<code>...</code>) to copy the previous <code>formData</code> object. Then it updates the value of the changed form field by setting its value prop with the new value.</p>
<p>By using an object to manage form data, we can easily keep track of the values of multiple form elements. This makes it easier to manage and manipulate the state of our form data, especially when dealing with complex forms with many form elements.</p>
<h3 id="heading-how-to-validate-form-input">How to validate form input</h3>
<p>Validating forms refers to the process of checking user input data to ensure that it meets specific criteria or requirements before it is submitted to a server or used in some other way.</p>
<p>Form validation can take various forms, depending on the type and complexity of the data being collected. Common types of form validation include:</p>
<ul>
<li>Required field validation: Checking that required fields are not left empty.</li>
<li>Format validation: Ensuring that input data is in the correct format (for example, email addresses, phone numbers, and so on).</li>
<li>Length validation: Checking that input data is within a certain length range.</li>
<li>Pattern validation: Checking that input data matches a specific pattern.</li>
</ul>
<p>Common methods for form validation include using built-in HTML validation attributes like <code>required</code>, <code>minlength</code>, and <code>maxlength</code>, as well as using React to perform custom validation logic.</p>
<p>As an example, suppose we have a form with an input field that requires a minimum of 5 characters. We can use state to track the value of the input field and display an error message if the length of the value is less than 5.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [inputValue, setInputValue] = useState(<span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> [inputError, setInputError] = useState(<span class="hljs-literal">null</span>);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleInputChange</span>(<span class="hljs-params">event</span>) </span>{
    <span class="hljs-keyword">const</span> value = event.target.value;
    setInputValue(value);

    <span class="hljs-keyword">if</span> (value.length &lt; <span class="hljs-number">5</span>) {
      setInputError(<span class="hljs-string">'Input must be at least 5 characters'</span>);
    } <span class="hljs-keyword">else</span> {
      setInputError(<span class="hljs-literal">null</span>);
    }
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault();
    <span class="hljs-keyword">if</span> (inputValue.length &gt;= <span class="hljs-number">5</span>) {
      <span class="hljs-comment">// submit form</span>
    } <span class="hljs-keyword">else</span> {
      setInputError(<span class="hljs-string">'Input must be at least 5 characters'</span>);
    }
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
        Fruit:
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{inputValue}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleInputChange}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      {inputError &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">color:</span> '<span class="hljs-attr">red</span>' }}&gt;</span>{inputError}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>}
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}
</code></pre>
<p><img src="https://i.imgur.com/Dfm7dtp.gif" width="700" height="300" alt="Dfm7dtp" loading="lazy"></p>
<p>In this example, we have a simple form that allows the user to input a fruit name. The form has two states:</p>
<ul>
<li><code>inputValue</code>: Represents the current value of the input field</li>
<li><code>inputError</code>: Represents any errors that may arise during form validation.</li>
</ul>
<p>The <code>handleInputChange</code> function is called every time a user types a character in the input field. It updates the <code>inputValue</code> state to reflect the current value of the input field, and then checks whether the value is at least 5 characters long.</p>
<p>If the value is less than 5 characters, it sets the <code>inputError</code> state to the appropriate error message. Otherwise, it sets the <code>inputError</code> state to <code>null</code> (indicating that there are no errors).</p>
<h2 id="heading-uncontrolled-components-in-react">Uncontrolled Components in React</h2>
<p>Uncontrolled components in React refer to form elements whose state is not managed by React. Instead, their state is handled by the browser's DOM.</p>
<p>For instance, let's say you have a form that consists of a text input field, a select box, and a checkbox. In a controlled component, you would create a state for each form element and write event handlers to update the state whenever the user interacts with any of the form elements.</p>
<p>In contrast, an uncontrolled component allows the browser to handle the form elements' state. When a user enters text into a text input field or selects an option from a select box, the browser updates the DOM's state for that element automatically.</p>
<p>To get the value of an uncontrolled form element, you can use a feature called "ref". "Refs" provide a way to access the current value of DOM elements. You can create a "ref" using the <code>useRef</code> hook, then attach it to the form element you want to access. This allows you to retrieve the current value of an element at any time, without needing to manage its state in your React component.</p>
<p>Here's an example of an uncontrolled component:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Uncontrolled</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> selectRef = useRef(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> checkboxRef = useRef(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> inputRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleSubmit</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault();
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Input value:"</span>, inputRef.current.value);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Select value:"</span>, selectRef.current.value);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Checkbox value:"</span>, checkboxRef.current.checked);
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Name:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{inputRef}</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Favorite color:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{selectRef}</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"red"</span>&gt;</span>Red<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"green"</span>&gt;</span>Green<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"blue"</span>&gt;</span>Blue<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
        Do you like React?
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{checkboxRef}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}
</code></pre>
<p><img src="https://i.imgur.com/4zXvzMm.gif" width="900" height="400" alt="4zXvzMm" loading="lazy"></p>
<p>In this example:</p>
<p>We have a form that contains a text input field, a select box, and a checkbox. Instead of creating state for each form element and writing event handlers to update the state, we're using uncontrolled components. This means that the browser is responsible for managing the state of the form elements.</p>
<p>When a user interacts with a form element, the browser automatically updates the DOM's state for that element. And to retrieve the current values of each form element, we're using the <code>useRef</code> hook.</p>
<p>Uncontrolled components can be useful in certain situations, such as when you need to integrate with third-party libraries or when you don't need to manipulate the form data.</p>
<p>Overall, uncontrolled components are a simpler approach to working with forms in React, and they can make your code more concise and easier to read. But it's important to note that using <code>ref</code> to access form element values can make your code harder to test and maintain, so use them judiciously.</p>
<h2 id="heading-how-to-use-react-component-libraries">How to Use React Component Libraries</h2>
<p>Creating forms in React can be overwhelming, especially if you're new to the framework. You need to manage form state, handle user input, validate input data and more.</p>
<p>But the good news is that there are third-party libraries available to make everything easier for you.</p>
<p>These libraries can help simplify your form creation process. They provide a wide range of features including form validation, input masking, submission handling, error handling, and more. This makes it much easier to create forms that are both user-friendly and functional.</p>
<p>Some popular form libraries include:</p>
<ul>
<li>Formik</li>
<li>Redux Form</li>
<li>React Hook Form</li>
<li>Yup.</li>
</ul>
<p>In this section, we'll focus on learning how to use the <strong>React Hook Form</strong> library.</p>
<h3 id="heading-how-to-use-react-hook-form">How to use React Hook Form</h3>
<p>React Hook Form is a lightweight library for managing forms in React applications. Whether you need to create a simple contact form or a complex multi-step form, React Hook Form can help simplify your form creation process.</p>
<h4 id="heading-installation">Installation</h4>
<p>Getting started with React Hook Form is straightforward and requires only a few steps. First, you'll need to install the library in your project. You can do this using <code>npm</code> by running the following command:</p>
<pre><code class="lang-npm">npm install react-hook-form
</code></pre>
<p>Alternatively, you can use yarn to install React Hook Form:</p>
<pre><code class="lang-yarn">yarn add react-hook-form
</code></pre>
<p>Once you've installed the library, you need to import the <code>useForm</code> hook from the <code>react-hook-form</code> package in your component.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span>  { useForm }  <span class="hljs-keyword">from</span>  <span class="hljs-string">"react-hook-form"</span>;
</code></pre>
<p>By importing the <code>useForm</code> hook, you can start using React Hook Form to manage forms in your application.</p>
<p>The <code>useForm</code> hook provides several functions and properties that you can use to manage your form:</p>
<ul>
<li><code>register</code>: This function is used to register form fields with React Hook Form.</li>
<li><code>handleSubmit</code>: This is used to handle form submissions. It takes a callback function that is called when the form is submitted.</li>
<li><code>errors</code>: This represents an object containing any validation errors that occur when a form is submitted.</li>
<li><code>watch</code>: This function is used to watch for changes to specific form fields. It takes an array of form field names and returns the current value of those fields.</li>
</ul>
<p>These are just a few examples of the functions and properties the useForm hook provides. You can find the complete list of functions and properties in the React Hook Form <a target="_blank" href="https://www.react-hook-form.com/api/useform/">documentation</a>.</p>
<h4 id="heading-how-to-set-up-the-form">How to set up the form</h4>
<p>After importing the <code>useForm</code> hook, you can invoke it to get access to the functions and properties that it provides:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> { register, handleSubmit, <span class="hljs-attr">formState</span>:{errors} } = useForm();
</code></pre>
<p>In the above code, we're using destructuring to extract the <code>register</code>, <code>handleSubmit</code>, and <code>errors</code> properties from the <code>useForm</code> hook.</p>
<h4 id="heading-how-to-register-form-fields">How to register form fields</h4>
<p>The next step is to register form fields using the <code>register</code> function. The <code>register</code> function takes two parameters:</p>
<ul>
<li><code>name</code>: The name of the form field.</li>
<li><code>validationOptions</code>: An optional object containing validation rules you can apply to a form field.</li>
</ul>
<p>Here's an example of registering an input field and adding a validation rule that it is a required field.</p>
<pre><code class="lang-jsx">&lt;input name=<span class="hljs-string">"firstName"</span> {...register(<span class="hljs-string">"firstName"</span>, { <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span> })} /&gt;
</code></pre>
<h4 id="heading-how-to-handle-form-submission">How to handle form submission</h4>
<p>To handle form submission, you can use the <code>handleSubmit</code> function.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> onSubmit = <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(data);

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit(onSubmit)}</span>&gt;</span>
  // form fields
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</code></pre>
<p>In this example, we pass the <code>onSubmit</code> function to the <code>handleSubmit</code> function. The <code>onSubmit</code> function will be called when the form is submitted and will receive an object containing the values of each form field.</p>
<h4 id="heading-how-to-display-validation-errors">How to display validation errors</h4>
<p>You can use the <code>errors</code> object to display any validation errors.</p>
<pre><code class="lang-jsx">&lt;input {...register(<span class="hljs-string">"firstName"</span>, { <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span> })} /&gt;
{errors.firstName &amp;&amp; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This field is required<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>}
</code></pre>
<p>In the above code, we're using the <code>errors</code> object to display a validation error message if the <code>firstName</code> field is not filled out. We can also display error messages for other validation rules, such as minimum and maximum lengths, regular expressions, and more.</p>
<h4 id="heading-how-to-put-it-all-together">How to put it all together</h4>
<p>With a basic understanding of React Hook Form, let's now put everything into practice and create a simple form with two fields: <code>email</code> and <code>password</code>. We'll require both fields to be filled out and validate the email field using a regular expression.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useForm } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-hook-form'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">LoginForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { register, handleSubmit, <span class="hljs-attr">formState</span>: { errors } } = useForm();

  <span class="hljs-keyword">const</span> onSubmit = <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(data);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit(onSubmit)}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Email<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> {<span class="hljs-attr">...register</span>("<span class="hljs-attr">email</span>", { <span class="hljs-attr">required:</span> <span class="hljs-attr">true</span>, <span class="hljs-attr">pattern:</span> /^\<span class="hljs-attr">S</span>+@\<span class="hljs-attr">S</span>+$/<span class="hljs-attr">i</span> })} /&gt;</span>
      {errors.email &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Email is required and must be valid<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}

      <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Password<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> {<span class="hljs-attr">...register</span>("<span class="hljs-attr">password</span>", { <span class="hljs-attr">required:</span> <span class="hljs-attr">true</span> })} /&gt;</span>
      {errors.password &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Password is required<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}

      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> LoginForm;
</code></pre>
<p><img src="https://i.imgur.com/zDd8ZDK.gif" width="900" height="450" alt="zDd8ZDK" loading="lazy"></p>
<p>In this section, we've covered the basics of how to use React Hook Form:</p>
<ul>
<li>To register form fields</li>
<li>Handle form submissions</li>
<li>Display validation errors</li>
</ul>
<p>But this is just the tip of the iceberg. React Hook Form offers many more features and capabilities that we haven't covered here. So I highly recommend that you check out the React Hook Form <a target="_blank" href="https://react-hook-form.com/get-started/">documentation</a> to learn more about how to use it effectively in your projects.</p>
<h2 id="heading-recap">Recap</h2>
<p>In this tutorial, we covered the basics of building forms in React. We learned that there are two common approaches to building forms in React: controlled and uncontrolled components.</p>
<p>Controlled components rely on state management to track the state of form inputs, while uncontrolled components use <code>refs</code> to access the form inputs and their values.</p>
<p>We also learned that using third-party libraries make form creation in React much easier. Libraries like React Hook Form provide a lot of functionality out of the box and can help reduce the amount of boilerplate code you need to build forms in React.</p>
<p>With these concepts in mind, you should be able to build complex forms in React that are easy to manage and provide a great user experience.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>If you want access to all the code used in this article, including the styling, I have compiled it all in a single <a target="_blank" href="https://github.com/dboatengg/react-forms">repository</a> for your convenience. Head over to the repository and you will find everything you need.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Submit a Form with JavaScript – JS Submit Button Example ]]>
                </title>
                <description>
                    <![CDATA[ When building applications and websites on the internet, you’ll sometimes need your users to supply information by filling out a form. But then you might wonder – how do you get this data from the form? Well, you can do this with JavaScript. In this ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-submit-a-form-with-javascript/</link>
                <guid isPermaLink="false">66d45fb3f855545810e93487</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Joel Olawanle ]]>
                </dc:creator>
                <pubDate>Fri, 20 Jan 2023 22:01:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/cover-template--10-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When building applications and websites on the internet, you’ll sometimes need your users to supply information by filling out a form.</p>
<p>But then you might wonder – how do you get this data from the form? Well, you can do this with JavaScript.</p>
<p>In this article, you will learn how to create a form and get data from it when the form is submitted with JavaScript.</p>
<p>This article won't cover how to input data into a database – it will only cover how to submit a form. But you should know that once you have this data, you can send it to the database of your choice, use it to manipulate information, and much more.</p>
<p>To submit a form using JavaScript, you must first create the form and add distinctive, specific attributes to the input fields. You will use these attributes to retrieve the data when the user submits and then calls a function to handle validations (possibly if any data is submitted).</p>
<h2 id="heading-how-to-create-the-html-form">How to Create the HTML Form</h2>
<p>To get started, let's create a basic HTML form with two fields: username and password. We'll also add a button that will be used to submit the form and trigger a JavaScript action.</p>
<pre><code class="lang-js">&lt;form action=<span class="hljs-string">""</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your Username..."</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your Password..."</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</code></pre>
<p>To get this form’s data via JavaScript, you’ll need to attach specific attributes to the form input field and the form itself. These attributes can be an <code>id</code>, a <code>class</code>, or even with the <code>name</code> tag. This will help get the data in JavaScript using their document methods.</p>
<p>For example, if you use an <code>id</code> attribute on your input field, you can access the input field data and other values using the document method <code>getElementByID('idName')</code>:</p>
<pre><code class="lang-js"><span class="hljs-comment">// HTML</span>
&lt;input type=<span class="hljs-string">"text"</span> id=<span class="hljs-string">"username"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-control"</span> placeholder=<span class="hljs-string">"Enter your Username..."</span>&gt;

<span class="hljs-comment">// JS</span>
<span class="hljs-keyword">let</span> myUsername = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'username'</span>);
<span class="hljs-built_in">console</span>.log(myUsername);
</code></pre>
<p>If you use a <code>class</code> attribute, you'll use <code>getElementsByClassName(className)</code>, which returns an array of all elements with the <code>className</code>. If it is only one element, you can use the index number <code>0</code> to access its data:</p>
<pre><code class="lang-js"><span class="hljs-comment">// HTML</span>
&lt;input type=<span class="hljs-string">"text"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"username"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-control"</span> placeholder=<span class="hljs-string">"Enter your Username..."</span>&gt;

<span class="hljs-comment">// JS</span>
<span class="hljs-keyword">let</span> myUsername = <span class="hljs-built_in">document</span>.getElementsByClassName(<span class="hljs-string">'username'</span>);
<span class="hljs-built_in">console</span>.log(myUsername[<span class="hljs-number">0</span>]);
</code></pre>
<p>If you use the <code>name</code> attribute, you'll use <code>getElementsByName(name)</code>. This is similar to how the class attribute works since it also returns an array which you can loop through or access with its index number:</p>
<pre><code class="lang-js"><span class="hljs-comment">// HTML</span>
&lt;input type=<span class="hljs-string">"text"</span> name=<span class="hljs-string">"username"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"form-control"</span> placeholder=<span class="hljs-string">"Enter your Username..."</span>&gt;

<span class="hljs-comment">// JS</span>
<span class="hljs-keyword">let</span> myUsername = <span class="hljs-built_in">document</span>.getElementsByName(<span class="hljs-string">'username'</span>);
<span class="hljs-built_in">console</span>.log(myUsername[<span class="hljs-number">0</span>]);
</code></pre>
<blockquote>
<p>Note: This will not return the input value but the input element itself.</p>
</blockquote>
<h2 id="heading-how-to-submit-a-form-with-javascript">How to Submit a Form with JavaScript</h2>
<p>The first step is to attach your preferred attribute to the form, which you can use to track when the form is submitted. This can be an <code>id</code>, <code>class</code> or <code>name</code> attribute, but for this article, I will use <code>id</code> for the form and input fields:</p>
<pre><code class="lang-js">&lt;form action=<span class="hljs-string">""</span> id=<span class="hljs-string">"loginForm"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your Username..."</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your Password..."</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
</code></pre>
<p>At this point, you can now handle form submission with JavaScript. You first get the form with your preferred attribute, which can be an id, and store it in a variable:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> loginForm = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"loginForm"</span>);
</code></pre>
<p>Then you can attach the <code>addEventListener</code> to the form variable and listen for a submit event. This event listener allows you to attach a callback function which gets triggered once the form is submitted:</p>
<pre><code class="lang-js">loginForm.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  e.preventDefault();

  <span class="hljs-comment">// handle submit</span>
});
</code></pre>
<p>At this point, you can now get the form data and handle any operation you wish. For this article, let’s first validate the data by checking if the input is empty before performing any operation:</p>
<pre><code class="lang-js">loginForm.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  e.preventDefault();

  <span class="hljs-keyword">let</span> username = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"username"</span>);
  <span class="hljs-keyword">let</span> password = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"password"</span>);

  <span class="hljs-keyword">if</span> (username.value == <span class="hljs-string">""</span> || password.value == <span class="hljs-string">""</span>) {
    <span class="hljs-comment">// throw error</span>
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// perform operation with form input</span>
  }
});
</code></pre>
<p>This is the entire JavaScript code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> loginForm = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"loginForm"</span>);

loginForm.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  e.preventDefault();

  <span class="hljs-keyword">let</span> username = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"username"</span>);
  <span class="hljs-keyword">let</span> password = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"password"</span>);

  <span class="hljs-keyword">if</span> (username.value == <span class="hljs-string">""</span> || password.value == <span class="hljs-string">""</span>) {
    alert(<span class="hljs-string">"Ensure you input a value in both fields!"</span>);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// perform operation with form input</span>
    alert(<span class="hljs-string">"This form has been successfully submitted!"</span>);
    <span class="hljs-built_in">console</span>.log(
      <span class="hljs-string">`This form has a username of <span class="hljs-subst">${username.value}</span> and password of <span class="hljs-subst">${password.value}</span>`</span>
    );

    username.value = <span class="hljs-string">""</span>;
    password.value = <span class="hljs-string">""</span>;
  }
});
</code></pre>
<p>See the Pen <a target="_blank" href="https://codepen.io/olawanlejoel/pen/xxzvdqQ">Form Submission JS</a> by Olawanle Joel (<a target="_blank" href="https://codepen.io/olawanlejoel">@olawanlejoel</a>) on <a target="_blank" href="https://codepen.io">CodePen</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you have learned how to submit a form with JavaScript and how it works with the various DOM methods.</p>
<p>There are other ways you can do this, but this is a straightforward way to handle submission in JavaScript.</p>
<p>You can access over 150 of my articles by <a target="_blank" href="https://joelolawanle.com/contents">visiting my website</a>. You can also use the search field to see if I've written a specific article.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Great HTML Form Controls ]]>
                </title>
                <description>
                    <![CDATA[ By Austin Gil Today I'm going to show you all the things to consider when building the perfect HTML input. Despite its seemingly simple nature, there's actually a lot that goes into it. How to Make the Control Well, we need to start somewhere. Might ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/perfect-html-input/</link>
                <guid isPermaLink="false">66d45d9ccc7f04d2549a372c</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 05 Jan 2023 17:43:37 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/HTML-Blog-Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Austin Gil</p>
<p>Today I'm going to show you all the things to consider when building the perfect HTML input. Despite its seemingly simple nature, there's actually a lot that goes into it.</p>
<h2 id="heading-how-to-make-the-control">How to Make the Control</h2>
<p>Well, we need to start somewhere. Might as well start with the control itself.</p>
<p>HTML offers three different form controls to choose from: <code>[&lt;input&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input)</code>, <code>[&lt;textarea&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)</code>, and <code>[&lt;select&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select)</code>. Today, we'll use <code>&lt;input&gt;</code>, but the same rules will apply to the others.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> /&gt;</span>
</code></pre>
<h2 id="heading-how-to-make-work">How to Make <code>&lt;input&gt;</code> Work</h2>
<p>Inputs are generally used to capture user data. To do so, they should be placed within a  <code>[&lt;form&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form)</code>  element, but that's not quite enough. When the form is submitted, it won't know how to label the input's data.</p>
<p>For a form to include an input's data when the form is submitted, the input needs a <code>[name](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#name)</code> attribute. You don't need state management or data binding. Just a <code>name</code>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"data"</span> /&gt;</span>
</code></pre>
<h2 id="heading-how-to-make-the-input-accessible">How to Make the Input Accessible</h2>
<p>Now that we've made the robots happy, it's time to focus on the humans.</p>
<p>Every input also needs a label, both for clarity and for accessibility. There are a few options:</p>
<ul>
<li>Add a <code>[&lt;label&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label)</code> element with a <code>[for](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label#attr-for)</code> attribute and assign it to the input's <code>[id](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)</code> (explicit label).</li>
<li>Wrap the input with a <code>&lt;label&gt;</code> element (implicit label).</li>
<li>Add an <code>[aria-label](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label)</code> attribute to the input.</li>
<li>Add an <code>[aria-labeledby](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-labelledby)</code> attribute to the input and assign it to the <code>id</code> of another element.</li>
</ul>
<p>Of all these options, the most reliable is an explicit label as it works across the most browsers, assistive technologies, and voice-control interfaces. Implicit labels do not work in Dragon Speech Recognition. ARIA attributes are finicky. </p>
<p>The <code>[placeholder](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#placeholder)</code> and <code>[title](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title)</code> attributes are not proper labels.</p>
<p>I recommend not wrapping everything in a <code>&lt;label&gt;</code> tag because:</p>
<ol>
<li>It's prone to include more content than what would be considered the label. This results in a poor experience for screen-reader users.</li>
<li>It's common to add styles to the input's wrapper element. These styles may conflict with the default behavior of a <code>&lt;label&gt;</code>.</li>
</ol>
<p>In general, I prefer using a <code>[&lt;div&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)</code> to isolate the control.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"input-id"</span>&gt;</span>Label<span class="hljs-tag">&lt;/<span class="hljs-name">input</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"input-id"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"data"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>If you ever want an input that does not show the label, don't remove the label from the HTML. Instead, hide it with CSS or use a less reliable option. Keep the label in the markup and visually hide it with a <code>class</code> with these styles. These styles keep it accessible to assistive technology, while also visually removing it:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.visually-hidden</span> {
  <span class="hljs-attribute">position</span>: absolute;
  <span class="hljs-attribute">overflow</span>: hidden;
  <span class="hljs-attribute">clip</span>: <span class="hljs-built_in">rect</span>(<span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span>);
  <span class="hljs-attribute">width</span>: <span class="hljs-number">1px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">1px</span>;
  <span class="hljs-attribute">margin</span>: -<span class="hljs-number">1px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
}
</code></pre>
<p>Note that it's still generally advised to include a visible label to avoid any confusion. A <code>placeholder</code> should not serve as a label.</p>
<h2 id="heading-how-to-choose-a-type-or-not">How to Choose a Type (or Not)</h2>
<p>In addition to the different tags listed above, you can change the control's behavior by setting an input's <code>[type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types)</code> attribute. For example, if you wanted to accept a user's email, you can set the <code>type</code> attribute to "email". </p>
<p>Input types can change the behavior or appearance of the UI. Here are just a few examples:</p>
<ul>
<li>The "<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number">number</a>" type changes behavior by preventing non-number value entries.</li>
<li>The "<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color">color</a>" type changes the UI by adding a button that opens a color picker.</li>
<li>The "<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date">date</a>" type improves the data entry experience by offering a date-picker.</li>
<li>The "<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email">email</a>" type enforces built-in constraint validation on form submission. </li>
</ul>
<p>However, some input types may be <a target="_blank" href="https://en.wikipedia.org/wiki/False_friend">false friends</a>.</p>
<p>Consider an input that asks for a US zip code. Only numerical entries are valid, so it might make sense to use a "number" <code>type</code>. However, one issue with the "number" input is that it adds a scroll event feature such that a user can scroll up on the input to increment the value or down to decrement it.</p>
<p>For a zip code input, it's possible that a user clicks on the input, enters their zip code, then tries to scroll down the page. This would decrement the value they entered, and it's very easy for the user to miss that change. As a result, the number they entered could be wrong.</p>
<p>In this case, it may be better to avoid the <code>type</code> attribute completely and use a <code>[pattern](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#pattern)</code> such as <code>[0-9]*</code> if you want to limit the input to only numeric values. In fact, the "number" type is <a target="_blank" href="https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/">often more problematic than it's worth</a>.</p>
<h2 id="heading-be-descriptive">Be Descriptive</h2>
<p>Since we've briefly touched on constraint validation, it's a good time to mention descriptions. </p>
<p>Although HTML has built-in validation attributes and there are several more robust JavaScript validation libraries, there is another effective approach to getting users to fill in proper data that can be less annoying.</p>
<p>Tell them exactly what it is you want.</p>
<p>Some form controls like "name" or "email" may be obvious, but for those that are not, provide a clear description for what you need. </p>
<p>For example, if you are asking users to create a new password, tell them what the requirements are <strong>before</strong> they try to submit the form. And don't forget about assistive technology users.</p>
<p>We can associate an input with a description through visual proximity as well as using the <code>[aria-describedby](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby)</code> attribute.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"password"</span>&gt;</span>Password<span class="hljs-tag">&lt;/<span class="hljs-name">input</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">aria-describedby</span>=<span class="hljs-string">"password-requirements"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"password-requirements"</span>&gt;</span>Please create a new password. Must contain at least 8 characters, one uppercase letter, one lowercase letter, and one special character.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Descriptions are also an effective place to put any validation feedback messages.</p>
<h2 id="heading-be-flexible">Be Flexible</h2>
<p>When creating inputs, it's often tempting to add constraints for the acceptable values to ensure the user only sends good data. But being too strict can lead to a poor user experience.</p>
<p>For example, if you ask the user to enter a phone number, consider that there are several different acceptable formats:</p>
<ul>
<li>8008675309</li>
<li>800 867 5309</li>
<li>800-867-5309</li>
<li>800.867.5309</li>
<li>(800) 867-5309</li>
<li>+1 (800) 867-5309</li>
<li>001 800 867 5309</li>
</ul>
<p>All of the above represent the same phone number. Ideally, a user would be able to enter any of these formats and still be able to submit the form without issue.</p>
<p>If you want your input to only send number characters, it's possible to allow the user to type in whatever format they want. Then you can use JavaScript to add an event handler to the <code>blur</code> event, and remove any unwanted characters (space, dash, period, and so on) from the input's value. This would leave only the numbers.</p>
<h2 id="heading-make-it-easy">Make it Easy</h2>
<p>If you've ever filled out a form using a mobile device, you may have noticed that your phone's keyboard looks different on different inputs. </p>
<p>For a basic text input you see the standard keyboard, for email inputs you may see the @ symbol more conveniently placed, and for number inputs you may see the keyboard replaced with a number pad.</p>
<p>In many cases, the browser will choose a more appropriate keyboard to show users if the input <code>type</code> is set. But as we saw above, it's often better to use just a basic text input.</p>
<p>We can still offer a nicer user experience to mobile users by asking the browser to show specific keyboards despite the input missing a <code>type</code> attribute. We can accomplish this with the <code>[inputmode](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#inputmode)</code> attribute which accepts eight different options.</p>
<ul>
<li>text (default value)</li>
<li>none</li>
<li>decimal</li>
<li>numeric</li>
<li>tel</li>
<li>search</li>
<li>email</li>
<li>url</li>
</ul>
<p>Want to give it a try? Head over to <a target="_blank" href="https://inputmodes.com/">inputmodes.com</a> on your mobile device. It's pretty cool.</p>
<h2 id="heading-continue-learning">Continue Learning</h2>
<p>That's over a thousand words I had to say about creating form controls. I hope you found it useful. </p>
<p>If you would like to continue learning, I wrote a five-part series on how to build better HTML forms:</p>
<ul>
<li><a target="_blank" href="https://austingil.com/how-to-build-html-forms-right-semantics/">Part 1: Semantics</a></li>
<li><a target="_blank" href="https://austingil.com/how-to-build-html-forms-right-accessibility/">Part 2: Accessibility</a></li>
<li><a target="_blank" href="https://austingil.com/build-html-forms-right-styling/">Part 3: Custom Styles</a></li>
<li><a target="_blank" href="https://austingil.com/build-html-forms-right-user-experience/">Part 4: User Experience</a></li>
<li><a target="_blank" href="https://austingil.com/how-to-build-html-forms-right-security/">Part 5: Security</a></li>
</ul>
<p>If you liked this article, please <a target="_blank" href="https://twitter.com/share?via=heyAustinGil">share it</a>. It's one of the best ways to support me. You can also <a target="_blank" href="https://austingil.com/newsletter/">sign up for my newsletter</a> or <a target="_blank" href="https://twitter.com/heyAustinGil">follow me on Twitter</a> if you want to know when new articles are published.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build an OTP Input in Vue 3 ]]>
                </title>
                <description>
                    <![CDATA[ By Paul Akinyemi OTP inputs are one of the most fun components you can use in your app. They make the dry process of filling in yet another form a little more engaging. In this article, you’ll learn how to build an OTP input from scratch in Vue 3. By... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-otp-input-vue-3/</link>
                <guid isPermaLink="false">66d4608db6b7f664236cbe2d</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vue ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 24 Aug 2022 15:00:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/otp-article-header.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Paul Akinyemi</p>
<p>OTP inputs are one of the most fun components you can use in your app. They make the dry process of filling in yet another form a little more engaging.</p>
<p>In this article, you’ll learn how to build an OTP input from scratch in Vue 3. By the end of the tutorial, you'll have built an OTP input that looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/finished-otp-demo.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here’s an overview of the steps the tutorial will follow:</p>
<ul>
<li>Project setup</li>
<li>Building the Basics</li>
<li>Adding functionality</li>
<li>Finishing touches</li>
<li>Conclusion</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To easily follow along with this tutorial, you should have the following:</p>
<ul>
<li>A basic understanding of Vue 3 and vanilla JavaScript</li>
<li>Node.js 16+ installed on your machine</li>
<li>A basic knowledge of CSS</li>
</ul>
<h2 id="heading-whats-an-otp-input">What's an OTP Input?</h2>
<p>In case you aren't familiar with the term, an OTP input is a form component for strings. Each character in the string is typed into a separate box, and the component switches between boxes as you type (as opposed to you needing to click into each box). </p>
<p>It's called an OTP input because they're usually used to let users type in an OTP (One Time Password) that they've received via some other channel, usually email or SMS.</p>
<h2 id="heading-project-setup">Project Setup</h2>
<p>This project won't use any external libraries, so all the setup you need is to create a Vue application with <a target="_blank" href="https://vitejs.dev/">Vite</a>.</p>
<p>Create the Vue project by running the following in a terminal window:</p>
<pre><code class="lang-sh">npm init vue@3
</code></pre>
<p>If you haven’t installed <code>create-vue</code> on your device, this command will install it. Next, it will present a series of options to you. The options let you specify the project name and select which add-ons you want to include. </p>
<p>Call the project <code>otp-input</code> and don't select any add-ons, as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/otp-input-install.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>After you’ve done that, run:</p>
<pre><code class="lang-sh"><span class="hljs-built_in">cd</span> otp-input
npm install
npm run dev
</code></pre>
<p>After the dev server starts up, you should see something like this in your terminal:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/otp-input-finish-setup.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Open the URL Vite gives you in your browser, and let’s get to the fun stuff.</p>
<h2 id="heading-how-to-build-the-basics">How to Build the Basics</h2>
<p>If you open the <code>otp-input</code> folder in your editor, it should have a file structure like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-121.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You’re going to adjust this setup to something more suitable. Start by opening <code>src/App.vue</code> and replacing its contents with this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">setup</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p>Next, select all the files inside <code>src/components</code> and delete them, and create a file inside components called <code>OTP.vue</code>. On Linux/Mac devices, you can do that by running the following in a new terminal window:</p>
<pre><code class="lang-sh">rm -rfv src/components
mkdir src/components
touch src/components/OTP.vue
</code></pre>
<p>Then, delete the <code>src/assets</code> folder, and remove the following line from <code>src/main.js</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./assets/main.css'</span>
</code></pre>
<p>Next, open <code>components/OTP.vue</code>, and put the starting template for your OTP into it:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"otpCont"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
      <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
      <span class="hljs-attr">class</span>=<span class="hljs-string">"digit-box"</span>
      <span class="hljs-attr">v-for</span>=<span class="hljs-string">"(el, ind) in digits"</span>
      <span class="hljs-attr">:key</span>=<span class="hljs-string">"el+ind"</span>
      <span class="hljs-attr">v-model</span>=<span class="hljs-string">"digits[ind]"</span>
      <span class="hljs-attr">:autofocus</span>=<span class="hljs-string">"ind === 0"</span>
      <span class="hljs-attr">:placeholder</span>=<span class="hljs-string">"ind+1"</span>
      <span class="hljs-attr">maxlength</span>=<span class="hljs-string">"1"</span>
    &gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
</code></pre>
<p>Let’s explain this.</p>
<p>The template starts with a container div that you've attached a ref to called <code>otpCont</code>. Inside the container, you have a text input with a <code>v-for</code> on it. The <code>v-for</code> will render one input for each element of a collection we called <code>digits</code>, and attach a two-way binding with the element of <code>digits</code> that shares its index. </p>
<p>The first rendered input will have the <code>autofocus</code> attribute, the placeholder for each input is its index plus one, and each input has a maximum length of one character.</p>
<p>Next is the script for the component. Place the following code into <code>OTP.vue</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">setup</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">import</span> { ref, reactive } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>;

  <span class="hljs-keyword">const</span> props = defineProps({
    <span class="hljs-attr">default</span>: <span class="hljs-built_in">String</span>,

    <span class="hljs-attr">digitCount</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">Number</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>
    }
  });

  <span class="hljs-keyword">const</span> digits = reactive([])

  <span class="hljs-keyword">if</span> (props.default &amp;&amp; props.default.length === props.digitCount) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i =<span class="hljs-number">0</span>; i &lt; props.digitCount; i++) {
      digits[i] = props.default.charAt(i)
    }
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i =<span class="hljs-number">0</span>; i &lt; props.digitCount; i++) {
      digits[i] = <span class="hljs-literal">null</span>;
    }
  }

  <span class="hljs-keyword">const</span> otpCont = ref(<span class="hljs-literal">null</span>)

</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>After the import, this code defines two props: a required number <code>digitCount</code> that controls the number of inputs, and an optional string <code>default</code>.</p>
<p>Then, it creates the reactive <code>digits</code> array the template needs. If the <code>default</code> prop was provided and its length matches the <code>digitCount</code> prop, <code>digits</code> is initialized using the characters in <code>default</code>. If not the elements of <code>digits</code> are filled with <code>null</code>.</p>
<p>Finally, the code creates the <code>otpCont</code> reference from the template.</p>
<p>The last task for this section is to give the inputs a bit of styling. Put the following at the end of <code>OTP.vue</code>:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>&gt;</span><span class="css">
<span class="hljs-selector-class">.digit-box</span> {
    <span class="hljs-attribute">height</span>: <span class="hljs-number">4rem</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">2rem</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid black;
    <span class="hljs-attribute">display</span>: inline-block;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">5px</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">15px</span>;
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">3rem</span>;
}

<span class="hljs-selector-class">.digit-box</span><span class="hljs-selector-pseudo">:focus</span> {
  <span class="hljs-attribute">outline</span>: <span class="hljs-number">3px</span> solid black;
}

</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p>And that creates the basic form of your OTP.</p>
<p>Next, you’re going to edit the home page of your app to render the input. Replace the contents of  <code>src/App.vue</code> with the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">otp</span> 
    <span class="hljs-attr">:digit-count</span>=<span class="hljs-string">"4"</span>
  &gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">otp</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">setup</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> otp <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/OTP.vue"</span>;
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>If you open the app in the browser, you should see the separate inputs rendered like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/otp-init-form.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-add-functionality">How to Add Functionality</h2>
<p>Right now, you don’t really have an OTP input yet. You need to manually switch focus between fields, and there’s no validation. Next, you’ll write the logic to fix that.</p>
<p>Open <code>components/OTP.vue</code>, and add a keydown event handler to the input tag:</p>
<pre><code class="lang-js"> @keydown=<span class="hljs-string">"handleKeyDown($event, ind)"</span>
</code></pre>
<p>Now, create the <code>handleKeyDown</code> function at the end of the <code>script setup</code> section like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> handleKeyDown = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event, index</span>) </span>{
    <span class="hljs-keyword">if</span> (event.key !== <span class="hljs-string">"Tab"</span> &amp;&amp; 
        event.key !== <span class="hljs-string">"ArrowRight"</span> &amp;&amp;
        event.key !== <span class="hljs-string">"ArrowLeft"</span>
    ) {
      event.preventDefault();
    }

    <span class="hljs-keyword">if</span> (event.key === <span class="hljs-string">"Backspace"</span>) {
      digits[index] = <span class="hljs-literal">null</span>;

      <span class="hljs-keyword">if</span> (index != <span class="hljs-number">0</span>) {
        (otpCont.value.children)[index<span class="hljs-number">-1</span>].focus();
      } 

      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">if</span> ((<span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">'^([0-9])$'</span>)).test(event.key)) {
      digits[index] = event.key;

      <span class="hljs-keyword">if</span> (index != props.digitCount - <span class="hljs-number">1</span>) {
        (otpCont.value.children)[index+<span class="hljs-number">1</span>].focus();
      }
    }
  }
</code></pre>
<p>Let’s break down this function. The event handler is called every time a key is pressed while one of the input fields is in focus.</p>
<p>If the pressed key isn’t tab or one of the horizontal arrow keys, the function will call <code>preventDefault()</code>, and move to the next if block.</p>
<p>If the pressed key was Backspace, the value of the <code>digit</code> array at the index of the target input will be set to null. Then if the target input wasn’t the first input, the code shifts focus to its previous sibling.</p>
<p>The last if block uses a regular expression to test if the pressed key was one of the digits 0 to 9. If it was, <code>digits</code> is updated appropriately, and focus is shifted to the next input.</p>
<p>If you open the app in your browser now, you should see that the OTP input automatically shifts focus between the boxes. Also, it only accepts numbers as input, and you can use the tab key to navigate between boxes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/midway-otp-demo.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-add-the-finishing-touches">Add the Finishing Touches</h2>
<p>The OTP input is now mostly complete, but it feels a little plain. Let’s add a last set of features:</p>
<ul>
<li>The input should emit the OTP value once all fields are filled.</li>
<li>A small bounce animation should trigger when the user enters a value.</li>
</ul>
<p>We’ll start with the logic for emitting the OTP value. First, you'll modify <code>App.vue</code> so it can display the emitted value. Replace the contents of <code>App.vue</code> with the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">otp</span> 
    <span class="hljs-attr">:digit-count</span>=<span class="hljs-string">"4"</span>
    @<span class="hljs-attr">update:otp</span>=<span class="hljs-string">"otpValue = $event"</span>
  &gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">otp</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>The current OTP value is: {{ otpValue }} <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">setup</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> otp <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/OTP.vue"</span>;
<span class="hljs-keyword">import</span> { ref } <span class="hljs-keyword">from</span> <span class="hljs-string">"vue"</span>;

otpValue = ref(<span class="hljs-string">''</span>)
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Not much has changed: you just created a reactive variable called <code>otpValue</code>, told the template to render it, and added an event listener to the OTP component to update <code>otpValue</code>.</p>
<p>Next, open <code>components/OTP.vue</code> and add the following code just before the <code>handleKeyDown</code> function:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> emit = defineEmits([<span class="hljs-string">'update:otp'</span>]);

<span class="hljs-keyword">const</span> isDigitsFull = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> elem <span class="hljs-keyword">of</span> digits) {
    <span class="hljs-keyword">if</span> (elem == <span class="hljs-literal">null</span> || elem == <span class="hljs-literal">undefined</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
  }

  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>This code defines the custom event <code>update:otp</code>, as well as a function <code>isDigitsFull</code> . <code>isDigitsFull</code> returns <code>false</code> if there’s any <code>null</code> value inside <code>digits</code> and <code>true</code> otherwise.</p>
<p>Add the following to <code>handleKeyDown</code> at the end of the last if block:</p>
<pre><code class="lang-js"><span class="hljs-keyword">if</span> (isDigitsFull()) {
  emit(<span class="hljs-string">'update:otp'</span>, digits.join(<span class="hljs-string">''</span>))
}
</code></pre>
<p>Each time a digit is pressed in an input box, this code calls the helper function <code>isDigitsFull</code> to determine if all the input boxes are filled.</p>
<p>If they are, it emits the <code>update:otp</code> event, combines the value of all input boxes to a single string, and sends it as the value of the event.</p>
<p>Your rendered page in the browser should now display the most recent (complete) OTP value:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/otp-semifinished-demo.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Finally, you’ll add animation to your OTP input. Paste the following CSS at the end of the style tag in <code>components/OTP.vue</code>:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.bounce</span> {
  <span class="hljs-attribute">animation</span>: pulse .<span class="hljs-number">3s</span> ease-in-out alternate;
}

<span class="hljs-keyword">@keyframes</span> pulse {
  0% {
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">scale</span>(<span class="hljs-number">1</span>);
  }

  100% {
    <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">scale</span>(<span class="hljs-number">1.1</span>);
  }
}
</code></pre>
<p>And then add the following class binding to the input in the template:</p>
<pre><code class="lang-js">:<span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"{bounce: digits[ind] !== null}"</span>
</code></pre>
<p>And that’s the code for the animation! Here’s how it works:</p>
<ul>
<li>The bounce class for each input is tied to <code>digits[index]</code></li>
<li>If the value of <code>digits[index]</code> <em>changes</em>, the expression is evaluated again</li>
<li>If the new value isn’t null, the bounce class gets applied</li>
<li>If it’s null, the bounce class is removed</li>
<li>If the value doesn’t change, the expression isn’t re-evaluated, so the animation doesn’t trigger.</li>
</ul>
<p>Here’s the final look of your OTP:  </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/finished-otp-demo-1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And you’re done!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned how to build an OTP input from scratch in Vue 3. You can find the source code for this component <a target="_blank" href="https://github.com/Morgenstern2573/otp-input">here</a>. I hope you enjoyed the read!</p>
<p>If you'd like to see more of my writing, you can follow me on <a target="_blank" href="https://twitter.com/apexPaul09">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Dynamic Forms in React ]]>
                </title>
                <description>
                    <![CDATA[ By Nishant Kumar In this tutorial, let's learn how to build dynamic forms in React. Using dynamic forms, we can add fields or remove them depending on our needs.  So, let's get started. How to Create a Form in React Let's create a simple form first. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-dynamic-forms-in-react/</link>
                <guid isPermaLink="false">66d46052246e57ac83a2c7a6</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 09 Feb 2022 18:08:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/02/How-to-Build-a-Weather-Application-using-React--54-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nishant Kumar</p>
<p>In this tutorial, let's learn how to build dynamic forms in React. Using dynamic forms, we can add fields or remove them depending on our needs. </p>
<p>So, let's get started.</p>
<h2 id="heading-how-to-create-a-form-in-react">How to Create a Form in React</h2>
<p>Let's create a simple form first. The syntax is straightforward:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">'name'</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Name'</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">'age'</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Age'</span>
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Here's what it'll look like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screenshot-2022-02-06-171620.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We have two input fields, which are Name and Age. But these fields are static. So, let's made them dynamic using React States.</p>
<h3 id="heading-how-to-make-forms-dynamic-in-react">How to Make Forms Dynamic in React</h3>
<p>Create one state called InputFields. It will have an object, with <strong>name</strong> and <strong>age</strong> properties.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [inputFields, setInputFields] = useState([
    {<span class="hljs-attr">name</span>: <span class="hljs-string">''</span>, <span class="hljs-attr">age</span>: <span class="hljs-string">''</span>}
])
</code></pre>
<p>Now, let's map our form fields from their <strong>inputFields</strong> state.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [inputFields, setInputFields] = useState([
    { <span class="hljs-attr">name</span>: <span class="hljs-string">''</span>, <span class="hljs-attr">age</span>: <span class="hljs-string">''</span> }
  ])
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
        {inputFields.map((input, index) =&gt; {
          return (
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'name'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Name'</span>
              /&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'age'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Age'</span>
              /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          )
        })}
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Now, we will see only one set of input fields, because we have only one object in the <strong>inputFields</strong> state. If we add more objects, we will see multiple input fields.</p>
<h2 id="heading-how-to-add-the-values-from-inputfields-state">How to Add the Values from inputFields State</h2>
<p>Now, let's add the values from the <strong>inputFields</strong> state to the input fields.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [inputFields, setInputFields] = useState([
    { <span class="hljs-attr">name</span>: <span class="hljs-string">''</span>, <span class="hljs-attr">age</span>: <span class="hljs-string">''</span> }
  ])
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
        {inputFields.map((input, index) =&gt; {
          return (
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'name'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Name'</span>
                <span class="hljs-attr">value</span>=<span class="hljs-string">{input.name}</span>
              /&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'age'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Age'</span>
                <span class="hljs-attr">value</span>=<span class="hljs-string">{input.age}</span>
              /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          )
        })}
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>The values will be <strong>input.name</strong> and <strong>input.age.</strong> </p>
<p>Let's also add an onChange event that will run when we type something in the input fields.</p>
<p>Create a function called <strong>handleFormChange</strong>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> handleFormChange = <span class="hljs-function">() =&gt;</span> {

}
</code></pre>
<p>Assign this function to the input fields as an onChange event.</p>
<pre><code class="lang-js">&lt;div key={index}&gt;
              <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'name'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Name'</span>
                <span class="hljs-attr">value</span>=<span class="hljs-string">{input.name}</span>
                <span class="hljs-attr">onChange</span>=<span class="hljs-string">{event</span> =&gt;</span> handleFormChange(index, event)}
              /&gt;</span>
              <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'age'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Age'</span>
                <span class="hljs-attr">value</span>=<span class="hljs-string">{input.age}</span>
                <span class="hljs-attr">onChange</span>=<span class="hljs-string">{event</span> =&gt;</span> handleFormChange(index, event)}
              /&gt;</span>
            &lt;/div&gt;
</code></pre>
<p>This onChange event takes two parameters, <strong>index</strong> and <strong>event</strong>. Index is the index of the array and event is the data we type in the input field. We are passing those to the <strong>handleFormChange</strong> function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> handleFormChange = <span class="hljs-function">(<span class="hljs-params">index, event</span>) =&gt;</span> {

}
</code></pre>
<p>But the thing is, if we try to type something in the input fields, we won't be able to. Because we haven't set the states in the <strong>formFields</strong> state. So, let's do that.</p>
<pre><code class="lang-js"> <span class="hljs-keyword">const</span> handleFormChange = <span class="hljs-function">(<span class="hljs-params">index, event</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> data = [...inputFields];
 }
</code></pre>
<p>Let's store our <strong>inputFields</strong> state into a variable called <strong>data</strong> using the spread operator (the three dots <code>...</code>).</p>
<p>Then, we will target the index of the data variable using the index parameter, and the name of the property, too. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> handleFormChange = <span class="hljs-function">(<span class="hljs-params">index, event</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> data = [...inputFields];
    data[index][event.target.name] = event.target.value;
}
</code></pre>
<p>For example, suppose we are typing in the input field with <strong>index 0</strong>. So, we are specifying the index in data, and the property name, using <strong>event.target.name.</strong> And inside this data index, we are storing the values from input fields using <strong>event.target.value.</strong></p>
<p>Now, we need to store this data back inside the <strong>inputFields</strong> array using the <strong>setInputFields</strong> method.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> handleFormChange = <span class="hljs-function">(<span class="hljs-params">index, event</span>) =&gt;</span> {
   <span class="hljs-keyword">let</span> data = [...inputFields];
   data[index][event.target.name] = event.target.value;
   setInputFields(data);
}
</code></pre>
<p>Now, if we type something in the input fields, it will show up in the input fields.</p>
<h2 id="heading-how-to-add-more-form-fields">How to Add More Form Fields</h2>
<p>Let's create a button to add more form fields. </p>
<pre><code class="lang-js">&lt;button&gt;Add More..&lt;/button&gt;
</code></pre>
<p>And a function, too, that will be triggered when this button is clicked.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> addFields = <span class="hljs-function">() =&gt;</span> {

}
</code></pre>
<p>Let's add the function to the button via an onClick event.</p>
<pre><code class="lang-js">&lt;button onClick={addFields}&gt;Add More..&lt;/button&gt;
</code></pre>
<p>Now, in the addFields function, we need to create an object. And every time we click the button, it will be pushed to the <strong>inputFields</strong> state, thus creating a new input field.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> addFields = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">let</span> newfield = { <span class="hljs-attr">name</span>: <span class="hljs-string">''</span>, <span class="hljs-attr">age</span>: <span class="hljs-string">''</span> }
}
</code></pre>
<p>Then set this newField inside the <strong>inputFields</strong> state.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> addFields = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">let</span> newfield = { <span class="hljs-attr">name</span>: <span class="hljs-string">''</span>, <span class="hljs-attr">age</span>: <span class="hljs-string">''</span> }

    setInputFields([...inputFields, newfield])
}
</code></pre>
<p>Here, we are also setting the existing <strong>inputFields</strong> using the spread operator, in conjunction with the newfield. </p>
<p>If we click the Add Field button now, it will create a new input field.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screenshot-2022-02-06-174542.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-create-a-submit-button">How to Create a Submit Button</h2>
<p>Let's create a Submit button and one function to see our data when we submit the form.</p>
<pre><code class="lang-js">&lt;button&gt;Submit&lt;/button&gt;
</code></pre>
<p>We also need a function that will be triggered when we click this button. It will log the data in the console, from the input fields. It also has a method called <strong>e.preventDefault()</strong> that will prevent the page from getting refreshed.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> submit = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    e.preventDefault();
    <span class="hljs-built_in">console</span>.log(inputFields)
}
</code></pre>
<p>Add this function to the Submit button:</p>
<pre><code class="lang-js">&lt;button onClick={submit}&gt;Submit&lt;/button&gt;
</code></pre>
<p>And also in the form tag:</p>
<pre><code class="lang-js">&lt;form onSubmit={submit}&gt;
</code></pre>
<p>If we submit, we will see our data in the console:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screenshot-2022-02-06-175919.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-remove-the-fields-using-a-remove-button">How to Remove the fields using a Remove Button</h2>
<p>Now let's create a Button for removing these fields if we don't want them.</p>
<pre><code class="lang-js">&lt;form&gt;
        {inputFields.map(<span class="hljs-function">(<span class="hljs-params">input, index</span>) =&gt;</span> {
          <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{index}</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'name'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Name'</span>
                <span class="hljs-attr">value</span>=<span class="hljs-string">{input.name}</span>
                <span class="hljs-attr">onChange</span>=<span class="hljs-string">{event</span> =&gt;</span> handleFormChange(index, event)}
              /&gt;
              <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                <span class="hljs-attr">name</span>=<span class="hljs-string">'age'</span>
                <span class="hljs-attr">placeholder</span>=<span class="hljs-string">'Age'</span>
                <span class="hljs-attr">value</span>=<span class="hljs-string">{input.age}</span>
                <span class="hljs-attr">onChange</span>=<span class="hljs-string">{event</span> =&gt;</span> handleFormChange(index, event)}
              /&gt;
              <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Remove<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
          )
        })}
      &lt;/form&gt;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screenshot-2022-02-06-174720.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We need a function as well.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> removeFields = <span class="hljs-function">() =&gt;</span> {

}
</code></pre>
<p>So, assign this function to the Remove button.</p>
<pre><code class="lang-js">&lt;button onClick={<span class="hljs-function">() =&gt;</span> removeFields(index)}&gt;Remove&lt;/button&gt;
</code></pre>
<p>We are passing the index as a parameter, which is the index of input fields.</p>
<p>Then, receive this index in the function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> removeFields = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {

}
</code></pre>
<p>And just like before, we need to create a new variable and store the <strong>inputFields</strong> state in that new variable.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> removeFields = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> data = [...inputFields];
}
</code></pre>
<p>Then, we need to splice this data variable by the index. Then we need to store it in the <strong>inputFields</strong> state using setInputFields.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> removeFields = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> data = [...inputFields];
    data.splice(index, <span class="hljs-number">1</span>)
    setInputFields(data)
}
</code></pre>
<p>Now, if we click remove, it will remove that form field.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screenshot-2022-02-06-175415.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>So we have five input fields here, with five different names. Let's remove the input of Nishant.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screenshot-2022-02-06-180336.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You see it has been removed. And if we submit, we will see our updated data in the console.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screenshot-2022-02-06-180434.jpeg" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Now you know how to create dynamic forms in React. Congrats!</p>
<p>You can also watch my video on the same topic <a target="_blank" href="https://youtu.be/LcAyJRlvh8Y">Dynamic Forms - How to Add Dynamic Forms in React</a>.</p>
<p>Try out the code here – <a target="_blank" href="https://github.com/nishant-666/Dynamic-Forms">https://github.com/nishant-666/Dynamic-Forms</a>.</p>
<p>Happy learning :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Convert react-dropdown-select's Default Value from Array to String ]]>
                </title>
                <description>
                    <![CDATA[ By Caleb Olojo Web forms play an important role on many sites on the internet, and they're something you should know how to build as a web developer.  From good ol' login forms to signup forms and survey forms (or whatever they're called these days),... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-send-the-right-data-type-from-a-form-to-the-backend-server/</link>
                <guid isPermaLink="false">66d45ddf55db48792eed3f45</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 10 Jan 2022 21:30:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/1641660058245.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Caleb Olojo</p>
<p>Web forms play an important role on many sites on the internet, and they're something you should know how to build as a web developer. </p>
<p>From good ol' login forms to signup forms and survey forms (or whatever they're called these days), their main purpose is to receive data and send them to a backend server where they're stored.</p>
<p>In this article, we're going to see how we can convert the data gotten from a form from one type to another with JavaScript. But, before you read this article any further, you should have an understanding of the following:</p>
<ul>
<li>The basics of React.js</li>
<li>How to preserve form state in React.js</li>
<li>How to create controlled input components</li>
</ul>
<p>Also, in this article, we'll be covering:</p>
<ul>
<li>How to send the form data that you obtain to a backend server through an API</li>
<li>How to get the exact value of a label in the <code>options</code> array of the react-dropdown-select package.</li>
</ul>
<p>Now that you know what you need to get started with this article, let's dive in.</p>
<h2 id="heading-getting-started">Getting Started</h2>
<p>We'll be building a simple form with React in this article so we can understand how the process works. To do that we'll be using <a target="_blank" href="https://nextjs.org">Next.js</a> to bootstrap our application. If you're new to Next.js, you can take a look at their documentation <a target="_blank" href="https://nextjs.org/docs/getting-started">here</a>.</p>
<p>Now let's get all the dependencies that we'll be needing in this project. Since it is a Next.js project, let's start by setting up a next-app:</p>
<pre><code>npx create-next-app name-<span class="hljs-keyword">of</span>-your-app
</code></pre><p>The command above will install all important dependencies that we need in a Next.js app function. The next dependencies that we need in this project are:</p>
<ul>
<li><strong>xios</strong> for data fetching, and </li>
<li><strong>styled-components</strong> to style the app.</li>
</ul>
<p>The command below does that for us:</p>
<pre><code>npm install styled-components react-dropdown-select axios --save-dev
</code></pre><p>A typical Next.js project structure is different from that of <a target="_blank" href="https://create-react-app.dev">create-react-app</a>. To keep this article concise, we won't be going over the full application structure – we'll only be focusing on what applies to us. </p>
<p>That being said, let's take a look at the app structure below: </p>
<pre><code>|__pages
|   |-- _app.js
|   |-- index.js
|__src
|   |__components
|   |    |__role
|   |    |   |__style
|   |    |     |-- role.styled.js
|   |    |__index.js        
|   |
|   |__containers
|   |    |__dropdown-select 
|   |        |-- index.js
|   
|__
</code></pre><h2 id="heading-overview-of-the-app-structure">Overview of the app structure</h2>
<p>In the last section, we got the required dependencies for this project. In this section, we'll be looking at the project structure and the function that each file performs.</p>
<p>The pages directory is where all the routing of the app takes place. This is an out-of-the-box feature of Nextjs. It saves you the stress of hard-coding your independent routes.</p>
<p><code>pages/api</code>: this API directory enables you to have a backend for your Next.js app. inside the same codebase. This means you don't have to go through the common way of creating separate repositories for your REST or GraphQL APIs and deploying them on backend hosting platforms like Heroku, and so on.</p>
<p>With the API directory, every file is treated as an API endpoint. If you look at the API folder, you'll notice that we have a file called user.js in it. That file becomes an endpoint, which means an API call can be performed using the path to the file as the base URL.</p>
<p><code>pages/_app.js</code> is where all our components get attached to the DOM. If you take a look at the component structure, you’ll see that all the components are passed as pageProps to the Component props too.</p>
<p>It is like the index.js file when using Create-React-App. The only difference here is that you are not hooking your app to the DOM node called “root”</p>
<pre><code class="lang-javascript">React.render(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>), <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>)
</code></pre>
<p><code>index.js</code> is the default route in the pages folder. That is where we'll be doing most of the work in this project. When you run the command below, it starts up a development server and the contents of index.js are rendered on the web page.</p>
<p><code>components/role</code> is the component file that houses the dropdown select component and its style</p>
<p>And lastly, <code>containers/dropdown-select</code> is where we're building the form component.</p>
<h2 id="heading-how-to-build-the-form-and-manage-state">How to Build the Form and Manage State</h2>
<p>Now that we have seen some of the basic functions of the folders/files in the app, let's start building the form component. We won't be focusing on writing the styles in this article.</p>
<p>The code snippet below shows the basic structure of the form component without the state variables. We'll take a step-by-step approach to understanding what is going on in the snippet.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> styled <span class="hljs-keyword">from</span> <span class="hljs-string">"styled-components"</span>;
<span class="hljs-keyword">import</span> { InputGroup } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/role/style/role.styled"</span>;
<span class="hljs-keyword">import</span> Role <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/role"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;

<span class="hljs-keyword">const</span> AuthForm = styled.form<span class="hljs-string">`
    ...
`</span>;

<span class="hljs-keyword">const</span> DropDownSelect = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">AuthForm</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">""</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Register an Account...<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">InputGroup</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"email"</span>&gt;</span>Email address<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span>
          <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter email address"</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">"inputs"</span>
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">InputGroup</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">InputGroup</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"password"</span>&gt;</span>Create password<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">name</span>=<span class="hljs-string">"password"</span>
          <span class="hljs-attr">id</span>=<span class="hljs-string">"password"</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Create password"</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">"inputs"</span>
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">InputGroup</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Role</span> /&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">AuthForm</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> DropDownSelect;
</code></pre>
<p>The component above doesn't have any means of tracking the input that the user types into the form fields, and we do not want that. To get that sorted out, we'll make use of React's <code>useState()</code> hook to monitor the state</p>
<p>Let's start by creating the state variables. You'll notice that we have three input fields in the component, so that means we'll have to create three state variables.</p>
<pre><code class="lang-js"> <span class="hljs-keyword">const</span> [email, setEmail] = React.useState(<span class="hljs-string">""</span>);
 <span class="hljs-keyword">const</span> [password, setPassword] = React.useState(<span class="hljs-string">""</span>);
 <span class="hljs-keyword">const</span> [role, setRole] = React.useState();
</code></pre>
<p>But we need a way to track the state of the data we're sending to the backend server, so we need another state variable to monitor the status of our asynchronous data fetching (POST) request. </p>
<p>A very popular pattern in the React ecosystem is to create a loading component that'll indicate this process.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [loading, setLoading] = React.useState(<span class="hljs-literal">false</span>);
</code></pre>
<p>Now that we have this in place we can set up our input fields to be controlled using the <code>onChange()</code> prop.</p>
<pre><code class="lang-js">&lt;input
  name=<span class="hljs-string">"email"</span>
  id=<span class="hljs-string">"email"</span>
  type=<span class="hljs-string">"email"</span>
  placeholder=<span class="hljs-string">"Enter email address"</span>
  className=<span class="hljs-string">"inputs"</span>
  value={email}
  onChange={<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> setEmail(e.target.value)}
/&gt;
</code></pre>
<p>The process is then repeated for the remaining input fields. But, there's a catch. You'll notice that we already imported the <code>&lt;Role /&gt;</code> component and we already passed some pre-defined props to the component. Let's take a look at the component itself before we go too deep.</p>
<h2 id="heading-the-role-component">The Role Component</h2>
<p>This component utilizes the <code>react-dropdown-select</code> package for its functionality, it takes in an array of values into its properties. </p>
<p>The least required prop is the <code>options</code> prop which receives an array of objects with <code>label</code> and <code>value</code> keys</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> options = [
   { <span class="hljs-attr">label</span>: <span class="hljs-string">"Manager"</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">"Manager"</span> },
   { <span class="hljs-attr">label</span>: <span class="hljs-string">"Worker"</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">"Worker"</span> }
]
</code></pre>
<p>Let's have a look at the component below: </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { InputGroup } <span class="hljs-keyword">from</span> <span class="hljs-string">"./style/role.styled"</span>;
<span class="hljs-keyword">import</span> Select <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dropdown-select"</span>;
<span class="hljs-keyword">import</span> propTypes <span class="hljs-keyword">from</span> <span class="hljs-string">"prop-types"</span>;

<span class="hljs-keyword">const</span> Role = <span class="hljs-function">(<span class="hljs-params">{ userRole, roleChange }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> options = [
    { <span class="hljs-attr">label</span>: <span class="hljs-string">"Worker"</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">"Worker"</span> },
    { <span class="hljs-attr">label</span>: <span class="hljs-string">"Manager"</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">"Manager"</span> },
  ];

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.Fragment</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">InputGroup</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"fullname"</span>&gt;</span>Role<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Select</span>
          <span class="hljs-attr">value</span>=<span class="hljs-string">{userRole}</span>
          <span class="hljs-attr">options</span>=<span class="hljs-string">{options}</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Please select your role"</span>
          <span class="hljs-attr">required</span>=<span class="hljs-string">{true}</span>
          <span class="hljs-attr">dropdownPosition</span>=<span class="hljs-string">"top"</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">"select"</span>
          <span class="hljs-attr">color</span>=<span class="hljs-string">"#ff5c5c"</span>
          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{roleChange}</span>
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">InputGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">React.Fragment</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Role;

Role.propTypes = {
  ...
};
</code></pre>
<p>I mentioned before that the <code>&lt;Role /&gt;</code> component has its own custom props, and you can see that above. </p>
<p>The component takes in two props: <code>userRole</code> that tracks the input based on the option that user selects, and the <code>roleChange</code> prop that gets passed as a value to the <code>onChange()</code> property of the <code>&lt;Select /&gt;</code> component.</p>
<p>The <code>&lt;Select /&gt;</code> component has various props that you can pass to it. From the <code>dropdownPosition</code> prop that specifies where the options menu is positioned on the page, to the <code>color</code> prop that affects the style of the items in the options menu, and so on. You can take a look at some of them <a target="_blank" href="https://www.npmjs.com/package/react-dropdown-select">here</a>.</p>
<p>We made an import statement that brings in the React <code>"prop-types"</code> module at the top of this component's file. We'll be using this module to validate the type of data that is passed into this component.</p>
<pre><code class="lang-javascript">Role.propTypes = {
  <span class="hljs-attr">userRole</span>: propTypes.array.isRequired,
  <span class="hljs-attr">roleChange</span>: propTypes.func.isRequired,
};
</code></pre>
<p>From snippet above, we stated that the type of data that will be passed into <code>userRole</code> as a value must be of a JavaScript array data-type and <code>roleChange</code> is required to be a function. Anything other than these will result in an error.</p>
<h2 id="heading-how-to-use-the-role-component">How to Use the Role Component</h2>
<p>Now that we have gone through the <code>&lt;Role /&gt;</code> component and learned how it works, let's take a look at how we can use it in the app below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> styled <span class="hljs-keyword">from</span> <span class="hljs-string">"styled-components"</span>;
<span class="hljs-keyword">import</span> { InputGroup } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/role/style/role.styled"</span>;
<span class="hljs-keyword">import</span> Role <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/role"</span>;

<span class="hljs-keyword">const</span> AuthForm = styled.form<span class="hljs-string">`
 ...  
`</span>;

<span class="hljs-keyword">const</span> DropDownSelect = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [role, setRole] = React.useState();

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">AuthForm</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSignUp}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Register an Account...<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      // previous details    
      <span class="hljs-tag">&lt;<span class="hljs-name">Role</span>
        <span class="hljs-attr">userRole</span>=<span class="hljs-string">{role}</span>
        <span class="hljs-attr">roleChange</span>=<span class="hljs-string">{(role)</span> =&gt;</span> setRole(role.map((role) =&gt; role.value))}
      /&gt;
   <span class="hljs-tag">&lt;/<span class="hljs-name">AuthForm</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> DropDownSelect;
</code></pre>
<p>The snippet above shows how the <code>&lt;Role /&gt;</code> component is being used. You can see the custom props in use too. <code>userRole</code> is assigned the <code>role</code> state value.</p>
<p>You may have been wondering why we did not assign any value to the <code>role</code> state value we declared it. Well, that's because the <code>&lt;Select /&gt;</code> component from <strong>react-dropdown-select</strong> has a default data-type value of an array, so there's no need to set an array in the <code>useState()</code> hook.</p>
<p>The <code>roleChange</code> prop looks totally different from the previous way we have been using the <strong>onChange</strong> prop in the input fields. Here, we had to place the items we needed into a separate array, so that we're able to get the exact data when the user selects an option.</p>
<pre><code class="lang-javascript">roleChange={<span class="hljs-function">(<span class="hljs-params">role</span>) =&gt;</span> setRole(role.map(<span class="hljs-function">(<span class="hljs-params">role</span>) =&gt;</span> role.value))}
</code></pre>
<p>If you can recall, we had an array called <code>options</code> which had key value pairs of <code>label</code> and <code>value</code>. The snippet above helps us place the <code>value</code> key into an entirely new array since that is what we need, and this is possible with the inbuilt <code>map()</code> method of JavaScript.</p>
<p>When the user clicks on any option, we'll be getting an array containing just one item that was selected. Say, for example, the user clicks on the "Worker" option, the value that is stored in form state is: <code>['Worker']</code>.</p>
<p>But we do not want this data type to be sent to the server – we want a string instead. How then do we fix this, you might ask? We'll see how we can do that in the next section.</p>
<h2 id="heading-how-to-send-the-form-data-to-the-server">How to Send the Form Data to the Server</h2>
<p>In the previous sections, learned about the structure of a Next.js app and how to build and manage state in a React form. </p>
<p>In this section, we'll be sending the data that we obtained from the form to the backend server via an API.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> styled <span class="hljs-keyword">from</span> <span class="hljs-string">"styled-components"</span>;
<span class="hljs-keyword">import</span> { InputGroup } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/role/style/role.styled"</span>;
<span class="hljs-keyword">import</span> Role <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/role"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;

<span class="hljs-keyword">const</span> AuthForm = styled.form<span class="hljs-string">`
  ...
`</span>;

<span class="hljs-keyword">const</span> DropDownSelect = <span class="hljs-function">() =&gt;</span> {
  ...
  const [loading, setLoading] = React.useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">const</span> handleSignUp = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();

    <span class="hljs-keyword">try</span> {
      setLoading(<span class="hljs-literal">true</span>);

      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios({
        <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
        <span class="hljs-attr">url</span>: <span class="hljs-string">"https://your-api-endpoint.com"</span>,
        <span class="hljs-attr">data</span>: {
          email,
          password,
          <span class="hljs-attr">role</span>: role.toString(),
        },
        <span class="hljs-attr">headers</span>: {
          <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
        },
      });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">AuthForm</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSignUp}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Register an Account...<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      // form feilds
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn"</span>&gt;</span>{loading ? "Registering" : "Register"}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">AuthForm</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> DropDownSelect;
</code></pre>
<p>We'll be focusing on the asynchronous data call function, <code>handleSignup</code>, which we'll be using to send the data to the server through the API endpoint.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> handleSignUp = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();

    <span class="hljs-keyword">try</span> {
      setLoading(<span class="hljs-literal">true</span>);

      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios({
        <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
        <span class="hljs-attr">url</span>: <span class="hljs-string">"https://your-api-endpoint.com"</span>,
        <span class="hljs-attr">data</span>: {
          email,
          password,
          <span class="hljs-attr">role</span>: role.toString(),
        },
        <span class="hljs-attr">headers</span>: {
          <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
        },
      });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  };
</code></pre>
<p>The initial value of the <code>loading</code> state was set to be <code>false</code>, but in the <code>try</code> block, it is <code>true</code>. This means that, if the asynchronous data call is going on, the loading value should be <code>true</code>. If not, it should be <code>false</code>.</p>
<p>We mentioned before that we do not want to send an array data type as an input value to the server. Instead we want a string. We do this by using the native string method [<code>toString()</code>] of JavaScript to transform this data type.</p>
<pre><code class="lang-javascript">data: {
  <span class="hljs-attr">role</span>: role.toString()
}
</code></pre>
<p>The <code>loading</code> state value can be seen in action below. We're using a ternary operator to check if the loadin state variable is true. If Yes, the text in button will be <strong>"Registering"</strong>. If No, the text remains unchanged.</p>
<pre><code class="lang-javascript">&lt;button className=<span class="hljs-string">"btn"</span>&gt;{loading ? <span class="hljs-string">"Registering"</span> : <span class="hljs-string">"Register"</span>}&lt;/button&gt;
</code></pre>
<p>You can play with the snippet below to confirm if the result is accurate or not.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> options = [
   { <span class="hljs-attr">label</span>: <span class="hljs-string">"Worker"</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">"Worker"</span> },
   { <span class="hljs-attr">label</span>: <span class="hljs-string">"Manager"</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">"Manager"</span> }
]

<span class="hljs-comment">// create a new array with the key value that you want</span>
<span class="hljs-keyword">const</span> mappedOptions = options.map(<span class="hljs-function"><span class="hljs-params">option</span> =&gt;</span> option.value)
<span class="hljs-built_in">console</span>.log(mappedOptions) <span class="hljs-comment">// ['Worker', 'Manager']</span>

<span class="hljs-comment">// convert the mapped option array to a string value</span>
<span class="hljs-keyword">const</span> mappedOptionsToString = mappedOptions.toString()
<span class="hljs-built_in">console</span>.log(mappedOptionsToString)
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>If your backend API lets you send an array data-type as a value from an input field, you can use what you have learnt here, because the react-dropdown-select package allows you to do that. </p>
<p>But in scenarios where the value that is required from your input field is a string, then you can consider using the native <code>toString()</code> method of JavaScript as you wish.</p>
<p>Here's the <a target="_blank" href="https://exdemo.netlify.app/demo/dropdown">link</a> to the deployed demo app and a GIF that shows you what it looks like with all the styles applied:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/ezgif.com-gif-maker--1-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Thank you for reading this article. If you've found it helpful, kindly share it with your peers.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Text Box in HTML – The Input Field HTML Tag ]]>
                </title>
                <description>
                    <![CDATA[ In this article you'll learn how to create a text input field in HTML. You'll also learn about web forms and get an overview of how they work, since text boxes are a common feature of every form. Let's get started! What are Web Forms? Forms are an ef... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/text-box-in-html-the-input-field-html-tag/</link>
                <guid isPermaLink="false">66b1e4ba98966ccde43c3c5e</guid>
                
                    <category>
                        <![CDATA[ forms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dionysia Lemonaki ]]>
                </dc:creator>
                <pubDate>Mon, 10 Jan 2022 20:02:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/aaron-burden-y02jEX_B0O0-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article you'll learn how to create a text input field in HTML. You'll also learn about web forms and get an overview of how they work, since text boxes are a common feature of every form.</p>
<p>Let's get started!</p>
<h2 id="heading-what-are-web-forms">What are Web Forms?</h2>
<p>Forms are an efficient way of gathering information.</p>
<p>There are many cases where you would need to fill out a physical form, a printed physical document, and give out personal details.</p>
<p>For example, you may fill out a form and hand it to someone when you're starting a new job, or when you're going for a medical checkup, or when you are in the process of renting/buying a house – or any other time when paperwork is necessary.</p>
<p>Just like physical forms, online digital web forms are a way to receive and collect input, information, and important data from users and visitors, using a combination of web technologies.</p>
<p>A web form mimics a physical form by containing spaces for users to fill out their information.</p>
<p>Web forms use a variety of tools, or <em>form controls</em>, to collect user input.</p>
<p>A website can have a search box, or a text input field, for entering a single line of text. This enables users to search for something specific.</p>
<p>A website can also contain a registration form that lets users sign up for a newsletter or other updates.</p>
<p>That would typically contain a text input field for entering the user's first name, last name, and email address. </p>
<p>Many websites also have sign-up / sign-in forms when making an online purchase, for example, where users enter their username in a text field and their password in a separate field. Although password fields are also text fields, each text character is covered up by a black dot to hide what is being typed.</p>
<p>A website can also have a larger textarea for users to enter longer passages of text, which is useaful for leaving a comment underneath a blog post.</p>
<p>Many forms also allow the user to choose a particular option from a number of options by selecting a radio button. They can allow the user to choose  more than one option by checking/unchecking a checkbox.</p>
<p>Lastly, all forms have a submit button, to submit the data to a server where it will be stored or processed.</p>
<h2 id="heading-how-web-forms-work">How Web Forms Work</h2>
<p>The Internet is a large global network that connects millions of computers all around the world.</p>
<p>Computers that are part of the network communicate with each other by sending and receiving information.</p>
<p>The way this is achieved is thanks to the web's client/server request/response architecture.</p>
<p>The client, which is typically a web browser such as Google Chrome, sends a request to a web server. </p>
<p>A web server is a piece of computer hardware or software that stores files that make up websites and distributes them whenever it receives a request to do so.</p>
<p>The request could be to view a form that's part of a webpage.</p>
<p>The server sends back the files that make up the web form as a response.  The web browser then assembles the files together and the user views the form in the web browser.</p>
<p>This request/response cycle is structured by a protocol, called HTTP (which stands for HyperText Transfer Protocol).</p>
<p>So, when using a web form, a user enters the necessary data. Then after the client-side validation that checks if all required fields are filled out and  whether the data is of the right format, the user clicks the submit button.</p>
<p>The data is then sent to the server in <em>name-value pairs</em> in an HTTP request. This method of organizing information in name-value pairs makes sure that the correct data corresponds to the correct form element. </p>
<p>Then a server-side language such as PHP, Ruby, or Python is used to process the information and store it in a database for later use or retrieval.</p>
<h2 id="heading-how-to-create-web-forms-in-html">How to Create Web Forms in HTML</h2>
<p>To create a form in HTML, you need to use the <code>&lt;form&gt;</code> element which is used for collecting information.</p>
<p>The <code>&lt;form&gt;</code> element has an opening <code>&lt;form&gt;</code> and closing <code>&lt;/form&gt;</code> tag.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>

    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The <code>&lt;form&gt;</code> element takes two attributes:</p>
<ul>
<li>The <code>action</code> attribute, which specifies the URL where you want the data to be sent and processed.</li>
<li>The <code>method</code> attribute that accepts as a value one of two HTTP verbs, either <code>GET</code> or <code>POST</code>. If no <code>method</code> attribute is included, the <code>GET</code> method is used by default.</li>
</ul>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>

    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>However, this alone does not collect any user input.</p>
<h2 id="heading-what-is-the-html-input-element">What is the HTML <code>input</code> element?</h2>
<p>The <code>&lt;input&gt;</code> element is most commonly used for collecting and retrieving user data from a web form.</p>
<p>It's where users enter their data.</p>
<p>It's nested inside the <code>&lt;form&gt;</code> element and it's a self closing element. This means it does not require a closing tag. (Closing tags have a forward slash, <code>&lt;/&gt;</code>.)</p>
<p>You use it to create different styles of input fields, or <em>form input controls</em>, for users to enter a variety of different kinds of information.</p>
<p>It creates textfields, email fields, password fields, checkboxes, radio buttons, drop-down menus, submit buttons, the ability to select and upload files and images from the user's computer, and much more.</p>
<p>The way to determine the type of input field, or form input control, is to set the <code>type</code> attribute and assign it a value.</p>
<p>The general syntax of <code>&lt;input&gt;</code> looks something like this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"value"</span>&gt;</span> <span class="hljs-comment">&lt;!-- the value of the type attribute determines the style of input field --&gt;</span>
</code></pre>
<p>For example, to create a field that allows users to upload a file, the <code>&lt;input&gt;</code> element would look like this:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The <code>type</code> attribute determines what kind of data the <code>input</code> element can accept.</p>
<h2 id="heading-how-to-create-an-html-text-box-input-field">How to Create an HTML Text Box Input Field</h2>
<p>The default value of <code>input</code>'s <code>type</code> attribute when not specified is <strong>text</strong>. So text input is the most common style of input.</p>
<p>The line <code>&lt;input type="text"&gt;</code> creates a single line text input field, where the user can type any text input.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please enter some text below:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>When you view the page in the browser, you can see that a single line text input field has been created:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screenshot-2022-01-09-at-5.52.22-PM.png" alt="Screenshot-2022-01-09-at-5.52.22-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-add-placeholder-text-to-a-text-field">How to Add Placeholder Text to a Text Field</h3>
<p>Placeholder text, also called filler text, is a way to prompt and give a hint to users as to what kind of information they need to fill out in the form. It can also offer a default value before they start typing.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please enter your first and last name:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"John"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Doe"</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The code from above would result in the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screenshot-2022-01-09-at-6.09.59-PM.png" alt="Screenshot-2022-01-09-at-6.09.59-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-importance-of-the-name-attribute-in-text-fields">The Importance of the <code>name</code> attribute in Text Fields</h3>
<p>When submitting the form and sending it to the server, the server needs to distinguish and differentiate between the different kinds of submitted data it gathers.</p>
<p>For example, it needs to know which is the username, which is the password, and which is the email address.</p>
<p>This means that each text field needs a <code>name</code> attribute and a value to make the type of data submitted clearer.</p>
<p>For example, you could use the following to prompt someone to enter their full name in a text field:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please enter your full name:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"John Doe"</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screenshot-2022-01-09-at-6.28.10-PM.png" alt="Screenshot-2022-01-09-at-6.28.10-PM" width="600" height="400" loading="lazy"></p>
<p>Say the user enters the name "John Bexley" in the text field. This will then become the value of the <code>name</code> attribute.</p>
<p>As mentioned earlier, the data in forms is sent in name-value pairs. In this case, the server would know that the <code>name</code> of the user is <code>John Bexley</code>, specifically it would look like <code>name=John Bexley</code>.</p>
<p>To give another example:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please enter your first  name:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"first_name"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"John"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please enter your last  name:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"last_name"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Doe"</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The code above has two separate text fields for the user to enter their first name and last names separately.</p>
<p>If they entered "John" as the first name, the name-value pair sent to the server would be <code>first_name=John"</code>.</p>
<p>If they entered "Bexley" as the last name, the name-value pair sent to the server would be <code>last_name=Bexley</code>.</p>
<h3 id="heading-how-to-make-text-information-required">How to Make Text Information Required</h3>
<p>You can make it so certain fields are required and need to be filled in by users.</p>
<p>HTML5 introduced client-side validation.</p>
<p>This is a feature where a message is displayed if the user has not filled in the required fields or has not entered information correctly. It also means that they won't be able to submit the form.</p>
<p>All you need to do to enable this is to add the <code>required</code> attribute to the <code>&lt;input&gt;</code> element. This attribute does not need to have a value.</p>
<p>Keep in mind that when adding multiple attributes to the <code>&lt;input&gt;</code> element, you don't have to add elements in a certain order.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please enter your first  and last name:<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"first_name"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"John"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"last_name"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Doe"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>  
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Look at what happens if a user does not fill in one of the fields:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screenshot-2022-01-09-at-6.59.44-PM.png" alt="Screenshot-2022-01-09-at-6.59.44-PM" width="600" height="400" loading="lazy"></p>
<p>A message will appear and the user won't be able to submit the form if the required fields have not been completed.</p>
<h3 id="heading-how-to-set-a-minimum-and-maximum-number-of-characters-in-a-text-box">How to Set a Minimum and Maximum Number of Characters in a Text Box</h3>
<p>You can specify the minimum and maximum number of characters that a user can enter in a text field.</p>
<p>To create a minimum number of characters, use the <code>minlength</code> attribute.</p>
<p>For example, you can have it so a user's username is <em>at least</em>  three characters long:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please enter your username<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">minlength</span>=<span class="hljs-string">"3"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>  
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The user will not be able to submit the form if the username is shorter than three characters:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screenshot-2022-01-10-at-4.04.00-PM.png" alt="Screenshot-2022-01-10-at-4.04.00-PM" width="600" height="400" loading="lazy"></p>
<p>To limit the number of characters a user enters in a text field, use the <code>maxlength</code> attribute.</p>
<p>An example of combining both the <code>minlength</code> and <code>maxlength</code> attributes could look like this:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Please enter your username<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">minlength</span>=<span class="hljs-string">"3"</span> <span class="hljs-attr">maxlength</span>=<span class="hljs-string">"20"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>  
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In the example above, a user's username has to be at least 3 characters long and no longer than 20 characters.</p>
<h3 id="heading-how-to-label-form-controls">How to <code>label</code> Form Controls</h3>
<p>So far I've been using a <code>&lt;p&gt;</code> element to write some text before the text box, in this way prompting the user and letting them know what they need to enter.</p>
<p>But this is not a best practice and is not accessible.</p>
<p>Each form control, in this case each text field, should have its own <code>&lt;label&gt;</code> element.</p>
<p>This makes the form accessible for visually impaired users that use assistive technologies such as screen readers.</p>
<p>One way to use it is to nest any introductory text and the <code>&lt;input type="text"&gt;</code> in a <code>&lt;label&gt;</code> element like so:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>
            Please enter your username
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">minlength</span>=<span class="hljs-string">"3"</span> <span class="hljs-attr">maxlength</span>=<span class="hljs-string">"20"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>  
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screenshot-2022-01-10-at-4.58.37-PM.png" alt="Screenshot-2022-01-10-at-4.58.37-PM" width="600" height="400" loading="lazy"></p>
<p>Another way to use the <code>&lt;label&gt;</code> element and to have the same result is to separate it from the <code>&lt;input&gt;</code> element.</p>
<p>In this case, the <code>for</code> attribute needs to be added to <code>&lt;label&gt;</code>, and the <code>id</code> attribute added to <code>&lt;input&gt;</code>, in order to associate both with one another.</p>
<p>The value of <code>for</code> will be the same with <code>id</code>.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Web form<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/url"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"GET"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"username"</span>&gt;</span> Please enter your username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span> <span class="hljs-attr">minlength</span>=<span class="hljs-string">"3"</span> <span class="hljs-attr">maxlength</span>=<span class="hljs-string">"20"</span> <span class="hljs-attr">required</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>  
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>To sum up, to create a text input field in HTML, you need at least:</p>
<ul>
<li>An <code>&lt;input&gt;</code> element, which typically goes inside a <code>&lt;form&gt;</code> element.</li>
<li>To set the <code>type</code> attribute to have a value of <code>text</code>. This will create a single line text input field.</li>
<li>Don't forget to add a <code>name</code> attribute. This identifies information for each form control that gets created and makes things clearer for the server.</li>
</ul>
<p>To learn more about HTML and CSS, check out the <a target="_blank" href="https://www.freecodecamp.org/learn/2022/responsive-web-design/">Responsive Web Design Certification</a> by freeCodeCamp, where you'll learn in an interactive way while building fun projects along the way.</p>
<p>Thanks for reading and happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
