[CRM 2011] Passer des valeurs à une Form CRM via l'URL

13. October 2011 16:41 by Renaud in   //  Tags:   //   Comments (0)

Vous savez sûrement tous comment ouvrir une Form à partir d'un peu de javascript, mais ce qui serait intéressant maintenant c'est de pouvoir y passer des valeurs! On peut par exemple vouloir créer une nouvelle entité, tout en initialisant certains champs avec des valeurs données: une référence à une entité, un statut, etc... Pour cela, il suffit d'ajouter ces paramètres directement dans l'URL de la Form que l'on veut ouvrir. Imaginons la situation suivante:  des entités Person et Family avec une relation One to many entre elles, ainsi qu'une autre relation entre deux entités Person pour pouvoir associer à chaque record Person un record parent!  Ce qu'on aimerait ici, c'est pouvoir ajouter un enfant à une entité personne, sans devoir lui ajouter une référence vers une famille! Cela devrait être fait implicitement, puisque logiquement l'enfant sera de la même famille que le parent. Pour atteindre cet objectif, on va simplement utiliser des paramètres. Vous pouvez lire la doc MSDN à ce sujet: Set Field Values Using Parameters Passed to a Form.

Pour rappel, voici quelques paramètres utiles lors de l'ouverture d'une Form.  

etn Le LogicalName de l'entité liée
pagetype entityrecord pour afficher un record en détail, et entitylist pour afficher une view.
extraqs optionnel: permet de passer des paramètres
id optionnel: pour les forms, il permet d'ouvrir la fenêtre d'édition d'une entité existante en précisant l'id du record

