Creating Contact Form Capture in Welcome Messages
This guide demonstrates how to create a contact information capture form that appears when the chatbot opens. This is ideal for lead generation, user registration, or collecting contact details before users interact with your AI assistant.
Overview
The contact form capture feature allows you to:
- Collect user contact information (name, email, etc.) when the bot opens
- Validate form data before submission
- Send structured data to your system via JSON
- Provide a seamless user experience with form validation and feedback
- Automatically hide the form after successful submission
Use Cases
- Lead Generation: Capture potential customer information
- User Registration: Collect details for personalized experiences
- Support Tickets: Gather contact info before support conversations
- Newsletter Signups: Build email lists through bot interactions
- Event Registration: Collect attendee information
Implementation Steps
Step 1: Configure the Welcome Message
- Go to Web Controls → ai12z-bot → Your Configuration
- Navigate to Info tab → Welcome Message
- Configure the HTML, Styles, and Script tabs as shown below
Step 2: Add HTML Structure
Add this HTML in the HTML Tab:
<div class="ai12z-contact-panel my-welcome-panel">
<div class="ai12z-contact-header">
<span class="ai12z-contact-icon" aria-hidden="true">📩</span> Share Your
Contact Information
</div>
<div class="ai12z-contact-message">
Please provide your details so we can connect with you.
</div>
<div class="ai12z-contact-inputs">
<input
type="text"
id="firstName"
placeholder="First Name"
aria-label="First Name"
required
/>
<input
type="text"
id="lastName"
placeholder="Last Name"
aria-label="Last Name"
required
/>
<input
type="email"
id="email"
placeholder="Email Address"
aria-label="Email Address"
required
/>
<button type="button" class="ai12zBtn" id="contactSubmit">Submit</button>
</div>
</div>
Step 3: Add Styling
Add this CSS in the Styles Tab:
.ai12z-contact-panel {
background: #fff;
border-radius: 18px;
box-shadow: 0 2px 12px 0 rgba(32, 149, 174, 0.07);
padding: 28px 20px;
margin: 18px auto 0 auto;
max-width: 480px;
text-align: center;
font-family: inherit;
border: 1px solid #e3f2f7;
}
.ai12z-contact-header {
font-size: 1.35rem;
font-weight: 600;
margin-bottom: 12px;
color: var(--ai12zBot-v2-title-color, #2095ae);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
letter-spacing: 0.01em;
}
.ai12z-contact-icon {
font-size: 1.5em;
}
.ai12z-contact-message {
font-size: 1.08rem;
margin-bottom: 20px;
color: #2a3342;
}
.ai12z-contact-inputs {
display: flex;
flex-direction: column;
gap: 12px;
align-items: stretch;
}
.ai12z-contact-inputs input {
padding: 12px;
border-radius: 7px;
border: 1px solid #d0e6ed;
font-size: 1rem;
outline: none;
}
.ai12z-contact-inputs input:focus {
border-color: #2095ae;
box-shadow: 0 0 0 3px rgba(32, 149, 174, 0.12);
}
.ai12zBtn {
color: var(--ai12zBot-v2-button-font-color, #fff);
background: var(--ai12zBot-v2-button-background, #2095ae);
font-weight: 500;
border: none;
border-radius: 7px;
padding: 13px 18px;
cursor: pointer;
font-size: 1rem;
box-shadow: 0 1px 4px 0 rgba(32, 149, 174, 0.07);
transition:
background 0.18s,
box-shadow 0.18s,
transform 0.02s ease-in-out;
}
.ai12zBtn:hover,
.ai12zBtn:focus {
background: #176e86;
color: #fff;
box-shadow: 0 2px 8px 0 rgba(32, 149, 174, 0.13);
}
.ai12zBtn:active {
transform: translateY(1px);
}
@media (max-width: 600px) {
.ai12z-contact-panel {
padding: 20px 10px;
max-width: 98vw;
margin: 10px auto 0;
}
.ai12z-contact-header {
font-size: 1.12rem;
}
}
Step 4: Add JavaScript Functionality
Add this JavaScript in the Script Tab:
;(() => {
// Run once per bot instance, even if the script is injected multiple times
if (ai12zBot.__contactFormLoaded) return
ai12zBot.__contactFormLoaded = true
/** Attach contact form behavior inside the Shadow DOM */
const initContactForm = (target) => {
const panel = target.querySelector(".my-welcome-panel")
if (!panel || panel.dataset.bound === "1") return
const firstNameEl = panel.querySelector("#firstName")
const lastNameEl = panel.querySelector("#lastName")
const emailEl = panel.querySelector("#email")
const submitBtn = panel.querySelector("#contactSubmit")
if (!firstNameEl || !lastNameEl || !emailEl || !submitBtn) return
const isValidEmail = (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)
const handleSubmit = () => {
const firstName = firstNameEl.value.trim()
const lastName = lastNameEl.value.trim()
const email = emailEl.value.trim()
if (!firstName || !lastName || !email) {
alert("Please fill out all fields.")
return
}
if (!isValidEmail(email)) {
alert("Please enter a valid email address.")
emailEl.focus()
return
}
submitBtn.disabled = true
const prevText = submitBtn.textContent
submitBtn.textContent = "Sending..."
try {
// Send JSON data to your system
ai12zBot.sendJSON(
{ email, firstName, lastName },
"Users Contact information"
)
// Clear & hide panel (conversation continues)
firstNameEl.value = ""
lastNameEl.value = ""
emailEl.value = ""
panel.style.display = "none"
ai12zBot.sendMessage("Thank you! Your information has been submitted.")
} finally {
submitBtn.disabled = false
submitBtn.textContent = prevText
}
}
submitBtn.onclick = handleSubmit
panel.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault()
handleSubmit()
}
})
panel.dataset.bound = "1"
}
/** Translation support (if using multilingual features) */
const translateWelcomePanel = (target) => {
const innerContent = target.querySelector(".my-welcome-panel")
if (!innerContent) return
// Add your translation code here if needed
initContactForm(target)
}
// Observer to detect when bot opens
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (
mutation.type === "attributes" &&
mutation.attributeName === "class"
) {
const target = mutation.target
if (target.classList.contains("is-open")) {
translateWelcomePanel(target)
initContactForm(target)
}
}
}
})
const waitAndObserveLayout = () => {
const layoutNode = ai12zBot.shadowRoot?.querySelector(".layout")
if (!layoutNode) {
setTimeout(waitAndObserveLayout, 100)
return
}
observer.observe(layoutNode, {
attributes: true,
subtree: true,
attributeFilter: ["class"],
})
if (layoutNode.classList.contains("is-open")) {
translateWelcomePanel(layoutNode)
initContactForm(layoutNode)
}
}
waitAndObserveLayout()
})()
Key Features
Form Validation
- Required Fields: All fields must be filled out
- Email Validation: Validates email format using regex
- Real-time Feedback: Shows alerts for validation errors
- Focus Management: Automatically focuses invalid fields
User Experience
- Loading States: Button shows "Sending..." during submission
- Form Clearing: Automatically clears form after successful submission
- Form Hiding: Hides form panel after submission to continue conversation
- Keyboard Support: Submit form using Enter key
- Responsive Design: Optimized for mobile devices
Data Handling
- JSON Submission: Sends structured data using
ai12zBot.sendJSON()
- Metadata: Includes descriptive metadata with the submission
- Error Handling: Graceful error handling with user feedback
Customization Options
Adding More Fields
You can extend the form with additional fields:
<!-- Add phone number field -->
<input
type="tel"
id="phone"
placeholder="Phone Number"
aria-label="Phone Number"
/>
<!-- Add company field -->
<input type="text" id="company" placeholder="Company" aria-label="Company" />
<!-- Add dropdown selection -->
<select id="interest" aria-label="Area of Interest">
<option value="">Select Interest</option>
<option value="sales">Sales</option>
<option value="support">Support</option>
<option value="partnership">Partnership</option>
</select>
Update the JavaScript to handle new fields:
const phoneEl = panel.querySelector("#phone")
const companyEl = panel.querySelector("#company")
const interestEl = panel.querySelector("#interest")
// In handleSubmit function:
const phone = phoneEl?.value.trim() || ""
const company = companyEl?.value.trim() || ""
const interest = interestEl?.value || ""
ai12zBot.sendJSON(
{
email,
firstName,
lastName,
phone,
company,
interest,
},
"Users Contact information"
)
Styling Customization
Customize the appearance by modifying CSS variables:
.ai12z-contact-panel {
/* Change colors */
--primary-color: #2095ae;
--border-color: #e3f2f7;
--background-color: #fff;
/* Customize spacing */
padding: 32px 24px;
margin: 20px auto;
/* Adjust sizing */
max-width: 500px;
border-radius: 20px;
}
Validation Rules
Add custom validation rules:
const isValidPhone = (v) => /^\+?[\d\s\-\(\)]+$/.test(v)
// In handleSubmit function:
if (phone && !isValidPhone(phone)) {
alert("Please enter a valid phone number.")
phoneEl.focus()
return
}
Integration with CTA Controls
If using this with CTA (Call-to-Action) controls instead of the bot, change the JSON submission method:
// For CTA controls, use:
ai12zCta.sendJSON({ email, firstName, lastName }, "Users Contact information")
// Instead of:
ai12zBot.sendJSON({ email, firstName, lastName }, "Users Contact information")
Best Practices
User Experience
- Keep it Simple: Only ask for essential information
- Clear Labels: Use descriptive placeholders and labels
- Progressive Disclosure: Consider showing form after initial interaction
- Mobile-First: Ensure form works well on mobile devices
Data Collection
- Privacy Compliance: Ensure GDPR/CCPA compliance
- Secure Transmission: Data is sent securely through the platform
- Data Validation: Always validate on both client and server side
- Clear Purpose: Explain why you're collecting the information
Performance
- Single Initialization: Script prevents multiple initialization
- Event Delegation: Efficient event handling
- Memory Management: Proper cleanup and scoping
- Lazy Loading: Form only activates when bot opens
Troubleshooting
Form Not Appearing
- Check that all CSS classes match between HTML and CSS
- Verify the bot configuration is active
- Ensure the script is properly loaded
Validation Issues
- Verify email regex pattern is working
- Check that all required elements exist in DOM
- Test form submission flow thoroughly
Data Not Sending
- Confirm
ai12zBot.sendJSON()
is the correct method for your setup - Check browser console for JavaScript errors
- Verify network connectivity and API endpoints
Mobile Display Issues
- Test responsive CSS media queries
- Ensure form is accessible on touch devices
- Verify viewport meta tag is present on your page
This contact form capture feature provides a professional way to collect user information while maintaining a smooth conversational experience with your AI assistant.
Advanced Features
Conditional Form Display
Show the form only for certain conditions:
const showContactForm = () => {
// Only show for new visitors
const hasVisited = localStorage.getItem("hasVisited")
if (hasVisited) {
panel.style.display = "none"
return false
}
// Mark as visited
localStorage.setItem("hasVisited", "true")
return true
}
Multi-step Forms
Create a multi-step contact form:
let currentStep = 1
const totalSteps = 3
const showStep = (step) => {
// Hide all steps
panel
.querySelectorAll(".form-step")
.forEach((el) => (el.style.display = "none"))
// Show current step
panel.querySelector(`.form-step-${step}`).style.display = "block"
// Update progress indicator
panel.querySelector(".progress-bar").style.width =
`${(step / totalSteps) * 100}%`
}
Integration with Analytics
Track form interactions:
const handleSubmit = () => {
// Analytics tracking
if (typeof gtag !== "undefined") {
gtag("event", "contact_form_submit", {
event_category: "engagement",
event_label: "bot_welcome_form",
})
}
// Rest of submit logic...
}
This comprehensive contact form system provides a powerful way to capture leads and engage users from the moment they interact with your AI assistant.
Common Errors and Troubleshooting
Error: "ai12zBot is not defined"
Cause: Script is not properly loaded or bot is not initialized Solution:
- Ensure the script is in the Script Tab of your bot configuration
- Verify the bot configuration is active and saved
- Check that the bot is properly embedded on your page
Error: "Cannot read property of undefined"
Cause: DOM elements not found Solution:
// Add safety checks in your script
const panel = target.querySelector(".my-welcome-panel")
if (!panel) {
console.log("Panel not found - check HTML structure")
return
}
Error: Form not submitting
Cause: Missing event handlers or validation issues Solution: Check browser console for JavaScript errors and ensure all form elements have correct IDs:
<!-- Ensure IDs match JavaScript selectors -->
<input type="text" id="firstName" placeholder="First Name" required />
<input type="text" id="lastName" placeholder="Last Name" required />
<input type="email" id="email" placeholder="Email Address" required />
<button type="button" class="ai12zBtn" id="contactSubmit">Submit</button>
Error: sendJSON is not a function
Cause: Incorrect method call or bot not ready Solution:
// Check if sendJSON exists before calling
if (typeof ai12zBot.sendJSON === "function") {
ai12zBot.sendJSON({ email, firstName, lastName }, "Users Contact information")
} else {
console.error("sendJSON method not available")
}
Error: Form appears but doesn't hide after submission
Cause: Panel hiding logic not working Solution:
// Ensure panel reference is correct
panel.style.display = "none"
// Alternative method:
panel.classList.add("hidden") // Add .hidden { display: none !important; } to CSS
Debugging Steps:
- Open Browser Console (F12) and check for error messages
- Verify Element IDs match between HTML and JavaScript
- Test Form Validation by submitting with empty/invalid fields
- Check Network Tab to see if data is being sent
- Verify Bot Configuration is active and saved
Quick Debug Script:
Add this to your Script tab to help diagnose issues:
// Debug helper - add at the beginning of your script
console.log("Contact form script loading...")
console.log("ai12zBot available:", typeof ai12zBot !== "undefined")
// Add this inside initContactForm function
console.log("Panel found:", !!panel)
console.log("Form elements found:", {
firstName: !!firstNameEl,
lastName: !!lastNameEl,
email: !!emailEl,
submit: !!submitBtn,
})