I. Introduction

De manière générale, l'Ajax est utilisé afin de rafraîchir des données sans avoir à rafraîchir la page elle-même. Dans Salesforce, cette technique est utilisée en standard dans l'édition en ligne des enregistrements.

Ajax rend également possible la création de listes de sélection dépendantes, dont les valeurs sont alimentées par des enregistrements d'objets, par exemple, les constructeurs et les modèles de voiture.

Autre exemple, la mise à jour automatique d'un tableau de bord d'indicateurs sans rafraîchissement de la page courante.

Dans cet article, je vous expliquerai comment appeler une méthode Apex via de l'Ajax dans Salesforce avec comme exemple, l'ajout d'un enregistrement en base de données sans rechargement de page et vous vous apercevrez, que ce n'est vraiment pas insurmontable.

Avant d'aller plus loin, une petite piqûre de rappel à propos des termes-clés qui se retrouveront tout au long de ce tutoriel :

- l'Ajax (Asynchronous JavaScript and XML) est un procédé permettant de faire une requête en direction du serveur web pour que celui-ci exécute des calculs et renvoie le résultat sous la forme de page web, cela permet de rafraîchir les données d'une page web sans avoir besoin de la rafraîchir elle-même ;

- l'Apex est un langage de programmation côté serveur permettant de modifier la logique métier et le traitement des données ;

- Salesforce est un CRM (Customer Relationship Manager) orienté SAAS (Software as a Service) et PAAS (Platform as a Service) permettant la gestion des relations clients d'une entreprise.

Je vous propose une illustration pour une meilleure compréhension du principe de ce qui est présenté :

Image non disponible

Lorsque nous sommes sur notre page Visualforce et que nous désirons rafraîchir nos informations ou d'exécuter des calculs, cela a pour effet de :

- envoyer une requête Ajax vers les serveurs de Salesforce ;

- traitement des données et mise en page ;

- renvoi des données traitées vers la page Visualforce.

II. Éléments requis

Avant toute chose, vous devez disposer d'une instance afin de pouvoir suivre ce tutoriel. Si ce n'est pas le cas, vous pouvez en obtenir une à cette adresse . Salesforce met à disposition plusieurs types d'instances qui proposent différentes fonctionnalités et donc, à différents prix (prix par licence utilisateur par mois). La seule instance que vous pourrez généreusement obtenir de la part de Salesforce est celle de développement (celle que je vous propose via le lien du dessus) qui comme son nom l'indique, sert à tester et développer des services. Je vous laisse juger par vous-même la grille tarifaire sur les diverses instances que propose Salesforce.

Salesforce permet d'exécuter cette fonctionnalité assez simplement puisqu'il est seulement nécessaire de créer une classe WSDL (Web Services Description Language) ainsi que la page Visualforce à partir de laquelle, la méthode Apex sera appelée.

III. Présentation du déroulement

Le scénario employé sera la création d'un modèle de voiture grâce à un formulaire. Pour ce faire et comme précisé dans la partie précédente, nous aurons seulement besoin d'une classe WSDL que nous nommerons « Voiture_Ajax » et d'une page Visualforce.

L'enregistrement que nous allons ajouter proviendra d'un objet « Voiture__c » comportant les champs suivants :

- Nom (Text) ;

- Référence (Text) ;

- Couleur (Picklist) ;

- Prix (Currency) ;

Le modèle de données doit ressembler à ceci :

Image non disponible

Les champs « Created By », « Last Modified By », « Owner » et « Voiture Name » sont par défaut, vous n'avez pas besoin de vous en préoccuper.

Notre exemple se déroule en trois étapes :

  1. L'utilisateur saisit les informations concernant l'enregistrement et valide le formulaire(à noter qu'aucune vérification de la conformité des données n'est effectuée ici).

    Image non disponible
  2. Du JavaScript (jQuery) appelle une classe WSDL qui crée l'enregistrement dans Salesforce et le retourne. J'utilise du jQuery par habitude, mais du JavaScript standard fonctionne tout aussi bien.


    Image non disponible
  3. Les données du formulaire sont réinitialisées et une méthode jQuery affiche les données de l'enregistrement renvoyées par la requête Ajax.



    Image non disponible