Le paramètre qui va nous intéresser réellement ici, c'est extraqs. Ce paramètre va vous permettre de passer des valeurs pour les champs de la fenêtre que l'on va ouvrir. Vous pouvez passer des données pour tout type de champs, et même les champs lookups! On va donc construire une chaîne de caractères! Pour faire simple, ça fonctionne comme ça: attribute=value La seule particularité concerne les champs lookups. Pour ceux-là, il est nécessaire de spécifier trois valeurs! Dans notre cas, nous allons par exemple remplir le champs new_family qui est une référence vers un objet de type Family. Les trois valeurs que nous allons devoir passer sont:

  • new_family: l'id du record Family
  • new_familyname: la valeur qui sera affichée dans le champs (en principe, la valeur du primary field du record Family mais vous pouvez décider d'afficher autre chose)
  • new_familytype: le type du record, donc new_family dans ce cas-ci.
En javascript, cela donnera ceci:
    var extRaqs = "";
    var family = Xrm.Page.getAttribute("new_family").getValue();
    if (policyid != null) {
        extRaqs += "&new_family=" + family[0].id;
        extRaqs += "&new_familyname=" + family[0].name;
        extRaqs += "&new_familytype=new_family";
    }
Une fois qu'on a nos paramètres, il reste à encoder cette chaîne, pour la passer dans l'url comme valeur de l'attribut extraqs!
var newFamilyURL = serverUrl + "/main.aspx?etn=new_family&pagetype=entityrecord&extraqs=";

newFamilyURL += encodeURIComponent(extRaqs);

window.open(newFamilyURL , "_blank", "width=900px,height=600px,resizable=1");
Utilisez de préférence la méthode encoreURIComponent() plutôt que encodeURI() parce que la première encode également les caractères suivants: ":", "/", ";", et "?" !

[CRM 2011] Pass values to a CRM 2011 through URL parameters

13. October 2011 09:10 by Renaud in   //  Tags:   //   Comments (2)

You probably already know how to open a CRM Form in javascript, but what you may want to know is how to set fields values in the same time. For example you may want to create a new entity and automatically initialize some of the fields! To achieve this, you just have to use URL parameters. Let's take an example! We have two entity types: Person et Family. Each Person has a reference to a Family record, and each Person has a list of children of type Person. What we would like to do here, is to have a button that allow us to create a new child related to this entity. This child will have a reference to the Family entity which is referenced by the parent Person. And this must be done implicitly of course. The user doesn't want to lose time with this task. So like I said earlier, we are going to use URL parameters. You can read the MSDN documentation here about this topic: Set Field Values Using Parameters Passed to a Form.

Let me remind you the main parameters that are used to open a Form in CRM 2011:  

etn The LogicalName of the concerned entity.
pagetype entityrecord to display the details form of an entity, and entitylist to display a view.
extraqs optional: use this parameter to pass values to the form
id optional: used with the entityrecord value of pagetype, when the id parameter is present, the corresponding record is displayed

extraqs is the parameter that we should focus on! This parameter is used to pass values to the form that we are going to open. You can pass values for any type of fields, and even lookup fields! To make it simple, this is how it works: attribute=value There is only a little trick for lookup fields. For those ones, you'll have to give three different values! What does this mean for the above example if we want to fill the new_family field which is a reference to a Family record. The three values that we have to pass are:

  • new_family: the id of the family record that we want to reference
  • new_familyname: the value that will be displayed in the field (usually it is the primary field of the referenced record, but actually you can put whatever you want to displya )
  • new_familytype: the type of the record: new_family.
In javascript, we will have to make something like this:
    var extRaqs = "";
    var family = Xrm.Page.getAttribute("new_family").getValue();
    if (policyid != null) {
        extRaqs += "&new_family=" + family[0].id;
        extRaqs += "&new_familyname=" + family[0].name;
        extRaqs += "&new_familytype=new_family";
    }
Once we have the parameters in a string, we can use a javascript method to encode it, and then use the result as a value for the extraqs parameter!
var newFamilyURL = serverUrl + "/main.aspx?etn=new_family&pagetype=entityrecord&extraqs=";

newFamilyURL += encodeURIComponent(extRaqs);

window.open(newFamilyURL , "_blank", "width=900px,height=600px,resizable=1");
You should use the encoreURIComponent() method instead of encodeURI() because the second one doesn't encode the following characters: ":", "/", ";", et "?" and it may result into errors!

[CRM 2011] Ouvrir une fenêtre à l'aide d'un bouton custom et d'un peu de javascript

10. October 2011 16:44 by Renaud in   //  Tags:   //   Comments (0)

Pour ouvrir une nouvelle fenêtre via un bouton custom, vous pouvez utiliser l'action URL lors de la customization du menu Ribbon, ou bien faire vous servir d'un peu de javascript! L'intérêt du javascript c'est que vous pourrez facilement passer des données à une autre Form via le paramètre extraqs, mais ça fera l'objet d'un prochain article :) Pour le moment on va se contenter d'ouvrir une nouvelle Form! Dans cet article, vous allez voir rapidement comment:

  • Ajouter du javascript à une form
  • Ouvrir une nouvelle fenêtre en javascript
  • Ajouter un bouton au menu ribbon d'une form
  • Appeler une fonction javascript lors d'un clic sur le bouton

1/ Ajouter une ressource web: javascript

Pour insérer une feuille de script dans une page, vous devez simplement ajouter une nouvelle ressource web. Vous pouvez le faire directement via la customization de la form dans laquelle vous voulez ajouter votre script. Vous pouvez soit ajouter une nouvelle ressource, soit en utiliser une existante. Ouvrez l'éditeur et ajoutez une nouvelle fonction, disons openNewForm().

2/ Ouvrir une fenêtre

