Image Resizer PCF

Save Your Cloud Storage Space

Wanna save some cloud storage space? here is a PCF to Help you. Nowadays, even a budget smartphone’s camera will also capture images with 3-5 MB size. Imagine a Dynamics 365 environment with 50 users and each user saving 10 images per day.

Photo by Gustavo Fring on Pexels.com

Though we can save these images to Azure Blob or SharePoint or even purchase additional storage, in most cases these images do not need a high definition quality. The Image Resizer PCF is my attempt to resize images on the fly. This control allows you to upload multiple images to Dynamics 365 notes or email and the PCF resizes the image files before saving to dynamics 365. Watch below video to view the PCF in action.

How to configure

  • Download the managed or unmanaged solution file from Git and import to your environment.
  • Insert a section with a single column on the form.
  • Add a field you would like to use that will not be used on the form.
  • Uncheck ‘Display label on the form’ for the field.
  • Add image resizer PCF control to your field.
  • Give parameter values
    • Image Height: Height of the resized image.
    • Image Width: Width of the resized image.
    • Image Quality Percentage: Resizing quality.
  • Save and publish your changes.

Technical Details

The PCF uses React Image File Resizer to resize the images and React Drop Zone for the file upload control. For quick development, I have reused Rama Rao’s Attachment Uploader for file upload logic. There are many improvement options like image preview, on screen resizing etc. You are always welcome to branch git repo here.

Shift your focus; Upgrade yourself

Upgrade Yourself

Be it any profession, upgrading your skills is unquestionably significant. Not only does it open the door to new career opportunities, but it also helps you enhance the quality of your life. To keep myself technically updated, I have bookmarked a list of blogs and YouTube channels.. I also frequently check Feedspot’s Top 35 Microsoft Dynamics 365/CRM Blogs, which is regularly updated by the moderators. But is it enough?

For a Business Application Consultant , critical thinking is as important as software skills , and I must say that reading ‘Farnam Street’ enhances your decision-making skills. Shane Parrish who is an ex-spy, investor, and writer, improves your critical thinking ability with every post in his blog “Farnam Street”.

Why Farnam Street?

MR Shane focuses on the importance of cultivating mental models and frameworks to tackle complex issues. The blog ‘guides to decision making’ especially when you’re in a challenging situation. I must say that reading a 3-minute post on Farnam Street equals watching a week of TED or simialr videos. It simply means that you are served with the most appropriate information that you need to boost your decision-making skills regardless of your professional or skillset.

Shane Parrish urges visitors to ‘Upgrade Yourself’ and that’s one of the biggest reasons he is promoting self-betterment over classic self-help fare. He believes that being responsible to yourself is imperative and learning is one of the best investments that you can make in your life.

Photo by Pixabay on Pexels.com

Here are some other ‘Be Better’ blogs that I would recommend:

For me, learning is like entering a world of opportunities. What about you?

Do you want to be a Dynamics 365/Power Platform expert? then docs.microsoft.com is the Key.

When my colleagues are stuck on something, I always encourage them to do their best in Google search and then ask for help in the respective tech community, because good research is always important to nurture knowledge. But having said that, I always ensure that they check the Microsoft docs, if they haven’t, I suggest them to look into docs.microsoft.com.

Googling is a mandatory skill. BUT

Most developers start their career at the same pace and depend on random Google Searches. Even I started my career with a trust in blogs and communities. The blogs and videos are always helpful to make you understand the topics easily, but when you need deep technical knowledge, official documents or SDK documentation is the best source. These documents let you know the capabilities and limitations of the platform you work on.

Let’s take an example, if you are stuck at some point while using Power Apps Functions or D365APIs, what will you generally do? You might search it randomly and copy/paste the available piece of code (like we all do).

Can you imagine what can happen later to the system?

Is the code you copied supported by Microsoft?

Is it the optimal solution for your system and users?

SDK documentation is the answer to all these questions. It is your responsibility to ensure that you are not doing any unsupported customization.

We all know that the official documents are helpful but, do you know why people are not looking into these documents while working on something? It’s because we are all lazy…. These documents contain a broad range of technical information and are not as simple and easy to understand as individual blogs. But for technical knowledge and long-term future in D365 and Power Apps, it is advisable not to go with easy solutions. Reading through the official documents will definitely pay back your efforts. Once you start reading these documents and comprehend the topics, they become your true consultant.

In the start of our career, people may be short on time or lazy to check and read the SDK Documents. It wasn’t different for me either. But back in those days, I came across the blog of Ben Hosk and one of his statements struck me so hard “The CRM SDK can be stubborn, difficult, and renowned for not suffering fools gladly.” Reading this was the time when I decided to look into the Microsoft Documents along with the solutions from other Blogs and Videos available.

