or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

attributes.mdcore-selection.mdcss.mddata.mddimensions.mdeffects.mdevents.mdforms.mdindex.mdmanipulation.mdtraversal.mdutilities.md
tile.json

forms.mddocs/

Forms and Input

Form-specific functionality for handling input values, form serialization, and form control manipulation.

Capabilities

Form Value Management

Get and set values for form inputs, selects, and textareas with proper type handling.

/**
 * Get the value of the first form element
 * @returns Element value as string or array of strings (for multi-select)
 */
val(): string | string[];

/**
 * Set the value of all form elements
 * @param value - Value to set (string or array for multi-select)
 * @returns The Cash collection for chaining
 */
val(value: string | string[]): this;

Usage Examples:

// Get form values
const textValue = $('.text-input').val();      // "user input"
const selectValue = $('.select').val();        // "option2"
const multiSelect = $('.multi-select').val();  // ["option1", "option3"]
const checkboxValue = $('.checkbox:checked').val(); // "checked-value"

// Set form values
$('.text-input').val('new value');
$('.select').val('option3');
$('.multi-select').val(['option1', 'option2']); // Select multiple
$('.checkbox').val('checked'); // For checkboxes, use prop() instead

// Clear form values
$('.form input[type="text"]').val('');
$('.form textarea').val('');
$('.form select').val('');

// Dynamic form population
const userData = { name: 'John', email: 'john@example.com', country: 'US' };
$('.name-input').val(userData.name);
$('.email-input').val(userData.email);
$('.country-select').val(userData.country);

// Form validation with values
$('.required-field').each(function() {
  const value = $(this).val();
  $(this).toggleClass('error', !value || value.trim() === '');
});

// Real-time value monitoring
$('.live-input').on('input', function() {
  const value = $(this).val();
  $('.character-count').text(`${value.length}/100`);
});

Form Serialization

Serialize form data into URL-encoded strings for submission.

/**
 * Serialize form data to URL-encoded string
 * @returns Serialized form data as string
 */
serialize(): string;

Usage Examples:

// Serialize entire form
const formData = $('.contact-form').serialize();
// Result: "name=John&email=john%40example.com&message=Hello%20World"

// AJAX form submission
$('.ajax-form').on('submit', function(e) {
  e.preventDefault();
  const data = $(this).serialize();
  
  $.ajax({
    url: '/api/submit',
    method: 'POST',
    data: data,
    success: function(response) {
      $('.success-message').show();
    },
    error: function() {
      $('.error-message').show();
    }
  });
});

// Serialize specific form sections
const personalData = $('.personal-info').serialize();
const preferences = $('.preferences').serialize();

// Combine serialized data
const allData = $('.form-section').map(function() {
  return $(this).serialize();
}).get().join('&');

// Form data comparison (for unsaved changes detection)
let originalData = $('.form').serialize();

$('.form').on('change', function() {
  const currentData = $(this).serialize();
  const hasChanges = currentData !== originalData;
  $('.save-button').prop('disabled', !hasChanges);
});

// Auto-save functionality
let autoSaveTimer;
$('.auto-save-form').on('input change', function() {
  clearTimeout(autoSaveTimer);
  autoSaveTimer = setTimeout(() => {
    const data = $(this).serialize();
    saveFormData(data);
  }, 1000); // Save after 1 second of inactivity
});

Form Control Patterns

Form Validation

// Basic validation
function validateForm(form) {
  let isValid = true;
  
  // Check required fields
  form.find('[required]').each(function() {
    const value = $(this).val();
    const isEmpty = !value || value.trim() === '';
    
    $(this).toggleClass('error', isEmpty);
    if (isEmpty) isValid = false;
  });
  
  // Email validation
  form.find('input[type="email"]').each(function() {
    const email = $(this).val();
    const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    const isInvalid = email && !emailPattern.test(email);
    
    $(this).toggleClass('error', isInvalid);
    if (isInvalid) isValid = false;
  });
  
  return isValid;
}

// Usage
$('.form').on('submit', function(e) {
  if (!validateForm($(this))) {
    e.preventDefault();
    $('.validation-error').show();
  }
});

Dynamic Form Fields

// Add/remove form fields
$('.add-field').on('click', function() {
  const fieldCount = $('.dynamic-field').length;
  const newField = $(`
    <div class="dynamic-field">
      <input type="text" name="field_${fieldCount}" placeholder="Field ${fieldCount + 1}">
      <button type="button" class="remove-field">Remove</button>
    </div>
  `);
  $('.field-container').append(newField);
});

$(document).on('click', '.remove-field', function() {
  $(this).closest('.dynamic-field').remove();
});

Form State Management

// Form state tracking
function createFormState(form) {
  return {
    data: form.serialize(),
    timestamp: Date.now(),
    isValid: validateForm(form)
  };
}

// Save/restore form state
function saveFormState(form, key) {
  const state = createFormState(form);
  localStorage.setItem(key, JSON.stringify(state));
}

function restoreFormState(form, key) {
  const saved = localStorage.getItem(key);
  if (saved) {
    const state = JSON.parse(saved);
    // Restore form values from serialized data
    restoreFormFromData(form, state.data);
  }
}

// Multi-step form navigation
$('.next-step').on('click', function() {
  const currentStep = $('.form-step:visible');
  if (validateForm(currentStep)) {
    currentStep.hide().next('.form-step').show();
  }
});

$('.prev-step').on('click', function() {
  $('.form-step:visible').hide().prev('.form-step').show();
});

Advanced Form Interactions

// Dependent form fields
$('.country-select').on('change', function() {
  const country = $(this).val();
  
  // Load states/provinces for selected country
  $.get(`/api/states/${country}`, function(states) {
    const stateSelect = $('.state-select').empty();
    states.forEach(state => {
      stateSelect.append(`<option value="${state.code}">${state.name}</option>`);
    });
  });
});

// Form field formatting
$('.phone-input').on('input', function() {
  let value = $(this).val().replace(/\D/g, ''); // Remove non-digits
  if (value.length >= 6) {
    value = value.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
  } else if (value.length >= 3) {
    value = value.replace(/(\d{3})(\d+)/, '($1) $2');
  }
  $(this).val(value);
});

// File upload handling
$('.file-input').on('change', function() {
  const files = this.files;
  const fileList = $('.file-list').empty();
  
  Array.from(files).forEach(file => {
    fileList.append(`
      <div class="file-item">
        <span class="file-name">${file.name}</span>
        <span class="file-size">${formatFileSize(file.size)}</span>
      </div>
    `);
  });
});

// Form reset with confirmation
$('.reset-form').on('click', function() {
  if (confirm('Are you sure you want to reset the form? All changes will be lost.')) {
    $(this).closest('form')[0].reset();
  }
});