Conditional Fields
// Marital = Married → show Spouse
function toggleSpouse() {
spouse.hidden = marital.value !== "Married";
spouse.required = !spouse.hidden;
}
JSON Schema-driven Form ⭐
{
"fields": [
{"name":"email","type":"email","required":true},
{"name":"spouse","type":"text",
"showIf":{"field":"marital","equals":"married"}}
]
}
// Renderer reads schema → generates UI
সুবিধা: UI code-change ছাড়াই form add, multi-tenant, A/B testing।
Form Builder Architecture
[Builder UI] → JSON → [forms table] → [Renderer] → [submissions]
Drag-Drop Libs
SortableJS, react-dnd, Vue.Draggable।
File Upload
// Frontend validation
if (file.size > 5*1024*1024) alert("Max 5MB");
// Backend
[RequestSizeLimit(5_000_000)]
public async Task<IActionResult> Upload(IFormFile file) {
var allowed = new[] {".jpg",".png",".pdf"};
var ext = Path.GetExtension(file.FileName).ToLower();
if (!allowed.Contains(ext)) return BadRequest();
// Magic byte check — real type, not extension
var fileName = $"{Guid.NewGuid()}{ext}";
return Ok(new {url = $"/uploads/{fileName}"});
}
Large Upload
- Chunked (5MB pieces), tus.io protocol
- S3 multipart, direct browser → S3 (presigned)
Digital Signature
// SignaturePad (Canvas) const pad = new SignaturePad(canvas); const data = pad.toDataURL(); // base64 PNG
Legal: PKI/X.509 (DocuSign, Adobe Sign)।
Submission Storage
submissions: id, form_id, data JSON SELECT data->>'email' FROM submissions WHERE form_id=5;