SmartInput
A universal input Web Component supporting 8+ types with built-in validation, event hooks, and form integration. Replaces <input>, <select>, <textarea> and more with a single consistent API.
<script src="smart-input.js"></script>
Live Playground
Modify attributes on the left and see the real <smart-input> component update in real time.
Controls
<smart-input type="text" label="Full Name" placeholder="Enter value..." ></smart-input>
Text / Email / Password
Standard text-based inputs. Supports all HTML input types: text, email, password, number, tel, url.
<smart-input type="text" name="username" label="Username" placeholder="Enter username" required ></smart-input> <smart-input type="email" name="email" label="Email" required no-autocomplete ></smart-input> <smart-input type="password" name="password" label="Password" required no-autocomplete ></smart-input>
Textarea
<smart-input type="textarea" name="message" label="Message" rows="4" placeholder="Write your message..." ></smart-input>
Select Dropdown
Pass data-options as a JSON array. Supports dynamic loading from a URL via data-url.
<smart-input type="select" name="status" label="Status" value="pending" data-options='[ {"id": "pending", "name": "Pending"}, {"id": "completed", "name": "Completed"}, {"id": "failed", "name": "Failed"} ]' required ></smart-input> <!-- Dynamic from URL --> <smart-input type="select" name="user" label="Select User" data-url="/api/users" ></smart-input> <!-- Multiple Selection from Dynamic from URL --> <smart-input type="select" name="user" label="Select User" multiple data-url="/api/users" ></smart-input>
Date Picker
Custom date picker with dd-mm-yyyy format. Supports min/max date constraints.
<!-- Always Shows Date in `23 March 2002` Format --> <smart-input type="datepicker" name="birthdate" label="Birth Date" value="15-03-1990" min-date="01-01-1950" max-date="31-12-2010" required ></smart-input>
File Upload
Drag-and-drop file uploader with type restrictions, size limits, and multi-file support.
<smart-input type="file" name="documents" label="Upload Documents" allowed-types="documents" max-size="5" max-files="3" ></smart-input> <!-- Image upload --> <smart-input type="file" name="images" label="Upload Images" allowed-types="images" max-files="5" max-size="10" ></smart-input>
Checkbox
<smart-input type="checkbox" name="agree" label="I agree to the terms and conditions" required ></smart-input>
Switch / Toggle
Three sizes: is-small, is-medium (default), is-big.
<smart-input type="switch" name="notif" label="Notifications" is-small></smart-input> <smart-input type="switch" name="dark" label="Dark Mode" value="true"></smart-input> <smart-input type="switch" name="email" label="Email Alerts" is-big></smart-input>
Radio Buttons
<smart-input type="radio" name="priority" label="Priority" value="medium" data-options='[ {"id": "low", "name": "Low Priority"}, {"id": "medium", "name": "Medium Priority"}, {"id": "high", "name": "High Priority"} ]' ></smart-input>
Attributes
| Attribute | Type | Description | Default |
|---|---|---|---|
| type | string | Input type: text, email, password, number, textarea, select, datepicker, file, checkbox, switch, radio | text |
| name | string | Form field name — used in FormData submission | input |
| label | string | Human-readable label shown above the field | — |
| value | string | Initial value. For datepicker use dd-mm-yyyy format. | — |
| placeholder | string | Placeholder text shown when empty | — |
| required | boolean | Marks field as required; prevents form submission if empty | false |
| data-error | string | Custom validation error message | Invalid {label} |
| data-options | JSON | Array of options for select/radio: [{id, name}] | — |
| data-url | string | URL to fetch select options dynamically | — |
| rows | number | Textarea visible rows | 4 |
| min-date | string | Minimum date constraint (dd-mm-yyyy) | — |
| max-date | string | Maximum date constraint (dd-mm-yyyy) | — |
| allowed-types | string | File type group: images, videos, documents, spreadsheets, archives, audio | — |
| max-size | number | Max file size in MB | — |
| max-files | number | Max number of files for file input | 1 |
| is-big | boolean | Large size for switch component | — |
| is-small | boolean | Small size for switch component | — |
Events
Event handler functions must be defined globally (on window). The function receives the native event object.
| Attribute | Trigger | Description |
|---|---|---|
| data-oninput | input | Called on every keystroke / value change |
| data-onchange | change | Called when the value changes and focus is lost |
| data-onclick | click | Called when the input element is clicked |
// Define handler globally function handleInput(event) { console.log('Value:', event.target.value); } function handleChange(event) { console.log('Changed to:', event.target.value); } <!-- In HTML --> <smart-input type="text" name="search" data-oninput="handleInput" data-onchange="handleChange" ></smart-input>
JavaScript API
const input = document.querySelector('smart-input[name="username"]'); // Get current value console.log(input.value); // Set value programmatically input.value = "john_doe"; // Validate (returns boolean) const isValid = input.validate(); // Focus the input input.focus(); // Get the underlying <input> element const el = input.getInputElement(); // For datepicker: get hidden input with raw value const hidden = input.getHiddenInput();
Form Integration
SmartInput writes values into hidden <input> elements so they appear in FormData natively. Validate all inputs before submission:
<form id="myForm"> <smart-input type="text" name="name" required></smart-input> <smart-input type="email" name="email" required></smart-input> <button type="submit">Submit</button> </form> <script> document.getElementById('myForm').addEventListener('submit', (e) => { e.preventDefault(); const inputs = e.target.querySelectorAll('smart-input'); let isValid = true; inputs.forEach(input => { if (!input.validate()) isValid = false; }); if (isValid) { const data = new FormData(e.target); // Send to Django view via fetch or form.submit() } }); </script>