Ribbon Workbench Archives - Aric Levin's Digital Transformation Blog https://aric.isite.dev/tag/ribbon-workbench/ Microsoft Dynamics 365, Power Platform and Azure Thu, 12 May 2022 03:39:13 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.3 Power Platform 2021 Release Wave 2 Maker Portal Updates – Modern Commanding http://aric.isite.dev/dynamics/post/2021-wave2-modern-commanding/ Mon, 11 Oct 2021 05:27:00 +0000 https://aric.isite.dev/index.php/2021/10/11/power-platform-2021-release-wave-2-maker-portal-updates-modern-commanding/ In preparation for our upcoming NYC BizApps event on October 27, 2021, and the Power Platform 2021 Wave 2 release (weekend of October 23/24), I am writing a series of blog posts related to some of the most sought after updates. In this post we will review the new modern commanding using Power FX.

The post Power Platform 2021 Release Wave 2 Maker Portal Updates – Modern Commanding appeared first on Aric Levin's Digital Transformation Blog.

]]>
In preparation for our upcoming NYC BizApps event on October 27, 2021, and the Power Platform 2021 Wave 2 release (weekend of October 23/24), I am writing a series of blog posts related to some of the most sought after updates. In this post we will review the new modern commanding using Power FX.

Command bars are at the core of every model-driven app and appear in many different locations. They are arranged in relation to other commands and are associated with a command bar location. The group of commands associated with a specific location make up a command bar.

One of the biggest deficiencies of the Classic Commands, formerly known as the Ribbon, is that there is no low code solution to customize these commands. Command bars can be difficult to customize and error prone (although life has been simplified with the Ribbon Workbench by Scott Durow).

Modern command bars address some of the gaps and difficulties that we had with the legacy commands, and provide support for both Power FX and JavaScript.

Let’s go ahead and take a look at how we can implement modern commanding within our apps. I will use one of the apps that I previously created for this, and add a command bar button that will use Power FX to show/hide the button as well as a custom function that will execute on the click of the button.

In order to start using the new Command functionality, we first need navigate to the page (table in this case) that we want to work with, and select the Edit command bar (preview) option by clicking on the more options to the right of the table name and selecting that option as shown in the image below. This has to be achieved from the Pages navigation pane.

Power FX Commanding - Edit Command Bar

This will pop up a dialog where we have to select what command bar we would like to customize. There are four available options to select which include the Main grid, Main form, Subgrid view and Associated view. The image below shows these options.

Power FX Commanding - Select Command Bar

Let’s go ahead and select Main form. When the Commands page open, we will see a view that contains all of the existing command bar buttons that are available for the table within the Main form. At this point in time (as this is still in preview, and we don’t know the exact timeline of release), modifying the existing buttons is not currently supported, so any customizations that is needed for this, will have to be done using Ribbon Workbench. The image below shows you the Main form Command Bar before we have added any additional buttons.

Power FX Commanding - Select Command Bar

Now let’s go ahead and create a new command. We will create a simple command that is called Calculate Credit Limit which when clicked will multiple the number of employees in the company by 10,000, and will set it to only be visible when the number of employees contains data.

To start creating a new command, we click on the new Command button on the top of the left navigation pane.

Power FX Commanding - New Command Bar button

Once we click on the new command button, we will see that a has been created. We can move the command (using drag and drop) within the Main form to place it in the appropriate location, however this can only be done for new commands, and not the existing ones. Let’s provide the new command some of the properties, such as the Label, Icon to use and the Tooltip text.

Power FX Commanding - Command Bar button properties

Next, we would like to set the functions for the Action that will be performed when the button is clicked as well as the Visibility of the button. On the right Command Pane, the last two options are Action and Visibility. The Action selection has two options: Run formula and Run JavaScript.

If we use the Run JavaScript option we can provide the name of the library and the name of the function to call when the button is clicked. This is more of a legacy type of action which might be used in the future for enabling the legacy buttons. The Run formula allows us to Run Power FX code when the command is clicked.

We can use the Patch function together with the Self.Selected.Item together in order to update the Credit Limit, and then compare the Number of Employees to Blank to control the visibility of the button. I am still working a few glitches as to what is working and what is not when it comes to Power FX for commanding, but the code below is working properly.

On Select:

Set(TotalCredit, Self.Selected.Item.’Number of Employees’ * 10000);

Patch(Accounts, Self.Selected.Item, {‘Credit Limit’: TotalCredit});

Visible:

Self.Selected.Item.’Number of Employees’ <> Blank()

The following Microsoft Docs pages provide an overview of Modern Commanding, directions on the use of the command designer and how to use Power Fx for modern commands.

Now, let’s look at the end result after adding the button and publishing the app commands.

Power FX Commanding - Calculate Credit Limit Command Bar in use

Additional posts related to the Dynamics 365 and Power Platform 2021 Release Wave 2 will be posted by following the link below:

Power Platform 2021 Wave 2 Release Posts

The post Power Platform 2021 Release Wave 2 Maker Portal Updates – Modern Commanding appeared first on Aric Levin's Digital Transformation Blog.

]]>
Removing your Command Bar Unmanaged Active Layer in Model Driven Apps http://aric.isite.dev/dynamics/post/remove-commandbar-unmanaged-layer/ Wed, 15 Sep 2021 04:16:00 +0000 https://aric.isite.dev/index.php/2021/09/15/removing-your-command-bar-unmanaged-active-layer-in-model-driven-apps/ In the last few months I have been working on upgrading the customer´s unmanaged environments to managed. The customer had been working with unmanaged environments for about 5 years, and after joining, this has been one of the first things that I determined would be needed for this customer.

The post Removing your Command Bar Unmanaged Active Layer in Model Driven Apps appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the last few months I have been working on upgrading the customer´s unmanaged environments to managed. The customer had been working with unmanaged environments for about 5 years, and after joining, this has been one of the first things that I determined would be needed for this customer.

The challenge was not so easy. We are still not fully managed in all the environments, but as a stepping stone, all environments with the exception of production are already managed and as we are working on a large migration, the final deployment is only a few months away.

