Episode 8: Forms and Data Collection
Creating User-Friendly Forms that Balance Ease of Use with Data Quality
Introduction
Forms are the primary way external users interact with your data in Power Pages. Whether users are submitting support tickets, updating their profiles, or registering for events, forms must be intuitive, secure, and efficient. This episode teaches you how to create forms that encourage completion while maintaining data quality and security standards.
Key Concepts
- Entity Forms: Forms connected to Dataverse tables for creating and editing records
- Basic Forms: Simple forms for data collection without complex entity relationships
- Web Forms: Multi-step forms with advanced logic and conditional fields
- Form Validation: Client-side and server-side validation to ensure data quality
- Form Security: Controlling who can submit forms and what data they can access
Learning Objectives
By the end of this episode, you will be able to:
- Design forms that users want to complete rather than abandon
- Implement validation that catches errors before they reach your database
- Configure conditional logic that shows relevant fields based on user input
- Set up proper security controls for form submissions
- Create multi-step forms for complex data collection scenarios
Why Good Form Design Matters
Poor form design is one of the primary reasons users abandon portal tasks. External users have less patience for confusing interfaces than internal users. A well-designed form can significantly improve user satisfaction and data quality while reducing support burden on your team.
Step-by-Step Guide
1. Planning Your Form Strategy
Before creating any form, consider:
- User Journey: How does this form fit into the user’s overall goal?
- Data Requirements: What information is absolutely necessary vs. nice-to-have?
- User Context: What information do you already have about the user?
- Device Considerations: Will users primarily complete this on mobile or desktop?
Form Type Selection Guide:
- Entity Form: Use when working with single Dataverse records (create/edit cases, update profile)
- Basic Form: Use for simple data collection that doesn’t map directly to entity records
- Web Form: Use for complex multi-step processes (application workflows, registrations)
2. Creating Your First Entity Form
Setting Up a Support Ticket Form:
-
Navigate to Form Configuration:
- Go to Portal Management → Entity Forms
- Click New to create a new entity form
- Set Name: “Customer Support Ticket”
- Set Table: Case (incident)
-
Configure Basic Settings:
Mode: Insert Success Message: "Your support ticket has been submitted. Reference number: {ticketnumber}" Form Name: "Portal Case Form" (create this in Dataverse) -
Set Security Permissions:
- Table Permissions: Create permission for authenticated users
- Entity Form: Allow Create for Customer role
- Validation: Ensure users can only create records assigned to them
-
Add Form to Page:
- Create or edit your support page
- Add Entity Form component
- Select your configured form
3. Designing User-Friendly Forms
Essential Form Usability Principles:
Progressive Disclosure:
// Example: Show additional fields based on issue type
function showAdditionalFields(issueType) {
const techFields = document.getElementById('technical-fields');
const billingFields = document.getElementById('billing-fields');
// Hide all additional fields first
techFields.style.display = 'none';
billingFields.style.display = 'none';
// Show relevant fields based on selection
if (issueType === 'technical') {
techFields.style.display = 'block';
} else if (issueType === 'billing') {
billingFields.style.display = 'block';
}
}
Smart Defaults and Pre-population:
<!-- Example: Pre-populate user information -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// Pre-populate customer information
document.getElementById('customerid').value = '{{ user.contactid }}';
document.getElementById('emailaddress').value = '{{ user.emailaddress1 }}';
document.getElementById('firstname').value = '{{ user.firstname }}';
document.getElementById('lastname').value = '{{ user.lastname }}';
// Set default priority and category
document.getElementById('prioritycode').value = '2'; // Normal priority
document.getElementById('casetypecode').value = '1'; // Question
});
</script>
Field Organization and Grouping:
- Contact Information: Group all contact fields together
- Issue Details: Separate section for problem description
- Technical Information: Optional section for technical users
- Attachments: Clear area for file uploads
4. Implementing Effective Validation
Client-Side Validation for Immediate Feedback:
// Example: Real-time email validation
function validateEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const emailField = document.getElementById('emailaddress');
const errorDiv = document.getElementById('email-error');
if (!emailRegex.test(email)) {
emailField.classList.add('is-invalid');
errorDiv.textContent = 'Please enter a valid email address';
errorDiv.style.display = 'block';
return false;
} else {
emailField.classList.remove('is-invalid');
errorDiv.style.display = 'none';
return true;
}
}
// Example: Required field validation
function validateRequiredFields() {
const requiredFields = document.querySelectorAll('[required]');
let allValid = true;
requiredFields.forEach(field => {
if (!field.value.trim()) {
field.classList.add('is-invalid');
allValid = false;
} else {
field.classList.remove('is-invalid');
}
});
return allValid;
}
Server-Side Validation Configuration:
- Business Rules: Use Dataverse business rules for complex validation
- Plugins: Implement custom validation logic in Dataverse plugins
- Form Scripts: Add validation in form OnSave events
5. Creating Multi-Step Forms with Web Forms
When to Use Web Forms:
- Complex registration processes
- Data collection requiring multiple entities
- Conditional workflows based on user responses
- Integration with external systems
Basic Web Form Setup:
-
Create Web Form:
- Go to Portal Management → Web Forms
- Set Name: “Customer Registration Process”
- Configure start step and success page
-
Add Form Steps:
- Step 1: Basic Information (contact details)
- Step 2: Company Information (account details)
- Step 3: Preferences and Settings
- Step 4: Review and Submit
-
Configure Step Logic:
Condition: If user selects "Business Customer" Next Step: Company Information Condition: If user selects "Individual Customer" Next Step: Preferences and Settings
6. Advanced Form Features
File Upload Configuration:
<!-- Example: Secure file upload with restrictions -->
<div class="file-upload-section">
<label for="attachment">Upload Supporting Documents</label>
<input type="file" id="attachment" name="attachment"
accept=".pdf,.doc,.docx,.png,.jpg"
multiple
data-max-size="5242880"> <!-- 5MB limit -->
<small class="form-text text-muted">
Accepted formats: PDF, DOC, DOCX, PNG, JPG. Maximum size: 5MB per file.
</small>
</div>
<script>
function validateFileUpload(input) {
const maxSize = parseInt(input.dataset.maxSize);
const allowedTypes = input.accept.split(',');
Array.from(input.files).forEach(file => {
// Check file size
if (file.size > maxSize) {
alert(`File ${file.name} is too large. Maximum size is 5MB.`);
input.value = '';
return;
}
// Check file type
const fileExtension = '.' + file.name.split('.').pop().toLowerCase();
if (!allowedTypes.includes(fileExtension)) {
alert(`File type ${fileExtension} is not allowed.`);
input.value = '';
return;
}
});
}
</script>
Conditional Field Display:
// Example: Show different fields based on customer type
function handleCustomerTypeChange(customerType) {
const businessFields = document.getElementById('business-customer-fields');
const individualFields = document.getElementById('individual-customer-fields');
if (customerType === 'business') {
businessFields.style.display = 'block';
individualFields.style.display = 'none';
// Make business fields required
businessFields.querySelectorAll('input, select').forEach(field => {
field.required = true;
});
// Remove required from individual fields
individualFields.querySelectorAll('input, select').forEach(field => {
field.required = false;
});
} else {
businessFields.style.display = 'none';
individualFields.style.display = 'block';
// Reverse the requirements
businessFields.querySelectorAll('input, select').forEach(field => {
field.required = false;
});
individualFields.querySelectorAll('input, select').forEach(field => {
field.required = true;
});
}
}
Practical Example: Complete Support Ticket Form
Let’s build a comprehensive support ticket form for TechStart Solutions:
Form Structure:
-
Customer Information (pre-populated):
- Name, Email, Phone (read-only for authenticated users)
- Account/Company (lookup to account record)
-
Issue Details:
- Issue Type (dropdown: Technical, Billing, General)
- Priority (dropdown: Low, Normal, High)
- Subject (required text field)
- Description (rich text area)
-
Technical Details (conditional, shown for technical issues):
- Product/Service Affected (dropdown)
- Error Messages (text area)
- Steps to Reproduce (text area)
-
Attachments:
- File upload with validation
- Multiple files allowed
- Size and type restrictions
Form Validation Rules:
- Subject must be at least 10 characters
- Description must be at least 50 characters for technical issues
- At least one attachment required for billing issues
- Phone number format validation
- Email format validation (if editable)
Security Configuration:
- Only authenticated users can submit
- Users can only create cases assigned to their contact record
- File uploads stored securely with access controls
- Form submissions logged for audit trail
7. Form Performance and Mobile Optimization
Performance Best Practices:
- Lazy Loading: Load lookup data only when needed
- Debounced Validation: Don’t validate on every keystroke
- Optimized Queries: Use efficient Dataverse queries for dropdowns
- Caching: Cache static dropdown values
Mobile-First Design:
/* Example: Mobile-optimized form styling */
.portal-form {
max-width: 100%;
padding: 1rem;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
font-size: 16px; /* Prevents zoom on iOS */
padding: 12px;
border-radius: 8px;
}
@media (max-width: 768px) {
.form-row {
flex-direction: column;
}
.form-col {
width: 100%;
margin-bottom: 1rem;
}
.btn {
width: 100%;
padding: 14px;
font-size: 16px;
}
}
Troubleshooting Common Form Issues
Problem: Form submissions create records but don’t redirect to success page Solution: Check entity form success settings and table permissions for redirect page
Problem: Validation messages don’t appear in the correct language Solution: Configure localized validation messages in form metadata
Problem: File uploads fail silently Solution: Check file size limits, allowed file types, and storage configuration
Problem: Users receive “Access Denied” when submitting forms Solution: Verify table permissions, entity form permissions, and user role assignments
Problem: Conditional logic doesn’t work on mobile devices Solution: Test JavaScript functionality across devices, ensure event handlers work with touch
Best Practices for Portal Forms
- User Experience First: Design forms from the user’s perspective, not the database structure
- Progressive Enhancement: Start with basic HTML forms, then add JavaScript enhancements
- Clear Error Messages: Tell users exactly what’s wrong and how to fix it
- Consistent Styling: Use your site’s design system for all form elements
- Accessibility: Ensure forms work with screen readers and keyboard navigation
- Security by Design: Validate everything server-side, never trust client-side validation alone
- Test Thoroughly: Test forms with real users on real devices with real data
Summary
Great forms feel effortless to users while collecting high-quality data for your organization. Focus on understanding your users’ goals, removing unnecessary friction, and providing clear feedback throughout the process. Remember that every field you add increases the chance of abandonment—be ruthless about what’s truly necessary.
In the next episode, you’ll learn how to provide rich information and functionality through detailed record pages that give users everything they need to accomplish their goals.