Tips and Tricks Archives - Aric Levin's Digital Transformation Blog http://aric.isite.dev/tag/tips-and-tricks/ Microsoft Dynamics 365, Power Platform and Azure Thu, 12 May 2022 03:15:14 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.3 Using Microsoft Multiselect Lookup in your Model Driven Apps – Part II http://aric.isite.dev/development/post/multiselect-lookup-pcf-overview-update-nn/ Sun, 09 Jan 2022 16:00:00 +0000 https://aric.isite.dev/index.php/2022/01/09/using-microsoft-multiselect-lookup-in-your-model-driven-apps-part-ii/ In the last blog post, I demonstrated how to use the Microsoft Multiselect Lookup control (similar to the Activity Party control), which was released as part of an update to Field Services to add new values to a backend many to many relationship. In this post, I am going to extend this further to show how to add and remove items from the multiselect control, and have them get updated in the relationship.

The post Using Microsoft Multiselect Lookup in your Model Driven Apps – Part II appeared first on Aric Levin's Digital Transformation Blog.

]]>
In the last blog post, I demonstrated how to use the Microsoft Multiselect Lookup control (similar to the Activity Party control), which was released as part of an update to Field Services to add new values to a backend many to many relationship. In this post, I am going to extend this further to show how to add and remove items from the multiselect control, and have them get updated in the relationship.

The post will go through adding existing values to a Multiselect control, and then removing the values and seeing how these values are adding and removed from the control.

Let’s go ahead and start with showing the way this works. The image below shows the control with the existing values, as well as the corresponding values of the JSON string and the text box containing the text values only of the control to be displayed in the view.

Microsoft Multiselect Lookup - N:N Update 1

You will notice that the form has three values of three separate contacts that were previously added on the create of the account record. I will now go ahead and remove two of the values from the form, and you will see that both the Contacts (JSON) string gets updated and the Contact Values text gets updated.

Microsoft Multiselect Lookup - N:N Update - Removal

Finally, let’s go ahead and add one of the contacts back. You will now see that the Contact Values and the Contacts (JSON) string got updated.

Microsoft Multiselect Lookup - N:N Update - Addition

At the end of the post, you will be able to see a video of this in action, including everything that was added in the previous post (of creating a new record). Now let’s jump into the lookup how this was built. This is slightly more complex that the create logic from the previous post as there are various conditions that have to be met.

First let’s take a look at the JSON configuration that will be added to the Plugin step. Note that the plugin step is now different, because it runs on a single attribute. If you have multiple attributes that you need to run this against, then each one will have a separate plugin step. The sample JSON below shows you how to configure this:

[{“_attributeName”:”crde5_contacts”,”_textAttributeName”:”crde5_contactvalues”,”_relationshipType”:”native”,”_relationshipName”:”crde5_accounts_contacts”,”_details”:

{

“_primaryEntityName”:”crde5_accounts_contacts”,

“_relatedAttributeName”:”accountid”,

“_linkToEntityName”:”contact”,

“_linkFromAttributeName”:”contactid”,

“_linkToAttributeName”:”contactid”,

“_linkToPrimaryAttributeName”:”fullname”

}

}]

The first section is the same as for the create, with the exception of the details. I used the same serialization class for both plugins (create and update). The details contain additional parameters which allow me to add a relationship to the related entity to pull values from. This is required to get the existing values that are already in the N:N relationship that is created for this object. You can omit the linked entity part, but I added in order to be able to retrieve the name value from the related entity to the relationship entity.

Next, let’s look at the changes to the serialization class. The LookupAttribute class now contains an additional Data Member called LookupAttributeDetails which is added as a variable and to the class constructor. An additional class of type Lookup attribute details is also created. You can see the code changes below:

[DataContract]
public class LookupAttribute
{
	[DataMember] 
	public string _attributeName { get; set; }
	[DataMember]
	public string _textAttributeName { get; set; }
	[DataMember] 
	public string _relationshipType { get; set; }
	[DataMember] 
	public string _relationshipName { get; set; }
	[DataMember] 
	public LookupAttributeDetails _details { get; set; }

	public LookupAttribute(string attributeName, string textAttributeName, string relationshipType, string relationshipName, LookupAttributeDetails details)
	{
		_attributeName = attributeName;
		_textAttributeName = textAttributeName;
		_relationshipType = relationshipType;
		_relationshipName = relationshipName;
		_details = details;
	}
}