After reading and watching the Microsoft blog and video on what they had to go through with Success Hub, I felt that my endeavor was not as complex. You can read the blog and see the video by clicking on the links below:

https://powerapps.microsoft.com/en-us/blog/how-a-microsoft-team-transitioned-from-unmanaged-to-managed-power-platform-solutions/

https://docs.microsoft.com/en-us/power-platform/alm/move-from-unmanaged-managed-alm

https://www.youtube.com/watch?v=3Uu5C9zkIjo (PowerCAT Live)

As with many of these special projects, there are sometimes blockers that you need to address with the functionality of your application. Ours was related to command bar customizations not being deployed from our development environment (unmanaged) to our QA environment (managed).
My apologies in advance for all the bluring, but this was the only way to get the screenshots.

The screenshots below show the difference between the functionality in our development and qa environments after the re-deployment of our managed solution to qa.

Command Bar UX - Dev Environment

Command Bar UX - Test Environment

As we saw this difference we wanted to go ahead and compare the Ribbon customization differences between the environments, and just as the UX had the differences, so did the commands themselves. It seemed like there was an enable rule missing in the qa environment that was not missing in the development environment. This was done of course using the Command Checker utility that can be invoked by adding the ribbondebug=true key/value to your query string
(ex: https://dev.crm.dynamics.com/main.aspx?appid=1234&forceUCI=1&ribbondebug=true&pagetype=entityrecord&etn=account&id=1234)

See image below for comparison

Command Bar Check - Dev Environment

Command Bar Checker - Test Environment

As with many of the know issues with managed solutions and customizations that do not get overwritten (we experienced this with cloud flows as well), the issue is usually when there is an Unmanaged Layer on top of a Managed layer, and then the customizations do not get overwritten.

When we clicked on the Command Checker, and selected the command that was not performing as expected (1), chose Command Properties (2) we can see the rules that were supposed to be enabled in this environment.

Command Bar Checker - Get to solution layers

The rule that we were expected was not visible. Clicking on the View command definitions solution layers (3) will display any layers that are being used for the command that we are looking at. The image below shows you the results that we saw when clicking on the link.

Command Bar Checker - Layers

In the Command checker solution layers pane, you can also select two layers and compare them to see the CommandDefinition code of the RibbonDiffXml.

Once we saw that there was an Unmanaged Layer (Active Layer) on top of our managed solution layer, the solution was pretty easy, but we required to do this in a few places.

The first thing is we created a new solution in our qa environment. We called this solution Command Bar Fixes, and added the table were we had to fix the customizations. When we added the table, we only selected Include table metadata from the options, and did not select any components. Image below:

Command Bar - Add Table to Solution (Table Metadata Only)

Our solution contained a single table with only the table metadata as shown below.

Command Bar - Export Table Metadata Solution

We then Export the solution. There should not really be a need to publish customizations before (as we have previously seen the results in the Command Checker), but if you are accustomed to this practice, do not change your ways…

Once we export the solution, we navigate to our downloads folder and extract the Command Bar Fixes solution. We open the newly created folder, and within the folder we open the customizations.xml file using an editor of our choice. The customizations.xml file should contain the table specific information as well as the Ribbon Diff Xml and other information about the table. The image below shows this file before we fix it.

Command Bar - Import Export Xml (Before Changes)

I collapsed the RibbonDiffXml containing all the commands, as these are not really relevant. We will go ahead and remove all of the inner Xml of the RibbonDiffXml section, and only leave the <RibbonDiffXml /> tag so that it looks like the image below.

Command Bar - Import Export Xml (After RibbonDiffXml removal)

We then save the changes, and select all the files that are in the extracted folder. Right click and select Send To, and Compressed Folder. We will reimport the newly created zip file.

Navigate back to the Maker portal, click on solutions and select import. In the browse panel, select the zip file that you just created containing the customizations.xml, solutions.xml and [Content_Types].xml.

Import the file and publish your changes. After this navigate back to the table were you experienced the issue and validate that the active layer is now gone and you only have the managed layer.

Hope this was helpful. It was painful for us to get the resolution, so maybe it will help some of you.

The post Removing your Command Bar Unmanaged Active Layer in Model Driven Apps appeared first on Aric Levin's Digital Transformation Blog.

]]>
Custom Page and Command Bars in Model-driven Apps http://aric.isite.dev/powerapps/post/powerapps-custom-pages-powerfx-commanding/ Thu, 29 Jul 2021 08:41:00 +0000 https://aric.isite.dev/index.php/2021/07/29/custom-page-and-command-bars-in-model-driven-apps/ In the last few days, Microsoft made some big announcements related to new features that are not available in public preview. These are the Public Preview of Custom Pages for converging mode-driven apps and canvas apps as well as the command designer for model-driven apps with Power FX (which is still in preview).

The post Custom Page and Command Bars in Model-driven Apps appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the last few days, Microsoft made some big announcements related to new features that are not available in public preview. These are the Public Preview of Custom Pages for converging mode-driven apps and canvas apps as well as the command designer for model-driven apps with Power FX (which is still in preview).

You can read about these two announcements in the Microsoft Power Apps blogs or by clicking on the links below:

https://powerapps.microsoft.com/en-us/blog/custom-pages-for-converging-model-driven-apps-and-canvas-apps/

https://powerapps.microsoft.com/en-us/blog/announcing-command-designer-with-power-fx-preview/

Now, let’s go ahead and review each one of these separately.

Custom Pages:

Let’s start with Custom pages. Custom pages can be used within our model-driven apps anywhere where all pages are supported. This means the main area of the application, dialogs or the new app side pane. It allows the ability to have functionality that is not achievable using the standard features of model-driven apps, but can be achieved using canvas apps.

Custom pages can be opened from the site map for ease of access or from existing model-driven app logic using the Client Api. Custom pages can also open other custom pages or model-driven app pages. They give us the ability to author pages that are too complex to achieve within the existing model pages.

