Stratégie de gestion des données et résolution des pièges courants avec la bibliothèque miniUI

Gestion dynamique des colonnes et injection de données

Pour maintenir une architecture propre, il est recommandé d'éviter la définition statique des colonnes directement dans le fichier HTML. La configuration via JavaScript offre plus de flexibilité pour l'ajout ou la modification de structures.

Voici comment définir les colonnes dans un tableau de configuration avant d'appliquer la mise à jour à la grille :

const columnConfig = [
    { field: "userId", width: 50, header: "ID Utilisateur" },
    { field: "username", width: 150, header: "Nom d'utilisateur" }
];

// Application de la configuration à l'instance de la grille
dataGrid.set({
    style: "width: 800px;",
    columns: columnConfig
});

Pour intégrer des données locales (mock data) dans la table, utilisez la méthode dédiée. Assurez-vous que la structure des objets correspond aux champs définis :

const localDataset = [     
    { id: 101, name: "Alice Dupont", genderCode: 1, age: 30 },
    { id: 102, name: "Bob Martin", genderCode: 1, age: 22 },
    { id: 103, name: "Claire Petit", genderCode: 0, age: 25 }
]; 

dataGrid.setData(localDataset);

Rendu personnalisé et styles conditionnels

Les valeurs binaires comme le genre (0/1) doivent souvent être converties en libellés lisibles (Femme/Homme). Créez une fonction de rendu spécifique associée à la colonne concernée :

const genderMapping = [
    { value: 1, label: 'Homme' },
    { value: 0, label: 'Femme' }
];

function renderGenderLabel(context) {
    const match = genderMapping.find(item => item.value === context.value);
    return match ? match.label : "";
}

Dans la définition de la colonne, référencez cette fonction via la propriété renderer.

Pour appliquer des styles basés sur des conditions de données (par exemple, mettre en rouge les lignes où l'âge est inférieur à 23), évitez de manipuler le DOM manuellement après chaque changement. Utilisez plutôt l'événement de dessin de cellule (drawcell) qui s'exécute automatiquement lors du rafraîchissement :

/* Définition CSS externe */
.row-alert {
    color: #ff4d4f;
    font-weight: bold;
}
dataGrid.on("drawcell", function(e) {
    // e.record contient les données brutes de la ligne actuelle
    if (e.record.age < 23) {
        e.rowStyle = "color:#ff4d4f"; 
        // Ou utiliser une classe CSS si supporté par votre version
    }
});

Cette approche centralise la logique de style et évite la duplication de code nécessaire si vous deviez parcourir les lignes manuellement avec findRows et addRowCls.

Gestion des interactions utilisateur et confirmation

Un piège fréquent concerne la suppression de données. Contrairement à la fonction native window.confirm(), mini.confirm() ne bloque pas l'exécution du script de manière synchrone simple. Il fonctionne de manière asynchrone via des callbacks.

Si vous appelez mini.confirm() sans gérer le callback correctement, l'action de suppression peut se déclencher indépendamment du choix de l'utilisateur. Voici la structure correcte :

function handleDeleteSelection(selectedRows) {
    if (!selectedRows || selectedRows.length === 0) {
        mini.alert("Veuillez sélectionner au moins une ligne.");
        return;
    }

    // Utilisation du callback pour garantir que la suppression n'a lieu qu'en cas de confirmation
    mini.confirm(
        "Confirmez-vous la suppression définitive ?", 
        "Avertissement", 
        function(action) {
            if (action === "ok") {
                dataGrid.removeRows(selectedRows);
            }
        }
    );
}

Communication inter-fenêtres et déploiement

Lorsque vous ouvrez une fenêtre modale (iframe) pour ajouter ou modifier des données, assurez-vous que le projet est servi via un serveur web (localhost, IIS, Nginx, etc.). Certains navigateurs, notamment Chrome, bloquent les fonctions comme CloseOwnerWindow si le fichier est ouvert localement (file://). Le protocole HTTP(S) est requis pour permettre la communication entre le parent et l'iframe.

Pour récupérer les données saisies dans la fenêtre enfant, accédez-y via l'événement ondestroy ou un callback de fermeture. Attention aux erreurs courantes :

  1. Oubli du paramètre de callback : Si la fonction de destruction attend un argument (ex: action) mais que celui-ci n'est pas passé depuis la fenêtre enfant, la condition échouera silencieusement.
  2. Mise à jour de la vue : Après avoir ajouté de nouveaux éléments à votre tableau de données local, vous devez impérativement ré-appliquer setData sur la grille pour refléter les chengements visuels.
// Dans la fenêtre parente
window.openModalDialog({
    url: "edit-form.html",
    ondestroy: function(returnData) {
        // Vérifiez que returnData contient bien l'action souhaitée
        if (returnData && returnData.action === "submit") {
            const newData = returnData.payload;
            
            // Clonage profond pour éviter les références partagées indésirables
            const clonedEntry = $.extend(true, {}, newData);
            
            // Ajout à la source de données locale
            localDataset.push(clonedEntry);
            
            // Rafraîchissement obligatoire de la grille
            dataGrid.setData(localDataset); 
        }
    }
});

Notez l'utilisation de $.extend(true, ...) ou mini.clone(). Copier simplement la référence de l'objet peut causer des bugs si la source de données change ailleurs dans l'application.

Validation des formulaires et état des contrôles

Pour rendre un champ non-éditable (comme un ID technique lors d'une modification), utilisez la méthode setReadOnly(true) sur l'instance du contrôle. Cela empêche la saisie tout en conservant la valeur visible.

function configureFormMode(formInstance, mode) {
    const fields = formInstance.getFields();
    const idField = fields[0]; // Supposons que le premier champ est l'ID
    
    if (mode === "edit") {
        if (idField.setReadOnly) {
            idField.setReadOnly(true);
        }
    } else {
        // En mode création, l'ID est généralement vide ou auto-généré
        idField.setReadOnly(false);
    }
}

La validation client-side doit être robuste. Pour vérifier un format de numéro de téléphone français ou international standard, attachez une fonction de validation personnalisée à l'événement onvalidation du textbox :

<input id="phoneInput" name="phoneNumber" class="mini-textbox" required="true" />
function validatePhoneNumber(event) {
    // Regex simplifiée pour numéros mobiles (commençant par 1 suivi de chiffres)
    const phonePattern = /^1[3-9]\d{9}$/;
    
    // event.isValid est true si les règles natives (required) sont passées
    if (event.isValid) {
        if (!phonePattern.test(event.value)) {
            event.errorText = "Format de numéro invalide.";
            event.isValid = false;
        }
    }
}

// Liaison de l'événement
document.getElementById('phoneInput').addEventListener('validation', validatePhoneNumber);

Cette approche permet de fournir des retours immédiats à l'utilisateur sans dépendre entièrement du backend pour les vérifications syntaxiques simples.

Étiquettes: miniUI JavaScript data-grid form-validation Frontend-Development

Publié le 9 octobre à 19h28