[DataContract]
public class LookupAttributeDetails
{
	[DataMember] 
	public string _primaryEntityName { get; set; }
	[DataMember]
	public string _relatedAttributeName { get; set; }
	[DataMember] 
	public string _linkToEntityName { get; set; }
	[DataMember] 
	public string _linkFromAttributeName { get; set; }
	[DataMember] 
	public string _linkToAttributeName { get; set; }
	[DataMember] 
	public string _linkToPrimaryAttributeName { get; set; }

	public LookupAttributeDetails(string primaryEntityName, string relatedAttributeName, string linkToEntityName, string linkFromAttributeName, string linkToAttributeName, string linkToPrimaryAttributeName)
	{
		_primaryEntityName = primaryEntityName;
		_relatedAttributeName = relatedAttributeName;
		_linkToEntityName = linkToEntityName;
		_linkFromAttributeName = linkFromAttributeName;
		_linkToAttributeName = linkToAttributeName;
		_linkToPrimaryAttributeName = linkToPrimaryAttributeName;
	}
}

Next, let’s look at our Plugin class. Same as the previous Create Plugin we are retrieving the Unsecure and Secure configuration from the Plugin step to be used to populate the lookupAttributes list.

using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(_unsecureConfigData)))
{
	DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(List<LookupAttribute>));
	lookupAttributes = (List<LookupAttribute>)deserializer.ReadObject(stream);
}

We then retrieve the data from the actual PCF control, which contains the JSON string of all the contacts that were previously added. This is still similar to the Create Plugin.

string controlData = target.GetAttributeValue<string>(attribute._attributeName);
using (MemoryStream dataStream = new MemoryStream(Encoding.Unicode.GetBytes(controlData)))
{
	DataContractJsonSerializer dataDeserializer = new DataContractJsonSerializer(typeof(List<LookupObject>));
	List<LookupObject> lookupObjects = (List<LookupObject>)dataDeserializer.ReadObject(dataStream);
}

The first difference is that now we want to retrieve the related entity values. We do this by creating a query expression that pulls the data elements based on what we set in the unsecured configuration of the plugin step. This is required so that we can have two list of values (current and previous), and add or remove values to the related entity based on changes in the PCF control. The code below shows the dynamic creation of the query expression, and retrieval of the related values and adding them to the collection of existing objects.

QueryExpression query = new QueryExpression(attribute._relationshipName);
query.ColumnSet.AddColumns(attribute._details._linkFromAttributeName, attribute._details._relatedAttributeName);
query.Criteria.AddCondition(attribute._details._relatedAttributeName, ConditionOperator.Equal, target.Id);
LinkEntity linkEntity = query.AddLink(attribute._details._linkToEntityName, attribute._details._linkFromAttributeName, attribute._details._linkToAttributeName);
linkEntity.EntityAlias = attribute._details._linkToEntityName;
linkEntity.Columns.AddColumn(attribute._details._linkToPrimaryAttributeName);

EntityCollection data = service.RetrieveMultiple(query);
if (data.Entities.Count > 0)
{
	List<LookupObject> existingObjects = new List<LookupObject>();
	foreach (Entity related in data.Entities)
	{
		existingObjects.Add(new LookupObject(
			related.GetAttributeValue<Guid>(attribute._details._linkToAttributeName).ToString(), 
			related.GetAttributeValue<AliasedValue>(attribute._details._linkToEntityName + "." + attribute._details._linkToPrimaryAttributeName).Value.ToString(), 
			attribute._details._linkToEntityName));
	}
}

Now that we have the two pieces of data, and both are of type Lookup Object, we want to make a comparison so that we can determine if to add or remove items them from the related relationship records. The code below created two lists of type Lookup Objects called Items to Add and Items to Remove, and populates them with data when there are elements to add or remove.

List<LookupObject> itemsToAdd = new List<LookupObject>(); 
List<LookupObject> itemsToRemove = new List<LookupObject>(); 

EntityReferenceCollection relatedReferencesToAdd = new EntityReferenceCollection();
foreach (LookupObject item in lookupObjects)
{
	var itemExists = existingObjects.Exists(x => x._id == item._id);
	tracingService.Trace("Item {0} does {1} exist in Related Table", item._id, itemExists.ToString());
	if (!itemExists)
	{
		itemsToAdd.Add(item);
		relatedReferencesToAdd.Add(new EntityReference(item._etn, new Guid(item._id)));
	}
}

EntityReferenceCollection relatedReferencesToRemove = new EntityReferenceCollection();
foreach (LookupObject item in existingObjects)
{
	var itemExists = lookupObjects.Exists(x => x._id == item._id);
	tracingService.Trace("Item {0} does {1} exist in Form Table", item._id, itemExists.ToString());
	if (!itemExists)
	{
		itemsToRemove.Add(item);
		relatedReferencesToRemove.Add(new EntityReference(item._etn, new Guid(item._id)));
	}
}

