CRM Development
May 13, 2013
IE Developer Tools – Three Quick Tips
Today’s post is for my fellow JavaScript junkies. If you aren’t using IE Developer Tools, then check out a few posts. I’d highly recommend checking out Microsoft’s pages to realize instant productivity gains. Seriously, it’s awesome.
Changing Scope
The first tip I wanted to share, is the “cd()” command. This allows you to change your scope of the console. I wish I would have found this years ago! It may seem trivial, but when coding with IFRAMES it’s always frustrating to prepend your code with “frames[0].” all of the time.
Let me give you an example, you open an entity record with some new JavaScript in mind. The first thing you want to do is get your bearings and start testing various logic. You type in Xrm.Page.data.entity.getId() and get an immediate error…
Why? Oh, because you forgot you’re in the wrong scope. You could always hit [up], [home], and then prepend the line with “frames[0]” – which is what I have always done in the past.
This is fine for a couple one liners but when you’re using Developer Tools to test/write various functions, it’s rather tedious. Instead, you can change the scope of the console by using the “cd(frames[0])” command.
Now, I can test and execute code exactly how it will appear within my JavaScript web resources. Want to go back, just type “cd()” and you’re back to the main.aspx page.
Logging to the Console
I’ve seen a lot of developers riddle their code with alert boxes to track down issues. While this is a fine approach, I find writing to the console to be more effective. There are times when the alert command makes more sense, but let’s delve into the console for a moment.
With writing to the console, you have four different message types: “log”, “info”, “warn”, and “error”. Here’s how they appear on the console:
I like to sprinkle these into my code during development. They offer sanity checks and are great when you are debugging. Most of the time, these statements aren’t pushed to production; however, if they accidentally do make it into UAT or PROD – these commands are much safer than alert messages nagging users unnecessarily.
When do alert messages make sense?
Alert messages are useful for making sure the user is told something. I try to use alert messages sparingly since when given too many users generally ignore all of the alert messages.
Profiling – Making your Code Faster
People often ask me how I get my JavaScript code to execute so quickly. Just kidding, no one has ever asked me that. But if they did, I would credit three things: Dub-step, Douglas Crockford, and the profiler built into Developer Tools. I’m sure you’ve heard of JSLint and you’re headphones are currently blaring some dub-step. You might be unfamiliar with using the profile in your JavaScript though, and I’d like to demonstrate an example for you about the profiler.
First, have you ever wanted to quantify the execution of your code within CRM? Well the profiler allows you to do this. Let’s say hypothetically you want to disable all of the fields on the form. There are several ways of doing this:
But which function would be the fastest? When comparing functions that provide the same results, it’s best to call the function more than once. So let’s call each function 100 times to quantify the speed of each call.
Additionally, let’s use this function to re-establish the form as fully enabled to make sure everything is consistent.
Here’s an example of testing the various functions 100 times each:
After executing our code, switch to the Profiler tab. Choose the speed test example and change your view to the “Call tree”. Now we can see the cumulative time of each function.
A one second difference between our fastest and slowest function at 100 times equates to an average savings of about 10 milliseconds when only ran once. Not really drastic, but hopefully this shows you how granular you can get.
Generally you won’t need to call each function 100 times. In this scenario, we were trying to save as many milliseconds as possible and comparing extremely similar functions. Typically you’d use the profiler for speeding up a slow form. By adding the profiling you can identify which functions are the culprit of any inefficiencies. Additionally, you can see if functions are inexplicably called more often than they are supposed to.
Summary
If you are developing JavaScript inside CRM 2011 and not using IE Developer Tools, I really hope this convinced you to check it out. If you’ve already been using Developer Tools, then I hope you learned something new. There are a ton of features within Developer Tools and I highly recommend taking advantage of them to improve your productivity and your code performance. I hope you enjoy!Posted by Paul Way on May 13, 2013 at 07:46 AM in CRM Best Practices, CRM Development, CRM Javascript, Dynamics CRM 2011, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
May 08, 2013
Health Plan Marketing in the Era of the Affordable Care Act with Dynamics CRM
Health Plan providers are working hard, not only to change the products they offer but the way they go to market. Because of Healthcare Reform, they will now have increased exposure to an entirely new market of consumers that previously didn’t exist. What is going to motivate and retain customers? Products? Price? Wellness Benefits? Coverage of Pre-Existing Conditions? Disease Management Programs?
Continue reading "Health Plan Marketing in the Era of the Affordable Care Act with Dynamics CRM" »
Posted by Denise Henke on May 08, 2013 at 09:35 AM in CRM Best Practices, CRM Business Process, CRM Development, Dynamics CRM 2011, Microsoft CRM Implementation, Microsoft CRM Reporting, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
March 27, 2013
Understanding FetchXML Outer Joins in Dynamics CRM
I’m often asked about Outer joins and there seems to be a little bit of confusion about them. As you can see from prior posts, I’m a big fan of using FetchXML to access data from Microsoft CRM. So today, I wanted to go over the outer join feature and show you an example of where I recently used one.
Our First Example
To get started, let me show you where I recently used an outer join and why:
This is a widget on a dashboard I recently put together that shows the user’s associated contacts. The images can come from three different sources: LinkedIn, Facebook, or CRM. In my case, the CRM image is an attachment on the contact. (I know most of you are thinking that Edward Anderson is one good looking dude, but let’s focus on the Fetch)
Let’s take a look at the Outer Join:
Notice, at the end of line 20 you’ll see the “link-type” attribute. This specifies our outer join. If this was an inner join, then only contacts with a “Thumbnail” attachment would be returned. We want contacts with AND without a “Thumbnail” attachment which an outer join provides.
Another Example
With CRM 2011, Outer Joins also provide aggregate counts. For example, let’s say you want a list of accounts with the number of opportunities associated to each account. This is quite easily done with an outer join.
In this example, we’re returning the number of opportunities associated to each account.
In a case similar to this (slightly different fetch though), we displayed the results on an HTML web resource. We sorted ascendingly and then via JavaScript only showed accounts where the opportunity count was zero. We were displaying a widget to show all accounts without an opportunity.
Going Forward
When I first was programming with CRM, I mainly used Query Expression. Once I started using Fetch, I’ve never looked back. If you aren’t familiar with Fetch, I strongly recommend learning it as it’s my preferred method for accessing data from CRM. Outer joins and aggregates are just the tip of the iceberg.
In our case, we had two pretty basic examples; however, I hope these conjured up some ideas for some of the problems you are trying to solve in your environment. I hope you enjoy!
Posted by Paul Way on March 27, 2013 at 10:47 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Tricks and Tips, XRM | 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)
October 26, 2012
JavaScript Fetch XML–Supporting IE10 and Other Browsers
Last year we looked at building FetchXML support with JavaScript and these two blog posts were quite popular. Surprisingly a few people at CRMUG thanked me for these specific blog posts. At CRMUG we got into a great discussion about the indirect benefits of using FetchXML versus OData and that led to someone mentioning the lack of support with my JavaScript code on non-IE browsers. After coming back home to Greenville, I realized the code also fails to work in IE10. Coincidentally we had some users who switched to Windows 8 mention our internal Gantt chart had to be run in compatibility mode to support IE10.
So today we’re going to look into updating the JavaScript FetchXML code to support Chrome, Firefox, Safari and especially Internet Explorer 10.
Why not use OData?
Before we get started though, I want mention that OData is great. The only reason I took the time to build out the initial fetch support was due to the complex querying that Fetch supports. Additionally, aggregates are only available with FetchXML. I still use OData but I often prefer FetchXML due to the flexibility and ease. I also prefer to use FetchXML with my C# code which offers several benefits including consistency when developing.
Secondly, I want to mention that when building your FetchXML you want to use a tool. An easy way is to use the Advanced Find and then click the Download Fetch XML button.
There are other tools available, like Stunnware Tools (which has moved to http://www.donaubauer.com/en/#!CrmInterface). Find what fits you.
Getting Started
The first thing I had to do was switch to using the DOMParser. Granted I’ve done a lot of development on non-IE browsers, but when it comes to XML, Internet Explorer has always done it very well (Gone are the days of XPath my friends).
Note: IE9 supports both parts of this IF clause but will use the DOMParser in this conditional statement.
This next bit of code highlights the slight nuances with the different parsers. The ActiveX approach would call the attribute by “baseName” and the value “text”; whereas, the DOMParser uses “localName” and “textContent” respectively.
This pretty much highlights the changes, but sadly took me a few hours to figure out. I went down the jQuery route successfully, but decided to keep these functions from requiring jQuery to be loaded. I also wasted some time on using RegEx which was for naught due to the XML namespace.
Downloading the Code
One thing I’ve noticed with my other blog posts has been issues related to getting the code downloaded. So I’ve placed everything out on GitHub and hopefully this will be more convenient for everyone.
https://github.com/paul-way/JCL
Finally, I hope this helps you with your IE 10 future and your fancy new Surface (I wish I preordered one). Let me know your thoughts by either commenting at blog.customereffective.com or tweeting me (@paul_way). Coming 10/26…
Posted by Paul Way on October 26, 2012 at 01:00 PM in CRM Development, CRM Javascript, Dynamics CRM 2011, Microsoft CRM Tricks and Tips, XRM | Permalink | Comments (0) | TrackBack (0)
October 03, 2012
Three Megatrends Affecting Today's Mobile CRM Environment
Accessing CRM from a mobile device is one one of the hottest topics in CRM today. In a previous blog post, I outlined four choices available today for using Microsoft CRM 2011 from a mobile device. I referenced three big trends in mobility that are affecting CRM mobile strategy today. A deeper dive into those trends is below.
1. CRM Users Expect More From Mobile Devices. Our information access options are growing. Since the introduction of the smartphone in the early 2000’s, we as mobile device users have rapidly increased our expectations about what we expect to be able to do away from the office computer.
Here’s a brief refresher of recent history:
- 2005: Early smartphone and mobile devices delivered texts, emails, and some awkward browsing. In 2005, your smartphone was a two-way voice communication device, but just a one-way data consumption device. Laptops were powerful and great for consuming and creating (MS Office, enterprise apps). Heavy-duty computing and analysis was still the domain of powerful desktops and servers.
- 2010: Consumer tablets take hold. Tablets, like smartphones, took off when they got really good at helping people consume data and media. EBooks were easy to read and movies easy to download. Laptops and desktops continued to get more powerful, but tablets really become the focus. iOS devices were popular for their perceived ease of use and quick startup times, but out-of-the box they were not ready for the enterprise because they were poor at helping people create the type of work product they expected. Third party app developers stepped in to fill the gap between hardware people liked and the work they needed to produce. (Currently, 4 of the top 5 business apps in the Apple App Store help people access and create MS Office compatible documents).
- 2012: Hybrids Surface. The gap between traditional consumer tablets and laptops is closing. Hybrid devices, such as the upcoming Microsoft Surface are giving users a light-weight, easy-on, and touch enabled device with the computing power of a laptop or desktop. I’m going to read the tea leaves here and predict that users will become less satisfied with trying to use a consumer tablet (and bolt-on business applications) to create work product. They tablet-laptop hybrid model should fill the gap between the devices users want the the work they need to do.
Notice the line is getting higher and flatter. We simply expect more computing power from any and every device we use.
So what does this have to do with CRM? Users today expect to be able to create from almost any device. They know they are limited by the real estate of a small, portable screen, but they expect two-way communication, mobile data entry and mobile content creation. Successful CRM solutions (those focused on productivity gains and user adoption) need to meet the consumption and creation expectations of their users.
2.User Experiences, Across All Forms, Become Unified. If user adoption is one of your key success indicators in a CRM project, then good UX design is going to be one of your best tools. Users are quick to adopt systems that look familiar and support the same conventions across channels. If CRM on my phone has different visual cues than the CRM on my desktop browser then I may be less likely to adopt. If the data architecture is different and results in different steps to access, then I may prefer one form over the other. Either way, more mental chatter is created on the way to get what I need from my system and I become further away from satisfied.
Windows 8 is a unified platform, meaning the same OS running the same apps across tablets, PCs, phones, etc. This creates a high comfort level among users who are looking for seamless experiences across devices. However, the real power of the Universal UX is not in the UI, but in the cloud. Since this new OS was built ‘from the cloud up’, you will be able to synchronize data across all devices. The things you create on your phone, and then tweak on your Surface are instantly available on your desktop system. The in-progress folder on your desktop is always available on your phone.
This approach is not being embraced by everyone. When asked about a tablet/laptop concept Apple’s Tim Cook famously quipped, “You can converge a toaster and a refrigerator, but those aren’t going to be pleasing to the user”.
3. The “App Effect” Creates Demand for Small, Personal Experiences. The App Effect refers to a book that was published by Sogeti Group and focuses on the revolution in business, thinking and behavior that has taken place in the post-PC era. Apps in this context refer to application software written for mobile devices. The shortened name reflects the size of target device (mobile) and the scope of the software.
To illustrate, think about the problem of wanting to know a weather forecast. If you were on your laptop, you would type “weather” in Bing, choose a weather site and then (after you close a pop-up) you would have access to literally 1000’s of options of weather data. Then you would perform another search for a location and activity and you would get what you need. With a weather app, you simply open it and based on your location and previous activity, your forecast is displayed on your mobile device. Your app experience is personal, gives you exactly what you need and it is, by design, not the entire world of weather data.
“So much information enters our brain that it becomes paralyzed, so to speak, and any kind of stimulus to take action can no longer penetrate. From combat situations, we know that an overload of new signals can paralyze the executive function,” notes the authors of The App Effect (p. 43). The answer to information overload is guided process via apps. Some of our most successful stories around mobile CRM are where we designed an app for a pre-defined, line of business process. The app displayed only relevant data from CRM and guided users through on-boarding steps. The platform was CRM, but the user experience was small, personal and exactly what they needed to get their job done.
Posted by Brad Koontz on October 03, 2012 at 08:27 AM in Books, CRM Development, Microsoft CRM Mobile Clients, Mobile Express, Web/Tech, XRM | 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
Get Ready for the CRM 2011 Cross-Browser Upgrade
You may or may not be aware that the long awaited CRM 2011 "R8/UR9/Q2-2012" upgrade is just around the corner – Much of the work that went into updating CRM in this release was to enable cross-browser support. (yay!)
For a while we’ve known that existing 4.0-style code (crmForm.*) would need to be upgraded to the CRM 2011 style (XRM.*) code. But until recently, the common assumption was that all 4.0-style code would continue to work in IE after the upgrade – but that’s not entirely accurate. – Some 4.0 style code will need to be updated in order to make it compatible with this upgrade - even in IE.
The Custom Code Validation Tool
The CRM Engineering / Support team recently released a tool to evaluate the code in a CRM environment for compatibility post R8. http://blogs.msdn.com/b/crm/archive/2012/06/21/microsoft-dynamics-crm-2011-custom-code-validation-tool-released.aspx
Follow the directions in the post to load the solution into your environment. Once you’ve loaded it into your CRM environment and you can access it directly via a URL like this – https://MyOrg.crm.dynamics.com//WebResources/msxb_/CustomCodeValidationTool.html
The navigation/interface is horrible, but the information it produces is really good.
In environments I’ve reviewed, I’ve seen a limited number of IE-breaking changes – But I see quite a few changes that will need to be updated in order to get CRM working in Chrome, and on iPads etc.
Conclusion
For more information on upgrading scripts to support R9 – please see this post - http://blog.customereffective.com/blog/2012/05/cross-browser-compatibility-in-crm-2011-r8-q2-2012.html
Let us know if you’ve found this information helpful – your comments are appreciated.
@ScottSewell
Posted by Scott Sewell on June 28, 2012 at 09:39 AM in CRM Development, CRM Javascript, Dynamics CRM 2011 | Permalink | Comments (0) | TrackBack (0)
June 19, 2012
CRM 2011–JavaScript Events
For the experienced developers, you might be quick to bind to HTML objects to handle events. Stop! Read my blog! And roll!
For those of you just picking up JavaScript, an Event is a way to “trigger” code to execute when something happens. For example, if a user selects something in a drop down you can use an “OnChange” event to show an otherwise hidden section. Events are a great way to enhance the user experience as well as to improve the quality of data input. Today we’re going to look at the events supplied by CRM 2011 and how to use those in a coherent way without having to bind to an event in a crazily unsupported fashion.
Posted by Paul Way on June 19, 2012 at 10:19 AM in CRM Best Practices, CRM Development, CRM Javascript, Dynamics CRM 2011, XRM | 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 29, 2012
Transform Multi-Select / Delimited fields into CRM Many-To-Many Relationships.
In many source systems (such as salesforce.com), the data from multi-select pick-lists is stored in a memo field as a long list of semicolon delimitated values:
ID Value 1 Option1;Option2;Option4 2 Option1;Option3
When upgrading to Microsoft Dynamics CRM, you may choose to convert those individual fields into N:N (many to many) relationships, but first you’ll need to de-concatenate those values into multiple rows along with the id of the source record.
ID Value 1 Option1 1 Option2 1 Option4 2 Option1 2 Option3
How To:
The following example code demonstrates converting a semicolon delimited text field on the opportunity record into a list that is then matched to a related entity and any missing many-to-many relationships are identified for creation.
Continue reading "Transform Multi-Select / Delimited fields into CRM Many-To-Many Relationships." »
Posted by Scott Sewell on May 29, 2012 at 09:56 AM in CRM Development, Microsoft CRM Tricks and Tips, Microsoft SQL Server, Scribe | Permalink | Comments (5) | 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)
March 26, 2012
Preparing a SQL Server Reporting Services (SSRS) Report to Use Filtering and Fetch XML in CRM 2011
Sooner or later, you will come across a more complicated report than can be handled in the report wizard or with custom views in CRM 2011. No problem, just write one in reporting services using Business Intelligence Developer Studio, right? But what if you want to use filtering in CRM to allow users the flexibility in selecting records? There are a few simple rules to follow in creating your report that will make publishing the report back to CRM painless, and very functional.
The first key is to make sure your development environment is configured to connect directly to CRM.
Posted by Michael Quattlebaum on March 26, 2012 at 11:22 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Reporting, Microsoft CRM Tricks and Tips | 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 20, 2012
Retrieving Activity Feed Post with the OrganizationService
One of the new features introduced with Update Rollup 5 for CRM 2011 was the introduction of activity feeds to CRM. Activity Feeds give users the ability to monitor what is happening to various business entities. The out of the box functionality includes auto posts that include activities such as status changes in business entities, and manual posts that are created by users. Users also have the ability to post comments to posts that are created in an activity feed.
Recently, I had the need to retrieve activity feeds for various business entities in order to display a summary of interactions that had recently taken place for a set of accounts and its related entities. While the out of the box functionality allows a user to see the record wall for an individual record, it does not give the user the ability to see activity posts for multiple records on a single wall, hence the need to retrieve the posts using the OrganizationService.
Continue reading "Retrieving Activity Feed Post with the OrganizationService" »
Posted by Nick Doriot on January 20, 2012 at 08:00 AM in Activity Feeds, CRM Development, Dynamics CRM 2011, Microsoft CRM Tricks and Tips | Permalink | Comments (0) | TrackBack (0)
January 18, 2012
Microsoft Dynamics CRM 2011 Standalone Sandbox Using VirtualBox Part 2
Back to Part 1... Microsoft Dynamics CRM 2011 Standalone on VirtualBox Part 1
2: Add the ASP.NET role service:
Install CRM 2011
Great! We are ready to finish and fulfill our goal. From the host machine unmount the SQL Server 2008 R2 and mount the Microsoft Dynamics CRM Server 2011. When you mount Microsoft Dynamics CRM Server 2011 from the host machine go to CRMDEMO2011 and run the splash.exe from the ‘D:’ drive.
Continue reading "Microsoft Dynamics CRM 2011 Standalone Sandbox Using VirtualBox Part 2" »
Posted by Manny Ed on January 18, 2012 at 08:03 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Implementation, Web/Tech | Permalink | Comments (1) | TrackBack (0)
Microsoft Dynamics CRM 2011 Standalone Sandbox Using VirtualBox Part 1
One of the best approaches to learn CRM is to have a sandbox. A lot of recommendations out there suggest having your IT administrator provide you with a CRM sandbox to play in. That is fine and is surely a good idea, but personally creating a sandbox will certainly give you the satisfaction of getting your hands dirty and will give you a little respect with your colleagues. So here we are going to look at getting a basic MS CRM 2011 up and running with Oracle’s VirtualBox.
Continue reading "Microsoft Dynamics CRM 2011 Standalone Sandbox Using VirtualBox Part 1" »
Posted by Manny Ed on January 18, 2012 at 08:00 AM in CRM Development, Dynamics CRM 2011, Microsoft CRM Implementation, Microsoft CRM Tricks and Tips, Microsoft SQL Server, Web/Tech | 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 (4) | 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 12, 2011
Jscript Pop-up in Microsoft Dynamics CRM - Internet Explorer vs. Outlook
Occasionally when developing custom solutions in CRM, there will be a need to open a new window from Jscript. Typically the window.open function is used to accomplish this, but this is not always ideal in CRM.
Consider developing a custom solution in CRM where you need to open another CRM record in a new window. In the web interface of CRM the window.open function works fine, but what about the Outlook integration functionality? Well, in On-Premise this doesn’t pose a big issue because Internet Explorer will typically use your logged in account to authenticate with CRM. But what if you are not using On-Premise, or what if you have another set of logins specifically for CRM in your Active Directory environment (not sure why you would, but it could happen).
Outlook allows a user to cache their credentials to allow communication with the CRM environment without having to log in every time. However, if you open a new window using the standard Jscript window.open function, it will open your window in Internet Explorer not Outlook. In situations where you have to log in to reach CRM (i.e. not using On-Premise with your standard Active Directory account), this will require the user to enter their credentials before opening the correct page. This really disrupts the flow of any process, and is annoying and confusing to end users.
Luckily, Microsoft provided a function to handle this situation (although it is undocumented). There is an openStdWin function that is a part of the CRM Jscript implementation that will check to determine if the user is using Outlook or Internet Explorer, and open the new window in the appropriate format. The following code displays the way this functions:
function openNewWindow(url) {
var name = "newWindow";
var width = 800;
var height = 600;
var newWindowFeatures = "status=1";
var oldWindowFeatures = "width=800,height=600,status=1";
// Regular Jscript function to open a new window
//window.open(url, name, oldWindowFeatures);
// CRM function to open a new window
openStdWin(url, name, width, height, newWindowFeatures);
// CRM function to open a new window
// with default CRM parameters
//openStdWin(url, name);
}
One point to note, if you simply pass the url and name to the openStdWin function and leave off the width, height, and windowFeatures, the window will be opened with the same parameters that regular CRM windows are opened with. (i.e. same width and height as a standard CRM pop-up with no address bar, but with the status bar and resizable)
Now you don’t have to worry if the user is in Outlook or Internet Explorer, your pop-up window will open correctly. Enjoy!
Notice: openStdWin is an internal function of CRM and may change at any given point without notice.
Posted by Tyler Compton on December 12, 2011 at 10:37 AM in CRM Development, Microsoft CRM for Outlook, Microsoft CRM Online | Permalink | Comments (0) | 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)
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)
