Using window.postMessage to interact with IFrame in CRM Form

This is similar to my earlier post (https://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

Form

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

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s