188 lines
6.7 KiB
PHP
188 lines
6.7 KiB
PHP
<?php
|
|
|
|
namespace Reservair\Forms;
|
|
|
|
/**
|
|
* Inline field collector used inside RsvFormBuilder::group().
|
|
*
|
|
* Each method appends a labelled input fragment. On render() all fragments
|
|
* are placed in a flex row, emitted as the <td> content of a single table row.
|
|
*/
|
|
class RsvFormGroup
|
|
{
|
|
/** @var string[] */
|
|
private array $items = [];
|
|
|
|
private function __construct() {}
|
|
|
|
public static function create(): static
|
|
{
|
|
return new static();
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Input methods
|
|
// -------------------------------------------------------------------------
|
|
|
|
public function text(
|
|
string $id,
|
|
string $label,
|
|
string $desc = '',
|
|
bool $required = false,
|
|
string $value = ''
|
|
): static {
|
|
$req = $required ? 'required' : '';
|
|
$ctrl = '<input class="regular-text" type="text" id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" value="' . esc_attr($value) . '" ' . $req . '>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
public function email(
|
|
string $id,
|
|
string $label,
|
|
string $desc = '',
|
|
bool $required = false,
|
|
string $value = '',
|
|
?string $list_id = null
|
|
): static {
|
|
$req = $required ? 'required' : '';
|
|
$list = $list_id !== null ? 'list="' . esc_attr($list_id) . '"' : '';
|
|
$ctrl = '<input class="regular-text" type="email" id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" value="' . esc_attr($value) . '" ' . $list . ' ' . $req . '>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
public function password(
|
|
string $id,
|
|
string $label,
|
|
string $desc = '',
|
|
bool $required = false,
|
|
string $placeholder = ''
|
|
): static {
|
|
$req = $required ? 'required' : '';
|
|
$ph = $placeholder !== '' ? 'placeholder="' . esc_attr($placeholder) . '"' : '';
|
|
$ctrl = '<input class="regular-text" type="password" id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" ' . $ph . ' ' . $req . '>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
public function number(
|
|
string $id,
|
|
string $label,
|
|
string $desc = '',
|
|
bool $required = false,
|
|
string|int $value = '',
|
|
?int $min = null,
|
|
?int $max = null
|
|
): static {
|
|
$req = $required ? 'required' : '';
|
|
$min_attr = $min !== null ? 'min="' . $min . '"' : '';
|
|
$max_attr = $max !== null ? 'max="' . $max . '"' : '';
|
|
$ctrl = '<input class="small-text" type="number" id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" value="' . esc_attr((string) $value) . '" ' . $min_attr . ' ' . $max_attr . ' ' . $req . '>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
public function date(
|
|
string $id,
|
|
string $label,
|
|
string $desc = '',
|
|
bool $required = false,
|
|
string $value = ''
|
|
): static {
|
|
$req = $required ? 'required' : '';
|
|
$ctrl = '<input class="regular-text" type="date" id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" value="' . esc_attr($value) . '" ' . $req . '>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
public function time(
|
|
string $id,
|
|
string $label,
|
|
string $desc = '',
|
|
bool $required = false,
|
|
string $value = ''
|
|
): static {
|
|
$req = $required ? 'required' : '';
|
|
$ctrl = '<input type="time" id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" value="' . esc_attr($value) . '" ' . $req . '>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
public function checkbox(
|
|
string $id,
|
|
string $label,
|
|
string $desc = '',
|
|
bool $checked = false
|
|
): static {
|
|
$c = $checked ? 'checked' : '';
|
|
$ctrl = '<input type="checkbox" id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" ' . $c . '>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
/**
|
|
* @param array<string|int, string> $options Associative: value => display text.
|
|
*/
|
|
public function select(
|
|
string $id,
|
|
string $label,
|
|
array $options,
|
|
string $desc = '',
|
|
bool $required = false,
|
|
string $selected = ''
|
|
): static {
|
|
$req = $required ? 'required' : '';
|
|
$opts = $this->build_options($options, $selected);
|
|
$ctrl = '<select id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" ' . $req . '>' . $opts . '</select>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
public function textarea(
|
|
string $id,
|
|
string $label,
|
|
string $desc = '',
|
|
bool $required = false,
|
|
string $value = '',
|
|
int $rows = 5
|
|
): static {
|
|
$req = $required ? 'required' : '';
|
|
$ctrl = '<textarea class="large-text" id="' . esc_attr($id) . '" name="' . esc_attr($id) . '" rows="' . $rows . '" ' . $req . '>'
|
|
. esc_textarea($value)
|
|
. '</textarea>';
|
|
return $this->item($id, $label, $ctrl, $desc);
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Rendering
|
|
// -------------------------------------------------------------------------
|
|
|
|
public function render(): string
|
|
{
|
|
return '<div style="display:flex; gap:1.5em; align-items:flex-end; flex-wrap:wrap;">'
|
|
. implode('', $this->items)
|
|
. '</div>';
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Private helpers
|
|
// -------------------------------------------------------------------------
|
|
|
|
private function item(string $id, string $label, string $control_html, string $desc): static
|
|
{
|
|
$d = $desc !== '' ? '<p class="description">' . esc_html($desc) . '</p>' : '';
|
|
$this->items[] = '<span style="display:flex; flex-direction:column; gap:.25em;">'
|
|
. '<label for="' . esc_attr($id) . '">' . esc_html($label) . '</label>'
|
|
. $control_html
|
|
. $d
|
|
. '</span>';
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array<string|int, string> $options
|
|
*/
|
|
private function build_options(array $options, string $selected): string
|
|
{
|
|
$html = '';
|
|
foreach ($options as $value => $text) {
|
|
$is_selected = (string) $value === $selected ? 'selected' : '';
|
|
$html .= '<option value="' . esc_attr((string) $value) . '" ' . $is_selected . '>' . esc_html($text) . '</option>';
|
|
}
|
|
return $html;
|
|
}
|
|
}
|