or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

attributes.mdforms.mdindex.mdloading.mdmanipulation.mdstatic-methods.mdtraversal.mdutils.md
tile.json

forms.mddocs/

Form Handling

Specialized methods for working with form elements and extracting form data. These methods provide convenient ways to serialize form data and work with form element values.

Capabilities

Form Serialization

Methods for converting form data into different formats for submission or processing.

/**
 * Encode form elements as a URL-encoded string for submission
 * @returns URL-encoded string of form data
 */
serialize(): string;

/**
 * Encode form elements as an array of name-value objects
 * @returns Array of objects with name and value properties
 */
serializeArray(): { name: string; value: string }[];

Usage Examples:

// HTML form example:
// <form id="user-form">
//   <input name="username" value="john_doe">
//   <input name="email" value="john@example.com">
//   <select name="country">
//     <option value="us" selected>United States</option>
//   </select>
//   <input type="checkbox" name="newsletter" checked>
//   <textarea name="bio">Software developer</textarea>
// </form>

// Serialize as URL-encoded string
const formString = $('#user-form').serialize();
// Result: "username=john_doe&email=john%40example.com&country=us&newsletter=on&bio=Software%20developer"

// Serialize as array of objects
const formArray = $('#user-form').serializeArray();
// Result: [
//   { name: "username", value: "john_doe" },
//   { name: "email", value: "john@example.com" },
//   { name: "country", value: "us" },
//   { name: "newsletter", value: "on" },
//   { name: "bio", value: "Software developer" }
// ]

Form Element Values

Enhanced form value handling methods (extends attribute methods).

/**
 * Get value of form elements or set values
 * @param value - Value to set (string or array for multi-select)
 * @returns Current value (when getting) or Cheerio instance (when setting)
 */
val(): string | undefined | string[];
val(value: string | string[]): Cheerio<T>;

Usage Examples:

// Text inputs and textareas
$('input[name="username"]').val()            // Get current value
$('textarea[name="description"]').val('New description') // Set value

// Select elements
$('select[name="category"]').val()           // Get selected value
$('select[name="category"]').val('electronics') // Set selected option

// Multi-select elements
$('select[multiple]').val()                  // Get array of selected values
$('select[multiple]').val(['opt1', 'opt3'])  // Select multiple options

// Radio buttons
$('input[name="gender"]:checked').val()      // Get checked radio value
$('input[name="gender"][value="female"]').prop('checked', true) // Set radio

// Checkboxes
$('input[name="newsletter"]').prop('checked') // Get checkbox state (boolean)
$('input[name="terms"]').prop('checked', true) // Check checkbox

Advanced Form Handling

Complete Form Data Processing

Comprehensive patterns for working with entire forms:

/**
 * Get all form data as a structured object
 * @param form - Cheerio form element
 * @returns Object with form field names as keys
 */
function getFormData(form: Cheerio<Element>): Record<string, any> {
  const data: Record<string, any> = {};
  
  // Process all form elements
  form.find('input, select, textarea').each((i, element) => {
    const $el = $(element);
    const name = $el.attr('name');
    const type = $el.attr('type');
    
    if (!name) return; // Skip elements without names
    
    switch (type) {
      case 'checkbox':
        // Handle checkboxes - collect checked values
        if ($el.prop('checked')) {
          if (data[name]) {
            // Multiple checkboxes with same name
            if (!Array.isArray(data[name])) {
              data[name] = [data[name]];
            }
            data[name].push($el.val());
          } else {
            data[name] = $el.val();
          }
        }
        break;
        
      case 'radio':
        // Handle radio buttons - only checked value
        if ($el.prop('checked')) {
          data[name] = $el.val();
        }
        break;
        
      case 'file':
        // Handle file inputs (value is filename)
        data[name] = $el.val();
        break;
        
      default:
        // Handle text inputs, textareas, selects
        const value = $el.val();
        if ($el.attr('multiple')) {
          // Multi-select
          data[name] = Array.isArray(value) ? value : [value];
        } else {
          data[name] = value;
        }
    }
  });
  
  return data;
}

/**
 * Set form data from an object
 * @param form - Cheerio form element
 * @param data - Object with field names and values
 */
function setFormData(form: Cheerio<Element>, data: Record<string, any>): void {
  Object.entries(data).forEach(([name, value]) => {
    const $field = form.find(`[name="${name}"]`);
    const type = $field.attr('type');
    
    switch (type) {
      case 'checkbox':
        if (Array.isArray(value)) {
          // Multiple checkboxes
          $field.each((i, el) => {
            $(el).prop('checked', value.includes($(el).val()));
          });
        } else {
          // Single checkbox
          $field.prop('checked', !!value);
        }
        break;
        
      case 'radio':
        // Set radio button with matching value
        $field.filter(`[value="${value}"]`).prop('checked', true);
        break;
        
      default:
        // Text inputs, textareas, selects
        $field.val(value);
    }
  });
}

// Usage examples:
const formData = getFormData($('#registration-form'));
console.log(formData);
// { username: "john", email: "john@example.com", interests: ["coding", "music"] }

setFormData($('#user-profile'), {
  username: "jane_doe",
  email: "jane@example.com",
  country: "ca",
  newsletter: true
});

Form Validation Support

Helper methods for form validation:

/**
 * Check if form has any validation errors
 * @param form - Cheerio form element
 * @returns Boolean indicating if form is valid
 */