When we create a new app we can now easily add custom pages and take advantage of Canvas Authoring.

There are a few ways to start with custom pages, but let’s go ahead and start by creating a new app.

First thing, let’s navigate to the maker portal, so that we can start creating the new app. As of the time of writing this blog post, we would need to access this by going to the preview maker portal at https://make.preview.powerapps.com.

To start creating the new app, click on the “+ New app” command bar button and select Model-driven from the drop down menu.

PowerApps Converged Apps - New Model Driven App

This will pop up the create model driven app from blank window, where we can select to use the Modern app designer (preview) or the Classic app designer. To start with the Modern app designer, select that choice, and click Create.

PowerApps Converged Apps - Select Design Experience

Next we will need to give the app a name, and an optional description, and click on the Create button.

PowerApps Converged Apps - Enter Name and Description

After a few seconds the new app will be created, and we can start adding pages. There are three different types of pages that can be created, these are table based view and form, dashboard and custom (which is currently in preview). The animated image below shows you the three options.

PowerApps Converged Apps - Select Page Type

We will start by selecting the table type, once selected you will have the option to select the appropriate table or tables that you want to add to your app, and with an option to add these pages to your site map as well.

When you click on the add button, you will be able to see a preview of your app directly from the designer window, basically a preview of what you app would look like. The image below shows you the preview window. You will notice that the center area is the preview, and on the left hand side we see the tables that were added to the app.

The preview area, not only shows you the way the app looks, but allows you to change the layout so that you see how the app will look in responsive design for different devices.

You will also notice the section to the left that is expanded to show the data tables, which contains links to the pages and navigation. This first link shows you the tables, dashboards and custom pages that make up your app, while the second link shows you the site map. These were covered in additional detail in a previous blog post.

New Model-Driven App Designer

Let’s go ahead and add a custom page. Under the pages left hand navigation area (or from the command bar), click on Add page, and select the Custom (preview) option. Once selected you will have the option to create a new custom page or use an existing custom page that was previously created. In our case, since we don’t have an existing custom page, we will Create a new custom page and give it a name.

PowerApps Converged Apps - New Custom Page

Once we enter a name, this will open a new designer, and we can start working on the new app. I have added to the app a couple of galleries and commands so that we can see how this looks and works in our model-driven app. The image below shows the app that we created. Once you are satisfied with the app, click on the Save button and then publish it.

Close the custom page, and then go ahead and Save and Publish the Model-driven app that you created. The animated image below shows the end result of the custom page inside the model-driven app.

PowerApps Converged Apps - Custom Page in Model Driven App

To learn how to navigate between your Canvas app and the model-driven app, you can read more about it in the following Microsoft Docs page : https://docs.microsoft.com/en-us/powerapps/maker/model-driven-apps/page-powerfx-in-model-app

Custom pages can also be available by calling them from JavaScript within the Model Driven App by using the Xrm.Navigation.navigateTo function and providing a page type “custom”, and providing the name of the custom page (canvas app). You can then open the custom page inline or as a centered dialog. The following Microsoft Docs page includes samples on how to open this page: https://docs.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/navigate-to-custom-page-examples

Command Bars using Power FX:

Next, we will take a look at using Command Bars. We will use the same app that we already created, and add a command bar button that will use Power FX to show/hide the button as well as a custom function that will execute on the click of the button.

In order to start using the new Command functionality, we first need navigate to the page (table in this case) that we want to work with, and select the Edit command bar (preview) option by clicking on the more options to the right of the table name and selecting that option as shown in the image below. This has to be achieved from the Pages navigation pane.

Power FX Commanding - Edit Command Bar

This will pop up a dialog where we have to select what command bar we would like to customize. There are four available options to select which include the Main grid, Main form, Subgrid view and Associated view. The image below shows these options.

Power FX Commanding - Select Command Bar

Let’s go ahead and select Main form. When the Commands page open, we will see a view that contains all of the existing command bar buttons that are available for the table within the Main form. At this point in time (as this is still in preview, and we don’t know the exact timeline of release), modifying the existing buttons is not currently supported, so any customizations that is needed for this, will have to be done using Ribbon Workbench. The image below shows you the Main form Command Bar before we have added any additional buttons.

Power FX Commanding - Select Command Bar

Now let’s go ahead and create a new command. We will create a simple command that is called Calculate Credit Limit which when clicked will multiple the number of employees in the company by 10,000, and will set it to only be visible when the number of employees contains data.

To start creating a new command, we click on the new Command button on the top of the left navigation pane.

Power FX Commanding - New Command Bar button

Once we click on the new command button, we will see that a has been created. We can move the command (using drag and drop) within the Main form to place it in the appropriate location, however this can only be done for new commands, and not the existing ones. Let’s provide the new command some of the properties, such as the Label, Icon to use and the Tooltip text.

Power FX Commanding - Command Bar button properties

Next, we would like to set the functions for the Action that will be performed when the button is clicked as well as the Visibility of the button. On the right Command Pane, the last two options are Action and Visibility. The Action selection has two options: Run formula and Run JavaScript.

If we use the Run JavaScript option we can provide the name of the library and the name of the function to call when the button is clicked. This is more of a legacy type of action which might be used in the future for enabling the legacy buttons. The Run formula allows us to Run Power FX code when the command is clicked.

We can use the Patch function together with the Self.Selected.Item together in order to update the Credit Limit, and then compare the Number of Employees to Blank to control the visibility of the button. I am still working a few glitches as to what is working and what is not when it comes to Power FX for commanding, but the code below is working properly.

On Select:

Set(TotalCredit, Self.Selected.Item.’Number of Employees’ * 10000);

Patch(Accounts, Self.Selected.Item, {‘Credit Limit’: TotalCredit});

Visible:

Self.Selected.Item.’Number of Employees’ <> Blank()

The following Microsoft Docs page provides some samples on using Power Fx for commands in the Model driven apps: https://docs.microsoft.com/en-us/powerapps/maker/model-driven-apps/commanding-use-powerfx