After adding the items to these collections, we create an Associate Request to add all of the related Items to Add, and create a Disassociate Request to remove all of the related Items that are no longer in the PCF control.

if (itemsToAdd.Count > 0)
{
	AssociateRequest addRequest = new AssociateRequest();
	addRequest.Target = target.ToEntityReference();
	addRequest.Relationship = new Relationship(attribute._relationshipName);
	addRequest.RelatedEntities = relatedReferencesToAdd;
	AssociateResponse addResponse = (AssociateResponse)service.Execute(addRequest);
}

if (itemsToRemove.Count > 0)
{
	DisassociateRequest removeRequest = new DisassociateRequest();
	removeRequest.Target = target.ToEntityReference();
	removeRequest.Relationship = new Relationship(attribute._relationshipName);
	removeRequest.RelatedEntities = relatedReferencesToRemove;
	DisassociateResponse removeResponse = (DisassociateResponse)service.Execute(removeRequest);
}

Finally, same as what we did for the Create Plugin, we are going to update the text value containing the list of Contact names to be displayed on the view.

You can find the code in the following my github repository below

https://github.com/ariclevin/PowerPlatform/tree/master/PCF/MultiSelectLookup

The post Using Microsoft Multiselect Lookup in your Model Driven Apps – Part II appeared first on Aric Levin's Digital Transformation Blog.

]]>
Power Platform 2021 Release Wave 2 Unified Interface Updates – Grid Enhancements http://aric.isite.dev/dynamics/post/2021-wave2-uci-powee/ Sun, 17 Oct 2021 05:45:00 +0000 https://aric.isite.dev/index.php/2021/10/17/power-platform-2021-release-wave-2-unified-interface-updates-grid-enhancements/ 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 Power Apps Read Only grid and the column options in the grid view page.

Some of the main changes that were made to the read-only grid, both within the View page and subgrid were made in order to be in compliance with the Microsoft Accessibility Standard. Due to this some great new features have been added, but also might have caused some features to stop working as expected. We will review these below.

The post Power Platform 2021 Release Wave 2 Unified Interface Updates – Grid Enhancements 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 Power Apps Read Only grid and the column options in the grid view page.

Some of the main changes that were made to the read-only grid, both within the View page and subgrid were made in order to be in compliance with the Microsoft Accessibility Standard. Due to this some great new features have been added, but also might have caused some features to stop working as expected. We will review these below.

First let’s take a look at the actual grid control. If you are looking at the grid in a Wave 2 Pre-GA instance vs a GA instance, there might be some differences between them.

Power Platform 2021 Release Wave 2 Unified Interface - Legacy Read Only Grid
Read-Only Grid in 2021 Release Wave 1 UCI

Power Platform 2021 Release Wave 2 Unified Interface - Wave 2 Read Only Grid (Pre-GA)
Read-Only Grid in 2021 Release Wave 2 Prior to GA

Power Platform 2021 Release Wave 2 Unified Interface - Wave 2 Read Only Grid (GA - South America Region)
Read-Only Grid in 2021 Release Wave 2 in GA

First there are some performance improvements to the grid as well as the ability for the remember the grid view settings across the session.

Next the new grid control provides the ability to change the width/resize of the columns directly in the view. Simply move your cursor between two columns and you will be able to resize the columns. A sample is shown below:

Power Platform 2021 Release Wave 2 Unified Interface - Resize Columns

Next, there is also the ability to reorder the columns in the view. You will notice that next to the Search there is a new icon called column options. Clicking on this icon will display all of the columns in the grid in a pane on the right hand side, and allow us to change the order of the columns using drag and drop functionality.

Power Platform 2021 Release Wave 2 Unified Interface - Columns Options/Reorder

We also have the ability to add new columns to the view, by clicking on the Add columns button in the column options pane. Clicking the button will display a list of all available columns in the table that we are viewing and simply clicking on the column name will add the column to the list of columns so that we can add a column and change the order. We also have the ability to add columns from related tables in this view as well.

Power Platform 2021 Release Wave 2 Unified Interface - Add Columns

Once you add the columns and apply, you will see the new column in the view, but also you will notice an asterisk next to the view name, specifying that this is not the original view. If you want to save the new changes that you made to the view as a new view, you can do this by clicking on the Create View button, and select the Save as new view option (as show in the image below)