function isFormValid(form: Cheerio<Element>): boolean {
  let isValid = true;
  
  // Check required fields
  form.find('[required]').each((i, element) => {
    const $el = $(element);
    const value = $el.val();
    const type = $el.attr('type');
    
    if (!value || (type === 'checkbox' && !$el.prop('checked'))) {
      isValid = false;
      $el.addClass('error');
    } else {
      $el.removeClass('error');
    }
  });
  
  // Check email fields
  form.find('input[type="email"]').each((i, element) => {
    const $el = $(element);
    const email = $el.val() as string;
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    
    if (email && !emailRegex.test(email)) {
      isValid = false;
      $el.addClass('error');
    } else {
      $el.removeClass('error');
    }
  });
  
  return isValid;
}

/**
 * Clear form validation errors
 * @param form - Cheerio form element
 */
function clearFormErrors(form: Cheerio<Element>): void {
  form.find('.error').removeClass('error');
  form.find('.error-message').remove();
}

// Usage:
if (isFormValid($('#contact-form'))) {
  // Submit form
  const data = $('#contact-form').serialize();
  console.log('Form is valid, submitting:', data);
} else {
  console.log('Form has validation errors');
}

Dynamic Form Manipulation

Methods for dynamically modifying forms:

/**
 * Add form field dynamically
 * @param container - Container to add field to
 * @param fieldConfig - Configuration for the new field
 */
function addFormField(container: Cheerio<Element>, fieldConfig: {
  type: string;
  name: string;
  label: string;
  value?: string;
  required?: boolean;
}): void {
  const fieldHtml = `
    <div class="form-field">
      <label for="${fieldConfig.name}">${fieldConfig.label}</label>
      <input 
        type="${fieldConfig.type}" 
        name="${fieldConfig.name}" 
        id="${fieldConfig.name}"
        ${fieldConfig.value ? `value="${fieldConfig.value}"` : ''}
        ${fieldConfig.required ? 'required' : ''}
      >
    </div>
  `;
  
  container.append(fieldHtml);
}

/**
 * Remove form field by name
 * @param form - Form containing the field
 * @param fieldName - Name of field to remove
 */
function removeFormField(form: Cheerio<Element>, fieldName: string): void {
  form.find(`[name="${fieldName}"]`).closest('.form-field').remove();
}

// Usage:
addFormField($('#dynamic-form'), {
  type: 'text',
  name: 'phone',
  label: 'Phone Number',
  required: true
});

removeFormField($('#dynamic-form'), 'optional-field');

Form Data Conversion

Utilities for converting between different data formats:

/**
 * Convert serialized form string to object
 * @param serializedString - URL-encoded form string
 * @returns Object with parsed form data
 */
function parseFormString(serializedString: string): Record<string, string | string[]> {
  const data: Record<string, string | string[]> = {};
  
  serializedString.split('&').forEach(pair => {
    const [key, value] = pair.split('=').map(decodeURIComponent);
    
    if (data[key]) {
      // Handle multiple values for same key
      if (!Array.isArray(data[key])) {
        data[key] = [data[key] as string];
      }
      (data[key] as string[]).push(value);
    } else {
      data[key] = value;
    }
  });
  
  return data;
}

/**
 * Convert form array to object
 * @param formArray - Array from serializeArray()
 * @returns Object with grouped form data
 */
function arrayToObject(formArray: { name: string; value: string }[]): Record<string, any> {
  const data: Record<string, any> = {};
  
  formArray.forEach(({ name, value }) => {
    if (data[name]) {
      // Multiple values for same name
      if (!Array.isArray(data[name])) {
        data[name] = [data[name]];
      }
      data[name].push(value);
    } else {
      data[name] = value;
    }
  });
  
  return data;
}

// Usage:
const serialized = $('form').serialize();
const formObject = parseFormString(serialized);

const formArray = $('form').serializeArray();
const formData = arrayToObject(formArray);

Form Element Types

Supported Form Elements

Cheerio form methods work with all standard HTML form elements:

// Text-based inputs
$('input[type="text"]').val()                // Text input
$('input[type="email"]').val()               // Email input  
$('input[type="password"]').val()            // Password input
$('input[type="tel"]').val()                 // Phone input
$('input[type="url"]').val()                 // URL input
$('input[type="search"]').val()              // Search input
$('textarea').val()                          // Multi-line text

// Choice inputs
$('input[type="radio"]').prop('checked')     // Radio buttons
$('input[type="checkbox"]').prop('checked')  // Checkboxes
$('select').val()                            // Select dropdowns
$('select[multiple]').val()                  // Multi-select

// Specialized inputs
$('input[type="number"]').val()              // Number input
$('input[type="range"]').val()               // Range slider
$('input[type="date"]').val()                // Date picker
$('input[type="time"]').val()                // Time picker
$('input[type="color"]').val()               // Color picker
$('input[type="file"]').val()                // File upload

// Buttons (for form structure)
$('input[type="submit"]').prop('disabled')   // Submit button
$('input[type="reset"]').prop('disabled')    // Reset button
$('button').prop('disabled')                 // Generic button

Serialization Behavior

Understanding what gets included in form serialization:

// Elements included in serialize() and serializeArray():
// - <input> elements with name attribute (except submit, reset, button, file)
// - <textarea> elements with name attribute  
// - <select> elements with name attribute
// - Only "successful" controls (enabled, not disabled)
// - Checkboxes and radio buttons only if checked
// - File inputs include filename only (not file content)

// Elements excluded:
// - Elements without name attribute
// - Disabled elements
// - Unchecked checkboxes/radio buttons
// - Submit, reset, and button inputs
// - Form elements outside of forms

Type Definitions

// Form serialization result types
interface SerializedFormField {
  name: string;
  value: string;
}

// Form data types
type FormValue = string | string[] | boolean | number;
type FormData = Record<string, FormValue>;

// Form element types for value handling
type FormElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;