Version de développement
Cette documentation décrit la version « next » (develop), non encore publiée. Pour la version stable, basculez sur « v5 » dans l'en-tête.
Composants UI

Personnalisation des listes intégrées

Afficher une liste d'enregistrements dans un formulaire ou une boîte de dialogue avec frappe.ui.EmbeddedList : source des données, colonnes, recherche, actions.

Personnalisation des listes intégrées

frappe.ui.EmbeddedList affiche un tableau d'enregistrements dans un conteneur : un onglet de formulaire, une boîte de dialogue, une page. Le desk l'utilise par exemple dans la boîte Paramètres du DocType et dans le formulaire Rôle.

Le composant n'est pas dans le bundle principal du desk. Chargez-le avant de l'utiliser :

await frappe.require("embedded_list.bundle.js");

Afficher une liste

frappe.ui.form.on("Customer", {
    async refresh(frm) {
        await frappe.require("embedded_list.bundle.js");
        const list = new frappe.ui.EmbeddedList({
            wrapper: frm.fields_dict.contacts_html.$wrapper.empty(),
            doctype: "Contact",
            fields: ["name", "full_name", "email_id", "is_primary_contact"],
            filters: [["Dynamic Link", "link_name", "=", frm.doc.name]],
            show_search: false,
            empty_message: __("Aucun contact"),
            columns: [
                { label: __("Nom"), fieldname: "full_name", type: "link", route: (row) => ["Form", "Contact", row.name] },
                { label: __("Email"), fieldname: "email_id" },
                { label: __("Principal"), fieldname: "is_primary_contact", type: "check" },
            ],
        });
        list.refresh();
    },
});

Exemple fictif : contacts_html est un champ HTML personnalisé du formulaire Client. Le filtre porte sur la table enfant Dynamic Link du contact. Appelez refresh() pour charger et afficher les lignes.

Options

OptionDéfautRôle
wrapper—Conteneur (élément ou jQuery). Obligatoire.
doctype, fields, filters, order_byfields: ["name"]Requête frappe.db.get_list. Toutes les lignes sont chargées (limit: 0).
get_data—Fonction qui renvoie une promesse de lignes. Remplace la requête par défaut.
get_page—Fonction ({ start, page_length, txt }) qui renvoie une page de lignes. Active la pagination et la recherche côté serveur.
page_size50Nombre de lignes affichées avant le bouton « Charger plus ».
columns[]Colonnes du tableau (voir plus bas).
show_searchtrueAffiche la zone de recherche. Mettez false pour une liste courte et fixe.
title, description—En-tête de la liste.
add_button—{ label, action(refresh) } : bouton d'ajout dans l'en-tête.
on_row_click—Fonction appelée avec la ligne cliquée.
empty_message, no_match_message, loading_message, error_messagetextes standardMessages des états vide, sans résultat, chargement et erreur.

Colonnes

CléRôle
label, fieldnameEn-tête et champ affiché. Le texte est échappé.
aligncenter ou right.
typecheck (coche), badge (avec color, texte ou fonction), link (avec route(row) ou url(row), et text(row) facultatif), actions.
render(row)Renvoie le HTML de la cellule. Échappez vous-même les valeurs.
on_click(row)Rend la cellule cliquable.

Une colonne type: "actions" contient des boutons :

{
    type: "actions",
    actions: [
        { label: __("Supprimer"), icon: "trash-2", danger: true,
          confirm: __("Supprimer {0} ?"), confirm_field: "full_name",
          action: (row, refresh) => frappe.db.delete_doc("Contact", row.name).then(refresh) },
    ],
}

confirm ouvre une confirmation avant l'action. {0} est remplacé par la valeur de confirm_field. Une action danger a un bouton rouge.

Révéler un contenu au survol de la ligne

Placez la classe embedded-list-hover-reveal sur l'élément à masquer dans une cellule. Il devient visible quand la ligne est survolée ou qu'un de ses éléments a le focus clavier.

{ label: "", render: (row) => `<span class="embedded-list-hover-reveal">${__("Voir le détail")}</span>` }

Le masquage utilise visibility : la largeur de la cellule ne change pas. Sur un écran tactile (sans survol), le contenu reste toujours visible. Réservez ce comportement aux contenus secondaires.