Quick Tip: Launch URL for Dynamics 365

Today I discovered by accident, an useful setting in Office 365 App launcher. Here is how the Office 365 App launcher looks like

App Launcher.png

This UI is shown when you click the launcher icon next to “Dynamics 365”. You can set an URL to open when you click this icon, instead of navigating to the default “home.dynamics.com”. You do this by clicking the gear icon on the top right and choosing “Preferences”.

Preferences.png

Set Url.png

Once this is set, you can head straight to the normal CRM Dynamics 365 area, instead of “home.dynamics.com” when you click the Dynamics 365 icon in the launcher.

 

 

Bookmarklet: Copy and Paste Lookup

Lookups (including partylist and customer) cannot be copy pasted. I have encountered couple of scenarios where I needed this capability. I have developed these bookmarklets to solve this issue.

Copy Lookup

Select and the drag the code below to the bookmark bar.

javascript:(function(){let contentPanels=Array.from(document.querySelectorAll('iframe')).filter(function(d){return d.style.visibility!=='hidden'});if(contentPanels&&contentPanels.length>0){let Xrm=contentPanels[0].contentWindow.Xrm;let currentControl=Xrm.Page.ui.getCurrentControl();if(currentControl&¤tControl.getControlType()==='lookup'){let currentLookup=currentControl.getAttribute().getValue();if(currentLookup){let serialisedLookupValue=JSON.stringify(currentLookup.map(x=>{let c={};({id:c.id,name:c.name,type:c.type,typename:c.typename,entityType:c.entityType}=x);return c;}));sessionStorage.setItem('ryr_serialisedLookup',serialisedLookupValue);alert('Lookup copied. Ready to paste');}}else{alert('No field has been selected or the currently selected field is not a lookup');}}else{alert('Entity form not detected');}})();void 0;

Source:

(function () {
	let contentPanels = Array.from(document.querySelectorAll('iframe')).filter(function (d) {
			return d.style.visibility !== 'hidden'
		});
	if (contentPanels && contentPanels.length > 0) {
		let Xrm = contentPanels[0].contentWindow.Xrm;
		let currentControl = Xrm.Page.ui.getCurrentControl();
		if (currentControl && currentControl.getControlType() === 'lookup') {
			let currentLookup = currentControl.getAttribute().getValue();
			if (currentLookup) {
				let serialisedLookupValue = JSON.stringify(
						currentLookup.map(x =  > {
								let c = {};
								({
									id : c.id,
									name : c.name,
									type : c.type,
									typename : c.typename,
									entityType : c.entityType
								}
										 = x);
								return c;
							}));
				sessionStorage.setItem('ryr_serialisedLookup', serialisedLookupValue);
				alert('Lookup copied. Ready to paste');
			}
		} else {
			alert('No field has been selected or the currently selected field is not a lookup');
		}
	} else {
		alert('Entity form not detected');
	}
})();

Paste Lookup

Select and the drag the code below to the bookmark bar.

javascript:(function(){let contentPanels=Array.from(document.querySelectorAll('iframe')).filter(function(d){return d.style.visibility!=='hidden'});if(contentPanels&&contentPanels.length>0){let Xrm=contentPanels[0].contentWindow.Xrm;let currentControl=Xrm.Page.ui.getCurrentControl();if(currentControl&¤tControl.getControlType()==='lookup'){let currentLookup=currentControl.getAttribute();let copiedLookupValue=sessionStorage.getItem('ryr_serialisedLookup');if(copiedLookupValue){currentLookup.setValue(JSON.parse(copiedLookupValue));} else{alert('Please select a lookup to copy first before pasting');}}else{alert('No field has been selected or the currently selected field is not a lookup');}}else{alert('Entity form not detected');}})();void 0;

Source:

