Skip to content

Form Assistant Demo

This demo shows how VOIX can help users fill out forms. The AI can understand form fields and fill them based on natural language instructions.

How It Works

The form provides tools for filling different sections and context about available fields and validation rules.

Code

html
<!-- Form filling tools -->
<tool name="fill_personal_info" description="Fill personal information fields">
  <prop name="firstName" type="string"/>
  <prop name="lastName" type="string"/>
  <prop name="email" type="string" description="Email address"/>
  <prop name="phone" type="string" description="Phone number"/>
</tool>

<tool name="fill_address" description="Fill address information">
  <prop name="street" type="string"/>
  <prop name="city" type="string"/>
  <prop name="state" type="string"/>
  <prop name="zipCode" type="string" description="5-digit ZIP code"/>
</tool>

<tool name="select_preferences" description="Set user preferences">
  <prop name="newsletter" type="boolean" description="Subscribe to newsletter"/>
  <prop name="notifications" type="string" description="email, sms, or none"/>
  <prop name="language" type="string" description="en, es, fr, or de"/>
</tool>

<tool name="submit_form" description="Submit the completed form">
</tool>

<tool name="clear_form" description="Clear all form fields">
</tool>

<!-- Form context -->
<context name="form_status" id="form-context">
  Form status: Empty
  Required fields: firstName, lastName, email
  Filled fields: none
  Validation errors: none
</context>

<!-- Form UI -->
<form id="demo-form">
  <fieldset>
    <legend>Personal Information</legend>
    <div class="form-group">
      <label>First Name *</label>
      <input type="text" name="firstName" required>
    </div>
    <div class="form-group">
      <label>Last Name *</label>
      <input type="text" name="lastName" required>
    </div>
    <div class="form-group">
      <label>Email *</label>
      <input type="email" name="email" required>
    </div>
    <div class="form-group">
      <label>Phone</label>
      <input type="tel" name="phone">
    </div>
  </fieldset>
  
  <fieldset>
    <legend>Address</legend>
    <div class="form-group">
      <label>Street</label>
      <input type="text" name="street">
    </div>
    <div class="form-group">
      <label>City</label>
      <input type="text" name="city">
    </div>
    <div class="form-group">
      <label>State</label>
      <input type="text" name="state">
    </div>
    <div class="form-group">
      <label>ZIP Code</label>
      <input type="text" name="zipCode" pattern="[0-9]{5}">
    </div>
  </fieldset>
  
  <fieldset>
    <legend>Preferences</legend>
    <div class="form-group">
      <label>
        <input type="checkbox" name="newsletter">
        Subscribe to newsletter
      </label>
    </div>
    <div class="form-group">
      <label>Notifications</label>
      <select name="notifications">
        <option value="none">None</option>
        <option value="email">Email</option>
        <option value="sms">SMS</option>
      </select>
    </div>
    <div class="form-group">
      <label>Language</label>
      <select name="language">
        <option value="en">English</option>
        <option value="es">Spanish</option>
        <option value="fr">French</option>
        <option value="de">German</option>
      </select>
    </div>
  </fieldset>
  
  <div id="form-message"></div>
</form>