Now, let’s look at the end result after adding the button and publishing the app commands.

Power FX Commanding - Calculate Credit Limit Command Bar in use

I hope that this blog post/article provided you with some insights as to what is coming in the new future.

The post Custom Page and Command Bars in Model-driven Apps appeared first on Aric Levin's Digital Transformation Blog.

]]>
Creating Web Resource with a Lookup Control http://aric.isite.dev/dynamics/post/creating-web-resource-with-lookup-control/ Sun, 11 Mar 2018 05:45:00 +0000 https://aric.isite.dev/index.php/2018/03/11/creating-web-resource-with-a-lookup-control/ A few years ago we had some requirements where we needed to pop up an html web resource where users could select a value from a related entity (in a manner similar to a lookup control). We originally developed this as a regular drop down and retrieving the values using Rest messages, but later on decided to change this and have the user click on a "lookup" style control inside the web resource to get this working.

The post Creating Web Resource with a Lookup Control appeared first on Aric Levin's Digital Transformation Blog.

]]>
A few years ago we had some requirements where we needed to pop up an html web resource where users could select a value from a related entity (in a manner similar to a lookup control). We originally developed this as a regular drop down and retrieving the values using Rest messages, but later on decided to change this and have the user click on a “lookup” style control inside the web resource to get this working.

In the recent weeks I saw a few posts in the community of people asking how to do this. In this article I will demostrate the logic of implementing this.

The first thing is we are going to need to create an Entity for the purpose of this solution, and add a button to the entity form to popup the message. We created an entity called Area Type and added a button to the entity called Change Owner using Ribbon Workbench. The button itself will call a JavaScript function that is called changeOwner.

Area Type and Change Owner

The Change Owner function contains the code snippet below which calls the dialog and also processes the changes from the callback of the dialog. I am using the Xrm.Internal.openDialog to open the web resource, and yes “I am aware that this is not supported”, but this is still working in Dynamics 365 v9, and you can feel free to modify the calling of the web resource. Once the button is clicked the popup window will open.

function changeOwner()
{
    var DialogOption = new Xrm.DialogOptions;
    DialogOption.width = 600; DialogOption.height = 550;
    Xrm.Internal.openDialog("/WebResources/xrm_dialog.htm", DialogOption, null, null, changeOwnerCallback);
}

function changeOwnerCallback(returnValue) {
    if (returnValue != null) {
		
		// If need to return multiple values;
	    var returnValues = returnValue.split(':');
        var ownerId = returnValues[0];
        var ownerName = returnValues[1];
		// Perform Actions on return values
		setLookup("ownerid", ownerId, ownerName, "systemuser");
    }
}

Since this was used in a previous project that we had, there is a text box for comments and the lookup control that will need to be popped up.

Web Resource/Dialog Window with Lookup Control

When the user clicks on the lookup icon in the dialog window, an additional Lookup Record window will pop up on top of the original dialog window.

function openOther() {

	var imgButton = $("#crmOtherLookup").attr("src");
	if (imgButton == "/_imgs/btn_off_lookup.png") {


		var objectTypeCode = 8;
		var url = "/_controls/lookup/lookupinfo.aspx?AllowFilterOff=0&DefaultType=8&DefaultViewId=%7bE88CA999-0B16-4AE9-B6A9-9EDC840D42D8%7d&DisableQuickFind=0&DisableViewPicker=1&IsInlineMultiLookup=0&LookupStyle=single&ShowNewButton=0&ShowPropButton=0&browse=false&dType=1&mrsh=false&objecttypes=8";

		var DialogOption = new Xrm.DialogOptions;
		DialogOption.width = 500; DialogOption.height = 400;
		Xrm.Internal.openDialog(url, DialogOption, null, null, openOtherCallback);
	}
	else {
		alert("Please select the radio button to the left of Other in order to select a system user.");
	}
}

function openOtherCallback(returnValue) {
	if (returnValue != null)
	{
		if (returnValue.items.length > 0) {
			var guid = returnValue.items[0].id;
			var name = returnValue.items[0].name;
			$("#crmOtherLookup_ledit").val(name); // text 
			$("#crmOtherLookup_lId").val(guid); // hidden                    
		}
	}
}

Select User

Select the User record that you want, and click the Add button to populate the values from the lookup window (as shown below):

Populated Lookup Control

Finally press the OK button to have the data from the lookup returned to the form, and update the original lookup field that is on the form (not required).

function applyChanges() {
	var returnValue = "";

	var message = $("#crmRoutingMessage").val();
	if (message != '') {

		var otherId = $("#crmOtherLookup_lId").val();
		var otherName = $("#crmOtherLookup_ledit").val();
		returnValue = otherId + ':' + otherName; 

		Mscrm.Utilities.setReturnValue(returnValue);
		closeWindow(true);
	}
	else
	{
		alert('Please enter a Routing Message');
	}
}

Final Result

The full source code and a sample solution (containing the test entity, customizations and all web resource files) is available here on github: https://github.com/ariclevin/WebResourceLookup

The post Creating Web Resource with a Lookup Control appeared first on Aric Levin's Digital Transformation Blog.

]]>
Disable Delete icon on subgrid http://aric.isite.dev/dynamics/post/disable-delete-icon-on-subgrid/ Mon, 05 Feb 2018 04:36:00 +0000 https://aric.isite.dev/index.php/2018/02/05/disable-delete-icon-on-subgrid/ We recently had a requirement that users wanted to hide the Delete icon on the subgrid to prevent users from deleting records. Of course it is possible to remove the Delete privilege on the entity in Security Roles, but the requirement was different. When the status of the parent record was Active, the Delete operation should be allowed, however when the parent record was Inactive, the Delete operation should not be allowed.

The post Disable Delete icon on subgrid appeared first on Aric Levin's Digital Transformation Blog.

]]>
We recently had a requirement that users wanted to hide the Delete icon on the subgrid to prevent users from deleting records. Of course it is possible to remove the Delete privilege on the entity in Security Roles, but the requirement was different. When the status of the parent record was Active, the Delete operation should be allowed, however when the parent record was Inactive, the Delete operation should not be allowed.