(function () {
	let contentPanels = Array.from(document.querySelectorAll('iframe')).filter(function (d) {
			return d.style.visibility !== 'hidden'
		});
	if (contentPanels && contentPanels.length > 0) {
		let Xrm = contentPanels[0].contentWindow.Xrm;
		let currentControl = Xrm.Page.ui.getCurrentControl();
		if (currentControl && currentControl.getControlType() === 'lookup') {
			let currentLookup = currentControl.getAttribute();
			let copiedLookupValue = sessionStorage.getItem('ryr_serialisedLookup');
			if(copiedLookupValue){
				currentLookup.setValue(JSON.parse(copiedLookupValue));
			}
			else{
				alert('Please select a lookup to copy first before pasting');
			}
		} else {
			alert('No field has been selected or the currently selected field is not a lookup');
		}
	} else {
		alert('Entity form not detected');
	}
})();

Instructions

  1. Select the lookup field to be copied. The lookup will usually be highlighted with a blue background when it is selectedlookup-selected
  2. Run the Copy Lookup bookmarklet. You will get a alert message confirming that the lookup has been copied
  3. Select the lookup field that is the target of the paste. The lookup has to be of the same type i.e. if the copied lookup was a contact lookup, the target lookup also has to be a contact lookup
  4. Run the Paste Lookup bookmarklet
  5. Save the record

I have tested these bookmarklets only in Chrome 53 and Firefox 50.

Convert Personal View to System View

When you design a query from the “Advanced Find” window, you can save the query for future use. I call this “Personal View”, but the official name for this is “Saved View”. This view is only visible to the person who saved the view (unless it is shared/reassigned).

As more personal views get created, it becomes an issue during migration, as these are not transported in the solution xml. You can of course use Solution Extender to copy this across, but I would like to do this right from the Advanced Find window. Apart from data migration, another scenario where you might find the need to create a system view from a personal view, is when you are constantly sharing views to a large number of people of group. When you are doing this, it is good time to actually make this a system view.

With these scenarios in mind, I have developed a solution that simplifies the process of creating a system view from a personal view. After installing the managed solution, you will see a new button called “Promote to System View” in the advanced find, when you switch to the “Saved Views” tab.

screenshot

To create a system view from the personal view, simply choose the views that need to be converted, and click the “Promote to System View” button. A message will be displayed after the conversion is complete. Once you refresh the window, you should be able to see the newly created system view(s).

Please log any issues/feedback/feature request in the github repo -> https://github.com/rajyraman/Personal-View-to-System-View/issues

You can download the managed solution from https://github.com/rajyraman/Personal-View-to-System-View/releases

Using Stylish to enhance CRM

What is Stylish?

Stylish is a browser extension available for both Firefox and Chrome. It helps you to alter the styles on any site that you don’t control. The change is localised i.e. it is visible only in your local machine.

How can I use this to enhance Dynamics CRM

I will give you three quick scenarios that you will find useful.

  1. Hide the new “friendly” and “informative” notification messages.
  2. Show the full width of a form label without truncation .
  3. Alter the navigation bar text and colour to easily differentiate various environments.

Hiding the notification messages

This is the CSS you’ll use to hide the notification messages. With this you can quick nuke all the messages, across all the environments you specify using the Stylish configuration. This can be done without going to “Settings” and turn each different notification classes (Get Outlook App, Get CRM App, Trial expiry, Mailbox notifications and Install Interactive Service Hub) off. The rule is for any site that ends with dynamics.com.

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("dynamics.com") {
  .crmAppMessageBar_green, .crmAppMessageBar {
    display: none !important;
  }
}

Before Stylish

Message Bar Before

After Stylish

Message Bar After

Show the full label width without truncation

Starting from CRM2015, labels are not fully displayed if they are too long. The standard approach is to wrap around, but that is not how it is in CRM. Instead, they are truncated. The workaround solution for this is to increase the section width, but there is a better solution. Using Stylish, you can change the CSS that controls this behaviour. Below is the CSS for this. The rule is for any site that ends with dynamics.com.

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("dynamics.com") {
  .ms-crm-InlineEditLabel, .ms-crm-InlineEditLabelText {
    white-space: normal !important;
  }
}

