Loading...
Loading...
Build public-facing web forms for data collection without Desk access. Use when creating customer submission forms, feedback forms, or self-service portals with Frappe Web Forms.
npx skill4agent add lubusin/agent-skills frappe-web-forms| Setting | Purpose |
|---|---|
| Login Required | Require authentication before form access |
| Allow Edit | Let users edit their submitted entries |
| Allow Multiple | Let users submit more than one entry |
| Show as Card | Display in card layout style |
| Max Attachment Size | Limit file upload sizes |
| Success URL | Redirect after successful submission |
| Success Message | Custom message after submission |
my_app/
└── my_module/
└── web_form/
└── contact_us/
├── contact_us.json # Web form metadata
├── contact_us.py # Server-side customization
└── contact_us.js # Client-side customization# contact_us.py
import frappe
def get_context(context):
"""Add custom context variables to the web form."""
context.categories = frappe.get_all("Support Category",
filters={"enabled": 1},
fields=["name", "label"],
order_by="label asc"
)
def validate(doc):
"""Custom validation before the document is saved."""
if not doc.email:
frappe.throw("Email address is required")
# Prevent duplicate submissions
existing = frappe.db.exists("Support Ticket", {"email": doc.email, "status": "Open"})
if existing:
frappe.throw("You already have an open ticket. Please wait for a response.")// contact_us.js
frappe.ready(function() {
// Handle field changes
frappe.web_form.on("field_change", function(field, value) {
if (field === "category" && value === "Urgent") {
frappe.web_form.set_df_property("description", "reqd", 1);
}
});
// Custom validation
frappe.web_form.validate = function() {
let data = frappe.web_form.get_values();
if (data.phone && !data.phone.match(/^\+?[0-9\-\s]+$/)) {
frappe.msgprint("Please enter a valid phone number");
return false;
}
return true;
};
// Custom after-save behavior
frappe.web_form.after_save = function() {
frappe.msgprint("Thank you for your submission!");
};
});<!-- Add custom CSS via Web Form → Custom CSS field -->
<style>
.web-form-container { max-width: 600px; margin: 0 auto; }
.web-form-container .form-group { margin-bottom: 1.5rem; }
.web-form-container .btn-primary { background-color: #2490EF; }
</style>/contact-usvalidatefrappe-doctype-developmentfrappe-frontend-developmentfrappe-api-developmentvalidate()frappe.utils.escape_html()| Mistake | Why It Fails | Fix |
|---|---|---|
| Missing DocType permissions | "Permission denied" on submit | Grant Create permission to Website User or Guest role |
| Not handling file uploads | Files don't attach to record | Configure Attach field properly; check upload limits |
| XSS vulnerabilities | Security risk | Escape user input in display; use ` |
| Forgetting to publish form | 404 error | Check "Published" checkbox in Web Form |
| Client-only validation | Invalid data in database | Add |
| Not testing as guest user | Works for admin, fails for users | Test in incognito/logged out mode |