Lire autres tables à partir d'un widget personnalisé

Bonjour
J’ai créer un widget personnalisé sur une table. Cette table est liée par référence multiple à d’autres tables sur id ligne
Quel script écrire dans mon widget personnalisé pour accéder aux informations de ces tables de référence.
Je suis débutant et je découvre Grist
Merci d’avance pour votre aide

Bonjour,

Je ne sais pas si c’est le plus simple de coder votre propre widget si vous débutez avec Grist :slight_smile: Mais à coeur vaillant rien d’impossible !

En tout cas ce n’est pas trivial de récupérer les colonnes de type référence depuis un widget, car elle ne sont pas incluses par défaut dans onRecords.

On peut utiliser grist.docApi.fetchTable('_grist_Tables_column') pour récupérer la liste complète des colonnes.

Un ex ici :

Avec ce script qui fonctionne bien :

grist.ready({ requiredAccess: 'full' });

const output = document.querySelector("#data");

async function loadData() {
  try {
    const table = await grist.getTable();
    const tableId = await table._platform.getTableId();
    const data = await grist.docApi.fetchTable(tableId);
    
    // Métadonnées pour résoudre les refs
    const docInfo = await grist.docApi.fetchTable('_grist_Tables_column');
    const tablesInfo = await grist.docApi.fetchTable('_grist_Tables');
    const currentTableNumericId = tablesInfo.id[tablesInfo.tableId.indexOf(tableId)];
    
    // Index des colonnes par id numérique
    const colById = {};
    for (let i = 0; i < docInfo.id.length; i++) {
      colById[docInfo.id[i]] = { colId: docInfo.colId[i], parentId: docInfo.parentId[i] };
    }
    
    // Identifier les colonnes Ref/RefList et construire les lookups
    const refLookups = {}; // colId -> { refData, displayColId, isRefList }
    
    for (let i = 0; i < docInfo.colId.length; i++) {
      if (docInfo.parentId[i] !== currentTableNumericId) continue;
      const colId = docInfo.colId[i];
      const type = docInfo.type[i];
      
      let refTable = null;
      let isRefList = false;
      if (type.startsWith('Ref:')) {
        refTable = type.substring(4);
      } else if (type.startsWith('RefList:')) {
        refTable = type.substring(8);
        isRefList = true;
      }
      
      if (refTable) {
        try {
          const refData = await grist.docApi.fetchTable(refTable);
          
          // Trouver la visibleCol configurée
          let displayColId = null;
          const visibleColRef = docInfo.visibleCol?.[i];
          if (visibleColRef && visibleColRef !== 0 && colById[visibleColRef]) {
            displayColId = colById[visibleColRef].colId;
          }
          if (!displayColId || !refData[displayColId]) {
            displayColId = Object.keys(refData).find(k => k !== 'id' && k !== 'manualSort');
          }
          
          // Construire un map id -> label
          const idToLabel = {};
          for (let j = 0; j < refData.id.length; j++) {
            idToLabel[refData.id[j]] = displayColId ? refData[displayColId][j] : refData.id[j];
          }
          
          refLookups[colId] = { idToLabel, isRefList };
        } catch (e) { }
      }
    }
    
    const columns = Object.keys(data).filter(c => c !== 'manualSort' && !c.startsWith('gristHelper'));
    const nbRows = data.id.length;
    
    let text = `Nombre de lignes: ${nbRows}\n\n`;
    text += `Colonnes: ${columns.join(", ")}\n\n`;
    
    for (let i = 0; i < nbRows; i++) {
      text += `--- Ligne ${i} ---\n`;
      columns.forEach(col => {
        let val = data[col][i];
        
        if (refLookups[col]) {
          const { idToLabel, isRefList } = refLookups[col];
          if (isRefList && Array.isArray(val)) {
            // RefList: val est ['L', id1, id2, ...]
            const ids = val.slice(1);
            val = ids.map(id => idToLabel[id] ?? id).join(", ");
          } else {
            // Ref simple: val est un id numérique
            val = idToLabel[val] ?? val;
          }
        }
        
        text += `${col}: ${val}\n`;
      });
      text += "\n";
    }
    
    output.textContent = text;
  } catch (e) {
    output.textContent = "Erreur: " + e.message;
  }
}

loadData();
grist.onRecords(() => loadData());

Sinon, vous avez des exemples plus simples pour débuter ici : Démarrer avec le Custom Widget Builder : exemples simples

Merci beaucoup audezu
Je m’aperçois enfin de la complexité de Grist, jusque là cela me paraissait simple.

En fait j’ai du code Html qui affiche des données et j’ai du javascript qui commence par
grist.onRecord(function(record) {
if (!record) return;

j’affiche simplement les informations de l’enregistrement courant
document.getElementById(‹ NomProjet ›).textContent = record.Nom_du_projet || ‹  ›;
document.getElementById(‹ Libprojet ›).textContent = record.Libelle_projet || ‹  ›;
document.getElementById(‹ Portmetier ›).textContent = record.Porteur_metier || ‹  ›;

dans ma table j’ai une colonne JalonProjet de type référence multiple qui stocke l’id ligne d’une autre table Jalons contenant plusieurs informations.
ma difficulté est d’aller chercher 3 ou 4 information dans cette table Jalons pour les afficher dans le Html.
Je pensais que ça allait être simple mais pas du tout vu le code. Je ne me décourage pas, je vais prendre le temps de comprendre votre exemple
Merci encore pour votre réactivité

}

Bonjour à tous
malgré mon acharnement, je ne réussi pas à récupérer les informations des colonnes (NomJalon, StatutJalon, DateDébut, DateFin) de ma table Jalons à partir de l’id ligne référencé (multiple) dans ma table projet sur lequel j’ai construit le widget personnalisé
De la même façon, j’aurai besoin de récupérer les données de ma table Risques mais si ça marche pour la table Jalon, je pense pour refaire la même chose pour les Risques
Merci d’avance pour votre aide
Merci d’avance pour votre aide