The first thing that of course we are aware of, is that if a record is inactive, the subgrid Delete functionality is still available, as shown in the image below.

Normal Subgrid Delete button visible on Inactive parent record

We then went ahead and hid the button.

Hide Delete button

This caused the expected result that the Delete button no longer showed up on the subgrid, but of course it did not show up for both enabled or disabled parent records.

Delete button does not show up.

Finally we came up with a resolution, the did not hide the delete button, but allowed us to prevent the Delete action for the disabled records. We went ahead and unhid the Delete button, and then selected the Customize Command option. This populated the Mscrm.DeleteSelectedRecord command under the Command in Ribbon Workbench. We added another Enable rule called RestrictDeleteFromSubgrid, as shown below:

Restrict Delete from Subgrid Command

The result of this action is that the Delete button will still be enabled on the subgrid (and associated grid), but when the Delete button is pressed, if the parent record is Inactive, a message will pop up displaying the you cannot delete a record if the parent record is Inactive.

Delete button clicked on Inactive record

The code on the RestrictDeleteFromSubgrid JavaScript method is very simple. It checks the status of the form and returns true or false whether the record can be deleted.

function RestrictDeleteFromSubgrid() {
    var formType = Xrm.Page.ui.getFormType();
    if (formType == 3 || formType == 4)
    {
        alert('You cannot remove an Inactive record');
        return false;
    } 
    else 
    {
        return true;
    }
}

The post Disable Delete icon on subgrid appeared first on Aric Levin's Digital Transformation Blog.

]]>
Retrieving data fields from subgrid http://aric.isite.dev/dynamics/post/retrieving-data-fields-from-subgrid/ Sun, 22 Oct 2017 06:25:00 +0000 https://aric.isite.dev/index.php/2017/10/22/retrieving-data-fields-from-subgrid/ This is probably a request that has been required many times, but recently, one of our customers had a request to open an OnBase document based on some data that was available in a subgrid. Since OnBase has a web to query the database using a query string in their web application, this seemed to be an easy enough solution.

The post Retrieving data fields from subgrid appeared first on Aric Levin's Digital Transformation Blog.

]]>
This is probably a request that has been required many times, but recently, one of our customers had a request to open an OnBase document based on some data that was available in a subgrid. Since OnBase has a web to query the database using a query string in their web application, this seemed to be an easy enough solution.

The first step was to create a button on the ribbon that will call a JavaScript function that will in turn execute the OnBase function call. To do this we created a button on the Command Bar of the entity using Ribbon Workbench. You can view our previous published post on how to create a button using Ribbon Workbench if you need further assistance with this process.

In this case we created a button called OnBase, which calls the showOnBase function and passes the CommandProperties. The reason that it is passing the CommandProperties, is that the button has various options for that same form. The image below shows the button that was created using Ribbon Workbench. This is a flyout button, thus has various different options.

Command Bar Flyout Button

Next we need to enter the JavaScript for the flyout button. In our case we used a single function for the flyout and passed the CommandProperties, in order to get the name of the button that was clicked. The following Script shows how to find out which button was clicked, and based on that we will be calling our process.

function showOnBase(CommandProperties)
{
    var controlId = CommandProperties.SourceControlId;
    var menuItemId = controlId.split('|')[3];
    var recordType = menuItemId.split('.')[2];
    
    switch (recordType)
    {
        case "OnBaseContract":
            showOnBaseContract();
            break;
        case "OnBasePurchaseOrder":
            showOnBasePurchaseOrder();
            break;
        case "OnBaseInvoice":
            showOnBaseInvoice();
            break;
        default:
            break;
    }
}

In our particular case, we are interested in getting the value for a subgrid, which means that the user would have to select the record from a subgrid and the click on the appropriate button. The image below shows our Purchase Order subgrid. When the user selects the PO subgrid row, and the clicks on the Command Bar Purchase Order command, we will open up the Purchase Order using OnBase. The image below displays the PO subgrid.

Selected Record on Subgrid

We can not get the purchase order number from the selected record and Open OnBase.

function showOnBasePurchaseOrder()
{
    var selectedRows = Xrm.Page.getControl("PurchaseOrders").getGrid().getSelectedRows();
    var selectedRow = selectedRows.getAll()[0];

    var attributes = selectedRow.getData().getEntity().getAttributes().getAll();
    // scag_ponumber
    attributes.forEach(function (attribute) {
        var attributeName = attribute.getKey();
        if (attributeName == "new_ponumber")
        {
            var poNumber = attribute.getValue();
            var url = "http://ecmweb/AppNet/docpop/docpop.aspx?KT123_0_0_0=" + poNumber + "&clienttype=activex&cqid=111";
            openOnBase(url);
        }
    });
}

function openOnBase(url)
{
    window.open(url);
}

You can use different methods to open your OnBase form if you don’t want to use the window.open, but this was a good option for the purpose that we needed.

The post Retrieving data fields from subgrid appeared first on Aric Levin's Digital Transformation Blog.

]]>
Cloning a Record in Dynamics CRM http://aric.isite.dev/dynamics/post/clone-record-in-dynamics-crm/ Sun, 22 Oct 2017 04:22:00 +0000 https://aric.isite.dev/index.php/2017/10/22/cloning-a-record-in-dynamics-crm/ Recenly we received requests from clients and some questions from Dynamics Community members on how to Clone records. Although there are some available solutions out there, and the various possibilities on how to implement this, we would like to demonstrate here one possibly and not to complicated way on how to implement this. This implementation involved using Ribbon Workbench to create the Clone button and a Command that will execute a JavaScript function, which will call an action and execute Plugin/Action code to copy the record.

The post Cloning a Record in Dynamics CRM appeared first on Aric Levin's Digital Transformation Blog.

]]>
Recenly we received requests from clients and some questions from Dynamics Community members on how to Clone records. Although there are some available solutions out there, and the various possibilities on how to implement this, we would like to demonstrate here one possibly and not to complicated way on how to implement this. This implementation involved using Ribbon Workbench to create the Clone button and a Command that will execute a JavaScript function, which will call an action and execute Plugin/Action code to copy the record.