Power Platform 2021 Release Wave 2 Unified Interface - Save Modified View

One of the issues that you should be aware of, is that if you added columns and wanted to revert back to the original state, do not use the Reset to default option. That will remove the column from the Column Options, but will not remove it from the grid, and you will not be able to remove it (unless you do a Hard Refresh of the page). If you want to remove a column that you added you will need to go to the column options panel, select the three dots next to the column that you want to remove, and choose Remove from the list of options (as seen below).

Power Platform 2021 Release Wave 2 Unified Interface -Remove Columns

Before closing this subject, there are a couple of known issues which Microsoft is addressing at the moment, and might be released a little after the GA of the product.

The first item, is that the ability to filter items by starting letter (See the first image from Wave 1) is no longer available. This has been reported to Microsoft, but a timeframe for this fix is not yet available, but the expectation is that this will be coming soon.

The second item, which might cause some frustration is the selection of multiple records. In Wave 1 (or previously), when wanting to select multiple records, you would need to have your mouse positioned in the cell of the check, and then select the rows that you wanted (shown below)

Power Platform 2021 Release Wave 2 Unified Interface - Select Multiple Items (Wave 1)

In Wave 2, there is a radio button in the cell. If you click on the radio button you can select multiple items, however if you click outside of the radio button, it will clear the previous selections, and only select that item that you clicked on. Hopefully this will be addressed soon as well, as it might be a little frustrating.

Power Platform 2021 Release Wave 2 Unified Interface - Select Multiple Items (Wave 2)

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 Unified Interface Updates – Grid Enhancements appeared first on Aric Levin's Digital Transformation Blog.

]]>
Credit Card Validator PCF Control http://aric.isite.dev/powerapps/post/credit-card-validator-pcf-control/ Mon, 27 May 2019 16:18:00 +0000 https://aric.isite.dev/index.php/2019/05/27/credit-card-validator-pcf-control/ Recently, I published a blog post on creating a PowerApp that validates a Credit Card number, and displays the correct image next to the card based on the Card number. As my first PowerApps Component Framework application, I took the same logic of the PowerApp that I created, and decided to create a PCF control that will do the same. I have also created a training guide for this, so that you can follow this logic step by step, which you can download at the bottom of this post.

The post Credit Card Validator PCF Control appeared first on Aric Levin's Digital Transformation Blog.

]]>
Recently, I published a blog post on creating a PowerApp that validates a Credit Card number, and displays the correct image next to the card based on the Card number. As my first PowerApps Component Framework application, I took the same logic of the PowerApp that I created, and decided to create a PCF control that will do the same. I have also created a training guide for this, so that you can follow this logic step by step, which you can download at the bottom of this post.

In order to develop a PCF control, there are a few prerequisites that need to be installed on your machine. The first is that you need to have Visual Studio 2017, so that you can use the Developer Command Prompt for VS 2017, and you need to download and install Node.js. In the demo document we use the 10.15.3 LTS version (at the time of writing this article). We also need to download and install the PowerApps Command Line Interface (CLI).

I prepared this lab particularly for part of a Dynamics 365 Saturday NYC workshop that will be held on June 7th and 8th. This lab will cover creating the project,  configuring the control manifest file, building the index.ts file and the stylesheet (if required), building the control, testing the control and deploying the control into your Microsoft Dynamics 365 or CDS environment. We will finally create a field for the Credit Card number, and add the control to the form.

The animated gif below shows the end result of using the PCF control on a form in Unified Interface

PCF Demo

You can download the lab instructions, source code and solution using the links below:

Demo and Lab pdf file

Dynamics 365 Solution file

PCF Control Source Code files

The post Credit Card Validator PCF Control appeared first on Aric Levin's Digital Transformation Blog.

]]>
Changing the details page link url for Entity Lists http://aric.isite.dev/dynamics/post/change-entity-list-details-page-link/ Thu, 12 Jul 2018 03:26:00 +0000 https://aric.isite.dev/index.php/2018/07/12/changing-the-details-page-link-url-for-entity-lists/ When displaying entity lists on a web page, there is usually a default column in a view which is displayed as a hyperlink. The link to the page is displayed based on the Web Page for Details View and the ID Query String Parameter Name attributes on the Entity List form (as shown in the image below). The problem is, what happens if my page that is displaying the Entity List already has query string parameters, and you want to keep those parameters on the next page that you are going to display.

