Monday, October 14, 2013

Merge forms in CRM 2013 form customizations


If you have upgraded from CRM 2011 to CRM 2013 you may have noticed that the forms in 2013 has been redesigned with the new look. After upgrading to CRM 2013 from CRM 2011, the Information form or any other classic form for any entity will be taken over to 2013. Moreover, if you have setup a new fresh CRM 2013 and want to use the classic Information form, you can see that in “Inactive” state as you can see in the below screen shot.


If you would like to use these forms in a new UI then you a new feature introduced in CRM 2013 would be very helpful for you. When you customize an entity form you will see a button called “Merge Forms” as highlighted below. 
 
 
The feature of this form is simply merging of forms with an existing form from an earlier version of CRM. Hence you can only use this feature on a 2013 forms. When you click on this button you will get the below lookup window which lists ALL THE CLASSIC forms that you have in your system irrespective of the form state.



Once the form is merged you will see the merged content at the end of the current form.

Changes you can see after merge forms:

  1. It will carry over all the previous java script libraries along with their registered events on the current form 
  2. All the tabs from the existing forms will get appended in the current form just after the previous tabs as highlighted below

3.  Once the form gets merged the header/footer fields of the previous form will get added under a new tab called “Information Header” or “Information Footer” as highlighted below.



In Addition to this, you cannot display more than 4 fields in the form header and as soon as you add fifth field you will see the below notification.


 
The process of Merging forms will save lot of time if you wish to use your previous form design back to new 2013 forms instead of re-designing it manually.


Monday, September 30, 2013

Now Store Images in CRM 2013

We got the first hint of the much awaited data type Image with the introduction of activity feeds where we were allowed to provide a profile image for a user. Though the Activity Feeds had it, it was still not available for other entities OOB or custom.

In CRM 2013, the Dynamics CRM Product team has moved a step further and made this data available to all entities custom and some of the OOB but with a catch. The catch being you can still have only one image associated per record This still serves the purpose in most common cases where you would like to store the contact or product image along with the record.

Let us see how to define this attribute in CRM and later check how to programmatically read/write the image attribute on the record.

By default CRM now ships with the image attribute added to the following OOB entities


Setting up an entity for Image:

A new setting is now available on the entity form “Primary Image”. Use this setting to enable the Image attribute. Setting it to none, will not enable this feature i.e the image will not be shown on the entity form.

If the Image feature is enabled, you will find an image container in the record header as can be seen below.


In the Contact Entity the Image feature is enabled by default. However though the image attribute has been added to the Sales Order entity, it is not enabled by default. You can enable it by customizing the entity and selecting the image attribute.

For Custom entities, you first need to add an image attribute.



Note: The attribute schema name is fixed to “entityimage” and cannot be modified.

Also there can be only one attribute of image data type per entity. Adding another will show the following error


Once the attribute is added, it is now available for selection on the Primary Image setting on the entity.

To show image on the form follow this steps:

Go to form customization - >> Form Properties ->> Go to Display tab ->> check the Image section ->> Show image in the form option as highlighted below then click ok. Save and publish.


Now create a record and check on the top left side as shown in the below screenshot. Click on the image to add/edit and browse new image


Programmatically Read/Write the Image to the record:

Reading entity records using Columns.AllColumns does not return the image attribute. You need to specifically list out the attribute for reading data stored in the image attribute.

Reading Image from a record:
//read the contact
                    var qry = from c in context.CreateQuery("contact")
                              orderby c.GetAttributeValue<string>("fullname")
                              select new
                                  {
                                      name = c.GetAttributeValue<string>("fullname"),
                                      id = c.GetAttributeValue<Guid>("contactid"),
                                      image = c.GetAttributeValue<byte[]>("entityimage")
                                  };

                    var contactid = qry.First().id;
                    var name = qry.First().name;

                    //read the image for the contact
                    byte[] data = (byte[]) qry.First().image;

                    //download the image
                    using (System.IO.FileStream fileStream = new FileStream(name + ".png", FileMode.OpenOrCreate))
                    {
                        fileStream.Write(data, 0, data.Length);
                    }

Add/Update the Image of a record:

//update the record with a new image
                    string path = @"C:\test.png";
                    byte[] uploaddata = null;

                    //download the image
                    using (System.IO.FileStream fileStream = new FileStream(path, FileMode.Open))
                    {
                        int size = (int) fileStream.Length ;
                        uploaddata = new byte[size];
                        fileStream.Read(uploaddata, 0, size);

                    }

                    Entity contact = context.CreateQuery("contact").Where(c => c.GetAttributeValue<Guid>("contactid").Equals(contactid)).First<Entity>();

                     //set the image data
                    contact.Attributes["entityimage"] =  uploaddata;

                    context.UpdateObject(contact);
                    context.SaveChanges();


Identify if an entity has image enabled:

The EntityMetadata now returns a property PrimaryImageAttribute that provides the name of the attribute that stores the image data.

Display the image in an IFRAME:

The image would always be cropped to a square with dimensions of 144x144 or less depending on the size of the image uploaded.

Not sure if this is the supported way, but you can display the image in an IFRAME using the “entityimage_url” property. It stores the link to the image. Using a hardcoded link the image could be displayed as shown below


Conclusion:

The next logical step would be to extend this design to allow for multiple image attributes per entity