Pour ça, rien de compliqué (c'est jamais compliqué au final quand on sait :) ). Vous trouverez pas mal d'infos ici : [MSDN] Open Forms, Views, and Dialogs with a URL. L'idée c'est qu'avec certains paramètres, vous pourrez facilement ouvrir les fenêtres désirées. Vous pouvez ouvrir des Form pour éditer ou créer une nouvelle entité, afficher des listes d'entités en spécifiant la View désirée, ou ouvrir des Dialogs.

function openNewForm() {

    var serverUrl;

    var errorMessage = "Context to retrieve the Server URL is not available.";
    if (typeof GetGlobalContext != "undefined") {
        serverUrl = GetGlobalContext().getServerUrl();
    }
    else {
        if (typeof Xrm != "undefined") {
            serverUrl = Xrm.Page.context.getServerUrl();
        }
        else {
            alert(errorMessage);
            return;
        }
    }
    if (serverUrl.match(//$/))
    { 
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);
    }

    var recordUrl = serverUrl + "/main.aspx?";

    var params = "etn=new_student";

    params += "&pagetype=entityrecord";

    var accountURL = recordUrl + params;

    window.open(accountURL, "_blank", "width=900px,height=600px,resizable=1");
}

Concrètement ici, on construit l'URL de la fenêtre que l'on veut ouvrir en récupérant d'abord l'URL du serveur, et en y ajoutant les paramètres nécessaires. Si vous êtes dans CRM Online, n'oubliez pas ces lignes, l'URL retournée se termine par un "/" supplémentaire. Si vous ne l'enlevez pas, le menu Ribbon ne s'affichera pas!

if (serverUrl.match(//$/))
{ 
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}

Quelques paramètres utiles:

 

etn Le LogicalName de l'entité liée
pagetype entityrecord pour afficher un record en détail, et entitylist pour afficher une view.
extraqs optionnel: permet de passer des paramètres
id optionnel: pour les forms, il permet d'ouvrir la fenêtre d'édition d'une entité existante en précisant l'id du record

Dans le code ci-dessus, on utilise les paramètres etn=new_student et pagetype=entityrecord sans préciser l'id, ce qui aura pour effet d'ouvrir la Form de création d'un nouvel étudiant.

3/ Ajouter un bouton au menu Ribbon

Pour ajouter un nouveau bouton au menu, commencez par créer une nouvelle solution dans CRM, et ajoutez-y l'entité pour laquelle vous voulez modifier le ribbon. (Dans mon cas j'ai fait ça sur une entité new_student, qui se trouvait déjà là dans mon organisation de test :) ) Exportez la solution, et éditez le fichier customizations.xml. Localisez la balise RibbonDiffXml.

<ImportExportXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Entities>
    <Entity>
      <Name LocalizedName="Student" OriginalName="Student">new_student</Name>
      <ObjectTypeCode>10001</ObjectTypeCode>
      <EntityInfo>...</EntityInfo>
      <FormXml>...</FormXml>
      <SavedQueries>...</SavedQueries>
      <RibbonDiffXml>
        <CustomActions>
          <CustomAction Id="form.CreateOne.CustomAction"
                        Location="Mscrm.Form.new_student.MainTab.Collaborate.Controls._children"
                        Sequence="1">
            <CommandUIDefinition>
              <Button Id="form.CreateOne.Button" Command="form.CreateOne.Command" 
                      LabelText="Star" ToolTipTitle="Tip" 
                      LabelText="$LocLabels:CreateOne.LabelText" 
                      ToolTipDescription="$LocLabels:CreateOne.ToolTip" 
                      TemplateAlias="o1" />
            </CommandUIDefinition>
          </CustomAction>
        </CustomActions>

C'est pas le but de ce billet d'expliquer en détails la customization du Ribbon, mais donc le principe est d'ajouter une balise CustomAction, en précisant l'attribut Location pour indiquer où sera placé le bouton. dans la balise Button, renseignez l'attribut Command. On va la définir tout de suite :)

4/ Appeler une fonction javascript

Un peu plus bas, vous devriez trouver la balise CommandDefinitions qui est une collection de CommandDefinition. Ajoutez-y votre propre commande. L'attribut intéressant ici est Actions, qui permet de dire ce que fera votre bouton. On va y ajouter un JavaScriptFunction avec deux attributs: Library, et FunctionName. Le premier indique la webresource contenant la librairie, et le second la fonction à appeler.

        <Templates>...</Templates>
        <CommandDefinitions>
          <CommandDefinition Id="form.CreateOne.Command">
            <EnableRules/>
            <DisplayRules/>
            <Actions>
              <JavaScriptFunction Library="$webresource:new_actionScript" FunctionName="openNewForm" />
            </Actions>
          </CommandDefinition>
        </CommandDefinitions>

On ne s'occupe pas des balises EnableRules et DisplayRules pour le moment, mais juste pour info, ils vous serviront à indiquer quand le bouton doit être affiché ou activé. Dans la partie LocLabels, on peut définir les labels et tooltips pour les différentes langues installées.

        <RuleDefinitions>...</RuleDefinitions>
        <LocLabels>
          <LocLabel Id="CreateOne.ToolTip">
            <Titles>
              <Title languagecode="1033" description="Create a new student" />
              <Title languagecode="1043" description="Crée un nouvel étudiant" />
            </Titles>
          </LocLabel>
          <LocLabel Id="CreateOne.LabelText">
            <Titles>
              <Title languagecode="1033" description="Create New" />
              <Title languagecode="1036" description="Créer nouveau" />
            </Titles>
          </LocLabel>
        </LocLabels>
      </RibbonDiffXml>
    </Entity>
  </Entities>
  <Roles></Roles>
  <Workflows></Workflows>
  <FieldSecurityProfiles></FieldSecurityProfiles>
  <Templates />
  <EntityMaps>
    <EntityMap>
      <EntitySource>new_student</EntitySource>
      <EntityTarget>new_student</EntityTarget>
      <AttributeMaps />
    </EntityMap>
  </EntityMaps>
  <EntityRelationships>...</EntityRelationships>
  <OrganizationSettings />
  <optionsets />
  <Languages>
    <Language>1033</Language>
    <Language>1036</Language>
  </Languages>
</ImportExportXml>

Vous pouvez maintenant sauver le fichiers customizations.xml, et réimporter la solution. Publiez les modifications, et ouvrer une Form de l'entité pour laquelle vous avez modifié le menu. Vous verrez un nouveau bouton apparaître, et si vous cliquez dessus, une nouvelle page s'ouvrira :)

[CRM 2011] Open a window with a custom button and some javascript code

10. October 2011 09:10 by Renaud in   //  Tags:   //   Comments (3)

If you want to open a CRM form with a custom button, you can either use some attributes in the URL when customizing the Ribbon menu, or you can use some javascript code! The interest of using javascript is that you can easily pass any informations to an other form via the extraqs parameter, but we will talk about it in the next post :) For the moment, we'll just open a new Form! In this post, you'll see the following topics:

  • Add a javascript webresource to a form
  • Build the URL and open a the new Form with javascript
  • Add a custom button to the ribbon
  • Make this button call a javascript function