Before Stylish

Label Truncation Before

After Stylish

Label Truncation After

Altering navigation bar text and colour

If you are working across multiple environments, you will like this one. You can change the colour and text using CSS, so that you’ll know where you are, when are constantly switching tabs. I did an extension to do just the colour change, but Stylish does it much better, as it exposes the full power of CSS. You can obviously use themes in CRM2016 to do this. But with this approach:

  1. You can have a theme you like, that is different from the published theme
  2. CRM2015 users can get the same theming goodness

Here is the CSS, you can use for this. The style is just for the navigation bar. You can go crazy and change the form styles, command bar styles and what not.

@-moz-document url-prefix(https://[ENTER THE URL FOR THE RULE]) {
  #navBar {
    background: green !important;
  }
  .navTabLogoText:after {
    content: " DEV" !important;
  }
}

Before Stylish

Navigation Bar Before

After Stylish

Navigation Bar After

Here is some screenshots from Firefox on how to get to the Stylish menu to add custom styles. It is a little bit different in Chrome.

Stylish Menu

I have one rule to do with message bar hiding and preventing label truncation.

Stylish

Here are the links for downloading Stylish

Chrome users head to https://chrome.google.com/webstore/detail/stylish/fjnbnpbmkenffdnngjfgmeleoegfcffe

Firefox users head to https://addons.mozilla.org/en-US/firefox/addon/stylish/

IE users, head to https://www.google.com.au/intl/en/chrome/browser/desktop/index.html Smile

This is a really productive tool to have and is also free.

Improving CRM grids with TableTools2

It is no secret that I am a big fan of the free/opensource tools that fit in nicely with Dynamics CRM. I am also a big fan of bookmarklets that improve your productivity around common repetitive tasks. Firefox is my primary browser for Dynamics CRM, and Chrome is my primary browser when it comes to Javascript debugging. I use Internet Explorer only when a CRM bug prevents me from using either or these, or an user report a issue that it IE specific.

If you don’t use Firefox, this post won’t be of much help to as this addon is Firefox only. The addon I am talking about is tabletools2. This extension is not open source, but is free to use. It would definitely be nice to look at the source, but it is free and super awesome, so I will ignore this point for now.

How this extension improves productivity

IMHO, CRM2016 lacks UX consistency in some areas. One of these is grid. You would not universally see the filter button on the right side, when a grid is displayed. In some pages, you would see it, in some pages you won’t. You can use the addon in grids that don’t display a filter or just in general with any page that displays a table like structure.

With Filter – Plugin Assemblies from Solution

WithFilter.png

Without Filter – Clicking a node inside the plugin assemblies

WithoutFilter.png

Without Filter – Bulk Record Deletion

WithoutFilter2

Without Filter – Add multiple users from Security area (popup)

WithoutFilter3

This one is a popup and so in this scenario, the behavior is consistent with the lookup popup window.

Now lets look how tabletools2 can improve the Bulk Record Deletion grid. Hover over the grid and do this: Ctrl – Shift – Left Click and then Ctrl – Shift – Right Click. This is how the page looks after you do this.

BulkDeleteWithFilter

Yellow text box on each column search and filter the current rows immediately. Turquoise text boxes display the list of unique values on each column and you can filter by this value (like Excel).

I tried this on the attribute screen, which doesn’t have OOB filter button either.

AttributeWithFilter

When the CRM grid lacks filter I usually follow one or both these approaches.

  1. Use browser search with Ctrl-F and highlight the matches
  2. Sort by a particular column

The extension is really useful in the regard, as it can add this functionality locally on the client side on-demand. One thing to note is the search and filter is restricted to the rows on the current page only. It doesn’t search across all pages. There is also heap on other functionalities with the extension, but this is what I currently use. Watch the video below for a quick overview.