IV. Code

Maintenant, place au code qui a servi à réaliser cette démonstration (un fichier .zip est disponible plus bas en téléchargement).

IV-A. Classe WSDL

Classe WSDL
Sélectionnez
global class Voiture_Ajax {

    webService static Voiture__c saveVoiture(String nom, String reference, String couleur, String prix) { 
        Voiture__c voiture = new Voiture__c(
            Nom__c = nom,
            Reference__c = reference,
            Couleur__c = couleur,
            Prix__c = Decimal.valueOf(prix)
        );
        
        insert voiture;
        
        return voiture;
    }
}

  1. Vous l'aurez sûrement remarqué, ici, nous n'utilisons pas une classe Apex classique, mais une classe globale et nous avons également une méthode Web Service (WebService Methods) afin de permettre qu'une application externe puisse interagir avec celle-ci.
    Nous récupérons plusieurs valeurs en paramètres, le nom de la voiture, sa référence, sa couleur et son prix. Nous créons ensuite notre objet de type « Voiture__c » (qui correspond au nom API de notre objet au sein du CRM) en lui fournissant les valeurs dont il a besoin pour continuer par l'insérer et le retourner à l'utilisateur (afin d'obtenir son identifiant Salesforce entre autres puisque que nous n'en disposons pas avant l'étape de l'insertion).

IV-B. Page Visualforce

Page Visualforce
Sélectionnez
<apex:page standardController="Voiture__c">

    <apex:includeScript value="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"/>
    <apex:includeScript value="/soap/ajax/15.0/connection.js" />
    <apex:includeScript value="/soap/ajax/15.0/apex.js" />
    
    <script type="text/javascript">
        $jquery = jQuery.noConflict();
        
        function init(){
            sforce.connection.sessionId = '{!$Api.Session_ID}';
        }
        
        function submitForm(){
            var voiture = sforce.apex.execute("Voiture_Ajax","saveVoiture",{
               nom : $jquery('[id$=nom]').val(),                              
               reference : $jquery('[id$=reference]').val(),
               couleur : $jquery('[id$=couleur]').val(),
               prix : $jquery('[id$=prix]').val(),
            });   
           alert("Completed !");
           resetForm(); 
           populateVoiture(voiture[0]);     
        }
        
        function resetForm(){
            $jquery('[id$=nom]').val('');                          
            $jquery('[id$=reference]').val('');
            $jquery('[id$=couleur]').val('');
            $jquery('[id$=prix]').val('');
        }
        
        function populateVoiture(voiture){
            $jquery('#nom_ajax').html(voiture.Nom__c);                          
            $jquery('#reference_ajax').html(voiture.Reference__c);
            $jquery('#couleur_ajax').html(voiture.Couleur__c);
            $jquery('#prix_ajax').html(voiture.Prix__c);
        } 
    </script>
    
    <style type="text/css">
        #fieldset_form{
            width:400px;
        }
    </style>
    
    <apex:form >
        <fieldset id="fieldset_form">
            <legend>Création d'une voiture en Ajax</legend>
            <div>
                <table>
                    <tr>
                        <th>Nom : </th>
                        <td><apex:inputField id="nom" value="{!Voiture__c.Nom__c}" /></td>
                    </tr>
                    <tr>
                        <th>Référence : </th>
                        <td><apex:inputField id="reference" value="{!Voiture__c.Reference__c}" /></td>
                    </tr>
                    <tr>
                        <th>Couleur : </th>
                        <td>
                            <apex:inputField id="couleur" value="{!Voiture__c.Couleur__c}" />
                        </td>
                    </tr>
                    <tr>
                        <th>Prix : </th>
                        <td><apex:inputField id="prix" value="{!Voiture__c.Prix__c}" /></td>
                    </tr>
                </table>
            </div>
            <a href="javascript:void(0)" onCLick="submitForm();return false;">Valider le formulaire</a>
        </fieldset>
    </apex:form>
    
    <fieldset id="fieldset_form">
        <legend>La voiture créée en Ajax</legend>
        <div>
            <table>
                <tr>
                    <th>Nom : </th>
                    <td><span id="nom_ajax"></span></td>
                </tr>
                <tr>
                    <th>Référence : </th>
                    <td><span id="reference_ajax"></span></td>
                </tr>
                <tr>
                    <th>Couleur : </th>
                    <td><span id="couleur_ajax"></span></td>
                </tr>
                <tr>
                    <th>Prix : </th>
                    <td><span id="prix_ajax"></span></td>
                </tr>
            </table>
        </div>
    </fieldset>
    
    <apex:outputLink value="/apex/test_ajax" >Rafraîchir la page</apex:outputLink>

    <script type="text/javascript">
        $jquery(function() {
            init();
        });
    </script>