1/ Add a new javascript webresource to a form

To insert a new script file into a form, you just have to create a new webresource. You can do it directly in the customization form. You can select an existing webresource or create a new one. Then open the text editor, and start writing a new function. In the following example we will call this function openNewForm().

2/ Open a window

Nothing complicated here! If you want more documentation about the possibilities, just browse this link: [MSDN] Open Forms, Views, and Dialogs with a URL. The point here is that you with some parameters you can easily open an existing window. For example you can open the Form of an existing entity to edit an existing record or open it with empty fields to create a new one. You can also open a list of record, specifying the view ID, or even open Dialogs. Here is the code to add in your webresource.

function openNewForm() {

    var serverUrl;

    var errorMessage = "Context to retrieve the Server URL is not available.";
    if (typeof GetGlobalContext != "undefined") {
        serverUrl = GetGlobalContext().getServerUrl();
    }
    else {
        if (typeof Xrm != "undefined") {
            serverUrl = Xrm.Page.context.getServerUrl();
        }
        else {
            alert(errorMessage);
            return;
        }
    }
    if (serverUrl.match(//$/))
    { 
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);
    }

    var recordUrl = serverUrl + "/main.aspx?";

    var params = "etn=new_student";

    params += "&pagetype=entityrecord";

    var accountURL = recordUrl + params;

    window.open(accountURL, "_blank", "width=900px,height=600px,resizable=1");
}

What we are doing here is building the URL of the Form we want to open. First we retrieve the server URL, and then we append some parameters to it. If you are in CRM Online, you need the following lines to remove the extra slash append a the end of the URL. Otherwise the ribbon menu won't appear.

if (serverUrl.match(//$/))
{ 
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}

Some useful parameters:

 

etn The LogicalName of the concerned entity.
pagetype entityrecord to display the details form of an entity, and entitylist to display a view.
extraqs optional: use this parameter 
id optional: used with the entityrecord value of pagetype, when the id parameter is present, the corresponding record is displayed

In the code above, we use the etn=new_student and pagetype=entityrecord parameters without giving any id. The consequence will be a Form to create a new new_student entity.

3/ Add a custom button to the ribbon

For customizing the ribbon menu, you have to create a new CRM solution, and add the entity for which you want to make changes. (In my case it was for a new_student entity that was in my test organization :) ). Then export the solution and edit the customizations.xml. Find the RibbonDiffXml tag.

<ImportExportXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Entities>
    <Entity>
      <Name LocalizedName="Student" OriginalName="Student">new_student</Name>
      <ObjectTypeCode>10001</ObjectTypeCode>
      <EntityInfo>...</EntityInfo>
      <FormXml>...</FormXml>
      <SavedQueries>...</SavedQueries>
      <RibbonDiffXml>
        <CustomActions>
          <CustomAction Id="form.CreateOne.CustomAction"
                        Location="Mscrm.Form.new_student.MainTab.Collaborate.Controls._children"
                        Sequence="1">
            <CommandUIDefinition>
              <Button Id="form.CreateOne.Button" Command="form.CreateOne.Command" 
                      LabelText="Star" ToolTipTitle="Tip" 
                      LabelText="$LocLabels:CreateOne.LabelText" 
                      ToolTipDescription="$LocLabels:CreateOne.ToolTip" 
                      TemplateAlias="o1" />
            </CommandUIDefinition>
          </CustomAction>
        </CustomActions>

I won't explain the ribbon customization in details, because it's not the purpose of this article ! But to make it simple, you need to add a CustomAction tag with a Location attribute to set where the button should appear in the ribbon. Then in the Button tag, don't forget the Command attribute. We will define it right now.

4/ Call a javascript function

Then you should find the CommandDefinitions tag which is of course a collection of CommandDefinition. Add it you own command definition. In the Actions tag, you will add a new JavaScriptFunction tag with two important attributes: Library, and FunctionName. The first indicate where is located the javascript webresource that you have created in the first part of this post, and the second attribute is for the name of the function you want to call when the button has been clicked!

        <Templates>...</Templates>
        <CommandDefinitions>
          <CommandDefinition Id="form.CreateOne.Command">
            <EnableRules/>
            <DisplayRules/>
            <Actions>
              <JavaScriptFunction Library="$webresource:new_actionScript" FunctionName="openNewForm" />
            </Actions>
          </CommandDefinition>
        </CommandDefinitions>

Don't pay attention to the EnableRules and DisplayRules attributes for the moment, but you should know that with those ones you can decide to display/enable or not an action according to some rules. For example you could say that the button is only visible when a given option is selected in an optionset or when a text field has a particular value. In the LocLabels part, you can specify different labels/tooltip for each language pack.

        <RuleDefinitions>...</RuleDefinitions>
        <LocLabels>
          <LocLabel Id="CreateOne.ToolTip">
            <Titles>
              <Title languagecode="1033" description="Create a new student" />
              <Title languagecode="1043" description="Crée un nouvel étudiant" />
            </Titles>
          </LocLabel>
          <LocLabel Id="CreateOne.LabelText">
            <Titles>
              <Title languagecode="1033" description="Create New" />
              <Title languagecode="1036" description="Créer nouveau" />
            </Titles>
          </LocLabel>
        </LocLabels>
      </RibbonDiffXml>
    </Entity>
  </Entities>
  <Roles></Roles>
  <Workflows></Workflows>
  <FieldSecurityProfiles></FieldSecurityProfiles>
  <Templates />
  <EntityMaps>
    <EntityMap>
      <EntitySource>new_student</EntitySource>
      <EntityTarget>new_student</EntityTarget>
      <AttributeMaps />
    </EntityMap>
  </EntityMaps>
  <EntityRelationships>...</EntityRelationships>
  <OrganizationSettings />
  <optionsets />
  <Languages>
    <Language>1033</Language>
    <Language>1036</Language>
  </Languages>
</ImportExportXml>

Now you can save the  customizations.xml file, and import it to your organization. Publish all the modifications and open the form for which you just customized the ribbon to see the new button. Click on it to open the new Form! :)

[CRM 2011] Afficher/masquer des éléments d'une form en javascript

3. October 2011 16:48 by Renaud in   //  Tags:   //   Comments (0)

Il est assez simple d'améliorer l'expérience utilisateur en utilisant du javascript. Une des choses que vous pouvez faire est de masquer des champs qui ne sont pas nécessaires et les afficher uniquement au moment opportun. Par exemple, imaginez une entité Payment, qui représente une transaction pour une facture. Ce paiement peut être de plusieurs types: chèque, virement bancaire, cash. Dans le cas d'un virement bancaire, on aimerait en plus stocker la communication structurée. A priori, sans utiliser de javascript, le champs Communication structurée serait constamment visible. Cela pourrait être perturbant, et donner l'impression aux utilisateurs que ce champs a une importance dans tous les cas. Dans l'exemple qui va suivre, on va prendre une entité account, qui possède une picklist Account type avec pour valeurs "Type A", "Type B", ... Chacun de ces types possèdent des champs propres. Pour éviter de devoir afficher tous ces champs en même temps, on va simplement ajouter du javascript sur l'évènement OnChange du control accounttype.

1/ lier un nouveau script à la form

Ouvrez la fenêtre de customization d'une form, et cliquez sur Form Properties.

Dans la nouvelle fenêtre, le premier grid contient les fichiers javascript chargé avec la form. Cliqez sur Add, et ensuite sur New.

Entrez un nouveau nom, et comme type sélectionnez Script (JScript). Cliquez ensuite sur Text Editor. C'est là que vous allez entrer votre code. Pour bien comprendre le code qui va suivre, voici à quoi ressemble la structure de la fenêtre:

Globalement, la structure ressemble à ça:

  • Tabs: Details
    • Section typea
      • Field Type A
    • Section typeb
      • Field Type B
Pour commencer, on va simplement ajouter une fonction qui va tester la valeur sélectionnée dans new_type, et afficher ou masquer les éléments correspondants:
function onTypeChange(){
    if( Xrm.Page.getAttribute("new_type").getValue() ==1)
    {
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typea_section").setVisible(true);
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typeb_section").setVisible(false);
    }
    else if(Xrm.Page.getAttribute("new_type").getValue() ==2)
    {
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typeb_section").setVisible(true);
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typea_section").setVisible(false);
    }else
    {
        Xrm.Page.ui.tabs.get("details_tab").setVisible(false);
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typea_section").setVisible(false);
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typeb_section").setVisible(false);
        return;
    }

    Xrm.Page.ui.tabs.get("details_tab").setVisible(true);
}

Sauvez, et cliquez sur Ok. La nouvelle ressource javascript apparaîtra dans le grid de la Form Properties.

2/ appeler une fonction lorsqu'un évènement se déclenche

Dans cette même fenêtre, vous pouvez maintenant ajouter un nouvel évènement. Dans la première listbox, sélectionnez l'attribut Type. L'évènement onChange sera sélectionné. Cliquez sur Add, et entrez le nom de la fonction qui doit être appelée par cet évènement: onTypeChange. Vous pouvez faire la même chose pour l'évènement onLoad de la form.  [1] Pas de valeur sélectionnée: la tab Details est masquée. [2] Type A sélectionné: la section typea est affichée. [3] Type B sélectionné: la section typeb est affichée.

3/ quelques explications

En vérité, il y a plusieurs façon de masquer des champs dans CRM, mais voici quelques uns des choix que j'ai fait:

  • Préférer masquer une section plutôt qu'un champs. Lorsque vous masquez un champs, cela ne supprime pas l'espace lui étant réservé, et vous risquez d'avoir des blancs dans votre formulaire. Pas très esthétique.
  • Pour que ce soit vraiment idéal, pensez à mettre les champs qui peuvent être masqués en non-visibles par défaut. Cela évitera de les voir apparaître une fraction de seconde au chargement de la page. 
  • Et pour finir, utilisez de préférence la fonction setVisible(false) du sdk plutôt qu'une méthode pour modifier la visibilité d'un élément du DOM. La principale raison est que le nom que vous donnez à une section ou un tab n'apparaît pas dans le code html de la page. Vous ne trouverez que des guid pour chacun de ces éléments. Donc à moins de rechercher vous-même les guid de ces éléments pour ensuite y accéder directement, ça risque d'être un peu compliqué de retrouver le bon élément. Ne vous compliquez pas la vie :)