The post Changing the details page link url for Entity Lists appeared first on Aric Levin's Digital Transformation Blog.

]]>
When displaying entity lists on a web page, there is usually a default column in a view which is displayed as a hyperlink. The link to the page is displayed based on the Web Page for Details View and the ID Query String Parameter Name attributes on the Entity List form (as shown in the image below). The problem is, what happens if my page that is displaying the Entity List already has query string parameters, and you want to keep those parameters on the next page that you are going to display.

Entity List Attributes

The Options tab on the Entity List form contains a custom JavaScript section, which we can control what happens when the document is loaded or when the grid refreshes/loads. We can use the $(“.entitylist.entity-grid”).on(“loaded”, function () { }) to process anytime the grid is reloaded, sorted or paged through. The image and code snippet below provide us with an example on how this can be accomplished.

Entity List Options (Javascript)

When the grid is loaded, we retrieve the existing query string and place it into a variable. We then loop through all the results of the table (entity list), by using the jquery each function. We get the current url that is in the anchor attribute, and append the existing query string to it. We finally write back to the anchor attribute the new url. The code below shows everything withing the document ready function.

$(document).ready(function () {
  $(".entitylist.entity-grid").on("loaded", function () { 
    var url = window.location.href;
    var queryStrings = url.substring(url.indexOf("?") +1);
    $("[href^='/business-info']").each(function(){
        var currentUrl = ($(this).attr('href'));
        var targetUrl = currentUrl + "&" + queryStrings;
        $(this).attr("href", targetUrl);
    });  
  });  
});  

If your page was start-business?id=999, when you click on the link the page you will be redirected to would be business-info?slid=12345678-1234-1234-1234-1234567890AB&id=999. The querystring from the previous page is now appended to the new page.

The post Changing the details page link url for Entity Lists appeared first on Aric Levin's Digital Transformation Blog.

]]>
Adding masking to form controls in Dynamics Portals http://aric.isite.dev/dynamics/post/dynamics-portals-textbox-masking/ Thu, 21 Jun 2018 13:21:00 +0000 https://aric.isite.dev/index.php/2018/06/21/adding-masking-to-form-controls-in-dynamics-portals/ It is a pretty known practice today, that when creating a web application that requests data from customers, certain fields are masked so that the system can prevent the entry of incorrect data. This has been done in desktop applications for a long time and is now also very common in web based applications.

The post Adding masking to form controls in Dynamics Portals appeared first on Aric Levin's Digital Transformation Blog.

]]>
It is a pretty known practice today, that when creating a web application that requests data from customers, certain fields are masked so that the system can prevent the entry of incorrect data. This has been done in desktop applications for a long time and is now also very common in web based applications.

Microsoft Dynamics Portals does not provide a way to implement this out of the box, but the path to implement this is simple and straight forward. The first thing that we need to do in order to get this working is get a jQuery mask plugin. The most common plugin that I have seen is the jQuery Mask Plugin created by Igor Escobar. It is available for download from github in the following link:

http://igorescobar.github.io/jQuery-Mask-Plugin/

Next we need to add that plugin to our Dynamics Portals application. In order to do this, I would refer you to a previously published article that I wrote called JavaScript Web Files in CRM Portals. You can read it on the Dynamics Community or my business web site using one of the links below:

https://community.dynamics.com/crm/b/briteglobalsolutions/archive/2018/05/02/javascript-web-files-in-crm-portals or https://www.briteglobal.com/blogs/community/portals-web-files/

Add the script file to the Tracking Code Content Snippet and upload it as a Web file so that it can be accessed across the application. At this point, the hard part is done. In the sample below, on the On my Entity Form Custom JavaScript, I will add the following code to mask my Tax Id and Social Security Numbers.

jQuery(function($){   
   $("#new_ein").mask("99-9999999");      
   $("#new_ssn").mask("999-99-9999"); 
});

The github site above contains plenty of examples for masking. The above was just a simple example. Finally, in the form that I would like to open, what I will see when I click on the control is the masking of the Tax Id number.

Dynamics Portal Masking

Next as I fill it out, it will only allow me to fill the numbers that I have specified in my jQuery function.

Dynamics Portals Masking

The post Adding masking to form controls in Dynamics Portals appeared first on Aric Levin's Digital Transformation Blog.

]]>
Using Placeholders in Portal Entity Form Text Controls http://aric.isite.dev/dynamics/post/using-placeholders-in-portal-text-controls/ Fri, 15 Jun 2018 23:32:00 +0000 https://aric.isite.dev/index.php/2018/06/15/using-placeholders-in-portal-entity-form-text-controls/ Recently I was working on a project, where the client needed all fields to have placeholders for accessibility reasons. When looking at the attribute metadata of the Entity Form, we are allowed to enter some text above or below the textbox control (or above the label), but the option is not available to prepopulate the control with some text when there is no data in it. After seeing a few community questions on how to implement this, I thought to share the solution.

The post Using Placeholders in Portal Entity Form Text Controls appeared first on Aric Levin's Digital Transformation Blog.

]]>
Recently I was working on a project, where the client needed all fields to have placeholders for accessibility reasons. When looking at the attribute metadata of the Entity Form, we are allowed to enter some text above or below the textbox control (or above the label), but the option is not available to prepopulate the control with some text when there is no data in it. After seeing a few community questions on how to implement this, I thought to share the solution.

Using JQuery we are able to easily add this functionality by using the attr function. The code sample below add placeholders for the Tax Id and Social Security Number fields. This code can be placed on either the Entity Form JavaScript section or on the Web Page JavaScript section.

$(document).ready(function () {
 // Add Placeholders for Tax Information
 $("#new_ein").attr("placeholder", "Enter your Tax Id Number" );
 $("#new_ssn").attr("placeholder", "Enter your Social Security Number" );
});

The screenshot below shows the result of displaying the placeholder on the Portal Form.

Dynamics CRM Portal Placeholder for Textbox

The post Using Placeholders in Portal Entity Form Text Controls appeared first on Aric Levin's Digital Transformation Blog.

]]>
Changing Portal Lookup Control to Hyperlink Style Control http://aric.isite.dev/dynamics/post/portal-lookup-control-hyperlink-style/ Sat, 19 May 2018 01:24:00 +0000 https://aric.isite.dev/index.php/2018/05/19/changing-portal-lookup-control-to-hyperlink-style-control/ Recently we had a requirement to change the Lookup Control in the Portal to look like a hyperlink, so that when the user clicked on the Hyperlink it would pop up the Lookup Dialog.
The Lookup control was displayed as part of an entity form, so the only way to really do this was with jquery.

The post Changing Portal Lookup Control to Hyperlink Style Control appeared first on Aric Levin's Digital Transformation Blog.

]]>
Recently we had a requirement to change the Lookup Control in the Portal to look like a hyperlink, so that when the user clicked on the Hyperlink it would pop up the Lookup Dialog.
The Lookup control was displayed as part of an entity form, so the only way to really do this was with jquery.

The first thing that we wanted to do was customize the label above the lookup control, so that it looked like a hyperlink, so we set a couple of styles on the label and modified the text.

$(“#accountid_label”).css(“color”, “#0039e6”);

$(“#accountid_label”).css(“cursor”, “pointer”);

$(“#accountid_label”).text(“Lookup Company”);

We then wanted to hide the actual lookup control

$(“#accountid_name”).parent().hide();

Then we added an onclick attribute to the label of the lookup control

  $(“#accountid_label”).attr(‘onclick’, ‘showLocationLookup()’);

The onclick attribute that we added called a function that would perform the click event of the lookup control to display the dialog.

function showLocationLookup()

{

$(“#sbs_site_locationid_name”).parent().find(‘.input-group-btn’).children().first().next().click();

}

Finally we added an onChange event to the lookup control so that we can retrieve the values from it, and display the control if we wanted to.

$(“#accountid”).change(function(){

    var accountId = $(“#accountid”).val();

    var accountName = $(“#accountid_name”).val();

  $(“#accountid_name”).parent().show();

    $(“#accountid_name”).parent().find(‘.input-group-btn’).children().first().next().hide();

});  

The image below shows the end result. Notice the Lookup Company label at the bottom of the page…

Portal Lookup Hyperlink

The post Changing Portal Lookup Control to Hyperlink Style Control appeared first on Aric Levin's Digital Transformation Blog.

]]>
Portals: Pass multiple parameters between Entity Forms http://aric.isite.dev/dynamics/post/pass-parameters-between-entity-forms/ Sat, 05 May 2018 01:03:00 +0000 https://aric.isite.dev/index.php/2018/05/05/portals-pass-multiple-parameters-between-entity-forms/ Recently we had the need to create multiple Entity forms in our portal, and be able to pass multiple parameters between the different pages of the portal. As it seems, you are able to pass a single parameter (such as the id of the created record) to the next form, but passing multiple does not seem to be the case. For this particular scenario, using Web Forms was not an option. 

The post Portals: Pass multiple parameters between Entity Forms appeared first on Aric Levin's Digital Transformation Blog.

]]>
Recently we had the need to create multiple Entity forms in our portal, and be able to pass multiple parameters between the different pages of the portal. As it seems, you are able to pass a single parameter (such as the id of the created record) to the next form, but passing multiple does not seem to be the case. For this particular scenario, using Web Forms was not an option.

The requirement was as follows: Gather the Business Information of the Signed in Contact in a Registration form, and pass some of the information from the Registration form to the Application form.

The first screenshot bellows shows the Business Registration form, which includes the Account (which was needed to be passed to the redirected form, along with other variables).

Registration Portal Page

The solution included various steps. The first thing that needed to be done was to make sure that the Registration Id was part of the application form, so that the application form could query that data, so the field was added to the solution. The second thing was that in the Registration form, in the On Success Settings, we would set the On Success to Redirect, Check the Append Record ID to Query String and populate the Record ID Query String Parameter Name with the name of the parameter we want to use.

Entity Form (Registration)

The next thing that we needed is to allow the Registration Entity to be available for querying using oData. In the Active Entity Lists, we created a new record, where we specified the view, Page Size, and oData Feed. The image below shows the oData Feed Settings.

oData Configuration

Since we don’t want people to be able to query our Registration database by providing an oData query, we set the Page Size to 1, so that only a single record can be retrieved.

Finally, in the Application page, we need to create custom JavaScript, that retrieved the query string parameter(s), and retrieved the Registration Information from the OData query, and populated it in the Application Entity form page (as shown in the code example below):

 1
$(document).ready(function(){

	var qsDictionary = parseQueryStringToDictionary(document.location.search);
  	var registrationId = qsDictionary['registrationid'];

    if (!isNullUndefinedOrEmpty(registrationId))
    {
        // get oData Registration Info
      	$("#xxx_registrationid_name").attr("value","Auto Populated");
      	$("#xxx_registrationid").attr("value",registrationId);
	    $("#xxx_registrationid_entityname").attr("value","xxx_registration");
        populateFields(registrationId);
    }
});

function populateFields(registrationId)
{
  var oDataUrl = "https://xxx.dynamics365portals.us/_odata/RegistrationSet?$filter=xxx_registrationid%20eq%20guid%27" + registrationId + "%27";
  
  var oDataResponse = getODataResponse(oDataUrl);
  
  if(oDataResponse != null){
  	$.each(oDataResponse, function (index, responseVal) {
      // Fields Populate Here
      
      var registrationNumber = getStringValue(responseVal.xxx_registration_number);
      $("#xxx_registrationid_name").attr("value",registrationNumber);
      
      var accountId = getStringValue(responseVal.xxx_accountid.Id);
      var accountName = getStringValue(responseVal.xxx_accountid.Name);
      setAccount(accountId, accountName);
      
  	});                 
  }           
}

function setAccount(accountId, accountName)
{
    if (!isNullUndefinedOrEmpty(accountId))
    {
    	$("#xxx_portal_accountid_name").attr("value",accountName);
    	$("#xxx_portal_accountid").attr("value",accountId);
		$("#xxx_portal_accountid_entityname").attr("value","account");
	      
    }  
}

function getODataResponse(oDataUrl) {         
	var response = null;
    $.ajax({
		type: "GET",
        url: oDataUrl,
        dataType: "json",
        async: false
        }).done(function (json) {
			response = json.value;                       
            });                
		return response;
}

function getStringValue(o)
{
  if (o)
    return o.toString();
  else
    return '';
}

function isNullUndefinedOrEmpty(o)
{
   return (typeof (value) === "undefined" || value === null || value === '');
}

The end result is that the that Registration and Account (and any other fields) are populated in the Application page.

Filled out information on Application Page

The post Portals: Pass multiple parameters between Entity Forms appeared first on Aric Levin's Digital Transformation Blog.

]]>
JavaScript Web Files in CRM Portals http://aric.isite.dev/dynamics/post/portals-web-files/ Thu, 03 May 2018 04:31:00 +0000 https://aric.isite.dev/index.php/2018/05/03/javascript-web-files-in-crm-portals/ As in any project, either CRM or Web application, the requirement to have JavaScript libraries that can be accessed across multiple files is common. In Dynamics 365 Portals, the use of Web Files is how we have the ability of create files that will be shared across the entire portal, or possibly only sections of the Portal. These common files are stored in the Web Files entity. This issue is that when we try to add a JavaScript web file, we get an error that the attachment is blocked. Web Files use the Notes entity to store the actual files that we add to the Web File entity. 

The post JavaScript Web Files in CRM Portals appeared first on Aric Levin's Digital Transformation Blog.

]]>
As in any project, either CRM or Web application, the requirement to have JavaScript libraries that can be accessed across multiple files is common. In Dynamics 365 Portals, the use of Web Files is how we have the ability of create files that will be shared across the entire portal, or possibly only sections of the Portal. These common files are stored in the Web Files entity. This issue is that when we try to add a JavaScript web file, we get an error that the attachment is blocked. Web Files use the Notes entity to store the actual files that we add to the Web File entity.

The error that we get when we attempt to do this is:

Attachment blocked: The attachment is not a valid file type.

How do we resolve this? The standard Dynamics 365 System Settings is configured to block a large set of extensions for uploading attachments for both email and notes, and this includes of course the .js attachment. The reasoning behind this is that JavaScript extensions could be used to execute unsafe code. Since the JS files that we want to add was created by us, and most likely will not cause any harm, we can modify this System Setting to allow us to upload js files.

If we navigate to Settings -> Administration, and click on System Settings, the System Settings dialog will pop up. On the General tab, under the section Set blocked file extensions for attachments, there is a long list of file extensions that are blocked from being uploaded to notes (annotations).

System Settings - Attachment Extensions

Find the js extension and remove it (include the semicolon that follows it – js;). Remember that it appears after the jar extension. Press OK to Save your changes.

Once you have made the change, you should be able to upload your JavaScript file again to the Web Files entity. If you created the Web File record previously simple update it and add the new attachments. You should keep only a single attachment per web file to simplify things.

After the Web File has been added, you can add the files to your code, by modifying the Tracking Code Content Snippet. Navigate to Content Snippets entity, and Find Tracking Code record. Open the record, and in the Value enter the following code:

<script src="/folder/filename.js"></script>

At this point, the js file should be accessible on the portal, and the functions of the js file can be accessed from within web templates or web pages.

The post JavaScript Web Files in CRM Portals appeared first on Aric Levin's Digital Transformation Blog.

]]>
Creating a Portal Web Form http://aric.isite.dev/dynamics/post/creating-portal-web-form/ Mon, 26 Mar 2018 03:17:00 +0000 https://aric.isite.dev/index.php/2018/03/26/creating-a-portal-web-form/ Microsoft Dynamics 365 Online comes with a Portal license which allows users to easily create forms that will capture user input and have that data populate the records of their different Dynamics CRM entities. In many community posts, I still see requests of how this process is done. In the following article I will demonstrate the step to create a web form in CRM and publish that form to the portal on the web site.