</apex:page>

Il est important d'inclure ces trois scripts (la bibliothèque jQuery ainsi que les fichiers connection.js et apex.js) sans quoi, l'appel à la méthode Apex en Ajax ne pourra fonctionner. Ces fichiers existent par défaut dans les instances de Salesforce. Peu importe la version de jQuery utilisée et il est tout à fait possible de ne pas l'utiliser, je rappelle que du JavaScript fonctionnerait parfaitement, je me sers du jQuery par habitude.

Il est intéressant de remarquer cette syntaxe :

 
Sélectionnez
$jquery = jQuery.noConflict();

Cela sert dans le cas où plusieurs bibliothèques JavaScript sont utilisées dans une même page, pour ne pas qu'elles interagissent et évite ainsi, tout conflit. Vous différenciez donc votre bibliothèque d'une autre grâce à cette syntaxe, mais il ne faudra pas oublier d'utiliser « $jquery » lorsque vous souhaiterez l'appeler.

Une deuxième ligne intéressante est celle-ci :

Enregistrement de la voiture
Sélectionnez
var voiture = sforce.apex.execute("Voiture_Ajax","saveVoiture",{
     nom : $jquery('[id$=nom]').val(),                              
    reference : $jquery('[id$=reference]').val(),
    couleur : $jquery('[id$=couleur]').val(),
    prix : $jquery('[id$=prix]').val(),
});

Elle signifie qu'elle recourt à la méthode execute() qui sert à faire l'appel Ajax d'une méthode Apex et qui prend en premier paramètre, le nom de notre classe WSDL suivi du nom de notre méthode Apex et enfin, un tableau contenant les valeurs à lui transmettre. Souvenez-vous un peu plus haut lorsque je vous ai détaillé le fonctionnement de la méthode statique saveVoiture() de la classe globale Voiture_Ajax. Nous retrouvons ici, les valeurs (récupérées dans le formulaire) qui y sont envoyées en paramètres afin de créer notre voiture dans Salesforce.

À savoir que la valeur de retour de cette méthode statique est l'enregistrement lui-même (celui de la voiture).

Il est tout à fait possible d'inclure la bibliothèque jQuery en tant que ressource statique dans l'instance de Salesforce (grâce à la syntaxe ci-dessous) une fois que celle-ci a été téléchargée :

Inclusion JavaScript
Sélectionnez
<apex:includeScriptvalue="{!$Resource.MyJavascriptFile}"/>

Mis à part cela, rien de bien exceptionnel en ce qui concerne cette page Visualforce. Nous créons un formulaire où les données seront saisies et lorsque ceci est fait, nous les récupérons en jQuery.

Vous l'aurez compris, utiliser de l'Ajax peut grandement vous simplifier la vie dans certains cas, mais surtout apporter plus de confort à l'utilisateur.

V. Conclusion

Pour clôturer ce tutoriel, je vous propose de télécharger ces trois fichiers (classe Apex, page Visualforce et l'objet Voiture) compressés dans une archive au format .zip icisources de ce tutoriel.

Source de ce tutoriel

Il est également disponible sur mon site personnel à cette adresse.

VI. Remerciements

Je souhaite remercier tous ceux qui ont contribué de près comme de loin à la réalisation de ce tutoriel, j'entends par là Max, Lana.Bauer, vermine et Deepin.