[CRM 2011] Dynamically show or hide fields using javascript

3. October 2011 10:10 by Renaud in   //  Tags:   //   Comments (3)

It's pretty easy to enhance the user experience with some javascript in CRM 2011. One of the things you should be able to do is to hide fields that are not necessary in some case and show them only when it's required. For example, imagine you have an account entity with an account type picklist (type A, type B, etc...) and for each type a couple of fields. if all of those fields are always visible,  it could fastly become confusing for the user. To fix this, you'll simply add some javascript on the onChange event of the paymenttype picklist.

1/ link a new javascript sheet to the form

Open the customization form of the entity, and click on Form Properties.

In the new window, there are two grids: the first one contains the javascript sheets loaded with the form, and the second one display the events handlers. Click on the Add button above the first grid and then click New. Add a name to your resource, select the Script (JScript) type, and click the Text Editor button. You can write your code here! To help you understand the following javascript code, here is what the form looks like: The structure is:

  • Tabs: Details
    • Section typea
      • Field Type A
    • Section typeb
      • Field Type B
First, we will simply add a new function to test the value of the new_type picklist (the one which contains account types). And according to the value we will display or hide the corresponding items.
function onTypeChange(){
    if( Xrm.Page.getAttribute("new_type").getValue() ==1)
    {
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typea_section").setVisible(true);
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typeb_section").setVisible(false);
    }
    else if(Xrm.Page.getAttribute("new_type").getValue() ==2)
    {
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typeb_section").setVisible(true);
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typea_section").setVisible(false);
    }else
    {
        Xrm.Page.ui.tabs.get("details_tab").setVisible(false);
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typea_section").setVisible(false);
        Xrm.Page.ui.tabs.get("details_tab").sections.get("details_typeb_section").setVisible(false);
        return;
    }

    Xrm.Page.ui.tabs.get("details_tab").setVisible(true);
}

