<?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" version="2.0"><channel><title><![CDATA[Nordvia Digital]]></title><description><![CDATA[Nordvia Digital]]></description><link>https://nordviadigital.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 12 Nov 2026 08:45:31 GMT</lastBuildDate><atom:link href="https://nordviadigital.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building an Accessible Enquiry Form Error Summary with the Constraint Validation API]]></title><description><![CDATA[By Nordvia Digital Enquiry forms are often the main way a Dubai business website turns a visitor into a conversation. When the form rejects input, the way…]]></description><link>https://nordviadigital.hashnode.dev/building-an-accessible-enquiry-form-error-summary-with-the-constraint-validation-api</link><guid isPermaLink="true">https://nordviadigital.hashnode.dev/building-an-accessible-enquiry-form-error-summary-with-the-constraint-validation-api</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Accessibility]]></category><category><![CDATA[webdev]]></category><category><![CDATA[HTML]]></category><category><![CDATA[forms]]></category><dc:creator><![CDATA[Nordvia Digital]]></dc:creator><pubDate>Tue, 10 Nov 2026 09:11:34 GMT</pubDate><content:encoded><![CDATA[<p><em>By <a href="https://nordviadigital.com/">Nordvia Digital</a></em></p>
<p>Enquiry forms are often the main way a Dubai business website turns a visitor into a conversation. When the form rejects input, the way it explains the problem matters: a vague red outline or a message that disappears is easy to miss, especially for keyboard and assistive-technology users.</p>
<p>This article walks through a small prototype we built to study one pattern: an error summary at the top of the form, inline messages tied to each field, and validation driven by the browser's native Constraint Validation API. The live code is on CodePen: <a href="https://codepen.io/nordviadigital/pen/01a1c241-0eae-7212-9a88-06076d89f449">Accessible enquiry form validation (no data sent)</a>.</p>
<p><strong>Scope first.</strong> This is a local, client-side UI study, not a production enquiry form. There is no backend. The demo’s own form code does not submit entered values, make network requests or write to browser storage. It is an original interface concept, not client work, and the sample values shown in its placeholders (such as "Layla Example") are fictitious.</p>
<h2>The markup: native constraints plus described-by links</h2>
<p>The form has four fields: full name, email, project type and project details. Each field uses the native HTML constraints that apply to it: all four are <code>required</code>, the email field uses <code>type="email"</code>, and the name and details fields use <code>minlength</code>. The form has <code>novalidate</code>, so the browser's own error bubbles are suppressed and the script can present messages consistently.</p>
<p>Each control points at its hint and error elements with <code>aria-describedby</code>:</p>
<pre><code class="language-html">&lt;input id="email" name="email" type="email" autocomplete="off" required
  placeholder="e.g. layla@example.com" aria-describedby="email-hint email-error"&gt;
&lt;p class="hint" id="email-hint"&gt;Use the format name@example.com.&lt;/p&gt;
&lt;p class="error" id="email-error"&gt;&lt;/p&gt;
</code></pre>
<p>As <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-describedby">MDN's <code>aria-describedby</code> reference</a> explains, the attribute takes a space-separated list of IDs in the same document, and the referenced text acts as a description of the control. Here that means the format hint and the current error message are both associated with the field. The error paragraph starts empty; the hint is available immediately, and error text is added when a problem is found.</p>
<h2>Turning ValidityState into readable messages</h2>
<p>Rather than writing custom regular expressions, the script reads each element's <code>validity</code> object. <a href="https://developer.mozilla.org/en-US/docs/Web/API/ValidityState">MDN's <code>ValidityState</code> page</a> lists the boolean flags; this demo only needs three of them: <code>valueMissing</code>, <code>typeMismatch</code> and <code>tooShort</code>.</p>
<pre><code class="language-js">function messageFor(el) {
  const v = el.validity;
  const label = form.querySelector(`label[for="${el.id}"]`).textContent;
  if (v.valueMissing) return el.tagName === 'SELECT' ? `Choose a ${label.toLowerCase()}.` : `Enter your ${label.toLowerCase()}.`;
  if (v.typeMismatch) return 'Enter an email address like name@example.com.';
  // minlength is only enforced natively after user edits, so check length explicitly too.
  if (v.tooShort || (el.minLength &gt; 0 &amp;&amp; el.value.trim().length &lt; el.minLength)) return `${label}: use at least ${el.minLength} characters (now ${el.value.trim().length}).`;
  return '';
}
</code></pre>
<p>Two details are worth noting. The message text is built from the visible <code>&lt;label&gt;</code>, so the wording in the summary matches what users see on screen. And native <code>minlength</code> validation does not cover values assigned by JavaScript, so the demo also checks the trimmed length explicitly (see MDN's <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation">guide to constraint validation</a>). The message also reports the current character count, which tells the user how far off they are.</p>
<p>A separate <code>check()</code> function writes the message into the field's error element and sets <code>aria-invalid</code> to <code>"true"</code> or <code>"false"</code>. Fields are re-checked on <code>blur</code> (when they contain a value) and on <code>input</code> once they are already marked invalid, so a message clears as soon as the problem is fixed instead of waiting for another submit.</p>
<h2>The error summary and focus</h2>
<p>On submit, the script calls <code>preventDefault()</code>, checks every field and collects the failures. If there are any, it builds a list of links inside a summary container that has <code>tabindex="-1"</code> and a heading ("Please fix the following"):</p>
<ul>
<li>each link's <code>href</code> points at the field's ID, and its click handler calls <code>el.focus()</code> on that field directly;</li>
<li>the summary is un-hidden and the script calls <code>summary.focus()</code>;</li>
<li>a status paragraph with <code>role="status"</code> and <code>aria-live="polite"</code> is updated with a count, for example "4 problems found. Nothing was sent."</li>
</ul>
<p>The intent is that keyboard and screen-reader users land on a single list of problems and can jump from each item to the field that needs attention. We should be clear about what has been checked: the focus behaviour is described here from the code. We have not manually tested focus movement in a range of browsers or with screen readers, and this article is not an accessibility audit.</p>
<p>In a check with an empty form in a browser, the summary listed four errors, each linked to its field. With valid fictitious values, the status line reads exactly: "Validation passed. This is a demo, so nothing was sent or stored."</p>
<h2>A deliberately disabled submit button</h2>
<p>The submit button is rendered with <code>disabled</code>, and the last line of the script enables it, after all handlers are registered. If JavaScript is unavailable, or if anything earlier in the script throws, the button stays disabled and a <code>&lt;noscript&gt;</code> note explains why.</p>
<p>That helps prevent accidental submission during ordinary use of this local demo. It is <strong>not</strong> a pattern we would recommend for a live enquiry form. A real form should still submit, and still be validated, when client-side scripts fail.</p>
<h2>What production would still need</h2>
<p>Client-side validation improves the experience, but it is not a security measure: anyone can bypass it. A real enquiry form also needs server-side validation of every field, spam and abuse protection, secure handling and storage of personal data, clear server error and success states, and reliable delivery to whoever answers enquiries. None of that is implemented in this prototype.</p>
<p>Feel free to fork the CodePen and adapt the summary pattern to your own forms. If you are planning a website or enquiry form for a business in Dubai and would like help, you can <a href="https://nordviadigital.com/contact">send an enquiry through the Nordvia Digital contact form</a>.</p>
]]></content:encoded></item></channel></rss>