(#2) - forms improvements

This commit is contained in:
Martin Slachta
2026-06-12 16:05:14 +02:00
parent 1294a177ae
commit 37bced77f4
17 changed files with 1152 additions and 1129 deletions
+62 -13
View File
@@ -5,24 +5,34 @@ namespace Reservair\Forms;
/**
* Fluent builder for WordPress admin settings forms.
*
* Renders a <table class="form-table"> with one row per field.
* Hidden inputs and datalist elements are emitted before the table;
* notices before, submit button after.
* Renders a self-contained "form-wrap" card: an optional heading and a <form>
* wrapping a <table class="form-table"> with one row per field. Hidden inputs
* and datalist elements are emitted before the table; notices before the card,
* submit button after the fields.
*
* Usage:
* echo RsvFormBuilder::create()
* echo RsvFormBuilder::create('settings', $action, 'PATCH', 'Saved.')
* ->heading('Settings')
* ->text('name', 'Name', required: true)
* ->email('email', 'Email')
* ->submit('Save');
*/
class RsvFormBuilder
{
private string $form_id = "";
private string $form_id;
/** Where the form submits, and how RsvAdminForm should send it. */
private string $action;
private string $rest_method;
private string $success_msg;
/** Optional heading shown inside the card. */
private string $heading = '';
/** @var string[] Rendered before the table (hidden inputs, datalists). */
private array $before = [];
/** @var string[] WP admin notice banners rendered before the table. */
/** @var string[] WP admin notice banners rendered before the card. */
private array $notices = [];
/** @var string[] <tr> elements inside the table. */
@@ -33,9 +43,29 @@ class RsvFormBuilder
private function __construct() {}
public static function create(string $id): static
/**
* @param string $rest_method Verb sent via data-method (POST, PUT, PATCH…).
* @param string $success_msg Message RsvAdminForm shows on success.
*/
public static function create(
string $id,
string $action,
string $rest_method = 'POST',
string $success_msg = ''
): static {
$builder = new static();
$builder->form_id = $id;
$builder->action = $action;
$builder->rest_method = $rest_method;
$builder->success_msg = $success_msg;
return $builder;
}
/** Heading shown inside the card, above the fields. */
public function heading(string $text): static
{
return new static();
$this->heading = $text;
return $this;
}
// -------------------------------------------------------------------------
@@ -206,6 +236,13 @@ class RsvFormBuilder
return $this;
}
/** WordPress nonce field, emitted inside the form before the table. */
public function nonce(string $action, string $name): static
{
$this->before[] = wp_nonce_field($action, $name, true, false);
return $this;
}
/**
* <datalist> element for email/text suggestions — emitted before the table.
*
@@ -257,15 +294,27 @@ class RsvFormBuilder
public function render(): string
{
$html = implode('', $this->notices);
$html .= implode('', $this->before);
$inner = implode('', $this->before);
if (!empty($this->rows)) {
$html .= '<table class="form-table"><tbody>' . implode('', $this->rows) . '</tbody></table>';
$inner .= '<table class="form-table"><tbody>' . implode('', $this->rows) . '</tbody></table>';
}
$html .= implode('', $this->after);
return $html;
$inner .= implode('', $this->after);
$success = $this->success_msg !== '' ? ' data-success-msg="' . esc_attr($this->success_msg) . '"' : '';
$form = '<form id="' . esc_attr($this->form_id) . '"'
. ' action="' . esc_url($this->action) . '"'
. ' method="post"'
. ' data-method="' . esc_attr($this->rest_method) . '"'
. $success . '>'
. $inner
. '</form>';
$heading = $this->heading !== '' ? '<h2>' . esc_html($this->heading) . '</h2>' : '';
return implode('', $this->notices)
. '<div class="form-wrap">' . $heading . $form . '</div>';
}
public function output(): void