<script>
// Form handlers
const handlers = {
  fill_personal_info: (data) => {
    const form = document.getElementById('demo-form');
    if (data.firstName) form.firstName.value = data.firstName;
    if (data.lastName) form.lastName.value = data.lastName;
    if (data.email) form.email.value = data.email;
    if (data.phone) form.phone.value = data.phone;
    updateFormContext();
  },
  
  fill_address: (data) => {
    const form = document.getElementById('demo-form');
    if (data.street) form.street.value = data.street;
    if (data.city) form.city.value = data.city;
    if (data.state) form.state.value = data.state;
    if (data.zipCode) form.zipCode.value = data.zipCode;
    updateFormContext();
  },
  
  select_preferences: (data) => {
    const form = document.getElementById('demo-form');
    if (data.newsletter !== undefined) {
      form.newsletter.checked = data.newsletter;
    }
    if (data.notifications) {
      form.notifications.value = data.notifications;
    }
    if (data.language) {
      form.language.value = data.language;
    }
    updateFormContext();
  },
  
  submit_form: () => {
    const form = document.getElementById('demo-form');
    const formData = new FormData(form);
    const data = Object.fromEntries(formData);
    
    // Check required fields
    if (!data.firstName || !data.lastName || !data.email) {
      showMessage('Please fill all required fields', 'error');
      return;
    }
    
    // Validate email
    if (!data.email.includes('@')) {
      showMessage('Please enter a valid email', 'error');
      return;
    }
    
    showMessage('Form submitted successfully!', 'success');
  },
  
  clear_form: () => {
    document.getElementById('demo-form').reset();
    updateFormContext();
    showMessage('Form cleared', 'info');
  }
};

// Attach event listeners
document.querySelectorAll('tool[name]').forEach(tool => {
  const name = tool.getAttribute('name');
  tool.addEventListener('call', (e) => {
    handlers[name]?.(e.detail);
  });
});

// Update form context
function updateFormContext() {
  const form = document.getElementById('demo-form');
  const formData = new FormData(form);
  const data = Object.fromEntries(formData);
  
  const filled = Object.entries(data).filter(([k, v]) => v).map(([k]) => k);
  const required = ['firstName', 'lastName', 'email'];
  const missing = required.filter(field => !data[field]);
  
  let status = 'Empty';
  if (filled.length > 0 && missing.length > 0) status = 'Partially filled';
  else if (missing.length === 0) status = 'Ready to submit';
  else if (filled.length > 0) status = 'In progress';
  
  document.getElementById('form-context').textContent = `
Form status: ${status}
Required fields: ${required.join(', ')}
Filled fields: ${filled.length ? filled.join(', ') : 'none'}
Validation errors: ${missing.length ? `Missing: ${missing.join(', ')}` : 'none'}

Available notification options: none, email, sms
Available languages: en (English), es (Spanish), fr (French), de (German)
  `;
}

// Show messages
function showMessage(text, type) {
  const msg = document.getElementById('form-message');
  msg.textContent = text;
  msg.className = `message ${type}`;
  setTimeout(() => {
    msg.textContent = '';
    msg.className = '';
  }, 3000);
}

// Initial context update
updateFormContext();
</script>

<style>
form {
  max-width: 500px;
  margin: 1rem 0;
}

fieldset {
  margin: 1rem 0;
  padding: 1rem;
  border: 1px solid #ddd;
  border-radius: 8px;
}

legend {
  font-weight: bold;
  padding: 0 0.5rem;
}

.form-group {
  margin: 0.75rem 0;
}

.form-group label {
  display: block;
  margin-bottom: 0.25rem;
  font-weight: 500;
}

.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="tel"],
.form-group select {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 1rem;
}

.form-group input[type="checkbox"] {
  margin-right: 0.5rem;
}

.message {
  margin: 1rem 0;
  padding: 0.75rem;
  border-radius: 4px;
  font-weight: 500;
}

.message.success {
  background: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

.message.error {
  background: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;
}

.message.info {
  background: #d1ecf1;
  color: #0c5460;
  border: 1px solid #bee5eb;
}
</style>

Try It

Form status: Partially filled Required fields: firstName, lastName, email Filled fields: language Validation errors: Missing: firstName, lastName, email Available notification options: none, email, sms Available languages: en (English), es (Spanish), fr (French), de (German)
Personal Information
Address
Preferences

Example Interactions

Try these with VOIX:

  • "Fill in John Doe with email john@example.com"
  • "Set the phone number to 555-1234"
  • "Fill the address as 123 Main St, San Francisco, CA 94105"
  • "Subscribe to newsletter and set notifications to email"
  • "Change language to Spanish"
  • "Submit the form"

The AI reads the form context to understand required fields and validation rules.

Released under the MIT License.