Now, referring the official documents for solution has more or less turned into a practice for me. If time does not permit to go through the documents, I would rather expand the deadline rather than compromise on the authenticity and quality of the solution. Moreover, I try to cover the topics during the weekend and learn something new from the official Microsoft Documents. So, if you are not familiar with these documents or fail to refer them even after knowing its benefits, it’s definitely a loss of opportunity to learn new things while at work. 

So, you should never bypass “learning something new with every customization you do”!!!!

Replacing Dialog in Model Driven Apps Part-1: Using Main Form Modal

Since the announcement of dialogue depreciation, I have been trying out different alternatives to replace dialog as I use them extensively in my projects. The first option I tried was using canvas apps as described in this post ,but I was not happy with that approach and tested other options and implemented those in my projects based on customer scenarios. I will be publishing these options as a series. This is the first post and let’s see how we can replace dialog with entity main form.

There are many gaps when we replace dialog with other alternatives, even though these gaps can be filled with workarounds, the maintainability is high when compared to a classic dialog. These issues can be handled to a great extend using main forms.

With the April 2020 preview release of the Unified Interface for model-driven apps in Power Apps you can now open a record in a dialog. The record will open in a modal dialog and users will have access to the command bar, header and tabs that you defined for the records main form.

We can us the above option replace classic dialog.

Scenario:

I have to request HR team to verify certain details about prospects, but HR team is not allowed to access contact details. I also need to capture feedback and remarks from HR team.

So I created an entity called “Requests(nj_dialoguebatchone)” , modified the main form as per my requirements and removed all the unwanted buttons using ribbon-workbench.

Next step is to call this form using JavaScript from contact form.

function loadDialogForm(executionContext) {

    formContext = executionContext.getFormContext();
    var pageInput = {
        pageType: "entityrecord",
        entityName: "nj_dialoguebatchone",
        formType:  2
// formType 2 opens a new record.
    };
    var navigationOptions = {
        target: 2,
        height: {value: 70, unit:"%"},
        width: {value: 35, unit:"%"},
        position: 1
//target: Number. Specify 2 to open the page in a dialog. 
//position:Number. Specify 1 to open the dialog in center.
    };
    Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(
        function success(result) {
               
                // Handle dialog closed
        },
        function error() {
                // Handle errors
        }
    );
    

   

}

I hope the code is self explanatory, more details can be found in the following links.

Now you can bind this script with ribbon button or other form events Boom dialog is ready.

You can also use quick create forms, but main form gives you more flexibility in terms using business rule and other form level formatting and validations. You can also easily configure Workflows, FLOWS, or Plugins based on user input in this as record create and update events are available.

See the dialog in Action

P.S. Am a classic dialog fan 🙂

Activity Summary Pro

So busy with year ending and 2020 plans. AsvI promised “The pro version will be released in two months”, I have to release the pro version today. Really sorry for the poor CSS, am actually bad at styling stuffs 😦 . But you can always improve the style and features in the Github, any updates are appreciated. Here is the github repo link.

New features added.

  • Click on Activity Name to Expand the list.
  • View activities as a chart
  1. Get the unmanaged solution file  Here
  2. Import the solution to your organization.
  3. Create a view with the required filters. If you do not require the control to consider certain activity types, you can exclude them in your view filter. The control will consider only the records returned by the view selected.
  4. Add sub-grid to the form with the created view.
  5. Add Activity Summary control to the sub-grid.
alt text
alt text

Note: If you need to exclude certain activity types, apply the same logic in the view filter.

Special mentions

Hari Narayanan Kumar for his Activity Analyzer which helped me to include the chart easily.

Andrew Butenko for his quick repleys and answers in the power users community 🙂

Happy New Year, let this be the year of Power Users

Canvas-Apps for Approvals in Dynamics 365-CE

There are scenarios where we need to configure approvals in Dynamics 365, for example, mark an account as a premium customer after approval or qualify leads after approval etc. We used dialog control to capture approval request and comments but, now dialog controls are depreciated and not advised for use in new projects.

As per Microsoft’s initial announcement

Dialogs are deprecated and are replaced by mobile task flows (available as of the December 2016 update), and business process flows. Both task flows and business process flows will continue to evolve to make the transition easier.

But either tasks flow or business process flow was not a perfect replacement for Dialog. Knowing this pain from users, Microsoft has now modified the announcement.

Dialogs are deprecated, and should be replaced by business process flows or canvas apps

Even though I knew canvas apps can be now embedded in model-driven apps, I hadn’t thought of this option until I came across this new announcement, so tried replicating my approval dialogs with a canvas app and it works fine. Pheww!!!! 🙂

For testing purpose I replicated the dialog for creating approval request for Account entity.

  1. created a canvas app to create approval request.