If the value of new_type equals 1 (Type A) then we show TypeA section and hide TypeB section, etc... Then you can click close this window, and it will appear on the first grid of the Properties Form window.

2/ call a function when an event is fired

In the same window, you can add a new event handler. First select the attribute (Type). The onChange attribute will then be selected. Click add, and type the name of the function you want to call: onTypeChange. To make this even better, you can also do the same with the onLoad event of the Form. [1] Nothing selected: Details tab is hidden. [2] Type A selected: Details tab and typea section are visible. [3] Type B selected: Details tab and typeb section are visible.

3/ explanations

The truth is that you have more than one possibility to show/hide fields. But in my opinion you should:

  • Prefer to hide section instead of fields. If you hide a field, it will not collapse the space, but a blank space will replace the field. So wherever you can, group your fields that need to be show/hide at the same time under one section, and play with that section!
  • Think to uncheck the Visible by default checkbox in the properties of the item you want to show/hide.  Otherwise, it will be visible during a fraction of a second while the page is loading, and it's not really what you want!
  • Finally, use the setVisible method of the crm sdk. It's easir than trying to retrieve element from the DOM and changing its display or visibility style because if you look at the HTML code of a CRM form, you'll see that the section name doesn't appear anywhere. You will only find a guid. So it will be a little tricky to find the right DOM element except if you look in your code to find the guid of each section you want to work with.

TextBox

About the author

I'm a developer, blog writer, and author, mainly focused on Microsoft technologies (but not only Smile). I'm Microsoft MVP Client Development since July 2013.

Microsoft Certified Professional

I'm currently working as an IT Evangelist with an awesome team at the Microsoft Innovation Center Belgique, where I spend time and energy helping people to develop their projects. I also give training to enthusiastic developers and organize afterworks with the help of the Belgian community.

MIC Belgique

Take a look at my first book (french only): Développez en HTML 5 pour Windows 8

Développez en HTML5 pour Windows 8

Membre de l'association Fier d'être développeur

TextBox

Month List