Chaque application métier contient la même page, réécrite pour chaque table : une liste avec une zone de recherche et un pageur, un formulaire pour créer et modifier, une confirmation pour supprimer, et le code qui écrit. Notre propre démo d'administration comptait quatre gestionnaires de requêtes et environ quatre cents lignes de constructeurs de page rien que pour les clients, puis la même chose pour les fournisseurs, et encore pour les factures.
sgcWebSockets 2026.10 ajoute TsgcHTMLComponent_CRUD, qui prend en charge cette page. La démo construit désormais la zone clients avec un adaptateur de six méthodes, et conserve la version écrite à la main juste à côté, pour que vous puissiez comparer les deux.
La page
uses
sgcHTML_Component_CRUD;
FCRUD := TsgcHTMLComponent_CRUD.Create(Self);
FCRUD.CRUDID := 'customers';
FCRUD.RoutePrefix := '/customers';
FCRUD.Title := 'Customers';
FCRUD.KeyField := 'ID';
FCRUD.PageSize := 15;
FCRUD.Actions := [caCreate, caEdit, caDelete, caView, caExport];
FCRUD.DataSet := FDQueryCustomers;
Relié à un jeu de données, il lit lui-même ses colonnes, et c'est toute la page : liste, recherche, pagination, formulaire de création et de modification, confirmation de suppression et export CSV de ce que la liste affiche.
Ou votre propre SQL
Un jeu de données est une façon de stocker des enregistrements, pas la seule. Tout ce qui modifie un enregistrement passe par un adaptateur, de sorte que le composant ne voit jamais de SQL, d'enregistrement ni de pilote de base de données :
type
TCustomersAdapter = class(TsgcHTMLCRUDAdapter)
public
function Locate(const aKey: string): Boolean; override;
function Read(const aKey: string; aValues: TStrings): Boolean; override;
function List(const aSearch: string; aPage, aPageSize: Integer;
aRows: TStrings): Integer; override;
function Insert(aValues: TStrings; var aKey: string;
aErrors: TStrings): Boolean; override;
function Update(const aKey: string; aValues, aErrors: TStrings)
: Boolean; override;
function Delete(const aKey: string; aErrors: TStrings): Boolean; override;
end;
FCRUD.SetAdapter(TCustomersAdapter.Create(FCRUD));
Six méthodes par-dessus ce que vous avez déjà. Dans la démo, chacune est un simple appel au pool de bases de données de l'application.
Les parties que vous auriez écrites ensuite
Verrouillage optimiste. Nommez une colonne de version, et un enregistrement compare ce que le navigateur envoie avec ce qui est stocké, de sorte que la deuxième personne à cliquer sur Enregistrer est informée que l'enregistrement a changé, au lieu d'écraser silencieusement le premier :
FCRUD.VersionField := 'UPDATED_AT';
Maître-détail. Les listes filles d'un enregistrement sont d'autres composants CRUD, affichés sous le formulaire pendant l'édition de l'enregistrement :
with FCRUD.Details.Add do
begin
CRUD := FCRUDOrderLines;
MasterField := 'ORDER_ID';
Caption := 'Lines';
end;
Une validation qui parle de vos données, pas de formulaires. Les colonnes obligatoires sont l'affaire du composant ; OnValidate est l'endroit où vivent les règles qui parlent des clients. Ajoutez une ligne par problème, et l'écriture est refusée, le formulaire revenant avec elles.
Deux façons de commencer
Dans l'IDE, il y a désormais un assistant : Tools › Nouvelle page CRUD sgcHTML. Nommez la table, la clé et les colonnes, et le composant est créé sur la fiche en cours de conception, avec les deux lignes qui le connectent déjà présentes dans le presse-papiers.
En dehors de l'IDE, il existe un outil en ligne de commande, sgcHTMLGen, qui écrit le source de la page en Object Pascal ou en C# :
sgcHTMLGen crud --table Customers --prefix /customers ^
--fields "ID:key CODE:req:32 NAME:req:120 CITY:80 NOTES:noform"
Comment la page répond
Chaque contrôle de la page envoie ses données de la même façon : la zone de recherche, le bouton Nouveau, les boutons Modifier et Supprimer d'une ligne, et le formulaire lui-même, portent trois champs cachés, action, crud et, quand cela a un sens, key. L'hôte les lit et appelle ProcessAction, qui renvoie le balisage à insérer.
Un message envoyé sur le socket ne porte aucun chemin, il n'atteint donc jamais le routeur et ne bénéficie jamais de sa propre vérification. L'autoriser est l'affaire de l'application, et le moteur vous donne désormais ce qu'il faut pour cela :
oSession := FHTMXEngine.MessageSession(aConnection, FAuth);
try
if not Assigned(oSession) then
Exit; // a write with nobody behind it is not a write
oPage.ProcessAction(vAction, oParams.Values['key'], oParams, aResponse);
finally
oSession.Free;
end;
La clé qui arrive depuis le navigateur est localisée avant qu'aucune écriture ne s'exécute, de sorte qu'une clé qui n'appartient à personne n'écrit rien.
Voir les deux versions
Dans Demos\60.HTML\01.RunTime\02.AdminCRUD, /customers est le composant et /customers-classic est la page qu'il remplace. Même base de données, mêmes données, même apparence. L'une des deux est plus courte de quatre cents lignes.
Mise à niveau
Le composant fait partie de sgcHTML et s'ajoute sans rien casser : rien ne change dans une page existante tant que vous n'en déposez pas un sur une fiche.
À lire aussi
- Posez une question à votre grille Delphi en anglais simple
- Atteindre un navigateur fermé, depuis Delphi
- sgcWebSockets 2026.10, tout le reste de cette version
Voir la vidéo
Il existe une courte vidéo à ce sujet sur la chaîne eSeGeCe.
Des questions, un retour ou besoin d'aide pour la migration ? Contactez-nous — vous recevrez une réponse des personnes qui ont écrit le code.
