Microsoft CRM Customizations
May 06, 2013
Data Types available with Microsoft Dynamics CRM 2011
When creating custom fields in Microsoft Dynamics CRM (CRM), the following data types are available to you as a customizer.
Single Line of Text – This is the simplest field type and is a string attribute. The length can be defined between 1 and 4000 characters. This field has special formatting if desired for storing Email, Text Area, Ticker Symbol, and Url. Using email will create a mailto link for that field. Ticker Symbol will provide a quote for the ticker entered into the field when the value is clicked. Url will display a link to the value entered in the field. Text Area can be displayed as more than one line on the form.
Option Set – This is commonly referred to as a pick list or drop down field. A user is only allowed to select from the choices provided. A “blank” value is acceptable. A default value can also be defined. NOTE: If you have an option set that will be used on other entities in your deployment, you will want to create a global option set for system consistency.
Two Options – This is similar to an option set but only contains two values, Zero (0) and One (1). The display of those values can be changed to represent whatever you like. No (0) and Yes (1) are common display values for this field. Another interesting note about this field is that it can be displayed on the form as a pick list, radio buttons, or check box. The value is set in the form designer after the field is placed on the form.
Multiple Lines of Text – This field is similar to Single Line of Text, however, it can store much more data than Single Line of Text. This field will be displayed as more than one line on the form.
Date and Time – This field stores date and time data. You can choose to have both the Date and Time displayed or only the Date portion.
Lookup – This field represents a link to another entity. It will create a 1:N relationship in the database with this field representing the “1” side of the relationship.
The fields below are different ways to store numerical values in CRM. In all cases, you can set minimum and maximum values. This is valuable if you want to constrain data entry to non-negative
values or from 0 to 100 for example. The minimum and maximum values are different for each data type and are set at the minimum and maximum range when the field is created.
Whole Number – This field allows you to store round (or whole) numbers, meaning no decimal points. The whole number field has different types which can be selected for Duration (activity), Time Zone, and Language (multilingual support).
Floating Point Number – This field allows for numeric values with up to five (5) decimal points. The precision of this field is arbitrary, which means it can be used to represent both very large numbers as well as very small numbers.
Decimal Number – This field stores numeric values with up to ten (10) decimal points. The precision of this field is absolute.
Currency – This field is used to store monetary values. Based on your currency settings, the correct currency symbol is also displayed such as the dollar sign or euro symbol. It can also hold up to four (4) decimal points.
Posted by Mark Weilandt on May 06, 2013 at 11:32 AM in Dynamics CRM 2011, Microsoft CRM Customizations | Permalink | Comments (0) | TrackBack (0)
January 24, 2013
CRM plus Spiderview : New Way of Visualizing Entities and Relationships
Businesses are constantly looking for new ways to view, analyze, and interact with their data, and we have developed several tools to facilitate this request. We recently had a request to pursue a new way of visualizing entities and relationships that allows the user to interact with the data in a different way. We call it Spiderview and it is a customization we built that leverages graph visualization technology.
Why this visualization is needed?
In the past we have pursued other techniques for allowing users to quickly view data about an entity and its relationships. We’ve designed customized global searches, hierarchical viewers, etc. but we had no tool that allowed users to physically navigate a relationship and view entities at a particular level. Enter this tool. Words can’t really describe the power of this technique, so what follows is a screencast demo of the tool in action.
Screencast Demo
Hopefully you got a good idea from the video the potential usefullness of this type of customization. Also please keep in mind that we can setup the viewer to show any entity/relationship and the customizations can also include different custom icons for each particular entity and things like scaling between the nodes, line color, depth, etc.
We are excited about how using graph visualizations of this nature can allow our users to see complex relationships and patterns in data that would otherwise be very cumbersome and expose data in a visual and interactive way. This type of data visualization is applicable across several industries and could be leveraged in multiple ways.
Please let us know your thoughts by commenting at blog.customereffective.com and for more information on this customization and other solutions we can provide for your organization please email us at product@customereffective.com.
Posted by Josh Greene on January 24, 2013 at 09:28 AM in Microsoft CRM Customizations | Permalink | Comments (0) | TrackBack (0)
January 03, 2013
Using LEGOs to help explain xRM and the Microsoft Dynamics CRM Platform
Microsoft provides the rich foundation, the various interconnecting blocks, and the many special pieces to easily extend Microsoft Dynamics CRM. Using Microsoft Dynamics CRM as a platform and extending CRM to meet new and different business needs is often referred to as xRM.I always enjoyed playing with LEGO® sets when I was a kid. I guess I still do, just look at my handy work for the images in this blog post. Maybe that explains why many enjoy working with Microsoft CRM. The two are similar in that you can build and create completely new and different things from the common set of building blocks.
Let’s take this analogy further. You could say that Microsoft provides three pre-built “Lego sets” with Microsoft Dynamics CRM. These sets include Sales, Service, and Marketing for a compelling Customer Relationship Management solution. You can use the features in Sales and even build on top of it if you wanted like adding your own custom fields. To perform specific tasks, you could use the special pieces that Microsoft provides such as workflow or charts for example. These special pieces fit nicely with the existing blocks. You could even dismantle Sales down to the core blocks and rebuild it your way. As a matter of fact, you could dismantle all three sets and build something completely new and different that had nothing to do with Sales, Service, or Marketing.
Using Legos to explain xRM
Building a solution using CRM that is completely new and has little or nothing to do with traditional Customer Relationship Management (sales, service, marketing) is sometimes a challenging concept to grasp. Hence, the Lego analogy. What occasionally throws people off is the name of the solution, CRM. Microsoft really can’t change the name of CRM at this point. I think that is why the term xRM is so popular and used so widely. xRM is not a product but rather a strategy for innovation using CRM. This makes CRM unique - using CRM as a platform to create solutions. Since this idea is similar to the use of Microsoft Access, I have sometimes heard CRM called “Access on steroids” but that is not a fair description. Not because CRM uses a more powerful Microsoft SQL Server database but that there is so much more in CRM as well as its well documented Software Development Kit (SDK).
Snap it all together with CRM
Microsoft has different offerings for businesses and people such as Outlook, Office, Skype, Lync, SharePoint, and Yammer to name a few. Microsoft CRM helps unify your experiences and connect these solutions together. By “together”, I mean data and a central point for solutions. Companies need one source (one database) to go to for the truth - the complete truth of a customer. Companies desire a true 360 degree view of customer activities, transactions, communications, social interactions - all the layers of customer information. Companies looking to deploy CRM often have customer data, product data, inventory data, financial data, events data, accounts receivable data, you name it, stored all over the place in separate databases and Excel files. Microsoft Dynamics CRM can help integrate to or replace those systems entirely. Just like adding the right Lego blocks, CRM can be extended to bring the data AND the business process of the retired solution directly into CRM. This makes Microsoft CRM a pivotal and key component to consolidating systems, operations, and experiences across a diverse set of screens.
Before you start putting blocks together
As easy as playing with Legos may sound, most companies seek experienced assistance to properly implement and strategically extend CRM. Before you start putting blocks together in CRM, it is recommended that you form a roadmap and plan that is specific to your CRM goals and business drivers. Start strategically by asking the critical “why” questions such as why are we doing this? As you seek help, look for partners that not only have many bright and shiny CRM blocks (some of which may already be put together for you giving you a head start), but more importantly a partner that has the discipline to know when to set those blocks aside to focus on developing your plan for measurable business improvement. Otherwise, without a plan for your CRM, you may end up with a bunch of pretty and flashy blocks snapped together that few wish to use.
CRM is like using Legos
The blocks all fit together – particularly the many unique special pieces – to consolidate business systems and data, connect applications, make it easy to use, and unify experiences.
-----------------------------
The use of the word “Lego” and “Legos” is a registered trademark under the LEGO® brand.
Posted by Will Slade on January 03, 2013 at 09:26 AM in Microsoft CRM Customizations, Microsoft CRM Implementation, XRM | Permalink | Comments (0) | TrackBack (0)
November 26, 2012
Microsoft Dynamics CRM vs. SalesForce.com Comparison: Simple Customizations
This blog is going to take a closer look at the Out of the Box (OOTB) codeless customization functionality of both Dynamics CRM and Salesforce.com. Why OOTB? Well of course in every implementation of software there is going to be some necessary customizations because every business is different; but what happens when the developers leave? What can you do in each system without spending any more money? What happens when a new position is created, a policy or process changes, or if a department is reorganized? A business is a living and breathing thing. Your software should be able to support that. The reality is that businesses evolve and so do their needs. This post will look at how each system’s OOTB functionality supports that reality without needing to call the IT department or write another check.
There are several business cases for wanting to customize your system. A very common type of customization is a change made to a record such as adding a new field or creating a view within the record to surface relevant data. Both Dynamics CRM and Salesforce.com facilitate basic record customization, and while the Dynamics approach in regards to this feature is clean, intuitive, and simple, the SalesForce.com approach is disjointed, cumbersome, and complex.
Let’s compare the two different systems in regards to these 3 simple and basic customization functions:
- Customizing record forms: fields
- Customizing record forms: Surfacing related records and data
- Saving/Publishing your customizations
First things first, let’s review the overall UI for record customizations:
In Dynamics CRM you can go to the record you want to customize and it’s one click on the customizations tab, and one click on the customize form button. You are then brought to a single screen that facilitates all 3 of the mentioned customizations as well as a few others.
SalesForce offers similar functionality (you can customize directly from the record) however each customization link brings you to a different screen. There is no one screen that allows the user to visually see the record AND all of the customization options in one place. The UI is disjointed and confusing.
Screen for Account customizations
Screen for customizing Account form
Feature 1: Customizing fields:
In Dynamics CRM you can customize fields right from the Customization form. A field explorer or list of fields menu is on your right hand side and you can drag/drop or edit fields as you choose.
To create a new field you simply select the “New Field” button from the customization form and a new screen pops up to create the field.
Once the field is created and saved it will appear on the Customization form in the field explorer menu for the user to place it where they choose.
Customizing a field in Salesforce.com can bring you to a few different screens. The user has to navigate all 5 of these screens just to create and place a custom field on the form.
Furthermore, Salesforce.com will automatically place the field on the form in a default location, you then need to go find it and move it where you want it. Overall, something as simple as customizing a field is very complex.
Feature 2: Surfacing related records and data:
Dynamics CRM provides the functionality to embed subgrids and charts into your record that are created from related or non related records. Why is this relevant? It allows the user to surface any other record or chart and any fields on the record itself. There are several business cases where this feature is helpful including an embedded chart of orders for an account or subgrid of activities associated with an account.
The best feature about subgrids and charts is that they allow the user to leverage multiple views, including custom ones. So let’s say you created multiple custom views for a specific record. You can have one custom view be the default for the chart or subgrid and still have the option to see other views as well all within the same place on the form.
Here we can see the order total by month chart on the account as a default, but we can also select a different chart for orders from the drop down if we choose.
Salesforce.com answers this function with “Lists”. The functionality is limited to which “lists” are available. You can’t just have a list of any records you want. Furthermore while you can customize which columns of data are displayed in the view, and apply relevant filters to the lists, you cannot have more than one view for the record. So you are married to whatever view you choose to surface for a specific record… Choose wisely.
Feature 3: Saving Customizations
The final feature we are going to compare is saving your customizations: (It’s more important than you think)
Dynamics offers a “save” function throughout their system as does salesforce.com, but when it comes to customizations they have added a “publish” feature that enhances the functionality quite a bit.
Saving a customization in Dynamics does not necessarily mean it will be globally changed automatically. The user is allowed to “save” and then get some input, think about it, and come back
later to finally “publish” their changes.
So why is this so great? Well, your CRM system runs your business. Any small glitch can cause a huge headache. So this feature allows the user to think through their decisions about changes to their system for as long as they like.
Salesforce.com only allows the user to “Save” the changes. Compared to Dynamics, this is obviously not as good.
Overall, the two systems both provide lots of functionality, especially around codeless customizations. But it seems apparent that Dynamics CRM provides a better UI for these customizations. Furthermore Dynamics provides a more comprehensive functionality that allows the user to perform relevant and simple customizations with ease and confidence. Dynamics seems to have put in extra effort where it counts in regards to OOTB codeless customization and the results reflect that effort.
Posted by Leah Quartano on November 26, 2012 at 12:35 PM in Microsoft CRM Customizations | Permalink | Comments (0) | TrackBack (0)
November 15, 2012
Workflow Process "Save As" functionality in Dynamics CRM 2011
Often there is a need to create a complex Process (workflow) and then shortly thereafter, recreate it with slightly different parameters. Dynamics CRM does not come with a "Save as" mechanism for workflows like it does for advanced finds and Views so it would seem you would have to go in and recreate the new workflow to match the one that already exists. There is a better (read 'easier') way!
Recently a customer had a need for the creation of multiple views (27 to be exact) and accompanying
workflows that could be run on demand to affect just the records in these views. The views were fairly easy to recreate as only one piece of data in the grid was changed and after creating one and doing a "Save As" for the other 26, the process was straight forward.
The workflows were not quite that easy to create but very simple to duplicate. Each workflow did
essentially the same thing (set a completion date on an entity after some validity checking) but each view represented a different date field on that entity. What we did was create a workflow for the first view and instead of saving with the ‘Activate As” value of "Process”, we saved it as a "Process Template”. We published this and as we created the other workflows, we simply chose to base them on this template.
All that needed to be done with this new workflow was to change the values being looked at in the
steps that determined if an update was required and also change the field that was being updated. After the 26 “copies” were made, we unpublished the original "template" workflow, set the “Active As” to “Process" resaved it and we had all 27 workflows done in a very short time.
As an additional benefit, all of the commenting of the workflow was identical so the end result was in a consistent form.
Posted by Jerry Martin on November 15, 2012 at 08:12 AM in CRM Best Practices, CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Implementation, Microsoft CRM Online, Microsoft CRM Tricks and Tips, Microsoft CRM Workflow | Permalink | Comments (0) | TrackBack (0)
August 29, 2012
Microsoft Dynamics CRM in the Call Center: How to leverage Multiple Source Systems through CRM - Third in Series
Another common challenge in the Contact Center is Customer Service Representatives (CSR’s) having to access multiple systems to get the information they need to do their job. Whether it’s a back-end Billing or Claims system to access policy information, each additional click to navigate adds precious seconds to each customer interaction.
Customer Effective created an Agent Desktop Solution Framework as a streamlined way to search across multiple systems. This Dynamics CRM solution was designed to provide Customer Service Centers with a quick, intuitive, and a consistent user- interface for logging customer interactions via Phone Calls, Emails, Faxes, Letters, etc.
Key Concepts of the CE: Agent Desktop Solution
Multiple Data Sources: For different reasons, many enterprises will want to have their data stored in disparate systems, but accessed in CRM. CE’s Agent Desktop Framework creates a streamlined way to search across multiple systems (via web services) and bring the results back in a native CRM way.
Activity Management: CSRs will often work on a case using multiple communication channels. As they work through the cases, their activities are tracked in the left hand navigation tab. Each activity can have different notes and outcomes, but they will roll to the same case, account, or customer. Each time the CSR accesses an outside system, an activity record is created automatically.
Activity Threads: In the screenshot above, it displays how this solution can serve as a CSR email solution. Each correspondence is rolled into an Activity Thread, which is associated with a customer and a policy.
Example: In a service center environment where each correspondence with customers will require actions to be taken by CSRs, these actions can be spread out over a series of touch points (email/phone call/fax/letter). With this requirement in mind the Customer Effective: Agent Desktop has incorporated custom code intended to rollup multiple related activities and the actions performed against them.In the screenshot example the following functionality is highlighted.
- Section A: CRM can be pre-populated with the caller’s record, also known as screen-pop, with integration to the Phone System (For example: it can perform a database lookup in the background based on the Phone# calling in).
- Section B: Ability to populate “Activity Type” along with free form text to capture the issue in the “Activity Notes” section.
- Section C: This section can be integrated with the phone system to prepopulate the Insured or Agency search results.
- Section D: This is the system accessing data from multiple data sources. In this example it shows the system is “Billing”. Search is being performed on the policy number.
The more ways you leverage Microsoft Dynamics to display relevant content to your CSR’s, the more you will alleviate them having to log into multiple systems creating increased efficiencies across the organization.
Posted by Denise Henke on August 29, 2012 at 10:33 AM in Activity Feeds, CRM Best Practices, CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
June 28, 2012
Using a Lookup Entity in CRM 2011 to handle default values and field lengths on a form
Business Problem:
A recent client of ours had extremely complex rules regarding creating new records. When the lookup was used the form needed to auto fill and limit the number of characters that can be entered. We could have accomplished this via JavaScript, but it soon became apparent that it would become unmanageable quickly. It would also be a management nightmare if the business rules changed tomorrow.
Solution:
Customer Effective, Inc. created a lookup entity that stored the lookup value, default values and length restrictions for fields. User selects a lookup value, the on-change event calls JavaScript which loops thru the lookup entity and set default values and control field lengths on the form.
Here are the pieces you need to build in order to replicate this functionality.
1.) Create a new lookup entity. We called it “Processors”. There are two main sections in this lookup entity. The first part we called “Field Lengths.” The following section called “Default Values” (See screenshots below) shows samples of the default values that to be set on the form.
This section allows an administrator to limit the length of fields on a form. When creating the length fields in the lookup entity make the attribute names the same as the attribute on the other entity. This makes writing the JavaScript to loop thru the form and setting the attribute length easier.
(Field Lengths)
Sample default values are listed below. Each processor lookup option could have had different default values. When creating these attributes we also made the attribute name the same but added “_def” to the attribute.
(Default Values)
2.) Create an entity that will use the new lookup to store the actual selected values based on the lookup value selected. This example entity called “Host Parameters.” A user selects a processor and the form status are “create” state we loop up thru the lookup entity to set field lengths and set the default values using JavaScript.
Click on Create Host Parameter
Select a Processor and see default fields get populated automatically based on the lookup entity.
Field lengths are now restricted based on the lookup entity.
3.) Create a new JavaScript web resource that calls the lookup entity. The JavaScript needs to retrieve the field lengths and default values from selected lookup value. Use JavaScript to set the field lengths and default values on the form.
If this is something your organization could leverage, feel free to reach out to Customer Effective at info@customereffective.com
Posted by Sean Shilling on June 28, 2012 at 11:39 AM in CRM Business Process, Customer Effective Success Story, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
June 11, 2012
Setting a Blank iFrame in CRM 2011
Occasionally there are times when you need to default an iFrame to a blank page. When this is the case, through JavaScript, you’ll then want to set the page to the desired URL.
With CRM 4.0, you could set your page to “/_root/blank.aspx”. This page however, is no longer an option inside CRM 2011.
With CRM 2011, I like to use the loading screen “/_static/loading.htm”. Although this page contains an animated .gif and slightly more HTML than a blank page, the reason I prefer this page is because it is already cached by the browser and provides the user with a nice loading graphic.
Posted by Paul Way on June 11, 2012 at 09:22 AM in CRM Best Practices, CRM Development, CRM Javascript, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips | Permalink | Comments (3) | TrackBack (0)
May 21, 2012
Asset Management: Making Connections in CRM 2011 with Dialogs
In my last blog, I talked about how Dialogs and Connections can be useful to Investment Bankers who use CRM. Another example of using Connections and Dialogs comes from the Asset Management arena, where it’s important to track, among other things, Consultants and Custodians for the customers of the Asset Management firm. The importance of these relationships, especially the Consultant, cannot be undersold. Using Connections is ideal in this case, but using Dialogs really simplifies the process of creating these Connections. Dialogs reduce the process of data entry to questions and answers that are very intuitive.
Continue reading "Asset Management: Making Connections in CRM 2011 with Dialogs" »
Posted by James Diamond on May 21, 2012 at 08:25 AM in CRM Best Practices, CRM Business Process, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
May 10, 2012
Managing Access to Activate/Deactivate Ribbon Buttons in Microsoft CRM 2011
Background:
When an account or a contact isn’t currently engaged in business with your company, we might think of them as “inactive.” – CRM offers a button on the ribbon to ‘deactivate’ the record - but is that the right way to manage the status of a record? - Typically not. – The Active/Inactive status of CRM records really refers to the status of the ‘record’ rather than the contact or account the record refers to. Setting a customer to ‘inactive’ means that it cannot be edited, re-assigned, shared and it immediately gets excluded from most views and reports.
While an administrator may ultimately want to de-activate records if the customer goes out of business or is merged, everyday users shouldn’t be deactivating records on-the-fly. Far more useful is to add a customer “Classification” options to include a more descriptive set of data around why the customer is not an ‘active customer.’ – Once that information is captured, a data administrator can review and deactivate those records through a more methodical process.
Continue reading "Managing Access to Activate/Deactivate Ribbon Buttons in Microsoft CRM 2011" »
Posted by Scott Sewell on May 10, 2012 at 09:00 AM in CRM Best Practices, CRM Development, Dynamics CRM Community, Microsoft CRM Customizations, Microsoft CRM Implementation, Microsoft CRM Tricks and Tips | Permalink | Comments (4) | TrackBack (0)
May 09, 2012
Cross-Browser Compatibility in Microsoft CRM 2011 R8 (Q2 2012)
As you’re thinking about or discussing the announced CRM cross-browser support coming in R8 (Q2 2012) be aware that there are some expectations that may or may not be realistic.
If you expect users in your organization to use browsers other than IE to access CRM, it's important to be ready to understand what is supported out of the box - and what modifications to your existing customizations will enable users to get the most out of CRM, regardless of their browser choice.
Continue reading "Cross-Browser Compatibility in Microsoft CRM 2011 R8 (Q2 2012)" »
Posted by Scott Sewell on May 09, 2012 at 08:45 AM in CRM Best Practices, CRM Development, CRM Javascript, Dynamics CRM 2011, Microsoft CRM Customizations | Permalink | Comments (0) | TrackBack (0)
April 25, 2012
Customer Effective Can Build You a Highly Tailored Trial of Microsoft Dynamics CRM 2011
Since the release of Microsoft Dynamics CRM 2011, Microsoft has encouraged users to a 30-day free trial of CRM. And this has been successful in demonstrating key features like Outlook integration, sales productivity, analytics, service productivity, and basic marketing automation. But extended features, like data mart and communication platform integration, have not been readily available in trial demos. Thanks to Microsoft’s recent release of Demo Builder, these features and other, are available by running a ClickOnce application.
Posted by Brad Koontz on April 25, 2012 at 10:27 AM in Customer Effective News, Microsoft CRM Customizations, Microsoft CRM Implementation, Microsoft CRM Online | Permalink | Comments (0) | TrackBack (0)
February 06, 2012
XRM 2011 JavaScript: Another 101 Lesson in Microsoft Dynamics CRM 2011
When you’re learning JavaScript, you’ll often come across the need to do something to every field on the form. When you do, it’s important to have efficient code to make such widespread changes so the user doesn’t have to wait for the JavaScript to finish. This lesson consists of several parts, some of which you’ll probably already know but hopefully there are some things in here for everyone.
Setting up our Environment
First thing first, open your CRM 2011 development environment and browse to an account form. Once the account form is open, hit F12 on your keyboard. A window should popup that looks like this:
Continue reading "XRM 2011 JavaScript: Another 101 Lesson in Microsoft Dynamics CRM 2011" »
Posted by Paul Way on February 06, 2012 at 08:25 AM in CRM Best Practices, CRM Development, CRM Javascript, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (1) | TrackBack (0)
February 01, 2012
Using a No-Operation Plugin to Examine the IPluginExecutionContext in Microsoft Dynamics CRM
If you have ever had the privilege of developing a plugin for CRM 2011 you know that one of the most important aspects of plugin development is understanding what is available in the context that is passed to the plugin by CRM. After creating a few plugins you generally have a good idea of what is available for the common operations of CRM such as Create, Retrieve, Update, and Delete, but some of the more uncommon request to the OrganizationService may still be cloudy.
One of the methods that I use to understand what is available in the IPluginExecutionContext of a plugin is to use a no-operation plugin registered for the message that I will be handling that will trace the context out to the event log. This is a great way to see a list of all of the data contained in the context’s InputParameters, OutputParameters, SharedVariables, and images. Once you have a trace of what is available in the context of the plugin, the plugin development seems like a much less arduous task.
Posted by Nick Doriot on February 01, 2012 at 09:48 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips | Permalink | Comments (3) | TrackBack (0)
January 30, 2012
Removing Query Data Cached by the OrganizationServiceContext in Microsoft Dynamics CRM
One of the great set of tools provided by the CRM 2011 SDK are the SDK Extensions which provide the OrganizationServiceContext for accessing data in CRM. The OrganizationServiceContext provides a way to access CRM and provides features such as change management, exposing an IQueryable interface, implementing a LINQ query provider, and providing caching services. It is the caching services that I would like to take a look at today.
Posted by Nick Doriot on January 30, 2012 at 09:46 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
January 13, 2012
XRM 2011 - Microsoft Dynamics CRM 2011 Style Buttons
There is already some code floating around to create a 4.0 style button inside of CRM 2011. The button we’re creating will instead create a CRM 2011 style button (i.e. “Example Button”).
Continue reading "XRM 2011 - Microsoft Dynamics CRM 2011 Style Buttons" »
Posted by Paul Way on January 13, 2012 at 08:53 AM in CRM Best Practices, CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (3) | TrackBack (0)
January 12, 2012
CRM 2011 - iFrames & Saving
After spending time on several of the CRM forums, I noticed a few people having trouble with iFrames and saving data inside of the iFrame. While a forum post is a little difficult to write a full response, I wanted to share some insight on capturing the form save event to then trigger a save event inside of your iFrame.
From a business case, this is a fantastic way to tie multiple systems together. If all you are doing is syncing data, then look first at a plugin or scribe. However, if you are looking for the user to interact with multiple systems simultaneously, then an iFrame is a wonderful way to integrated with an existing system. A good example might be where CRM is only storing the summary information and the iFrame contains the details. The user may update the details which should save both the CRM record and the details of the web site.
Posted by Paul Way on January 12, 2012 at 01:22 PM in CRM Javascript, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Online, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (3) | TrackBack (0)
January 03, 2012
Microsoft Dynamics CRM 2011 – Pre-Populated Emails (Alternative Approach)
Recently, we came across the need for a single-click email feature on the ribbon of a custom entity. The idea was to be able to share CRM data as quickly and easily as possible. Another interesting caveat was the client wanted to have the email come directly from Outlook.
For those of you old enough to have used the internet before the iPad, you may recall that fancy-dancy “mailto” feature. (Granted I’m only 29 but my Omron body age says I’m 50 ).
Back to the point at hand though, CRM already has a few built in email features. Our situation calls for something a little different.
What’s Installed By Default
CRM already has the feature of sending a link to the CRM entity you’re working with.
CRM also has a really nice Email Template feature.
Which can automatically mail-merge information pertaining to the entity to eliminate any of that “automated” feel.
What We Need
Our situation is somewhat unique, but really we want both features combined. We want to open a new message like the link feature: inside outlook and with one click. However, we need more than just the link. We want to have a brief summary of the call report with a link to it.
Here’s an example email of what we’d like to send:
Adding the Button
The first thing we need to do is add the button to the ribbon like so:
If you are unfamiliar with the ribbon, Microsoft offers some really nice walkthroughs. I’d start with http://msdn.microsoft.com/en-us/library/gg334341.aspx.
For our situation, the XML that matters is our Action
<Actions> <JavaScriptFunction Library="$webresource:cei_example.js" FunctionName="emailContact" /></Actions>
Adding our JavaScript
At this point, the button should be on the form. From here, we need to add the JavaScript to open our populated email message.
To do this, add to the Form OnLoad events the following function:
emailContact = function() {
if (Xrm.Page.data.entity.getId() != null) {
var sRptID = Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');
var sLink = "http://paul.customereffective.com/userdefined/edit.aspx?id=" + sRptID + "&etc=10011";var sSubject = 'Contact - ' + Xrm.Page.getAttribute("firstname").getValue() + ' ' + Xrm.Page.getAttribute("lastname").getValue();
var sCustomer = '';
if (Xrm.Page.getAttribute("parentcustomerid").getValue().length > 0){
sCustomer = Xrm.Page.getAttribute("parentcustomerid").getValue()[0].name;
}
var sBody = '---\n\nCustomer:\t' + sCustomer + '\n\n' + sLink + '\n\n---';
var sMailTo = 'mailto:?subject=' + escape(sSubject) +
'&body=' + escape(sBody);parent.location=sMailTo;
} else {
alert('You must save the contact before emailing.');
}
}
Note: If you change the name of the function, make sure it matches the name inside your Ribbon XML.
What about Window.Open
If you use Window.Open to trigger the email (or OpenStdWin), the user will get a blank IE page inside of Outlook. By using the parent.location for your mailto, you’ll have a consistent user experience across IE and Outlook.
Seeing the Final Results
Now whenever a user wants to share a call report, they can easily hit the “Email Call Report” button. Add any of the fields you want.
For our needs I ended up with the following; however, this technique can add whatever field you’d like.
Well this isn’t a tool in the toolbox I’d use daily, it can be valuable when the situation calls for it. I hope you enjoy!
Posted by Paul Way on January 03, 2012 at 01:58 PM in CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM for Outlook, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (0) | TrackBack (0)
December 23, 2011
Dynamically Generating URLs for Cached Web Resources for Microsoft Dynamics CRM
CRM 2011 supports several methods for accessing web resources. These includes using the $webresource: directive when referencing web resources from the site map or ribbon, a relative URL, or an absolute URL. While this allows a web resource to be accessed in virtually any situation, if a scenario arises in which an absolute URL must be used, the benefit and speed of retrieving the cached web resource is lost. The reason for this has to do with the caching mechanism used by CRM for web resources. Take the following URL that could be generated by CRM when using the $webresource: directive or when a web resource is included on a CRM form as an example.
https://yourorgname.crm.dynamics.com/%7B634594655730000000%7D/WebResources/cei_/test.htm
Notice the magic number that is highlighted in the example URL. CRM automatically inserts this token into the URL and the CRM 2011 SDK indicates that this magic number is a GUID value that ensures the latest cached version of the requested web resource is used. If you use a tool like Fiddler to examine the response returned by the GET request for the web resource, you will notice that it has caching headers that set it to be cached for one year. If the magic GUID value is removed from the URL so that the URL would resemble an absolute URL to the web resource, the response returned by the GET request for the web resource, depending upon your version of CRM, will be a non cached version or a version that is cached for a short amount time such as 24 hours.
This caching functionality provided by CRM is great, but what if you need to dynamically generate the URL for a large web resource? It would be preferable to access the cached version, but in order to do that you need the magic GUID value. Fortunately, the magic GUID value is not magic at all, and not actually a GUID. The caching token inserted into the URL for the web resource by CRM is merely a timestamp that represents the modified time of the last web resource to be modified. The timestamp is represented as ticks in UTC time as generated by the .NET Framework.
Now in order to get the URL for a web resource, it is merely necessary to generate this timestamp. The example function below shows exactly how to generate the timestamp for the caching token using a quick call to the REST service in CRM and a simple conversion from the JavaScript Date object to the timestamp value.
1: function getWebResourceUrl(webResourceName) {
2:
3: var dotNetMillisecondsAt_1970_01_01 = 62135596800000,
4: ticksPerMillisecond = 10000,
5: lastWebResourceModifiedOn = null,
6: webResourceCachingToken = null,
7: webResourceUrl = "/WebResources/" + webResourceName;
8:
9: // Retrieve the modified date of the last web resource to be modified
10: $.ajax({
11: async: false,
12: beforeSend: function (xhr, settings) {
13: xhr.setRequestHeader("Accept", "application/json");
14: },
15: contentType: "application/json; charset=utf-8",
16: datatype: "json",
17: global: false,
18: success: function (data, textStatus, xhr) {
19:
20: // Extract the modified date from the results
21: lastWebResourceModifiedOn = +(/\/Date\((\d*)\)\//.exec(data.d.results[0].ModifiedOn)[1]);
22:
23: // Convert the JavaScript Date value to the caching token value
24: webResourceCachingToken = (lastWebResourceModifiedOn + dotNetMillisecondsAt_1970_01_01) * ticksPerMillisecond;
25: },
26: type: "GET",
27: url: Xrm.Page.context.prependOrgName("/XRMServices/2011/OrganizationData.svc/WebResourceSet()?$select=ModifiedOn&$orderby=ModifiedOn%20desc&$top=1")
28: });
29:
30: // If we have a caching token value then prepend it to the current URL.
31: if (webResourceCachingToken !== null) {
32: webResourceUrl = "/%7B" + webResourceCachingToken + "%7D" + webResourceUrl;
33: }
34:
35: // Return the URL to the web resource prepended with the organization name if necessary
36: return Xrm.Page.context.getServerUrl().replace(/\/$/,"") + Xrm.Page.context.prependOrgName(webResourceUrl);
37: }
Notice the function takes the name of a web resource, e.g. cei_/mypage.htm, and prepends it with the caching token, organization name if necessary, and the server URL. Now this function can be used to dynamically generate the URL for a web resource and still retrieve the cached web resource. Of course, there could be some improvements made, such as wrapping the call to retrieve the caching token in a closure so that it is only retrieved the first time a URL is generated, but I will leave that up to you.
**Note, that generating a URL in this manner is not supported by Microsoft and the caching mechanism used by CRM for web resources could be changed in the future.
Posted by Nick Doriot on December 23, 2011 at 09:28 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (0) | TrackBack (0)
December 16, 2011
Setting Lookup Field Values on Microsoft Dynamics CRM Forms with Silverlight
Recently, I have found myself developing a lot of Silverlight customizations for CRM 2011. If you happen to find yourself in the realm of Silverlight and CRM you will more than likely have the need to interact with the CRM form in context. The tool that Silverlight provides for interacting with the hosting web page is the HTML Bridge. The types and methods exposed by the HTML Bridge allow access to the hosting pages DOM and JavaScript objects. By utilizing the types and methods of the HTML Bridge it is possible to access the Xrm JavaScript object of the CRM SDK to set field values so let’s take a look at how the HTML Bridge can be leverages to do so.
There are a couple of different methods that can be used when accessing the Xrm object of CRM. One is to create an object model around the Xrm object that mirrors the Xrm object in JavaScript and the other is to use a dynamic object in Silverlight. I am going to use a dynamic object in this instance as it requires much less code, however, the downside is that there is not any compile-time type checking and errors may not be discovered until runtime.
1: // Get a reference to the Xrm object
2: dynamic Xrm = HtmlPage.Window.GetProperty("Xrm");
3:
4: // Set a string field value
5: Xrm.Page.getAttribute("cei_stringfield").setValue("Hello World!");
6:
7: // Set a floating point field value
8: Xrm.Page.getAttribute("cei_floatfield").setValue(3.14159);
Notice in the previous example I simply use the HtmlPage.Window object to get a reference to the Xrm property on the hosting page. Also, notice that the local Xrm object is declared as a dynamic variable. Declaring the local Xrm object as a dynamic object allows the object to bypass static type checking. At this point, it is simply a matter of using the Xrm object just as if it were being used from JavaScript. In line 5 of the previous code snippet I have done just that. A reference to the cei_stringfield attribute is obtained and the value is set to a “Hello World!”. In line 8, the same approach is used to set a numeric field.
After seeing how the previous snippet of code works, you may think, as I did, that setting a lookup field’s value could be done using the same technique with an anonymous array object that mimics a lookup fields value as the argument to the setValue function. However, calling the setValue function for a lookup field will not work from within Silverlight due to the way the HTML Bridge marshals managed objects to JavaScript. Fortunately, there is another method that can be used, although it is not quite as elegant. The following snippet shows how a lookup field can be set from within Silverlight.
1: private void SilverlightSetLookupValue(string fieldName, Guid? id, string entityLogicalName, string name)
2: {
3: // Define eval statements for setting lookup to a value and null
4: string setLookupJscript = @"Xrm.Page.getAttribute(""{0}"").setValue([ {{ id: ""{1:B}"", typename: ""{2}"", name: ""{3}"" }}])";
5: string setLookupToNullJscript = @"Xrm.Page.getAttribute(""{0}"").setValue(null)";
6: string evalStatement = null;
7:
8: // Set the statement to be evaluated based upon the value of the id argument
9: if (id.GetValueOrDefault().Equals(Guid.Empty))
10: {
11: // Setting the lookup to null
12: evalStatement = string.Format(setLookupToNullJscript, fieldName);
13: }
14: else
15: {
16: // Setting the lookup to a value
17: evalStatement = string.Format(setLookupJscript, fieldName, id, entityLogicalName, name);
18: }
19:
20: // Set the lookup
21: HtmlPage.Window.Eval(evalStatement);
22: }
That’s right, I broke out the big dog, the EVIL EVAL function. As I said previously, it is not the most elegant solution, however, sometimes the heavy hitters like the eval function need to be dusted off and it works beautifully. As you can see, the method in the snippet builds the JavaScript necessary to set a lookup field dynamically as a string and then evaluates the string on the hosting page using the HtmlPage.Window.Eval method within Silverlight.
Posted by Nick Doriot on December 16, 2011 at 09:55 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (0) | TrackBack (0)
December 08, 2011
Using the CRM 2011 REST Services and Deep Insert to Create Activities
One of the nice features of CRM 2011 is the REST based OrganizationData service. Lately, I have found myself using the REST service more often as it provides a simpler and cleaner method of accessing data from client side JScript. The REST service also provides the ability to do deep inserts of entity and related records. This capability can be leveraged to provide an elegant solution to creating activity records using client side JScript.
In my particular use case, I needed to create a new email activity from the currently logged in user with the regarding record set to a new custom entity record. It would have been possible to issue a couple of calls to the REST service that created the regarding record and then the email, but it is just as easy to create the email and related records in one call avoiding the need to clean up any records should one of the calls fail.
The first thing that needs to be done is to create the activity party record for the from field on the email. The activity party is a separate entity that stores all of the parties related to an activity, i.e. sender, recipient, etc. The activity party data needs to be specified as an array of activity party entities. The following snippet creates an activity party record for the from field on the email.
1: // Create the activity party records
2: var emailPartyEntities [{
3: PartyId: { LogicalName: "systemuser", Id: Xrm.Page.context.getUserId() },
4: ParticipationTypeMask: { Value: 1 }
5: }];
As I mentioned earlier, I also needed to create a custom entity record that will be set as the regarding on the created email. In my case, this custom entity is used to track an email thread. Since this is a N:1 relationship for the email entity, the record created does not need to be stored in an array and is merely an object with properties specifying the fields of my custom entity.
1: // Build the activity thread entity
2: var activityThreadEntity = {
3: cei_Department: { Value: 29669000 },
4: cei_Subject: "Activity Thread for Account",
5: };
Finally, I need to build the email entity that will be passed to the REST service during the create request. In order for the deep insert to work, the activity party array and the activity thread object created earlier will need to be set to properties on the created object that specify the relationships to the related entities as shown below.
1: // Build the email record
2: var emailEntity = {
3: Subject: "Test Email",
4: cei_activitythread_Emails: activityThreadEntity,
5: email_activity_parties: emailPartyEntities,
6: };
In the previous snippet, notice that the activityThreadEntity object and the emailPartyEntities array are set to their corresponding relationships, i.e. cei_activitythread_Emails is the name of the N:1 relationship for my custom entity to the regarding field on the email entity, and email_activity_parties is the name of the 1:N relationship from the email entity to the activity party entity.
Now that all of the required objects have been created we can issue the call to the REST service to create the email and related records. The following snippet utilizes a jQuery plugin from our custom JScript library. It is merely doing a POST request to the REST service with the data for the POST being the JSON serialized emailEntity object that was created.
1: // Create the email by POSTing the data to the REST service
2: var createResult = $.xrm.orgData.buildRequest().
3: async(false).
4: dataset("Email").
5: data(emailEntity).
6: create();
7: if (createResult.errorExists) {
8: alert("There was an error creating the email.");
9: } else {
10: alert("Success!");
11: }
That’s it! It really is that simple. The email, activity party, and regarding records were all created in a single call.
In this example, I utilized the deep insert capabilities of the REST services to create an email, but the deep insert feature can be used on any entity in order to create multiple records in a single call. The biggest hurdle that you will probably run into is determining whether to create the related records as JScript objects or arrays of objects. Just remember that 1:N relationships require and array of objects and that N:1 relationships require a single object.
Posted by Nick Doriot on December 08, 2011 at 08:05 AM in Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (1) | TrackBack (0)
December 01, 2011
CRM 2011–Excessive Sub-Gridding
Sub-grids enhance the user experience by conveniently providing associated information. Within a sub-grid the user can easily view, create, or modify a related entity. By default, Microsoft will auto-populate up to four sub-grids.
One thing to note however is that if the form contains more than four sub-grids, then sub-grids 5+ will contain a message inside the sub-grid “To load x records, click here”. To populate the sub-grid, the user has to click the refresh button or the link.
CRM 2011 does this intentionally to make sure the User is presented with the Form as quickly as possible. Each sub-grid is another Fetch call to the database, so reducing those inherently speeds up the form.
Now what if you only need a few more sub-grids and you are ok with the potential performance trade-off? Well, let’s add a little JavaScript to auto load all of our sub-grids that didn’t auto load already:
function getLinksWithClassName(classname) {
var bdy = document.getElementsByTagName("body")[0];
var els = [];
var re = new RegExp('\\b' + classname + '\\b');
var lnks = bdy.getElementsByTagName("a");for(var i=0,j=lnks.length; i<j; i++)
if(re.test(lnks[i].className))
els.push(lnks[i]);return els;
}
var lnksUnloaded = getLinksWithClassName('ms-crm-List-LoadOnDemand');for (var i = 0; i < lnksUnloaded.length; i++){
lnksUnloaded[i].click();
}
Now adding the bottom four lines to our OnLoad event will cause all of our sub-grids to auto-load. Hope you enjoy!
Posted by Paul Way on December 01, 2011 at 08:00 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips | Permalink | Comments (5) | TrackBack (0)
November 01, 2011
Controlling Tabs and Sections with JScript in Microsoft Dynamics CRM 2011
The options for managing Microsoft Dynamics CRM forms dynamically has increased tremendously in CRM 2011 – we can now, more than ever, tailor the look of a form to the specific type of record displayed.
Here are 2 functions I use to manage the form at runtime to show or hide sections or tabs based on data in the form.
The first function, “toggleTabDisplayState” hides or shows a tab and can show it collapsed or expanded. Call the function by passing in the ‘name’ of the tab, desired ‘display state’ [either “expanded” or “collapsed”] and whether the tab should be visible [ true or false ].
The second function, “toggleSectionDisplayState” hides or shows a section by setting its isVisible attribute to [ true or false ].
In this Example, I’ve named the “Prospect” tab: “tabProspect” in the form configuration - and based on whether a (previously set) variable “typeProspect” is true or not, I want to hide or show this tab – and when it’s displayed, I want it expanded. – I also want to hide/show the Customer tab based on whether the record is for a prospect or not.
// If the 'Prospect type' == true, // then Show and expand the Prospect tab and hide the Customer section // Otherwise, // Show the Customer Section and hide the Prospect Tab if (typeProspect == true) { toggleTabDisplayState("tabProspect", "expanded", true); toggleTabDisplayState("sectionCustomer", false); } else { toggleTabDisplayState("tabProspect", "collapsed", false); toggleTabDisplayState("sectionCustomer", true); } function toggleTabDisplayState(tabName, tabDisplayState, tabIsVisible) { //Hide/Show and/or Expand/Collapse tabs var tabs = Xrm.Page.ui.tabs.get(); for (var i in tabs) { var tab = tabs[i]; if (tab.getName() == tabName) { tab.setVisible(tabIsVisible); tab.setDisplayState(tabDisplayState); } } } function toggleSectionDisplayState(sectionName, sectionIsVisible) { //Hide or Show Sections var tabs = Xrm.Page.ui.tabs.get(); for (var i in tabs) { var tab = tabs[i]; tab.sections.forEach(function (section, index) { if (section.getName() == sectionName) { section.setVisible(sectionIsVisible); } }); } }
Posted by Scott Sewell on November 01, 2011 at 02:34 PM in CRM Development, Microsoft CRM Customizations, Microsoft CRM Implementation, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
October 26, 2011
CRM 2011 and Windows Identity Foundation
This is a quick reminder that if you are deploying custom applications on servers other than where you install CRM, you need to manually install WIF (Windows Identity Foundation). These pieces are not included in the .Net Framework 4. Here is a sample error message you may receive if you run a custom application without WIF installed.
You can download and install the appropriate WIF from here. I also noticed that Microsoft upgraded the download site for this piece. You no longer need to know what OS you are on to download the appropriate file.
Posted by Sean Shilling on October 26, 2011 at 03:30 PM in CRM Development, Microsoft CRM Customizations, XRM | Permalink | Comments (0) | TrackBack (0)
October 25, 2011
Microsoft CRM 2011 -- When to Use an iFrame vs a Web Resource
Sit back and relax a bit because we aren’t going to get into any code today. Instead we are going to take a higher level look at some interesting caveats within CRM 2011.
Even if you aren’t a developer, if you customize the form with Web Resources or iFrames, this should be helpful to you.
Silverlight
First of all, I came across this due to a colleague using Silverlight. Like many of you out there, we do some crazy stuff with Silverlight. Silverlight is awesome and can be leveraged to do some serious heavy lifting. I’m actually more of a JavaScript guy, but until JavaScript supports multi-threading, Silverlight cannot be overlooked.
When using Silverlight, you have three options to put Silverlight on your form:
- Embed a Web Resource and select the XAP file (Figure A – 1)
- Embed a Web Resource and select an HTML wrapper (Figure A – 3)
- Embed an iFrame and enter an HTML wrapper (Figure A – 4)
Figure A (Before)
If you are embedding the XAP file (1), then all is good in the world and everything should behave like any other control. Problems only arise with the magnitude of what you are doing. Let’s say you have a couple of JavaScript resources you need to support your Silverlight control to talk to the form. If that’s the case, setup and maintenance is a little more cumbersome.
To make life easier for you and your customer, you could upload your own HTML file with everything self-contained. Now that you have everything nicely contained in an HTML web resource, we can either insert a web resource and select our HTML file (3) or we can use an iFrame and point to our HTML file (4). What’s the difference? Watch what happens when I select a Related entity (e.g. Activities) and then come back to my form. Notice how the Web Resource is blank? That’s because the form reloaded my web resource.
Figure B (After)
HTML
Ok, some of you out there may be saying, “but I don’t use Silverlight”. That’s fine, but this actually applies to HTML files as well. When embedding an HTML page, again you can either use a web resource or an iFrame. If you choose a web resource however, the page will reload when toggling to a new related entity. If you choose an iFrame, it will NOT reload (look back at Figure A&B paying attention to 2 and 5).
Well why?
This is all about your purpose. If you have a HTML page or Silverlight control that is read-only (e.g. graphs, charts, or accessing another system), then a Web Resource would be the better method most of the time. If you are expecting users to input data, then you’ll want to use an iFrame instead of a Web Resource so that the data is persistent. For some of you this could be a gotcha and for others it can be a feature. Hopefully none of your users are on the wrong end of this! Enjoy.
Posted by Paul Way on October 25, 2011 at 07:43 AM in CRM Best Practices, CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (0) | TrackBack (0)
October 05, 2011
Cases and Resolution Activities in Microsoft Dynamics CRM 2011
Many CRM users use the Case entity in CRM 2011 to track issues. These issue range from customer complaints to tracking actual software development bugs. The Case entity does a good job of allowing users to track a wide variety of issues and work on them them through resolution. What seems odd though is that when a user closes a case he/she cannot see those “resolution” activities anywhere.
The funny part of this problem is that a “resolution” is nothing more than another type of activity. Microsoft Dynamics CRM is just filtering out these activities from the activities views (see example 1) by setting the “Is Regular Activity” to “Yes.”
Example 1
You can probably see where we are going with this, but one of the easiest ways that we have found to show these on cases is to create a new view called “Resolution Activities” (See examples 2) and set the type of activity to resolution.
Example 2
As a result of those changes (Example 3), it is then very easy, especially under CRM 2011, to show the new view in a sub-grid on the case form. Users can now view a closed case and see what the resolution.
Example 3
Posted by Sean Shilling on October 05, 2011 at 01:36 AM in Microsoft CRM Customizations, Microsoft CRM Reporting, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
September 30, 2011
Hiding Ribbons in CRM 2011
I was recently involved in implementing Microsoft CRM for a large organization, and one of their requirements was a simplified, stripped down UI. One of the ways that we accomplished this goal was by hiding ribbon buttons that were not used in their deployment.
First, I found a great tool that made it very easy to add or remove ribbon buttons. I would recommend giving this tool a try. It was created by Pragma and did a pretty good job; and, it can be found on CodePlex.
Here is an example screenshot of hiding buttons for the case entity.
However, when you are editing the ribbon, either by using a tool or editing an entity xml manually, you can make mistakes that cause problems with your customization. In my case, I accidentally created two "hide" entries for the same item in the xml. As a result of this, the solution could not be imported.
Here is sample XML associated with hiding a ribbon entry. I placed big **** next to my duplicate records.
Once I deleted one of the duplicate rows from the xml file and reimported the solution, everything worked fine.
Lesson learned: It is fine to use tools and utilities to help customize your environment, but it is important that you still understand what is being changed "under the hood," as you may need to edit the xml file in case something doesn't work right.
Posted by Sean Shilling on September 30, 2011 at 08:35 AM in CRM Development, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
September 29, 2011
How to get the Microsoft CRM “Closed Activities” Nav Bar Link Back (if you delete it)
As we have covered earlier on the CEI blog, Microsoft Dynamics CRM 2011 introduces some great new form customization capabilities. One of my favorites is the ability to remove Navigation bar links from a form.
Prior to 2011, the only way to remove nav bar links was to use jscript to hide them. This complicated form customization, and also made the form appear to “dance” when you first opened it, as all of the hidden nav bar links would appear momentarily and then hide.
Now, with CRM 2011, you can go to the form customization and select the “Navigation” node from the ribbon.
Then from the left side of the form customization, you can select visible navigation bar links and remove them by either clicking delete on your keyboard, or clicking “Remove” from the ribbon.
If you want to add a link to the navigation bar that is not currently displayed on the navbar, you can select the link from the “Relationship Explorer” on the right side of the customization form, and drag and drop it to where you want to display it on the navigation bar. So if you remove one, then want to add it back, just move it over from the Relationship Explorer.
This will work with most of the relationships in CRM. One of the few for which it doesn’t work however is the “Closed Activities” link.
"Closed Activities" is basically a link to the same entity as the “Activities” nav bar link, just filtered to show a different view—Closed activities.
If you delete the Closed Activities nav bar link, you will not be able to add it from the relationship pane. It will no longer exist.
To get the link back, create a solution containing the entity from which the link was deleted and export the solution.
Then from another CRM environment, export the same entity, extract the solution .zip file, and edit the customization.xml file. Search for “<NavBarByRelationshipItem.“ You will find a section in the XML that looks like this:
<NavBarByRelationshipItem RelationshipName="Incident_ActivityPointers" Id="navActivityHistory" TitleResourceId="Tab_Label_History" Icon="/_imgs/ico_18_history.gif" ViewId="21E2B905-6FDB-470d-8517-AD69B4C01268" Sequence="20" Area="Info">
<Privileges>
<Privilege Entity="" Privilege="ReadActivity" />
</Privileges>
<Titles>
<Title LCID="1033" Text="Closed Activities" />
</Titles>
</NavBarByRelationshipItem>
Note this section may be different based on the entity in question. In this example, I’m using the case entity.
Copy this section, then go to your exported solution customization.xml for the environment where you deleted the closed activity link. Paste this section in the appropriate place, then zip up your solution and import into your environment.
You will once again see the “Closed Activities” navigation bar link.
Posted by Joel Lindstrom on September 29, 2011 at 04:41 PM in CRM Best Practices, Dynamics CRM 2011, Microsoft CRM Customizations | Permalink | Comments (0) | TrackBack (0)
August 29, 2011
CRM 2011 Form Customization (Part 2)
A while back we looked at customizing the CRM 2011 header and footer. I got some really positive feedback, but some people were tripped up. Troubleshooting via blog is difficult, so whenever you have problems feel free to tweet me (@paul_way). Today, I’m going to go into great detail of changing the form again, but this time we’re going to add a new twist. Take a look at the before and after:
Before
After
Now some of you may be wondering what I changed. First, we still have the light blue shading on the header. Secondly, we moved the footer to the left navigation. User’s may never request changing the color of the forms, but that was intended to show you that you could style the forms any which way you wanted. Moving the footer to the left hand navigation is quite practical. Some users may be faced with smaller screen resolutions and this will really free up space if you intend to put a lot of information in the footer (especially if you are adding to the header already).
Step-by-Step
Setting up our Web Resources
The first thing you’ll need to do is create a solution. I called mine “Form CSS Customization”. In it we are going to add two web resources.
For our initial web resource we’ll create is a CSS file:
.ms-crm-Form-HeaderContainer {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffB3CAEC, endColorstr=#fff6f8faE)
}
.ms-crm-Form-Footer {
display: none;
}
.ftLabel {
color: #999;
font-style: italic;
padding-left: 4px;
}
.ftValue {
padding: 2px 2px 8px 12px;
text-align: left;
}
#myCustomNav { padding: 2px }
.myNavFoot {
margin-left: 4px;
border: solid 1px #999;
width: 99%;
}
Take note of the name of your CSS file, as we’ll use this in a minute. The CSS file contains the shading on the header as well as some custom table formatting that we’ll use with our JavaScript file.
Now, let’s add our JavaScript file:
function load_css_file(filename) {
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
document.getElementsByTagName("head")[0].appendChild(fileref)
}function myFormOnLoad() {
load_css_file('/WebResources/cei_/css/case.css'); // don’t forget to change the file!
moveFooterToNav();
}function moveFooterToNav() {
var tbl = document.getElementById('crmNavBar');
var row = tbl.insertRow(tbl.rows.length);
var cFoot = row.insertCell(0);
var txt = document.createTextNode('testing...');
cFoot.appendChild(txt);
cFoot.id = 'myCustomNav';
document.getElementById('myCustomNav').innerHTML = "<table class='myNavFoot' cellspacing='0' cellPadding='0'>" +
"<tr><td class='ftLabel'>Created</td></tr>" +
"<tr><td class='ftValue'>" + document.getElementById('footer_createdby_d').childNodes[0].innerHTML +
"<br />" + document.getElementById('footer_createdon_d').childNodes[0].innerHTML + "</td></tr>" +
"<tr><td class='ftLabel'>Modified</td></tr>" +
"<tr><td class='ftValue'>" + document.getElementById('footer_modifiedby_d').childNodes[0].innerHTML +
"<br />" + document.getElementById('footer_modifiedon_d').childNodes[0].innerHTML + "</td></tr>" +
"</table>";}
The JavaScript file is doing two important things. First, it is injecting the CSS file into the header of the page. This basically tells the browser to pickup the CSS file as if it was always part of the page. After loading the CSS file, the JavaScript will append a table to the left area nav bar. This table is completely custom and you can style it any which way you want. Be careful using Xrm.Page.getAttribute() here, because even though the field is in the footer it may not be accessible to the Xrm object. In my case, the attributes I’m using were not on any of my tabs.
Changing the JavaScript
You must change the “load_css_file” function to contain your specific web resource. To find the web resource name, it’s easiest to look at the CSS web resource inside of CRM:
Configuring the Form
Now we need to go to the form we are customizing. The first step is to add everything we want to onto the footer.
Next, we’ll edit the form properties.
When editing the Form Properties, we’ll need to add the JavaScript library and add our onLoad function to the Form OnLoad. In our example, the function we’re using is called “myFormOnLoad”.
After this, we simply hit OK, Save, and Publish.
Reviewing the Finished Product
As you can see, we made subtle changes to improve the overall look and feel for the user. We also provided a real-life situation where you may need to squeak out some additional room for the user. Hope you enjoy!
Posted by Paul Way on August 29, 2011 at 03:58 PM in CRM Development, Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (6) | TrackBack (0)
August 23, 2011
CRM 2011–Changing the Form Header and Footer Colors
CRM 2011 has a beautiful default theme. Microsoft has already organized the CRM 2011 folder structure to support themes, but currently only supplies the Silver theme. Office 2010 on the other hand contains Silver, Blue, and Black.
Today we aren’t going to modify the entire theme, but modify the form header and footer. The code I’m going to include is a small gradient, but you could choose a solid background or any color you’d like. I was going to use a Clemson, I mean Customer Effective, Orange, but instead focused more on the blue theme look.
Before
After
Adding our CSS Web Resource
Granted this change was very minor, but you could do about anything you wanted to with it. To accomplish this basic change you must first upload a CSS web resource (I named mine new_header.css) with the following styling:
.ms-crm-Form-HeaderContainer{
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffB3CAEC, endColorstr=#fff6f8faE);
}.ms-crm-Form-Footer{
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffB3CAEC, endColorstr=#fff6f8faE);
background-image: none;
}
Note: The filter property is an IE specific CSS attribute. It isn’t supported in any other browsers (they will just ignore it), but Internet Explorer 7+ supports it just fine.
Modifying the OnLoad
Our next step is to modify the onLoad to inject the CSS file. We’ll do this by adding the following JavaScript to a web resource:
function load_css_file(filename){
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
document.getElementsByTagName("head")[0].appendChild(fileref)
}function myFormOnLoad(){
load_css_file('/WebResources/new_header.css');
}
Changing the Form Properties
Finally we need to change the form properties to include this JavaScript web resource in the library and add our “myFormOnLoad” function to the OnLoad Event for the Form:
Conclusion
After going through this blog, hopefully you will see how easy it is to change the form header, footer, or anything else. By embedding a CSS file, our ideas are our only limits. Hope you enjoy!
Posted by Paul Way on August 23, 2011 at 08:00 AM in Dynamics CRM 2011, Microsoft CRM Customizations, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (4) | TrackBack (0)
Technorati Tags: CRM, header, Microsoft CRM, ribbon, ribbon color
