Using window.postMessage to interact with IFrame in CRM Form
This is similar to my earlier post (http://dreamingincrm.com/2015/10/27/using-sessionstorage-to-interact-with-iframe-in-crm-forms/) that discussed using sessionStorage events to interact with IFrame and the IFrame to interact with the ClientApiWrapper. ClientApiWrapper is the IFrame that hosts the form scripts. Here is the code I used.
IFrame
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form IFrame</title>
<script>
window.addEventListener('message', function(e) {
if(e.origin != parent.Xrm.Page.context.getClientUrl()) return;
document.getElementById('messageFromParent').textContent = 'Parent says "' + e.data+'"';
});
document.addEventListener('DOMContentLoaded' , function() {
document.getElementById("buttons").addEventListener("click", function(e){
var url = parent.Xrm.Page.context.getClientUrl();
var fieldName = document.getElementById("crmFieldName").value;
switch(e.target.id){
case "enableField":
parent.postMessage(['setFieldEditability', [fieldName,false]],url);
break;
case "disableField":
parent.postMessage(['setFieldEditability', [fieldName,true]],url);
break;
case "hideField":
parent.postMessage(['setFieldVisibility', [fieldName,false]],url);
break;
case "showField":
parent.postMessage(['setFieldVisibility', [fieldName,true]],url);
break;
}
});
});
</script>
</head>
<body>
<p id="messageFromParent"></p><br><br>
<input type="text" id="crmFieldName"><br><br>
<div id="buttons">
<button id="enableField">Enable Field</button>
<button id="disableField">Disable Field</button>
<button id="hideField">Hide Field</button>
<button id="showField">Show Field</button>
</div>
</body>
</html>
Form Script
(function(){
var CVN = window.CVN || {};
var childChannel;
parent.addEventListener('message', function(e) {
if(e.origin != Xrm.Page.context.getClientUrl()) return;
childChannel = e.source;
CVN[e.data[0]].apply(null,e.data[1]);
}, false);
CVN.onSave = function(){
};
CVN.setFieldEditability = function(fieldName, isDisabled){
Xrm.Page.getControl(fieldName).setDisabled(isDisabled);
if(childChannel) childChannel.postMessage(fieldName+' has been '+(isDisabled ? 'disabled' : 'enabled'),Xrm.Page.context.getClientUrl());
};
CVN.setFieldVisibility = function(fieldName, isVisible){
Xrm.Page.getControl(fieldName).setVisible(isVisible)
if(childChannel) childChannel.postMessage(fieldName+' has been '+(isVisible ? 'hidden' : 'unhidden'),Xrm.Page.context.getClientUrl());
};
CVN.onLoad = function(){
};
window.CVN = CVN;
})();
Screenshot

The eventhandler for message has to be attached to the parent for messages originating from both the form script (ClientApiWrapper) and the HTML webresource embedded into the form.
I envision the use of this technique primarily for form script -> html webresource communication, and common functions that are called by both form script and html webresource.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
This was originally posted here.

Like
Report
*This post is locked for comments