So the first step of course is using Ribbon Workbench to create the button, enable/display rules and the command. We start of by adding our entity that we want to customize to a new Unmanaged solution. We only need to add the entity, and not all of the components of the entity. Once we created the solution we open Ribbon Workbench, and select the new solution that we created.

We can not add a new button with an image to the form command bar, as shown in the picture below:

Add Button to Form Command Bar

You should also add the Label, Alt, Tool Tip Text and Tool Tip Description. It is a good habit to have the Tooltip Description display a different text that the Tool Tip Text. We can now create the display rule. We created a simple display rule only with a FormStateRule that has a State of Existing. This means that the Clone Command will only be available for records that already exist in the System, but not for newly or disabled records. You can change the display rule, as you wish.

Once we have the display rule, we will create the command. You should have a JavaScript Library in place for your entity that you wish to clone ahead of time, so that you can use it for the Command. You can also use a Global library if you are planning to use the same logic for multiple entities. In the command we will Create a Custom JavaScript action and specify the name of the library and function that will be used when the Clone Command Bar button is clicked (shown is the image below).

Clone Record Command

Let’s go ahead and look at the finalized button properties before publishing the solution changes.

Clone Button

We can now click on the Publish button in Ribbon Workbench to finish adding the button to our form. The next step is to add the JavaScript code to our library that we previously created. There are a few ways of calling actions from JavaScript, but we prefer to use the process.js JavaScript Library. This library can be downloaded from github, and is available here: https://github.com/PaulNieuwelaar/processjs. Add this library to your form where you added the Clone button to, so that you can use it in your JavaScript Library.

function cloneGlobalSetting()
{
    var entityId = Xrm.Page.data.entity.getId();
    var entityName = "new_globalsetting";
    var messageName = "new_CloneGlobalSetting";
    var success = callCloneAction(entityId, entityName, messageName);
    if (success) {
        Xrm.Page.ui.setFormNotification("Record has submitted for cloning.", "INFO", "GEN")
        setTimeout(function () {
            reloadPage(entityId);
        }, 3000);
    }
}

The above function calls the callCloneAction, and passes the Guid of the entity record, the name of the entity and the name of the SDK message that will be created. The below code snippets show the callCloneAction and callProcessAction functions. Although these can be combined into one, we separated them, since we have multiple function calls to Actions in our code, and use the callProcessAction for multiple purposes. If you only have one call to callProcessAction, you can keep it separate, or add it to your global script library to be used across multiple entities.

function callCloneAction(entityId, entityName, messageName, name) {

    var inputParams =
        [
            {
                key: "Target",
                type: Process.Type.EntityReference,
                value: new Process.EntityReference(entityName, entityId)
            }
        ];
    var success = callProcessAction(entityId, entityName, messageName, inputParams);
    return success;
}

function callProcessAction(entityId, entityName, messageName, inputParams) {
    var success = true;
    Process.callAction(messageName, inputParams,
    function (params) {
        // Success
        var result = "";
        for (var i = 0; i < params.length; i++) {
            result = params[i].key + "=" + params[i].value + ";";
        }
        // alert(result);
        success = true;
    },
    function (e, t) {
        // Error
        success = false;
        alert(e);

        if (window.console && console.error)
            console.error(e + "n" + t);
    }
    );
    return success;
}

Now that we have added our JavaScript code to our library, we need to upload and publish this file, as well as add it to the form. Once that is done, we need to create the Action Process in our solution. We do this by navigating to Settings -> Processes and Creating a New Action. The screenshot below shows the Action Process that we created. Note that there is a parameter called Action Type, which is not required for this particular case, but is used for our cloning process, since the record can be cloned in a few different ways.

Create Action Process

We now have to add the Plugin/Action code and register it. The first thing to do is create a new plugin. If this is the first time you are creating a new plugin, please follow the Microsoft MSDN article on how to create a Basic Plugin here. In our Plugin project, we created two classes, although this can be done with one. The first class shown below is just the entry point which calls the actual class that processes the action.

    public class GlobalSetting : Plugin
    {
        public GlobalSetting()
            : base(typeof(GlobalSetting))
        {
            this.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(40, "new_CloneGlobalSetting", "new_globalsetting", new Action<LocalPluginContext>(ExecutePostGlobalSettingClone)));
        }

        protected void ExecutePostGlobalSettingClone(LocalPluginContext localContext)
        {
            if (localContext == null)
            {
                throw new ArgumentNullException("localContext");
            }
            string entityName = localContext.PluginExecutionContext.PrimaryEntityName;
            Guid entityId = localContext.PluginExecutionContext.PrimaryEntityId;
            string actionType = localContext.PluginExecutionContext.InputParameters["ActionType"].ToString();


            ITracingService tracingService = localContext.TracingService;
            tracingService.Trace("Entered {0} Plugin Method", "ExecutePostGlobalSettingClone");

            using (GlobalSettingLogic logic = new GlobalSettingLogic(localContext.OrganizationService, localContext.TracingService))
            {
                logic.CloneGlobalSetting(entityName, entityId, actionType);
            }
        }
    }

In our second class (GlobalSettingLogic), which is only a class that hold the logic of the requirement we will add the following function:

        private Guid CloneGlobalSetting(Entity globalSetting)
        {
            Entity newGlobalSetting = new Entity(new_GlobalSetting.EntityLogicalName);

            foreach (KeyValuePair<String, Object> attribute in globalSetting.Attributes)
            {
                string attributeName = attribute.Key;
                object attributeValue = attribute.Value;

                switch (attributeName.ToLower())
                {
                    case "new_globalsettingid":
                        break;
                    case "new_name":
                        newGlobalSetting[attributeName] = attributeValue + " - Cloned";
                        break;
                    default:
                        newGlobalSetting[attributeName] = attributeValue;
                        break;
                }

            }

            try
            {
                Guid globalSettingId = service.Create(newGlobalSetting);
                return globalSettingId;
            }
            catch (FaultException<OrganizationServiceFault> ex)
            {
                throw new InvalidPluginExecutionException("An error occurred in the CloneGlobalSetting function of the plug-in.", ex);
            }
        }

