Download File : Power Automate and JavaScript

What is Issue?

When working on D365 CRM, Some time user wants to download file from SharePoint, OneDrive or CRM Notes itself. So how you will do it in shortest way?

The Reason-

Downloading file from SharePoint or any other cloud location it will be time consuming process if you choose Web service or any WCF service.

Solution-

Now Power Automate provides less code and quick solutions. Power Automate has all the connectors and Actions which help you to connect these cloud locations and process on the files.

Let’s see a scenario, I want to download a file on button click on my CRM Account form. The file is located in my account record Timeline Notes.

Let’s go step by step.

First of all, as this is action on click of button on form, we can choose “When Http Request Received” trigger in Power Automate. And in HTTP request we need record id i.e. accountid to retrieve specific Note attachment i.e. “CustomerInfoDoc”-

Now from above step we will get the Document – File name and Document body (base64) content.

So we need a variable to store files in array and another variable for document content-

Setting the variables from the Notes list which we got from “List rows” action-

We need to append array with below json-

{
“Name”: @{items(‘Apply_to_each’)?[‘filename’]},
“ContentBytes”: @{items(‘Apply_to_each’)?[‘documentbody’]}
}

We will use Name and ContentBytes in JavaScript Code which will be in the response of HttpRequest.

Now once file we got file content we need to send them in response-

We need the only file from Notes, In List Row action we can add row count =1, but still in response we can set formula in body first(variable(‘ContentArray’). As this is document in response add headers “Content-type”:”multipart/form-data”

Now our complete flow is ready and it looks like –

So now remaining part is calling the flow from button to download the file-

Add the below javascript and call “callPowerAutomateFlow” function on button click. Below is complete code for download –

function callPowerAutomateFlow(formContext) { 
    id = formContext.data.entity.getId().replace("{", "").replace("}", ""); 
    var account = '{ "accountid": "' + id + '"'+ '}'; 
    var flowUrl = "https://prod-04.centralindia.logic.azure.com:443/workflows/xxxxxxxxxxxxxxxxxxxxxxxxxx/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=xxxxxxxxxxxx"; 
 
    var req = new XMLHttpRequest(); 
    req.open("POST", flowUrl, true); 
    req.setRequestHeader("Accept", "application/json"); 
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); 
    req.onreadystatechange = function () { 
        if (this.readyState === 4) { 
            req.onreadystatechange = null; 
            if (this.status === 200) { 
                    var result = JSON.parse(this.response); 
                    var fileName = result.Name; 
                    var fileCont = result.ContentBytes; 
                    var filebyte = base64ToBufferArray(fileCont); 
                    downloadFile(fileName, [filebyte]); 
            } else { 
                Xrm.Utility.alertDialog(this.responseText); 
            } 
        } 
    }; 
    req.send(account); 
} 
 
function base64ToBufferArray(base64content) { 
    var binaryString = window.atob(base64content); 
    var binaryLen = binaryString.length; 
    var bytes = new Uint8Array(binaryLen); 
    for (var i = 0; i < binaryLen; i++) { 
        var ascii = binaryString.charCodeAt(i); 
        bytes[i] = ascii; 
    } 
    return bytes; 
} 
 
function downloadFile(name,data) { 
        var blob = new Blob(data, { type: "octet/stream" }), 
            url = window.URL.createObjectURL(blob); 
        if (window.navigator && window.navigator.msSaveOrOpenBlob) { 
            window.navigator.msSaveOrOpenBlob(blob, name); 
        } else { 
            const url = window.URL.createObjectURL(blob); 
            const a = document.createElement('a'); 
            document.body.appendChild(a); 
            a.href = url; 
            a.download = name; 
            a.click(); 
            window.URL.revokeObjectURL(url); 
            document.body.removeChild(a); 
        } 
}

That’s it!! when I am clicking on Download button in CRM Account record, it is downloading my Attachment file from Notes which is with title “CustomerInfoDoc”.

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech

ReadOnly Subgrids in MS CRM

What is Issue?

While working on MS CRM projects I had requirement of readOnly subgrids in MS CRM. You can achieve this to some extent by hiding buttons on subgrids. But if the requirement is like links should not be clickable for some of the security roles or for some conditions, it is not possible using out-of-box subgrids. That time we had no other option than going with html and JavaScript web resources for this.

The Reason-

This can not be achieve using out-of-box subgrids controls.

Solution-

There are 2 solution for this-
1. Go with HTML webresource.
2. Create Your own Custom Control using PCF (PowerApps Control Framework)

I created the completely read-only subgrid with pagination functionality similar to out-of-box subgrid.

Taking my current scenario-
I have to make subgrid completely read-only if the “More Contact Required?”= NO
Or else the subgrid will be normal subgrid.

So what I did –

  1. On form I added 2 similar subgrids with different Names.
  2. Added script on change of “More Contact Required?” field to show required subgrid.
  3. Changed the control for subgrid which is visible when “More Contacts Required?”= NO
    Open Form Editor -> Select Subgrid -> Change Properties -> Controls Tab ->Add Control -> Selected my own custom Control ->ReadOnlySubgridPage -> Click Add
  4. Save Form and Publish.

Now I found it so simple as I can make any subgrid readonly with my custom control.

