I have an HTML page that gets opened when clicking a ribbon button of a custom entity page. The JS code running in this page is does some business logic, and eventually needs to update a lookup field back on the custom entity page.
Currently, for setting the lookup value, I'm doing something like the following*:
window.opener.Xrm.Page.getAttribute("ik_reportid").setValue([{
id: "d67aa9d8-c528-e711-80f2-005056b74923",
name: "test record",
entityType: "ik_report"
}]);
*Note: The above is written hard-coded for simplifying this question. I assure you the problem is not in these values, but somewhere else.
After doing so, the HTML page continues with its existing code, and eventually calls window.opener.Page.data.refresh(true)
, and then closes itself with window.close()
.
The problem is that when the opener page is refreshing, I get an error "function expected", and opening the debugger get me to the following line in JsProvider.ashx
:
Mscrm.FormInputControl.LookupUIBehavior.$2I=function($p0,$p1){if(!parseInt($p0.type)&&!parseInt($p1.type)||parseInt($p0.category)===LookupItemCategories.UNKNOWN_EMAIL&&parseInt($p1.category)===LookupItemCategories.UNKNOWN_EMAIL)
I watched the values of p0
and p1
, and I noticed they don't have a category
property. However, when I tried using the same code for setting the value of the same lookup field when I'm on the page itself (i.e., omitting the window.opener', and even calling a
refresh`), I get no error.
In addition, I commented-out the refresh
call inside the HTML page code. That didn't help, too: when I clicked the save button on the entity page, I again got the "function expected" error, now in Global.ashx
(b
was expected to be a function, apparently) :
Sys._isInstanceOfType=function(c,b){if(typeof b==="undefined"||b===null)return false; if(b instanceof c) return true;
No idea what's the cause for it. Any help is welcomed.
Posting messages between windows should meet your requirements here. You can find more information here Basically in your parent window do something like this:
window.onmessage = function (e) {
//e.data will contain some payload
Xrm.Page.getAttributes("xxx").setValue(e.data);
};
Or to be compatible with all browsers:
if (window.addEventListener) {
window.addEventListener('message', function (e) {
//e.data will contain some payload
Xrm.Page.getAttributes("xxx").setValue(e.data);
});
}
else { // IE8 or earlier
window.attachEvent('onmessage', function (e) {
//e.data will contain some payload
Xrm.Page.getAttributes("xxx").setValue(e.data);
});
}
Now in your child window only send the result using postMessage
window.opener.postMessage("I'm the result", '*');
I usually handle the scenarios that you described this way. The other solution would be to create a callback on parent window
window.callback = function() {
//do your stuff here
}
and from child window calling this callback:
childWindow.opener.callback();
But personally I prefer the postMessage approach, I had some problems with the callbacks sometimes.