We now how to Build our Plugin, and deploy it using the Plugin Registration Tool (as shown in the following screenshot). The Action Process must have been completed prior to this step in order for it to appear as a Message in the Plugin Registration Tool.

Register Action

Once the Plugin is registered, you are basically done. You can now test it out, and go to your form, click on the Clone button and a newly Cloned record can be created. The final form will look like this with the Clone button:

Clone Button on Form

The post Cloning a Record in Dynamics CRM appeared first on Aric Levin's Digital Transformation Blog.

]]>
Creating a Ribbon Button Using Ribbon Workbench to call a JavaScript action http://aric.isite.dev/dynamics/post/create-ribbon-button-using-ribbon-workbench/ Tue, 03 Oct 2017 15:57:00 +0000 https://aric.isite.dev/index.php/2017/10/03/creating-a-ribbon-button-using-ribbon-workbench-to-call-a-javascript-action/ This blog post will demonstrate how to create a simple button using Ribbon Workbench which will execute a JavaScript function on the client. In order to do this make sure that you have Ribbon Workbench installed in your CRM environment, or you can use the Ribbon Workbench that is available with XRMToolbox.

The post Creating a Ribbon Button Using Ribbon Workbench to call a JavaScript action appeared first on Aric Levin's Digital Transformation Blog.

]]>
This blog post will demonstrate how to create a simple button using Ribbon Workbench which will execute a JavaScript function on the client. In order to do this make sure that you have Ribbon Workbench installed in your CRM environment, or you can use the Ribbon Workbench that is available with XRMToolbox.

To download Ribbon Workbench, you can go to https://www.develop1.net/public/rwb/ribbonworkbench.aspx.

So the first step of course is using Ribbon Workbench to create the button, enable/display rules and the command. We start of by adding our entity that we want to customize to a new Unmanaged solution. We only need to add the entity, and not all of the components of the entity. Once we created the solution we open Ribbon Workbench, and select the new solution that we created.

We can not add a new button with an image to the form command bar, as shown in the picture below:

Add Button to Form Command Bar

You should also add the Label, Alt, Tool Tip Text and Tool Tip Description. It is a good habit to have the Tooltip Description display a different text that the Tool Tip Text. We can now create the display rule. We created a simple display rule only with a FormStateRule that has a State of Existing. This means that the Clone Command will only be available for records that already exist in the System, but not for newly or disabled records. You can change the display rule, as you wish.

Once we have the display rule, we will create the command. You should have a JavaScript Library in place for your entity that you wish to clone ahead of time, so that you can use it for the Command. You can also use a Global library if you are planning to use the same logic for multiple entities. In the command we will Create a Custom JavaScript action and specify the name of the library and function that will be used when the Clone Command Bar button is clicked (shown is the image below).

Clone Record Command

Let’s go ahead and look at the finalized button properties before publishing the solution changes.

Clone Button

We can now click on the Publish button in Ribbon Workbench to finish adding the button to our form. The final step is to add the JavaScript code to our library that we previously created.

function cloneGlobalSetting()
{
   Xrm.Page.ui.setFormNotification("I clicked on a new button!!!", "INFO", "GEN")
}

The post Creating a Ribbon Button Using Ribbon Workbench to call a JavaScript action appeared first on Aric Levin's Digital Transformation Blog.

]]>
Create Email a Link to Selected Records in KBArticle Grid View http://aric.isite.dev/dynamics/post/create-email-link-to-selected-records-in-kbarticle-view/ Tue, 15 Aug 2017 22:50:00 +0000 https://aric.isite.dev/index.php/2017/08/15/create-email-a-link-to-selected-records-in-kbarticle-grid-view/ Recently somebody asked, why does the KB Article home page view does not have an option to Email a Link to multiple records like a lot of the other entities do, In looking at the Ribbon Xml, we notice that is true and there is no Email a Link split button to display that, so we were looking at the best approach to implement this.

The post Create Email a Link to Selected Records in KBArticle Grid View appeared first on Aric Levin's Digital Transformation Blog.

]]>
Recently somebody asked, why does the KB Article home page view does not have an option to Email a Link to multiple records like a lot of the other entities do, In looking at the Ribbon Xml, we notice that is true and there is no Email a Link split button to display that, so we were looking at the best approach to implement this.

We will be cover an mixed way of doing this with Ribbon Workbench and customizing this with the Customizations.xml file that is part of the part of an export solution.

In order to get this working, the first thing that we need to do is take a look at how this is implemented in an entity that the Split button exists, such as the Contact or Account entity.

First we are going to create a new solution, and include only the Contact entity in it. You can include All Assets. Launch Ribbon Workbench, and then choose the solution that you just created.

Launch Ribbon Workbench

In the home page command bar of Ribbon Workbench, right click on the Email A Link button, and then select Customize Button. Repeat the same and select Customize Command. This will load all the button and customizations of the Email A Link button for the Contact Entity.

Click on the Xml tab in the solution area of Ribbon Workbench, and then click on the Refresh button. This will show you the Xml portion of your Email A Link button and command. Copy the Xml to a text editor, and do the follow steps:

  • Remove the Xml element line from the file
  • In the RibbonDiffXml section start tag, remove any namespaces, so that it only shows
  • Replace within the file all occurences of contact with kbarticle

You can close Ribbon Workbench. In your solutions area, create a new solution and add the KB Article Entity to the solution. Include All Assets. Export the solution as an unmanaged solution.

Extract the unmanaged solution that you created, and in the extracted folder open the customizations.xml file in a text editor. Navigate to the RibbonDiffXml section of the customizations file, and replace it with the RibbonDiffXml that you modified from what you copied from Ribbon Workbench. The following is a sample of the RibbonDiffXml section of the file:

>
  
    "Mscrm.HomepageGrid.kbarticle.Send.CustomAction" Location="Mscrm.HomepageGrid.kbarticle.MainTab.Collaborate.Controls._children" Sequence="61">
      
        "Mscrm.SendShortcutSelected.AlwaysEnabled" Id="Mscrm.HomepageGrid.kbarticle.Send" Image32by32="/_imgs/ribbon/SendShortcut_32.png" Image16by16="/_imgs/ribbon/EmailLink_16.png" LabelText="$Resources:Ribbon.HomepageGrid.Record.Shortcut.Send" Sequence="61" TemplateAlias="o2" ToolTipTitle="$Resources:Ribbon.HomepageGrid.Record.Shortcut.Send" ToolTipDescription="$Resources:Mscrm_HomepageGrid_Other_MainTab_ExportData_Send_ToolTipDescription" ModernImage="EmailLink">
“Mscrm.HomepageGrid.kbarticle.Send.Menu”> “Mscrm.HomepageGrid.kbarticle.Send.MenuSection” Sequence=“10” DisplayMode=“Menu16”> “Mscrm.HomepageGrid.kbarticle.Send.MenuSection.Controls”>
        
      
    
  
  
    "Mscrm.Templates" />
  
  
    "Mscrm.SendShortcutSelected.AlwaysEnabled">
      
        "Mscrm.Enabled" />
        "Mscrm.IsValidForHierarchyView" />
      
      
        "Mscrm.HideOnModern" />
      
      
        "Mscrm.CommandBarActions.sendSelectedRecordsUrl" Library="/_static/_common/scripts/CommandBarActions.js">
          "true" />
          "SelectedControlSelectedItemReferences" />
          "SelectedEntityTypeCode" />
        
      
    
  
  
    
    
      "Mscrm.HideOnModern">
        "Modern" InvertResult="true" />
      
    
    
      "Mscrm.Enabled">
        "Mscrm.CommandBarActions.alwaysEnabled" Library="/_static/_common/scripts/CommandBarActions.js" />
      
      "Mscrm.IsValidForHierarchyView">
        "Mscrm.CommandBarActions.isValidForHierarchyView" Library="/_static/_common/scripts/CommandBarActions.js" />
      
    
  
  

Save your changes of the Customizations.xml file. Re-compress the extracted file, and import the created zip file into your solutions. Publish your changes.

Navigate to Articles, and you will see that the Email A Link button is visible and enabled on the form.

The post Create Email a Link to Selected Records in KBArticle Grid View appeared first on Aric Levin's Digital Transformation Blog.

]]>
Add Command using Ribbon Workbench – Part II http://aric.isite.dev/dynamics/post/add-command-ribbon-workbench-2/ Mon, 14 Aug 2017 00:10:00 +0000 https://aric.isite.dev/index.php/2017/08/14/add-command-using-ribbon-workbench-part-ii/ The purpose of the original post (Part I), was to demonstrate how to add a button to a read only entity record, in order to create a new child record. This is a complex scenario that requires a lot of customization to the Ribbon/Command Bar. A much easier solution exists, if all you are looking for is to add the capability of adding child records to a read only record, as we discussed in the first part of this article.

The post Add Command using Ribbon Workbench – Part II appeared first on Aric Levin's Digital Transformation Blog.

]]>
The purpose of the original post (Part I), was to demonstrate how to add a button to a read only entity record, in order to create a new child record. This is a complex scenario that requires a lot of customization to the Ribbon/Command Bar. A much easier solution exists, if all you are looking for is to add the capability of adding child records to a read only record, as we discussed in the first part of this article.

The first thing that we need is to open the child entity using Ribbon Workbench as shown in the previous solution. The previous solution had the Contract Detail entity, however in this solution we will need to Contract Detail Child entity, since we are making modifications to the subgrid and not the form. When looking at the form that is in Read-Only state, the add sign of the Contract Detail Child entity does not exist. We only see the table sign (associated grid) next to it, as shown in the image below.

No Add New Button Available

In order to add the button, we will first have to create (or modify) a solution that will contain this entity, so that we can modify the properties in Ribbon Workbench. The screenshot below shows the solution that we created, containing only the custom entity that will contain a subgrid inside of the Contact Detail form.

Solution Components

We can now open Ribbon Workbench, by clicking on the Ribbon Workbench 2016 button in our Solutions view. When opening we will select the solution that we just created or modified, and this will display the Contract Detail Line custom entity that we created. As in the previous post, there are three command bars visible. In this scenario we will modify the Subgrid command bar.

We are not going to add any additional buttons to this subgrid, but customize the Add New Command of the subgrid. When you right click on the Add New (1) command, it will open a drop down of options. From here we want to select the Customize Command (2) option, in order to make changes to the command that controls the visibility (and enable status) of the command and button. The screenshot below shows this.

Customize Command

Once we click on the Customize command, the center area of the solution will display the Command, Display Rules and Enable Rules of the command that we selected, and allow us to make modifications to them. The rule that we are looking to make changes to is the Mscrm.EntityFormIsEnable EnableRule. Since we are not going to need the rule, because we always want to display the add sign regardless of the State of the Form, we can just delete it. We delete it by right clicking on the Mscrm.EntityFormIsEnable Enable Rule (1), and choosing/clicking the Delete option (2).

If you need to customize this further, and only enable the Add New command in certain conditions (such as when form is only existing or read only), you can add Display or Enable rules here to control this here. We demonstrated how to create those rules in the previous post.

Modify Enable Rule

Once the Enable Rule has been deleted, we are now ready to Publish the Customizations. On the top Navigation area in Ribbon Workbench, click on the Publish button. This will publish the changes to the entity. The screenshot below shows us the condition of the subgrid after the customization changes have been completed.

Post Customization Subgrid

That is basically it. I would like to thank Alex Shlega for helping with this solution.

The post Add Command using Ribbon Workbench – Part II appeared first on Aric Levin's Digital Transformation Blog.

]]>