The object exposes the following properties:
1. ParentId – this is the parent entity key. If not specified the viewer uses the current entity crmForm.ObjectId.
2. ParentOtc – this is the parent object type code. Again if not specified the crmForm.ObjectTypeCode is used.
3. RelationshipName – this is the relationship id as it appears in customization.
4. Tabset – this is the name of the tabset parameter which is required for the associated view to work. Use the iedevtoolbar to extract this parameter.
Enjoy...
function OnCrmPageLoad()
{
var assocViewer = new AssocViewer("IFRAME_RelatedContacts");
/* Optional - crmForm.ObjectId */
assocViewer.ParentId = 'D74D44AD-36D0-DC11-AA32-0003FF33509E';
/* Optional - crmForm.ObjectTypeCode */
assocViewer.ParentOtc = 1;
/* Mandatory - relationship schema name */
assocViewer.RelationshipName = "contact_customer_accounts"
/* Mandatory - tabset query string parameter */
assocViewer.Tabset = "areaContacts";
assocViewer.Load();
}
function AssocViewer(iframeId)
{
var av = this;
if (crmForm.FormType == 1)
{
return;
}
av.IFrame = document.all[iframeId];
if (!av.IFrame)
{
alert("Iframe " + iframeId + " is missing!");
}
var _locAssocOneToMany = null;
av.ParentId = crmForm.ObjectId;
av.ParentOtc = crmForm.ObjectTypeCode;
av.Tabset = null;
av.RelationshipName = null;
av.Load = function()
{
if (av.ParentId == null || av.ParentOtc == null || av.Tabset == null || av.RelationshipName == null)
{
return alert("Missing Parameters: ParentId or ParentOtc or Tabset Name!");
}
var security = crmFormSubmit.crmFormSubmitSecurity.value;
av.IFrame.src = "areas.aspx?oId=" + av.ParentId + "&oType=" + av.ParentOtc + "&security=" + security + "&tabSet=" + av.Tabset
av.IFrame.onreadystatechange = av.OnIframeReady;
}
av.OnIframeReady = function()
{
if (av.IFrame.readyState != 'complete')
{
return;
}
av.IFrame.contentWindow.document.body.scroll = "no";
av.IFrame.contentWindow.document.body.childNodes[0].rows[0].cells[0].style.padding = "0px";
_locAssocOneToMany = locAssocOneToMany;
locAssocOneToMany = av.locAssocOneToMany;
}
av.locAssocOneToMany = function(iType, sRelationshipName)
{
_locAssocOneToMany(iType,sRelationshipName);
if (sRelationshipName == av.RelationshipName)
{
av.IFrame.contentWindow.document.all.crmGrid.Refresh();
}
}
}
//Entry Point
OnCrmPageLoad();
35 comments:
Dear Adi,
Thank you soo much for posting this valuable information. This is what I was exactly looking for. Let me test it in my environment.
I have been a regular/avid reader of your blogs for the past 1 yr and find it one of the most finest and informative blogs for crm customization.
Thank you once again....
Regards
Prince
Hi Adi,
The iFrame is not refreshing for quote details. I have created an iFrame inside quotes for "quote details". I want tomake it dynamic. This is my code. Pls let me know where have I gone wrong
function OnCrmPageLoad()
{
var assocViewer = new AssocViewer("IFRAME_Quotedetails");
/* Optional - crmForm.ObjectId */
assocViewer.ParentId = crmForm.ObjectId;
/* Optional - crmForm.ObjectTypeCode */
assocViewer.ParentOtc = crmForm.ObjectTypeCode;
/* Mandatory - relationship schema name */
assocViewer.RelationshipName = "quote_details"
/* Mandatory - tabset query string parameter */
assocViewer.Tabset = "areaExistingProducts";
assocViewer.Load();
}
function AssocViewer(iframeId)
{
var av = this;
if (crmForm.FormType == 1)
{
return;
}
av.IFrame = document.all[iframeId];
if (!av.IFrame)
{
alert("Iframe " + iframeId + " is missing!");
}
var _locAssocOneToMany = null;
av.ParentId = crmForm.ObjectId;
av.ParentOtc = crmForm.ObjectTypeCode;
av.Tabset = null;
av.RelationshipName = null;
av.Load = function()
{
if (av.ParentId == null || av.ParentOtc == null || av.Tabset == null || av.RelationshipName == null)
{
return alert("Missing Parameters: ParentId or ParentOtc or Tabset Name!");
}
var security = crmFormSubmit.crmFormSubmitSecurity.value;
av.IFrame.src = "areas.aspx?oId=" + av.ParentId + "&oType=" + av.ParentOtc + "&security=" + security + "&tabSet=" + av.Tabset
av.IFrame.onreadystatechange = av.OnIframeReady;
}
av.OnIframeReady = function()
{
if (av.IFrame.readyState != 'complete')
{
return;
}
av.IFrame.contentWindow.document.body.scroll = "no";
av.IFrame.contentWindow.document.body.childNodes[0].rows[0].cells[0].style.padding = "0px";
_locAssocOneToMany = locAssocOneToMany;
locAssocOneToMany = av.locAssocOneToMany;
}
av.locAssocOneToMany = function(iType, sRelationshipName)
{
_locAssocOneToMany(iType,sRelationshipName);
if (sRelationshipName == av.RelationshipName)
{
av.IFrame.contentWindow.document.all.crmGrid.Refresh();
}
}
}
//Entry Point
OnCrmPageLoad();
Regards
prince
Indeed the quote and similar entities like invoice and order that add products as children behave completely different then your regular associated view. For example the product window is not a dialog but a window which complicated things. MS function which opens the product (openFrmObj) does not return a reference to the window which further complicates the process. To make this work you’ll need to make many unsupported customizations so I suggest you let it go.
Hi ,
i need to hide a custom queue that i 've created from the users with CSR role...is there any way i could achieve this? plz help
Not sure how your comment is related to this post. I suggest opening a thread on ms forums. you’ll probably get an answer immediately.
I know that itz irrelavant but i wasn't getttin any workarnds or solutions so i thought i can ask u on this as ur blogs we quite helpful for me in the past.
Any way i've also posted it in MS forms titled " HIDE MS CRM Queues"...would be so kind enough to to look in to it and let me know if i can achieve this as this seems to be quite a crucial requirement for contact center implementations
I Have made our Queue Manager wizard available for purchasing on our website.
if you're interested in developing it your self you'll need to use plug-ins.
I am having a slight problem with this code - perhaps someone can help me? I have found it works great in most cases, but I am trying to display the activities and history grids inside IFRAMEs on the Opportunity, and having problems with the refresh. I think it may be because these entities are a bit more complex, with some data on the activitypointer entity. If anyone can point the way to how to tweak this code for this scenario, I would be grateful!
Hi Adi,
One question. I want to put a filter to my associated view using your code. In my associated view I have 2 status- Draft and closed. I want to show only records in the draft mode.
How can I or where should I incorporate the filter using fetch xml in your code so that the iframe shows only records in draft mode. Can you pls advice.
The associated view is a built in view. There isn’t any fetchxml involved with this view. You can use a different method as described here and build a fetchxml that mimics the associated view display.
Hi Adi,
Thanx for the link. I tried your code. Everything seems to be working. I am able to create records and put filter to it and its getting refreshed also.
The only issue which I am facing is when I try to retrieve one of the existing records from the iFrame instead of showing the record, its opening up a new form with blank data. I am not able to access the existing records but I can see the created records in the view inside the iframe.
Can you pls guide me where I am going wrong? Would you like to see the code?
Thanx
Hello Adi,
Glad to see you are still monitoring these comments.
I posted on 7/1 - I am having problems using this code for the Activity and History views (on the Opportunity entity) - the refresh is not working correctly.
Do you have any ideas how I might get this working? It would be a huge help for me.
Thanks
The Assoc viewer overrides the locAssocOneToMany function. When you create an iframe that references the activity or history views you need to override the auto function. Try the following changes…
Replace line 29:
var _auto = null;
replace lines 56 and 57:
_auto = top.auto;
top.auto = av.auto;
replace the av.locAssocOneToMany(…) with:
av.auto = function auto(iObjectTypeCode,sFindValue)
{
/* original function call */
_auto(iObjectTypeCode,sFindValue);
av.iFrame.contentwindow.document.all.crmGrid.Refresh();
}
make sure this does not influence other grid refreshes
About the opening of existing records. I made a quick change to the OnWindowOpen function. Try it now.
Hi Adi,
Tried your new code for "Display fetch in IFrame-part2" after you made the changes.
Now the moment I open the parent form inside which the Iframe is located a message comes "Iframe IFrame_quote_fltsch is undefined". IFrame_quote_fltsch is the name of my Iframe and it is located in the first tab. I've given the url as about:blank and removed the check from restrict cross-frame scripting. Now the Iframe is totaly blank.
Pls advice
Adi,
Your code for activity and history worked great, however I have one wrinkle.
I have both grids on one form in two separate IFRAMEs. What I am seeing is that when you complete and activity the activities grid refreshes correctly, but the history grid does not. The auto function does not seem to get called in this scenario.
Any ideas as to how to get the history grid to refresh when you open and complete an activity from the IFRAME holding the activity grid?
Thank so much in advance for any guidance you can give - you have been so helpful to date!
Dear Adi,
I'm sorry for the previous post. It seems to be working now. I gave a wrong id for my iFrame which I figured out. Anyways eventually its working and I can retrieve the existing records from the view. Thanx a million it works like charm....!!
¿Where I have to put de code in order to work? ¿Do I have tu put it in OnLoad event?? please your help. Thanks.
Yes, put the code in the onload event and change the OnCrmPageLoad content with the correct associated view information
Hi adi
I would like to know how has anonymous added the same code for displaying pending activities and history in two iframes.I am creating two iframes on the case entity to display pending on one and history on the other.
Kindly help.Thanx for all the useful customizations posted on your blog.
regards
Hi,
Thanks, it helped for me to solve my problem. Keep posting...
Hi Adi
Great post, thank you.
Is there any way to make the associated view writeable?
Joe
What do you mean by writable? CRM grid is not editable. You can create a master detail from. Take a look at the following post:
http://mscrm4ever.blogspot.com/2008/09/crm-master-detail-page-part-1.html
Hi Adi,
Sorry I meant editable. Thanks for the link.
I've read in several places that inline editing of records in the CRM grid may be available in CRM 5.0 - can you shed any light on this?
Thanks
Joe
Hi Adi,
The code is working great for my views of one-to-many relationships, but is obviously not for many-to-many ones since you wrote this to override the locAssocOneToMany function. Would it be possible to modify this to work for views of many-to-many relationships?
Thanks,
Shawn
Joe - can't say much about crm 5.0.
shawn - follow this link for many2many viewer
http://mscrm4ever.blogspot.com/2009/04/crm-40-many-2-many-iframe-viewer.html
Hey Adi,
I tried your many-to-many solution and it works perfectly. Thanks so much for all the work you've done on your blog. Just discovered it yesterday when looking for a better view solution and after perusing it I see that there are lot of gems on it. I'm going to try your script loader next. It'll save me a lot of headaches.
Thanks!
Shawn
Hi Adi,
Great posts! I've been using both of the viewers without any issues, until recently...
I have 4 of the 1 to Many Iframes on the account entity, and until recently its been running without issues. Now all of a sudden, each form that has this code on it is causing IE to "lock up" for about 20-30+ seconds between clicks (CPU spikes to 50% too)
this is happening on our case entity as well (2 - 1 to many's there too)
**all other entities work as they should without any pauses.
Hi Adi
I was customized in your instruct. It's only run local. When run to network, it's not display. Why? Please help me.
Hi Adi,
Awesome scripting. You responded to a question about using this script for activities with the following:
replace the av.locAssocOneToMany(…) with:
av.auto = function auto(iObjectTypeCode,sFindValue)
{
/* original function call */
_auto(iObjectTypeCode,sFindValue);
av.iFrame.contentwindow.document.all.crmGrid.Refresh();
}
I think I'm understanding this wrong - can you clarify?
Thanks!
Hi Adi,
This was great. Hope this doesn't show up twice - my first comment didn't appear, maybe I didn't save it.
Back on July 15 2009 you responded to a question about using this code for activities by instructing the person who asked to replace certain parts of the code. I think I'm understanding this replacement incorrectly:
replace the av.locAssocOneToMany(…) with:
av.auto = function auto(iObjectTypeCode,sFindValue)
{
/* original function call */
_auto(iObjectTypeCode,sFindValue);
av.iFrame.contentwindow.document.all.crmGrid.Refresh();
}
What is the /* original function call */? I'm doing that wrong - can you clarify? My IFRAME refrshes when an activity is closed, but not when a new one is created.
Thanks!
This solution suppose to work even for read-only forms, because i got an empty grid when the form is in reda-only state
I have just found a solution for my post. It is working for read only forms but you have to deeal somehow with the iframe src. For the read only forms the path is different. My solution was not to change the path but to add the areas.aspx page in the readonly folder adding to the name a suffix(1 for account, 2 for contact and so on)
Hi Adi,
I am a very newbie to CRM. I designed an entity which has no relationships. It has a small workflow to send email and assign cases. Users also add their notes. Now my question is how can we show the history of each actiivty performed by the user for every record in an IFRAME? Can you please help me out with this?
Thanks!
Post a Comment