The post Creating a Portal Web Form appeared first on Aric Levin's Digital Transformation Blog.

]]>
Microsoft Dynamics 365 Online comes with a Portal license which allows users to easily create forms that will capture user input and have that data populate the records of their different Dynamics CRM entities. In many community posts, I still see requests of how this process is done. In the following article I will demonstrate the step to create a web form in CRM and publish that form to the portal on the web site.

The first step is creating the form that will be used to fill in the information. One of the most common requests is a Contact Us form or a lead form. In our case we will create a lead form in CRM that will be used to populate that data. Note that this is only for new data entry, and not to modify existing data, as that requires enabling of authentication.

The screenshot below shows the designed lead form that will be used as a Contact Us form:

Contact Us Lead Form

Once the lead form is designed, simply save the form and Publish your Customizations (or just Publish the lead entity). The next step is to create an Entity Form record. Creating an Entity form record tells the system, that this lead form will be used to capture data. In order to create an Entity form, we need to specify the Name of the Entity, the Name of the Form, the Tab name within the form that is being used and the Mode. The Mode in our case will be Insert, as we are planning to create a new record from this. We will also set the Success Settings to Display a message after all fields have been entered.

The screenshot below shows the Contact Us Entity form that we created for this purpose.

Contact Us Entity Form

The next step is to create the web page. Although this page will be mostly made out of the form, we can insert text before the actual form, and we need to specify the Url of the page. To create the web page, we enter the website the page belongs to (usually you will only have one), the parent page, the partial url, the page template, and finally we must remember to enter the name of the Entity Form which we just created. The screenshot below shows the top portion of the Web Page:

Contact Us Web Page

After the Web Page is saved, the system will create by default an additional Localized Web Page for the default language. If you are set to using English, a US English localized web page will be created. You can navigate to the localized web page to add heading text or to include script/css code.

Finally, we can navigate to the actual page in our browser. In our particular case the Contact Us parent page is the home page, and the partial url will be contact-us, which means we will be able to navigate to the page by entering: https://mysite/contact-us

The end result is shown below:

Contact Us Portal Form

The post Creating a Portal Web Form appeared first on Aric Levin's Digital Transformation Blog.

]]>