Skip to content
Viames Marino edited this page Mar 26, 2026 · 3 revisions

Pair framework: Text

Pair\Html\FormControls\Text is the standard single-line text input. It is the simplest and most reusable control in Pair, and many other input controls mirror its API because they all rely on the same FormControl::renderInput(...) machinery.

Rendered HTML:

<input type="text" ... />

Main methods

Text adds only one concrete method of its own:

  • render(): string

In practice, most of the API you use comes from FormControl:

  • value()
  • required()
  • minLength()
  • maxLength()
  • pattern()
  • placeholder()
  • inputmode()
  • label()
  • description()
  • id()
  • class()
  • data()
  • aria()
  • title()
  • form()
  • validate()

What render() actually does

Text::render() delegates to the shared helper:

// Text reuses the shared input renderer with type="text".
return parent::renderInput('text');

That means the control automatically benefits from the common behavior defined in FormControl:

  • escaped name and value
  • minlength and maxlength
  • required, readonly, disabled
  • placeholder, pattern, CSS classes and custom attributes

Most-used patterns

Basic required field

$title = (new \Pair\Html\FormControls\Text('title'))
    // Explicit label keeps the form layout readable.
    ->label('Title')
    // Base validation will reject an empty POST value.
    ->required()
    // These limits are both rendered in HTML and checked server-side.
    ->minLength(3)
    ->maxLength(120)
    // Placeholder is a visual hint only.
    ->placeholder('Insert title');

Input used as slug or code

$slug = (new \Pair\Html\FormControls\Text('slug'))
    ->label('Slug')
    // Restrict the accepted shape on text-like controls.
    ->pattern('^[a-z0-9-]+$')
    // Hint the keyboard without changing validation behavior.
    ->inputmode('text')
    ->placeholder('my-page-slug');

Editable field preloaded from a record

$customerName = (new \Pair\Html\FormControls\Text('customerName'))
    // Stable ids help when labels, JS, or tests target the field directly.
    ->id('customer-name')
    ->label('Customer name')
    // Preload the current value shown to the user.
    ->value($customer->name)
    ->class(['form-control', 'form-control-lg']);

Search-like field with frontend hooks

$query = (new \Pair\Html\FormControls\Text('query'))
    ->label('Search')
    // Keep the placeholder focused on the search domain.
    ->placeholder('Name, email or company')
    // data-* attributes are convenient for autocomplete widgets.
    ->data('endpoint', '/api/customers/search')
    ->data('min-length', '3')
    ->class(['form-control', 'js-customer-search']);

Field rendered outside the form tag

$notesFilter = (new \Pair\Html\FormControls\Text('notesFilter'))
    ->label('Filter')
    // The browser will submit this field with the target form.
    ->form('orders-filter-form');

Validation

Text does not override validate(), so it uses the generic validation from FormControl.

What is checked:

  • required value not empty
  • minimum length
  • maximum length

What is not checked by the base validator:

  • the pattern(...) rule
  • business-specific constraints
  • uniqueness or database-driven checks

Example:

$username = (new \Pair\Html\FormControls\Text('username'))
    // Reuse the same control definition for HTML hints and server-side baseline checks.
    ->required()
    ->minLength(3)
    ->maxLength(20);

// validate() reads Post::get('username'), not the object's current value property.
$isValid = $username->validate();

Secondary methods worth knowing

These methods are inherited but frequently useful with Text:

  • renderLabel() Useful when the layout prints label and control separately.
  • print() Small echo helper around render().
  • arrayName() Rare for a text field, but useful in dynamic tag/filter UIs.
  • autofocus() Good for search bars, modal forms, and first-step wizards.

Notes

  • pattern(...) is allowed on Text, but the default server-side validator does not enforce the regex; use model/request validation when the pattern matters for security or correctness.
  • inputmode(...) is only a browser hint.
  • Since Text uses the shared base implementation, custom HTML attributes passed in the constructor or via data(), aria(), title(), and form() are all appended automatically.

See also: FormControl, Textarea, Search, Email, Form.

Clone this wiki locally