JSFiddle - React, Tailwind, and code Playground

by Leko Inoue

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<h1>Constraint validation demo</h1>
<p>全パターン網羅は手描きじゃ辛いのである程度抑えました</p>

<h2>テキスト系</h2>
<ul>
	<li>
		<label for="form-text">お名前</label>
		<input class="form-control" id="form-text" type="text" required maxlength="30">
		<pre><code></code></pre>
	</li>
	<li>
		<label for="form-password">おパス</label>
		<input class="form-control" id="form-password" type="password" required minlength="8">
		<pre><code></code></pre>
	</li>
	<li>
		<label for="form-search">お検索</label>
		<input class="form-control" id="form-search" type="search" required minlength="1">
		<pre><code></code></pre>
	</li>
	<li>
		<label for="form-url">おアドレス</label>
		<input class="form-control" id="form-url" type="url" required minlength="0" maxlength="255" list="bookmarks">
		<pre><code></code></pre>
		<datalist class="form-control" id="bookmarks">
			<option value="http://leko.jp"></option>
		</datalist>
	</li>
	<li>
		<label for="form-email">おメール</label>
		<input class="form-control" id="form-email" type="email" required>
		<pre><code></code></pre>
	</li>
	<li>
		<label for="form-text">おスネークケース</label>
		<input class="form-control" id="form-text" type="text" required pattern="^[a-z_]+$" data-pattern-name="スネークケース">
		<pre><code></code></pre>
	</li>
	<li>
		<label for="form-textarea">お長文</label>
        <textarea class="form-control" id="form-textarea" maxlength="100" required></textarea>
		<pre><code></code></pre>
	</li>
</ul>

<h2>数字系</h2>
<ul>
	<li>
		<label for="form-number">お年齢</label>
		<input class="form-control" id="form-number" type="number" required min="18" max="100024" step="1">
		<pre><code></code></pre>
	</li>
</ul>

<h2>日付系</h2>
<ul>
	<li>
		<label for="form-date">お誕生日</label>
		<input class="form-control" id="form-date" type="date" required min="2015/11/24" max="2015/12/31" step="3">
		<pre><code></code></pre>
	</li>
	<li>
		<label for="form-time">お誕生時</label>
		<input class="form-control"...

Babel + JSX

// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
// https://developer.mozilla.org/en-US/docs/Web/API/ValidityState
var Validator = (function() {
	var Validator = {};

	function closestLabel(input) {
		var el = input;
		while(el.parentNode !== document.body) {
            if(el.tagName.toLowerCase() === 'label') {
                return el;
            }
			el = el.parentNode;
		}
		return null;
	}

	function getLabel(input) {
		if(input.id) {
			return document.querySelector('[for="' + input.id + '"]');
		}

		if(input.labels && input.labels.length > 0) {
			return input.labels[0];
		} else {
			return closestLabel(input);
		}
	}

	function getLabelText(input) {
		var label = getLabel(input);
		if(label === null) {
			return input.value;
		} else {
			return label.textContent.trim();
		}
	}

    // 参考: https://github.com/fuel/core/blob/1.8/develop/lang/en/validation.php
	Validator.templates = {
		badInput: function(label, input) {
			return `The valid string rule ${input.type} failed for field ${label}`;
		},
		customError: function(label, input) {
			return input.validity.customError;
		},
		patternMismatch: function(label, input) {
			var name = input.dataset.patternName ? input.dataset.patternName : input.pattern;
			return `The field ${label} must match the pattern ${name}.`;
		},
		rangeOverflow: function(label, input) {
			return `The maximum numeric value of ${label} must be ${input.max}`;
		},
		rangeUnderflow: function(label, input) {
			return `The minimum numeric value of ${label} must be ${input.min}`;
		},
		stepMismatch: function(label, input) {
			return `The field ${label} must in units of ${input.step}`;
		},
		tooLong: function(label, input) {
			return `The field ${label} may not contain more than ${input.maxLength} characters.`;
		},
		tooShort: function(label, input) {
			return `The field ${label} has to contain at least ${input.minLength} characters.`;
		},
		typeMismatch: function(label, input)...