Composant ProTable
ProTable est le composant de tableau distant générique de Page Designer. Il permet d'appeler directement une API HTTP et de configurer les colonnes, les outils de recherche, la pagination et les actions de ligne.
Ce guide explique comment :
- Connecter une Custom URL à une API paginée GET ou POST
- Transmettre la valeur courante d'un Input ou d'un autre composant via Query Context
- Lancer une nouvelle recherche depuis la première page avec un bouton Search
- Conserver les critères actifs pendant la pagination
- Configurer les chemins de réponse, les colonnes, la clé de ligne et le rendu
- Implémenter une API compatible avec ProTable à partir de l'exemple Java
Le guide utilise l'exemple de recherche de produits fourni par Spark. L'API contient 23 produits de démonstration et accepte un keyword pour rechercher partiellement, sans tenir compte de la casse, dans le code et le nom du produit.
1. Quand utiliser ProTable
1.1 Cas d'utilisation recommandés
Utilisez ProTable lorsque :
- La page doit appeler directement une API backend spécifique
- Les données proviennent d'un service tiers ou d'agrégation plutôt que d'un seul Business Object
- L'API possède sa propre logique de pagination, de filtrage, de tri ou d'autorisation
- Un bouton appelle une API puis écrit le tableau obtenu avec
setTableData
1.2 ProTable, DataList et TaskList
| Composant | Données principales | Usage recommandé |
|---|---|---|
| ProTable | Custom URL ou Model Data Source | API HTTP génériques, données agrégées et contrats de pagination spécifiques |
| DataList | Business Object | DQL, champs de modèle, Object Actions et autorisations de données |
| TaskList | Spark Tasks | Filtres de tâches, statuts, traitement et contexte de tâche |
ProTable prend également en charge Model Data Source, dont la liaison au modèle est proche de DataList. Pour les Business Objects, DQL et filtres de modèle, consultez le guide du composant DataList. Ce guide se concentre sur la source Custom URL de ProTable.
2. Exemple utilisé dans ce guide
API d'exemple :
POST https://spark.hiforce.ai/spark/api/sample/protable/products
La page d'exemple utilise :
- Source de données : Custom URL
- Méthode : POST
- Taille par défaut : 10 enregistrements
- Left Toolbar : un Input
Key Wordet un ButtonSearch - Query Context : mappe la valeur de l'Input vers le champ
keyword - Interaction Search : appelle
reloadTablesur le ProTable courant - Colonnes :
code,name,category,priceetstock
Après connexion à Spark avec les droits nécessaires, ouvrez la page Runtime de cet exemple pour le vérifier.
3. Contrat de pagination Custom URL
3.1 Requête POST
Au chargement de la première page, ProTable fusionne les champs de pagination et les paramètres Query Context dans un corps JSON :
{
"current": 1,
"pageSize": 10,
"keyword": "Graphite"
}
| Champ | Type | Description |
|---|---|---|
current | number | Numéro de page courant, à partir de 1 |
pageSize | number | Nombre d'enregistrements par page |
keyword | string | Paramètre métier ajouté par Query Context dans cet exemple |
ProTable gère automatiquement current et pageSize. Ne les redéfinissez pas dans Query Context.
3.2 Requête GET
Avec GET, les mêmes paramètres deviennent une Query String :
/spark/api/sample/protable/products?current=1&pageSize=10&keyword=Graphite
Les valeurs undefined, null et chaînes vides sont omises. Les tableaux et objets sont sérialisés en chaînes JSON, que le backend doit analyser comme du JSON.
3.3 Structure de réponse par défaut
L'exemple renvoie le ApiResult standard de Spark, avec les données paginées sous data :
{
"success": true,
"code": 200,
"message": "Les donnees produit ont ete chargees avec succes.",
"data": {
"total": 1,
"current": 1,
"pageSize": 10,
"requestContext": {
"environment": "DEV",
"renderMode": "RUNTIME"
},
"records": [
{
"id": 4,
"code": "DSP-2002",
"name": "Graphite Monitor 32",
"category": "DISPLAY",
"status": "ACTIVE",
"price": 699.00,
"stock": 21,
"updatedAt": "2026-07-25T16:40:00Z"
}
]
}
}
Configurez les chemins ainsi :
Rows Path: data.records
Total Path: data.total
Current Page Path: data.current
Page Size Path: data.pageSize
Les chemins utilisent la notation pointée. Si les lignes se trouvent dans result.items, saisissez result.items dans Rows Path.
Une API paginée doit renvoyer le nombre total d'enregistrements filtrés, et non la taille du tableau de la page courante. Sinon ProTable ne peut pas calculer le nombre de pages.
3.4 En-têtes de contexte des requêtes de page
Lorsqu'il envoie une requête HTTP réelle via Custom URL, ProTable ajoute automatiquement deux en-têtes standard. Le backend peut les utiliser pour choisir des données de test, limiter l'accès depuis le designer ou enregistrer l'origine de la requête :
| En-tête | Valeurs | Description |
|---|---|---|
X-Spark-Page-Environment | DEV, TEST, PROD | Environnement courant de la page ; les aperçus de données dans Page Designer utilisent DEV |
X-Spark-Page-Render-Mode | DESIGN_PREVIEW, RUNTIME | Page Designer, l'aperçu ouvert depuis le designer et l'aperçu d'enregistrements réels utilisent DESIGN_PREVIEW ; les pages d'exécution normales utilisent RUNTIME |
L'environnement et le mode de rendu sont deux dimensions indépendantes. Par exemple, une page d'exécution dans l'environnement de développement envoie DEV + RUNTIME, tandis que le chargement d'enregistrements réels dans Page Designer envoie DEV + DESIGN_PREVIEW. Ces valeurs sont des énumérations stables ; le backend ne doit pas déduire le contexte à partir de l'URL de la page ou du Referer.
Il s'agit du contrat commun à toutes les requêtes backend de Page Designer et Page Runtime, pas seulement à ProTable ou Custom URL. Model Data Source, Data Form, les composants Task, les téléversements, les actions de ligne et Send Request utilisent les mêmes en-têtes. GET et POST se comportent de la même manière. Si une Custom URL cible un service d'une autre origine, sa configuration CORS doit autoriser ces deux en-têtes dans Access-Control-Allow-Headers.
4. Ajouter et configurer ProTable
4.1 Ajouter le composant
- Ouvrez la page cible dans Page Designer.
- Développez Data dans la palette.
- Faites glisser ProTable dans un conteneur compatible.
- Donnez au composant un nom stable et lisible, par exemple
productTable.
Ce nom permet de sélectionner facilement la bonne cible dans une interaction Component API.
4.2 Configurer Custom URL
Sélectionnez Custom URL dans Data Source, puis saisissez :
| Propriété | Valeur |
|---|---|
| URL | https://spark.hiforce.ai/spark/api/sample/protable/products |
| Request Method | POST |
| Rows Path | data.records |
| Total Path | data.total |
| Current Page Path | data.current |
| Page Size Path | data.pageSize |
Trois formes d'URL sont acceptées :
https://api.example.com/products
connection://erp/products
/products # Sélectionnez également un Connection Key
- Pour une API Spark de même origine, utilisez une URL complète ou un chemin relatif au site.
- Pour un service externe, configurez une External Connection dans les paramètres de l'application et utilisez son Connection Key.
- Conservez secrets, tokens et mots de passe dans la connexion, jamais dans l'URL ou Query Context.
- L'API reste soumise à l'authentification, aux droits sur les données et à l'autorisation backend. L'ouverture directe d'une API protégée dans le navigateur peut renvoyer
401.
Configurer les Response Fields
Model Data Source peut lire directement les métadonnées des champs du Business Object. Avec Custom URL, renseignez les Response Fields dans Data Source. Chaque élément contient :
| Propriété | Description |
|---|---|
| Field Path | Chemin relatif à un enregistrement, par exemple name ou owner.name |
| Label | Nom affiché dans Columns et les autres sélecteurs de champs |
| Data Type | TEXT, NUMBER, BOOLEAN, DATE, DATETIME, URL, OBJECT ou ARRAY |
Ajoutez les champs manuellement avec le bouton plus, ou cliquez sur Test & Import pour demander jusqu'à 20 enregistrements et fusionner les champs détectés. L'import respecte les règles suivantes :
- Le backend n'est appelé qu'après un clic explicite ; l'ouverture de la boîte de dialogue n'envoie aucune requête.
- La requête utilise les valeurs courantes de URL, Method, Query Context et Rows Path.
- Les objets imbriqués deviennent des chemins pointés ; pour un tableau, seul le champ du tableau est enregistré.
- Les Label, Data Type et l'ordre existants sont conservés ; seuls les nouveaux chemins sont ajoutés.
- Les valeurs d'exemple ne sont pas enregistrées, et une réponse vide ou en échec ne remplace jamais les champs existants.
Test & Import utilise le contexte de requête DEV + DESIGN_PREVIEW. Les modifications de Data Source n'entrent dans la configuration de la page qu'après Save ; Cancel abandonne le brouillon courant.
4.3 Configurer Columns
Ajoutez dans Columns, dans cet ordre :
| Label | Data Field |
|---|---|
| Code | code |
| Name | name |
| Category | category |
| Price | price |
| Stock | stock |
Data Field accepte les chemins pointés. Pour une valeur owner.name, saisissez :
owner.name
Adaptez la largeur au contenu. Une colonne de code peut être étroite, tandis qu'un nom demande plus d'espace. Un texte long ne doit pas déformer tout le tableau.
4.4 Configurer la pagination et la clé de ligne
Réglages recommandés :
Pagination / Page Size: 10
Row Unique Key: id
Row Unique Key doit être stable et unique. N'utilisez pas un nom, un statut ou une autre valeur susceptible d'être dupliquée ou modifiée.
Dans Runtime, l'utilisateur peut choisir 10, 20 ou 50 lignes par page. Un changement de page ou de taille relance l'API tout en conservant les critères Query Context.
5. Ajouter un critère dans Left Toolbar
Sélectionnez ProTable et ajoutez un Input dans Left Toolbar :
Label: Key Word
Name: productKeywordInput
Allow Clear: true
L'ID interne de l'Input dans la page d'exemple est field_bfd1e2b2. Ne le recopiez pas. Sélectionnez votre propre Input dans l'éditeur FX.
Avec Allow Clear, l'icône d'effacement apparaît lorsque l'Input contient du texte. Effacer modifie uniquement la valeur ; cliquez ensuite sur Search pour recharger sans mot-clé.
Organisation recommandée :
- Left Toolbar : Input, Date Picker, Select, Radio et Search
- Toolbar : Create, Import, Export et autres actions métier
Placez Search dans Left Toolbar pour maintenir le critère et le bouton sur la même ligne, comme dans cet exemple.
6. Lier keyword avec Query Context
Query Context mappe les valeurs Runtime vers les paramètres HTTP. L'exemple utilise :
Valeur courante de l'Input → variable productKeyword → champ keyword
6.1 Ajouter une variable
- Modifiez Data Source du ProTable.
- Cliquez sur FX dans Query Context.
- Cliquez sur Add Variable.
- Saisissez
productKeyworddans Variable Name. - Choisissez Component Value comme Source.
- Choisissez l'Input
Key Wordcomme Component.
6.2 Ajouter un paramètre de requête
Ajoutez ce paramètre :
Parameter: keyword
Value: [[productKeyword]]
Avant chaque requête, Runtime relit la valeur de l'Input. Si elle est vide, keyword est vide ; le backend d'exemple ignore alors ce filtre et renvoie tous les enregistrements.
6.3 Sources de variables courantes
| Source | Usage |
|---|---|
| Component Value | Valeur courante d'un Input, Select, Radio, Date Picker, Uploader ou autre composant |
| URL Parameter | Paramètre de l'URL du navigateur |
| Page Context | Contexte de page ou valeur écrite par une interaction précédente |
| Current Row | Champ de l'enregistrement courant dans une action de ligne |
| Static Value | Chaîne, nombre ou booléen fixe |
Target Value peut référencer une variable ou combiner des valeurs :
[[productKeyword]]
prefix-[[productKeyword]]
Lorsque Target Value vaut exactement [[variableName]], Runtime conserve si possible le type d'origine. Il n'est pas nécessaire de convertir les tableaux, objets, nombres ou booléens en chaînes.
7. Configurer le bouton Search
Ajoutez un Button dans Left Toolbar :
Text: Search
Button Type: Primary
Configurez ensuite son interaction :
- Sélectionnez Search et ouvrez Interaction editor.
- Ajoutez une action Component API.
- Choisissez le ProTable courant, par exemple
productTable, dans Target Component. - Choisissez
reloadTabledans Function. - Enregistrez l'interaction.
reloadTable démarre une nouvelle recherche :
- La page courante revient à
1. - Les valeurs Query Context sont recalculées.
- L'API reçoit les nouveaux
current,pageSizeetkeyword.
Cela évite un problème fréquent : si l'utilisateur se trouve en page 2 et recherche un mot-clé qui ne possède qu'un résultat, envoyer current: 2 renverrait correctement un tableau vide. Avec reloadTable, Search envoie current: 1 et affiche le résultat.
La pagination normale n'est pas une nouvelle recherche. Elle change uniquement current et conserve keyword :
Clic sur Search : retour à la page 1 + derniers critères
Clic sur la pagination : nouvelle page + critères conservés
8. Exemple de backend Java
L'implémentation complète se trouve dans :
spark-sample/src/main/java/hiforce/spark/sample/protable/
spark-console inclut spark-sample, l'API est donc publiée avec Spark Console. Les sections suivantes présentent le code principal attendu par Custom URL.
8.1 DTO de requête
package hiforce.spark.sample.protable.model;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
@Getter
@Setter
public class ProTableProductQueryRequest {
private Integer current = 1;
private Integer pageSize = 10;
private String keyword;
private String category;
private String status;
private BigDecimal minPrice;
private BigDecimal maxPrice;
}
Outre keyword, l'exemple prévoit la catégorie, le statut et l'intervalle de prix. L'implémentation complète comprend aussi conditions et la map sortBy.
8.2 DTO de ligne et résultat paginé
package hiforce.spark.sample.protable.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
@Getter
@AllArgsConstructor
public class ProTableProductDTO {
private final Long id;
private final String code;
private final String name;
private final String category;
private final String status;
private final BigDecimal price;
private final Integer stock;
private final Instant updatedAt;
}
@Getter
@AllArgsConstructor
public class ProTablePageResult<T> {
private final long total;
private final int current;
private final int pageSize;
private final List<T> records;
}
Dans un projet réel, placez ces deux classes public dans deux fichiers portant leur nom. Elles sont regroupées ici uniquement pour présenter le contrat.
8.3 Controller
package hiforce.spark.sample.protable.web;
import hiforce.spark.base.model.result.ApiResult;
import hiforce.spark.base.web.SparkApiResultHelper;
import hiforce.spark.sample.protable.model.ProTablePageResult;
import hiforce.spark.sample.protable.model.ProTableProductDTO;
import hiforce.spark.sample.protable.model.ProTableProductQueryRequest;
import hiforce.spark.sample.protable.service.ProTableProductService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Locale;
@RestController
@RequestMapping("/spark/api/sample/protable/products")
public class ProTableProductController {
private final ProTableProductService productService;
public ProTableProductController(ProTableProductService productService) {
this.productService = productService;
}
@PostMapping
public ApiResult<ProTablePageResult<ProTableProductDTO>> query(
@RequestBody(required = false) ProTableProductQueryRequest request,
@RequestHeader(value = "Accept-Language", required = false) String language) {
Locale locale = SparkApiResultHelper.resolveLocale(language);
return SparkApiResultHelper.success(
locale,
productService.query(request),
"SPARK-SAMPLE-PROTABLE-0001");
}
}
Le Controller renvoie des DTO et un résultat paginé dans ApiResult. Le message de succès visible est internationalisé avec le Message Code Lattice SPARK-SAMPLE-PROTABLE-0001, et non codé en dur.
8.4 Recherche partielle et pagination
package hiforce.spark.sample.protable.service;
import hiforce.spark.sample.protable.model.ProTablePageResult;
import hiforce.spark.sample.protable.model.ProTableProductDTO;
import hiforce.spark.sample.protable.model.ProTableProductQueryRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@Service
public class ProTableProductService {
private static final int MAX_PAGE_SIZE = 100;
private static final List<ProTableProductDTO> PRODUCTS = List.of(
product(1, "SPK-1001", "SparkBook Air", "COMPUTING", "ACTIVE", "999.00", 32,
"2026-07-27T14:20:00Z"),
product(2, "SPK-1002", "SparkBook Pro", "COMPUTING", "ACTIVE", "1599.00", 18,
"2026-07-28T09:10:00Z"),
product(3, "DSP-2001", "Aurora Monitor 27", "DISPLAY", "ACTIVE", "499.00", 45,
"2026-07-26T08:30:00Z"),
product(4, "DSP-2002", "Graphite Monitor 32", "DISPLAY", "ACTIVE", "699.00", 21,
"2026-07-25T16:40:00Z"),
product(5, "ACC-3001", "Pulse Mechanical Keyboard", "ACCESSORY", "ACTIVE", "129.00", 86,
"2026-07-24T11:00:00Z"),
product(6, "ACC-3002", "Flow Wireless Mouse", "ACCESSORY", "ACTIVE", "79.00", 120,
"2026-07-23T13:15:00Z"),
product(7, "ACC-3003", "Runtime Dock", "ACCESSORY", "ACTIVE", "219.00", 38,
"2026-07-22T09:45:00Z"),
product(8, "STO-4001", "Core SSD 1TB", "STORAGE", "ACTIVE", "149.00", 64,
"2026-07-21T15:20:00Z"),
product(9, "STO-4002", "Core SSD 2TB", "STORAGE", "ACTIVE", "269.00", 41,
"2026-07-20T10:05:00Z"),
product(10, "NET-5001", "Lattice Router", "NETWORK", "ACTIVE", "189.00", 27,
"2026-07-19T17:25:00Z"),
product(11, "NET-5002", "Mesh Access Point", "NETWORK", "ACTIVE", "139.00", 54,
"2026-07-18T12:35:00Z"),
product(12, "CMP-6001", "Build Station", "COMPUTING", "DRAFT", "2399.00", 7,
"2026-07-17T08:50:00Z"),
product(13, "DSP-2003", "Silk Portable Display", "DISPLAY", "ACTIVE", "329.00", 33,
"2026-07-16T14:10:00Z"),
product(14, "ACC-3004", "Spark AI Headset", "ACCESSORY", "ACTIVE", "199.00", 49,
"2026-07-15T10:45:00Z"),
product(15, "ACC-3005", "Console Camera", "ACCESSORY", "ACTIVE", "159.00", 72,
"2026-07-14T09:35:00Z"),
product(16, "STO-4003", "Archive Drive 8TB", "STORAGE", "ACTIVE", "289.00", 25,
"2026-07-13T18:20:00Z"),
product(17, "NET-5003", "Secure Gateway", "NETWORK", "DRAFT", "799.00", 5,
"2026-07-12T07:30:00Z"),
product(18, "CMP-6002", "Runtime Server", "COMPUTING", "ACTIVE", "3499.00", 4,
"2026-07-11T16:00:00Z"),
product(19, "ACC-3006", "USB-C Travel Hub", "ACCESSORY", "DISCONTINUED", "59.00", 0,
"2026-07-10T11:40:00Z"),
product(20, "DSP-2004", "Aurora Display Mini", "DISPLAY", "DRAFT", "279.00", 12,
"2026-07-09T13:05:00Z"),
product(21, "PRN-7001", "Flow Label Printer", "OFFICE", "ACTIVE", "249.00", 28,
"2026-07-08T08:25:00Z"),
product(22, "AUD-8001", "Aurora Conference Speaker", "AUDIO", "ACTIVE", "349.00", 16,
"2026-07-07T15:35:00Z"),
product(23, "PWR-9001", "Core Power Station", "POWER", "DRAFT", "899.00", 9,
"2026-07-06T10:15:00Z"));
public ProTablePageResult<ProTableProductDTO> query(ProTableProductQueryRequest request) {
ProTableProductQueryRequest query = request == null
? new ProTableProductQueryRequest()
: request;
int current = Math.max(query.getCurrent() == null ? 1 : query.getCurrent(), 1);
int pageSize = Math.min(
Math.max(query.getPageSize() == null ? 10 : query.getPageSize(), 1),
MAX_PAGE_SIZE);
String keyword = StringUtils.trimToNull(query.getKeyword());
List<ProTableProductDTO> filtered = PRODUCTS.stream()
.filter(product -> keyword == null
|| StringUtils.containsIgnoreCase(product.getCode(), keyword)
|| StringUtils.containsIgnoreCase(product.getName(), keyword))
.sorted(Comparator.comparing(ProTableProductDTO::getCode))
.toList();
long requestedOffset = (long) (current - 1) * pageSize;
int fromIndex = (int) Math.min(requestedOffset, filtered.size());
int toIndex = Math.min(fromIndex + pageSize, filtered.size());
return new ProTablePageResult<>(
filtered.size(),
current,
pageSize,
new ArrayList<>(filtered.subList(fromIndex, toIndex)));
}
private static ProTableProductDTO product(long id, String code, String name,
String category, String status, String price,
int stock, String updatedAt) {
return new ProTableProductDTO(
id, code, name, category, status,
new BigDecimal(price), stock, Instant.parse(updatedAt));
}
}
Trois comportements sont essentiels :
StringUtils.trimToNulltransforme un mot-clé vide ennull, donc aucun filtre n'est ajouté.containsIgnoreCaserecherche dans le code et le nom ;Graphitetrouve doncGraphite Monitor 32.- Le service filtre et calcule
totalavant d'extraire la page aveccurrentetpageSize.
Pour garder l'exemple centré sur keyword, le Service ci-dessus omet les filtres de catégorie, statut, prix, conditions génériques et tri multichamp de l'implémentation complète. Les 23 produits et la pagination sont identiques.
8.5 Extension GET
Pour prendre aussi en charge GET, construisez le même Request DTO à partir des paramètres et réutilisez la méthode POST :
@GetMapping
public ApiResult<ProTablePageResult<ProTableProductDTO>> queryByGet(
@RequestParam(defaultValue = "1") Integer current,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String keyword,
@RequestHeader(value = "Accept-Language", required = false) String language) {
ProTableProductQueryRequest request = new ProTableProductQueryRequest();
request.setCurrent(current);
request.setPageSize(pageSize);
request.setKeyword(keyword);
return query(request, language);
}
L'API réelle accepte aussi :
| Paramètre | Description |
|---|---|
category | Égalité de catégorie, sans tenir compte de la casse |
status | Égalité de statut, sans tenir compte de la casse |
minPrice / maxPrice | Intervalle de prix |
conditions | Tableau de conditions génériques |
sortBy | Map ordonnée des champs vers asc ou desc |
Avec GET, conditions et sortBy sont des chaînes JSON encodées dans l'URL. Avec POST, ils sont envoyés directement comme tableau ou objet JSON.
9. Configuration avancée
9.1 Plusieurs critères
Ajoutez un Category Select, Status Radio ou Price Input dans Left Toolbar, puis mappez chaque valeur :
{
"keyword": "[[productKeyword]]",
"category": "[[productCategory]]",
"status": "[[productStatus]]",
"minPrice": "[[minimumPrice]]",
"maxPrice": "[[maximumPrice]]"
}
Le backend décide si une valeur vide signifie « ne pas filtrer ». Pour une chaîne optionnelle, utilisez trimToNull ; pour un nombre optionnel, utilisez null plutôt qu'une chaîne spéciale.
9.2 Row Actions
Ajoutez View, Edit, Delete ou d'autres opérations dans Row Actions. Une action reçoit le contexte de l'enregistrement courant ; FX peut donc lire id, code ou tout autre champ de la ligne.
Après une modification réussie, appelez reloadTable sur le ProTable courant. Ajoutez une confirmation aux actions dangereuses et appliquez les contrôles d'autorisation et métier dans le backend.
9.3 setTableData
Si un bouton a déjà appelé une API et obtenu un tableau complet, il peut appeler :
setTableData(data)
Cette fonction remplace les données locales et revient à la page 1. Elle ne persiste rien et n'extrait pas automatiquement data.records d'une réponse enveloppée. La valeur doit être le tableau d'enregistrements lui-même.
Pour une pagination distante standard, préférez reloadTable afin que les critères, le total et la pagination restent gérés par le backend.
9.4 Propriétés d'affichage
| Propriété | Description |
|---|---|
| Enable Row Number | Affiche dans la première colonne un numéro continu entre les pages |
| Table Size | Définit la densité large, middle ou small |
| Show Header | Affiche ou masque l'en-tête de colonnes |
| Bordered | Affiche ou masque les bordures |
| Row Unique Key | Champ unique de chaque ligne, id par défaut |
10. Vérifier l'exemple
Après enregistrement, vérifiez dans Preview et Runtime :
- Sans mot-clé, le premier chargement affiche la page 1 et 23 enregistrements au total.
- Passez en page 2 ; les données suivantes s'affichent.
- En page 2, saisissez
Graphitepuis cliquez sur Search. - La requête utilise
current: 1et renvoie uniquementDSP-2002 / Graphite Monitor 32. - Effacez l'Input puis cliquez sur Search ; les 23 enregistrements redeviennent disponibles depuis la page 1.
- Recherchez un mot-clé couvrant plusieurs pages, puis paginez ; les requêtes suivantes conservent ce mot-clé.
Dans les outils de développement du navigateur, contrôlez le POST Request Payload :
{
"current": 1,
"pageSize": 10,
"keyword": "Graphite"
}
Vérifiez que data.total, data.current, data.pageSize et data.records correspondent à la requête.
11. Dépannage
11.1 Graphite est introuvable après une recherche depuis la page 2
Search exécute peut-être une requête ordinaire au lieu de reloadTable. Vérifiez :
Interaction: Component API
Target Component: ProTable courant
Function: reloadTable
reloadTable revient à la page 1 ; la pagination normale conserve les critères.
11.2 Les données ne changent pas après la saisie
Vérifiez dans cet ordre :
- Query Context contient le paramètre
keyword. productKeywordlit Component Value depuis le bon Input.- Target Value vaut
[[productKeyword]]. - Le champ du DTO backend s'appelle aussi
keyword. - Search appelle
reloadTablesur le bon ProTable.
11.3 L'Input n'affiche pas l'icône d'effacement
Activez Allow Clear et vérifiez que l'Input Runtime contient du texte. L'icône n'apparaît pas pour une valeur vide. Après effacement, cliquez sur Search.
11.4 L'API renvoie des données mais le tableau est vide
Vérifiez Rows Path. Dans cet exemple :
data.records
Si un chemin personnalisé incorrect est configuré, ProTable ne devine pas un autre chemin et affiche un tableau vide.
11.5 Le total ou la page est incorrect
Vérifiez que :
- Total Path pointe vers le total filtré
- Current Page Path pointe vers la page renvoyée par le serveur
- Page Size Path pointe vers la taille réellement utilisée
- La numérotation du backend commence à 1
11.6 L'API renvoie 401, 403 ou une erreur CORS
401: la session est invalide ou l'API exige une authentification.403: l'utilisateur n'a pas les droits sur l'API ou les données.- CORS : le service externe n'autorise pas l'origine Spark courante.
Pour un système externe, préférez External Connection ou un proxy backend contrôlé. N'exposez jamais d'identifiants permanents dans la page.
11.7 Les conditions GET ne sont pas analysées
GET sérialise objets et tableaux en chaînes JSON. Décodez l'URL et utilisez un parseur JSON côté backend au lieu de découper les objets par virgules. Pour des critères complexes, préférez POST.
11.8 Aucun choix dans Data Field avec Custom URL
Ouvrez Data Source, configurez les Response Fields, puis enregistrez. Vous pouvez les ajouter manuellement ou utiliser Test & Import. Les Response Fields font partie du contrat de la source de données ; charger un enregistrement dans l'aperçu du tableau ne modifie pas temporairement le catalogue de champs.
12. Liste de contrôle
- ProTable possède un nom stable et unique
- Data Source utilise Custom URL
- Les Response Fields ont été ajoutés manuellement ou importés avec Test & Import, puis enregistrés
- URL, Request Method et authentification sont corrects
- Les chemins Rows, Total, Current Page et Page Size correspondent à la réponse
- Les Data Fields des colonnes correspondent aux champs des enregistrements
- Row Unique Key est stable et unique
- Les paramètres Query Context correspondent aux champs du DTO backend
- Les variables FX lisent le bon Component Value
- Search appelle
reloadTablesur le ProTable courant - Une nouvelle recherche revient à la page 1
- La pagination normale conserve les critères
- Les cas mot-clé vide, valide et sans résultat ont été testés
- Barre d'outils, tableau et pagination ont été vérifiés dans Preview et Runtime
Une fois ces réglages terminés, ProTable fournit une liste stable pour une API HTTP personnalisée et coordonne correctement les contrôles de recherche, la pagination serveur et les interactions de page.