This sample app changes account status to pending verification and captures the comments in one custom field.

2. Now we need to call this app from account form, obtain the app ID from app details section.

select app details to get the App GUID

3. I need to call this canvas app as a popup when user clicks a button. I created a custom button for account entity-> added a JavaScript as button action to call an HTML web-resource and embedded my canvas app in this html I-frame.

<html><head>
<title>Approval</title>

<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style="padding: 0px; font-family: arial; overflow-wrap: break-word;" onload="LoadPowerApp()">
<center>


<iframe id="Approval" width="800" height="600"></iframe>



</center>
<script id="myScript">
function LoadPowerApp()
{
var AccountID = window.parent.opener.Xrm.Page.data.entity.getId().slice(1, -1);
var url ="https://web.powerapps.com/webplayer/iframeapp?source=iframe&appId=/providers/Microsoft.PowerApps/apps/56123673-f45c-4b96-b9e6-ece1b0a8069a&ID="+AccountID;
document.getElementById("Approval").src=url;
}
</script>


</body>
</html>

I know you have many questions now. "https://web.powerapps.com/webplayer/iframeapp?source=iframe&appId=/providers/Microsoft.PowerApps/apps/56123673-f45c-4b96-b9e6-ece1b0a8069a&ID="+AccountID;

This is the key and I will breakdown it into parts “https://web.powerapps.com/webplayer/iframeapp?source=iframe&appId=/providers/Microsoft.PowerApps/apps/APP GUID&CUSTOM PARAMETER NAME=”+PARAMETER VALUE

App GUID I explained in step 2, now regarding custom parameter, I deliberately didn’t mention it when we discussed the app creation and kept for this section. When we open this canvas from an account form(like we start a dialogue) the app needs the record GUID to update the account status

I have used form control in the canvas app and filtered the item using the ID Parameter.

4. Now try your button and you can see the magic.

You can download the sample APP from TDG Power Apps bank.

Please note this is a basic app I tried for testing purpose and needs many improvements to use in a live project. you are always welcome to discuss with on this app.

Hope this helps….. 🙂

WEB API- Part 6 : Create record

Create record using WEB API 

Following code shows how to create an Account record using WEB API and how to set different types of fields

function CreateAccount() {
 
    var serverURL = Xrm.Page.context.getClientUrl();
    var account = {};
    account["name"] = "New Account";
   
   
 //Set LookUp
    account["primarycontactid"] = {
        "firstname": "Sample",
        "lastname": "Contact"
    };// this will create new contact ,if you need to link an existing contact use the following
 //account["primarycontactid@odata.bind"]="/contacts(contactId)"; 
 
    //optionset
    account["companytype"] = 2;
    //two options
    account["donotemail"] = true;
    //number
    account["numberofemployees"] = 30;
 
    var req = new XMLHttpRequest();
    req.open("POST", serverURL + "/api/data/v8.0/accounts", true);
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.onreadystatechange = function() {
        if (this.readyState == 4 /* complete */ ) {
            req.onreadystatechange = null;
            if (this.status == 204) {
                var NewAccount = this.getResponseHeader("OData-EntityId");
                var NewAccountId = NewAccount.substr(NewAccount.length - 38).substring(1, 37); 
                Xrm.Utility.openEntityForm("account", NewAccountId); //Open newly created account record
            } else {
                var error = JSON.parse(this.response).error;
                alert(error.message);
            }
        }
    };
    req.send(JSON.stringify(account));
}

 

Please note following code for setting an existing lookup value

 account["primarycontactid@odata.bind"]="/contacts(contactId)";

“contacts” is plural name for contact entity .

var NewAccount = this.getResponseHeader(“OData-EntityId”);  will give  you the newly created record…

Field Conflicts

Recently I faced a strange issue, I used a filed (lookup) twice in the form and applied a pre-filtering java-script to the field. But only one filed is getting filtered by the script.I tried many options and I couldn’t identify the issue. Have you even faced  this issue ? Finally I got the answer from  Scott Durow ( Thank you Scott!!! ). I decided to post this issue because if someone is facing the same issue , this will help them to solve the issue. Following is the explanation for this issue.

The issue you are experiencing is because the ‘getControl’ method returns only the first control – so in fact you are only adding the custom filter to the first control.

An attribute object has a ‘controls’ collection that can give you all the controls for a specific attribute. So you can add the filter to all the controls by using something like:

Xrm.Page.getAttribute(“fieldname”).controls.forEach(

function (control, i) {

control.addPreSearch(filterCustomerAccounts);

var customerAccountFilter = “<filter type=’and’><condition attribute=’accountcategorycode’ operator=’eq’ value=’1’/></filter>”;

control.addCustomFilter(customerAccountFilter, “account”);

}

);

Hope this helps!!!

Nijo