You can download the Solution from here and import in Dynamics 365 to use the control.

If you want to check source code download from here.

To work with source code you need some of the basic setup in your computer-
1. Nodejs installed
2. VS or Visual Studio Code installed
3.Understanding of below commands-

pac pcf init --namespace yourNamespace --name yourControlName --template dataset
npm install
npm run build
npm start
pac solution init --publisher-name yourPubliserName --publisher-prefix yourPrefix
pac solution add-reference --path "pcfproj folder path"
msbuild /t:restore
msbuild

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech

Color Picker Custom Control for MS Dynamics CRM

What is Issue?

One of my previous projects had requirement of color picker in MS CRM to provide users flexibility to select any color to can display notifications(using HTML) on their records. But we had no other option than going with html and JavaScript web resources for this.

The Reason-

MS CRM don’t provide any color picker field out-of-box.

Solution-

As I already had a blog written for color picker using web resources and spectrum libraries-Color Picker in MS CRM ?

But it is web resource which needs much efforts to match to field styles in crm.

I have created the custom pcf control (PowerApps Custom Control). This control can be used for the single line text fields.

Depends on browser it appears in supported way-

On Browsers other than IE-

This slideshow requires JavaScript.

In IE it will appear as –

This slideshow requires JavaScript.

If you want to use it you form you can download ready custom control from here-ColorPickerSolution.zip

How to use it-
1. Import downloaded solution in CRM-
ColorPicker5

2. Create single line of Text field in any entity you want and add it on form.
3. when adding to form select field, click on change field property and in controls tab add custom control “ColorPicker”-

This slideshow requires JavaScript.

4.Save and publish the form.
Now the control is available and ready on form to use.

 

You can also download the source code from here-ColorPickerSource.zip

To work with source code you need some of the basic setup in your computer-
1. Nodejs installed
2. VS or Visual Studio Code installed
3.Understanding of below commands-


pac pcf init --namespace yourNamespace --name yourControlName --template field
npm install
npm run build
npm start
pac solution init --publisher-name yourPubliserName --publisher-prefix yourPrefix
pac solution add-reference --path "pcfproj folder path"
msbuild /t:restore
msbuild

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech

Add floating Chat Bot (Microsoft Virtual Agent) on Power Portal (PowerApps)

What is Issue?

Microsoft is providing the Virtual Agents(chat bots) to provide the customers better communication ability on many channels like websites, Skype, Teams. Microsoft is also introduced the Power Portals. But how to integrate this Virtual Agent(chat bot) with Power Portal?

The Reason-

Power Portal provides the way adding the extra code snippet in portals. But when we try to embed the Virtual Agents in Power Portal using this code snippet it shows the chatbot window at the bottom of the portal. Code provided by Microsoft Virtual Agent after publishing is just an IFrame. So user is not able to see floating chat bot.

Solution-

To make your Virtual agent float you need some customized embed code with some JavaScript and CSS.
1. Create a CSS Style-sheet File with below CSS-

/* Button used to open the chat form - fixed at the bottom of the page */
.open-button {
background-color: #555;
color: white;
padding: 16px 20px;
border: none;
cursor: pointer;
opacity: 0.8;
position: fixed;
bottom: 23px;
right: 28px;
width: 280px;
}
.closePopUp{
display: block;
position: fixed;
bottom: 312px;
right: 50px;
border: 3px solid #f1f1f1;
z-index: 99;
width:30px;
height:30px;
background-color: transparent;
color:#f1f1f1;
}
/* The popup chat - hidden by default */
.chat-popup {
display: none;
position: fixed;
bottom: 0;
right: 15px;
border: 3px solid #f1f1f1;
z-index: 9;
height:350px;
}

This CSS will help to float chat bot at bottom left corner.

2.Add the saved CSS file to power portal –
Navigate -> make.powerapps.com ->Apps -> Select Portal-> Click on Edit

VAPowerPortal1

3.When Editor Opens -> Click on Themes and upload the CSS
VAPowerPortal2

Save the Code Editor and close the Portal editor.

4. Open the Portal Management Model-Driven App
VAPowerPortal3

5. Navigate to Content Snippet under Content and search for “Chat Widget Code”-
VAPowerPortal4
If you want you can create other Content Snippet of HTML type and add it on “Home” Web Template.

6. Open the Content Snippet-Chat Widget Code or newly created content snippet by you-

VAPowerPortal5

7. Add the Below code in Value as HTML and save the content snippet-


<script>
  function openForm() {
    document.getElementById("myForm").style.display = "block";
  }
  function closeForm() {
    document.getElementById("myForm").style.display = "none";
  }
</script><button onclick="openForm()" class="open-button">Chat</button><button onclick="openForm()" class="open-button">Chat</button>
  <div id="myForm" class="chat-popup">
[your iframe code as belows from Microsoft Virtual Agent after Publishing]  
   <button onclick="closeForm()" class="closePopUp">X</button>
</div>
<p></p>

8. replace [your iframe code as belows from Microsoft Virtual Agent after Publishing] in above code with something like below-

VAPowerPortal8

9. Load the portal again you will find Chat option at the right-bottom corner. When you click on chat button it will open your chat bot.

This slideshow requires JavaScript.

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech