Dynamics CRM 2011 · Javascript · Ribbon · Xml

CRM 2011: Filtered Lookup for Add Existing button for Many-to-many Relationship

Following up from the previous post , we want to take filtered lookup to ‘Add Existing’ button. Please note that this only works for a Many-to-many relationship.

To do this we need to replace the view (query and layout) of the ‘Add Existing’ button control. For this example we will use ‘Add Existing’ Account.

1. Query and Layout
Please refer to post for query and layout part.

2. Generic Javascript replace view function for ‘Add Existing’ button. Create web resource file for this eg. new_CustomAddExistingView

function replaceAddExistingButtonView(params) {
    var relName = params.gridControl.getParameter("relName"),
        roleOrd = params.gridControl.getParameter("roleOrd"),
        viewId = "{1DFB2B35-B07C-44D1-868D-258DEEAB88E2}"; //Random GUID
    
    var customView = {
        fetchXml: params.fetchXml,
        id: viewId, 
        layoutXml: params.layoutXml,
        name: params.name,
        recordType: params.gridTypeCode,
        Type: 0
    };

    var lookupItems = LookupObjects(null, "multi", params.gridTypeCode, 0, null, "", null, null, null, null, null, null, viewId, [customView]);
    if (lookupItems && lookupItems.items.length > 0) {
        AssociateObjects(crmFormSubmit.crmFormSubmitObjectType.value, crmFormSubmit.crmFormSubmitId.value, params.gridTypeCode, lookupItems, IsNull(roleOrd) || roleOrd == 2, "", relName);
    }
}

3. Function to call to replace ‘Add Existing’ Account button. Add this to new_CustomAddExistingView Web Resource file.

function replaceAddExistingButtonViewForAccount(gridTypeCode, gridControl) {
    replaceAddExistingButtonView({
        gridTypeCode: gridTypeCode,
        gridControl: gridControl,
        fetchXml: "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
					  "<entity name='account'>" +
						"<attribute name='name' />" +
						"<attribute name='primarycontactid' />" +
						"<attribute name='telephone1' />" +
						"<attribute name='accountid' />" +
						"<order attribute='name' descending='false' />" +
						"<filter type='and'>" +
						  "<condition attribute='name' operator='like' value='Abc%' />" +
						"</filter>" +
					  "</entity>" +
					"</fetch>",
        layoutXml: "<grid name='resultset' object='1' jump='name' select='1' icon='1' preview='1'>" +
					  "<row name='result' id='accountid'>" +
						"<cell name='name' width='300' />" +
						"<cell name='primarycontactid' width='150' />" +
						"<cell name='telephone1' width='100' />" +
					  "</row>" +
					"</grid>",
		name: "Accounts Beginning with Abc"
    });
}

4. Export solution with ‘Account’ entity and look for Mscrm.AddExistingRecordFromSubGridAssociated. It should looks something like this:

<CommandDefinition Id="Mscrm.AddExistingRecordFromSubGridAssociated">
	<EnableRules>
	  <EnableRule Id="Mscrm.AppendPrimary" />
	  <EnableRule Id="Mscrm.AppendToPrimary" />
	  <EnableRule Id="Mscrm.EntityFormIsEnabled" />
	</EnableRules>
	<DisplayRules>
	  <DisplayRule Id="Mscrm.AddExisting" />
	  <DisplayRule Id="Mscrm.ShowForManyToManyGrids" />
	  <DisplayRule Id="Mscrm.AppendPrimary" />
	  <DisplayRule Id="Mscrm.AppendToPrimary" />
	  <DisplayRule Id="Mscrm.AppendSelected" />
	  <DisplayRule Id="Mscrm.AppendToSelected" />
	  <DisplayRule Id="Mscrm.CanWriteSelected" />
	</DisplayRules>
	<Actions />
</CommandDefinition>

Add new Action

<Actions>
  <JavaScriptFunction FunctionName="replaceAddExistingButtonViewForAccount" Library="$webresource:new_CustomAddExistingView">
	<CrmParameter Value="SelectedEntityTypeCode" />
	<CrmParameter Value="SelectedControl" />
  </JavaScriptFunction>
</Actions>

Add the above to RibbonDiffXml, it should look something like this

<RibbonDiffXml>
	<CustomActions />
	<Templates>
	  <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
	</Templates>
	<CommandDefinitions>
		<CommandDefinition Id="Mscrm.AddExistingRecordFromSubGridAssociated">
			<EnableRules>
			  <EnableRule Id="Mscrm.AppendPrimary" />
			  <EnableRule Id="Mscrm.AppendToPrimary" />
			  <EnableRule Id="Mscrm.EntityFormIsEnabled" />
			</EnableRules>
			<DisplayRules>
			  <DisplayRule Id="Mscrm.AddExisting" />
			  <DisplayRule Id="Mscrm.ShowForManyToManyGrids" />
			  <DisplayRule Id="Mscrm.AppendPrimary" />
			  <DisplayRule Id="Mscrm.AppendToPrimary" />
			  <DisplayRule Id="Mscrm.AppendSelected" />
			  <DisplayRule Id="Mscrm.AppendToSelected" />
			  <DisplayRule Id="Mscrm.CanWriteSelected" />
			</DisplayRules>
			<Actions>
			  <JavaScriptFunction FunctionName="replaceAddExistingButtonViewForAccount" Library="$webresource:new_CustomAddExistingView">
				<CrmParameter Value="SelectedEntityTypeCode" />
				<CrmParameter Value="SelectedControl" />
			  </JavaScriptFunction>
			</Actions>
		</CommandDefinition>
	</CommandDefinitions>
	<RuleDefinitions>
	  <TabDisplayRules />
	  <DisplayRules />
	  <EnableRules />
	</RuleDefinitions>
	<LocLabels />
</RibbonDiffXml>

5. Zip the solution files, import and publish.

Note: For One-to-Many relationship, read this post.

Cheers – Sy

16 thoughts on “CRM 2011: Filtered Lookup for Add Existing button for Many-to-many Relationship

  1. Thank you but I have a problem when trying it on a many to many relationship I’ve encountered a strange error. I can get the lookup to be filtered, but as soon as I select an item the “Add” button of the lookup gets greyed out. Anyone have any ideas on how to fix this issue?

  2. Hi… I tried the same and I am able to get the lookup… but when after selecting the items and when i click ‘ok’ button, I am getting an error… ‘object doesnt support the method or property’….
    Any idea why its coming?

    1. Hi Aishwarya,

      What relationship are you working on?

      If you post or send me the customizations that you have done, I can have a quick look and a better idea of your issue.

      Cheers – Sy

  3. Hi , sliong As Aishwarya Said even i have creaed N to N relation and i can get filtered Look up , while selecting record itz not getting save.. Can u guide where i am going Wrong.

    1. Hi, if you can send me what you have done I can have a better look. Otherwise I am just making a blind guess.

  4. As u said in above method , i did the same and similar method , i have created N to N relation with account entity and pasted your code , and made customization in Xml file and i imported every thing , i could get filtered View and records are displaying According to it , while i select and give add those records are not getting saved in my add existing ..
    Why such strange Error..

    1. Hi, without looking at your code I can’t provide much help as I’m just blind guessing. There is probably an error in the code somewhere about relationship type or entity type, but this is just guessing.

  5. when I export the solution the ribbon does not contain the command definition for Mscrm.AddExistingRecordFromSubGridAssociated

    1. Hi, you need to export the ribbon command definition using export ribbon tool included in sample code in crm 2011 sdk.

  6. function replaceAddExistingButtonView(params) {
    var relName = params.gridControl.getParameter(“relName”),
    roleOrd = params.gridControl.getParameter(“roleOrd”),
    viewId = “{1DFB2B35-B07C-44D1-868D-258DEEAB88E2}”; //Random GUID

    var customView = {
    fetchXml: params.fetchXml,
    id: viewId,
    layoutXml: params.layoutXml,
    name: params.name,
    recordType: params.gridTypeCode,
    Type: 0
    };

    var lookupItems = LookupObjects(null, “multi”, params.gridTypeCode, 0, null, “”, null, null, null, null, null, null, viewId, [customView]);
    if (lookupItems && lookupItems.items.length > 0) {
    AssociateObjects(crmFormSubmit.crmFormSubmitObjectType.value, crmFormSubmit.crmFormSubmitId.value, params.gridTypeCode, lookupItems, IsNull(roleOrd) || roleOrd == 2, “”, relName);
    }
    }

    Question : what is this and how to set, what does mean. Sorry because i am fresh??
    params how to set ???
    how to you get “relName”?????
    function replaceAddExistingButtonView(params) {
    var relName = params.gridControl.getParameter(“relName”),
    roleOrd = params.gridControl.getParameter(“roleOrd”),

    1. Hi Li Ying,

      Params is passed as a parameter to the function replaceAddExistingButtonView() by the function replaceAddExistingButtonViewForAccount().

      If you see step 3 line 2, params passed is {gridTypeCode: gridTypeCode, …}

      The function replaceAddExistingButtonViewForAccount() is then called by the ribbon passing CrmParameter SelectedEntityTypeCode and SelectedControl. relName is obtained from the gridControl.

      Hope this helps.

      Cheers – Sy

Leave a reply to sliong Cancel reply