CRM 2011 Custom Filtered Lookup

Sometimes the filtered lookup functionality provided by CRM 2011 doesn't fit your requirement. However Microsoft provides a function for us to add our own custom view for the lookup field.

Example: In a 'Case' form we have customer field. I use this field only for 'Contacts', and I have created a relationship to the 'Account' so that we can see both on the form. I want the Accounts to only show Contacts that have 'Connections To' and vice versa (Only show Contacts that have 'Connections From' if I specified the Account first). If nothing is specified then I want both to show just Active Contacts/Accounts.



The script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//////////////////////////////
///Account Filtered Lookup ///
//////////////////////////////
function setAccountLookup(contactFieldName, lookupFieldName, resetSelection) {
    var defaultViewId = "00000000-0000-0000-00AA-000010001002";
 
    // Get the selected Contact Id in the [accountFieldName] indicated control
    var contact = Xrm.Page.getAttribute(contactFieldName).getValue();
 
    if (contact != null) {
        var contactId = contact[0].id;
        var contactName = contact[0].name;
 
        if (resetSelection == true) {
            resetAccountSelection(lookupFieldName);
        }
 
        // use randomly generated GUID Id for our new view
        var viewId = "{1DFB2B35-B07C-44D1-868D-258DEEAB88E2}";
        var entityName = "account";
 
        // give the custom view a name
        var viewDisplayName = "Active Accounts for " + contactName + "";
 
        // find all accounts where [Primary Contact Id] = [Contact indicated by ContactId]
        // AND where [Statecode] = Active
        var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
                     "<entity name='account'>" +
                     "<attribute name='name' />" +
                     "<attribute name='accountnumber' />" +
                     "<attribute name='address1_city' />" +
                     "<attribute name='telephone1' />" +
                     "<attribute name='emailaddress1' />" +
                     "<attribute name='accountid' />" +
                     "<order attribute='accountnumber' descending='false' />" +
                     "<filter type='and'>" +
                     "<condition attribute='statecode' operator='eq' value='0' />" +
                     "</filter>" +
                     "<link-entity name='connection' alias='aa' to='accountid' from='record2id'>" +
                     "<filter type='and'>" +
                     "<condition attribute='record1id' operator='eq' value='" + contactId + "' />" +
                     "</filter>" +
                     "</link-entity>" +
                     "</entity>" +
                     "</fetch>";
 
        // build Grid Layout
        var layoutXml = "<grid name='resultset' " +
                               "object='1' " +
                               "jump='accountid' " +
                               "select='1' " +
                               "icon='1' " +
                               "preview='1'>" +
                           "<row name='result' " +
                                "id='accountid'>" +
                             "<cell name='name' " +
                                   "width='200' />" +
                             "<cell name='accountnumber' " +
                                   "width='200' />" +
                             "<cell name='address1_city' " +
                                   "width='200' />" +
                             "<cell name='telephone1' " +
                                   "width='200' />" +
                             "<cell name='emailaddress1' " +
                                   "width='200' />" +
                           "</row>" +
                         "</grid>";
 
        // add the Custom View to the indicated [lookupFieldName] Control
        Xrm.Page.getControl(lookupFieldName).addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, true);
    }
    else {
        // no Contact selected, reset Account Lookup View to the default view such that all Accounts are displayed for selection
        if (resetSelection == true) {
            resetAccountSelection(lookupFieldName);
        }
        Xrm.Page.getControl(lookupFieldName).setDefaultView(defaultViewId);
    }
}
 
function resetAccountSelection(lookupFieldName) {
    // reset old selection for Account
    Xrm.Page.getAttribute(lookupFieldName).setValue(null);
    Xrm.Page.getAttribute("new_accountnumber").setValue(null);
}
 
//////////////////////////////
///Contact Filtered Lookup ///
//////////////////////////////
function setContactLookup(accountFieldName, lookupFieldName, resetSelection) {
    var defaultViewId = "00000000-0000-0000-00AA-000010001004";
 
    // Get the selected Contact Id in the [accountFieldName] indicated control
    var account = Xrm.Page.getAttribute(accountFieldName).getValue();
 
    if (account != null) {
        var accountId = account[0].id;
        var accountName = account[0].name;
 
        if (resetSelection == true) {
            resetContactSelection(lookupFieldName);
        }
 
        // use randomly generated GUID Id for our new view
        var viewId = "{1DFB2B35-B07C-44D1-868D-258DEEAB88E3}";
        var entityName = "contact";
 
        // give the custom view a name
        var viewDisplayName = "Active Contacts for " + accountName + "";
 
        // find all accounts where [Primary Contact Id] = [Contact indicated by ContactId]
        // AND where [Statecode] = Active
        var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
                     "<entity name='contact'>" +
                     "<attribute name='fullname' />" +
                     "<attribute name='telephone1' />" +
                     "<attribute name='contactid' />" +
                     "<attribute name='address1_line1' />" +
                     "<attribute name='address1_city' />" +
                     "<attribute name='address1_postalcode' />" +
                     "<attribute name='address1_stateorprovince' />" +
                     "<attribute name='emailaddress1' />" +
                     "<order attribute='fullname' descending='false' />" +
                     "<filter type='and'>" +
                     "<condition attribute='statecode' operator='eq' value='0' />" +
                     "</filter>" +
                     "<link-entity name='connection' alias='aa' to='contactid' from='record1id'>" +
                     "<filter type='and'>" +
                     "<condition attribute='record2id' operator='eq' value='" + accountId + "' />" +
                     "</filter>" +
                     "</link-entity>" +
                     "</entity>" +
                     "</fetch>";
 
        // build Grid Layout
        var layoutXml = "<grid name='resultset' " +
                               "object='1' " +
                               "jump='contactid' " +
                               "select='1' " +
                               "icon='1' " +
                               "preview='1'>" +
                           "<row name='result' " +
                                "id='contactid'>" +
                             "<cell name='fullname' " +
                                   "width='200' />" +
                             "<cell name='telephone1' " +
                                   "width='200' />" +
                             "<cell name='address1_line1' " +
                                   "width='200' />" +
                             "<cell name='address1_city' " +
                                   "width='200' />" +
                             "<cell name='address1_postalcode' " +
                                   "width='200' />" +
                             "<cell name='address1_stateorprovince' " +
                                   "width='200' />" +
                             "<cell name='emailaddress1' " +
                                   "width='200' />" +
                           "</row>" +
                         "</grid>";
 
        // add the Custom View to the indicated [lookupFieldName] Control
        Xrm.Page.getControl(lookupFieldName).addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, true);
    }
    else {
        // no Contact selected, reset Account Lookup View to the default view such that all Accounts are displayed for selection
        if (resetSelection == true) {
            resetContactSelection(lookupFieldName);
        }
        Xrm.Page.getControl(lookupFieldName).setDefaultView(defaultViewId);
    }
}
 
function resetContactSelection(lookupFieldName) {
    // reset old selection for Account
    Xrm.Page.getAttribute(lookupFieldName).setValue(null);
}


Then you can use it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Form_onload() {
    setAccountLookup("customerid", "new_accountid", false);
}
 
function Contact_onchange() {
    setAccountLookup("customerid", "new_accountid", false);
    setContactLookup("new_accountid", "customerid", false);
}
 
function Account_onchange() {
    retrieveAccountNumber("new_accountnumber", "new_accountid");
    setContactLookup("new_accountid", "customerid", false);
    setAccountLookup("customerid", "new_accountid", false);
}


However there is still a major limitation of FetchXML that you cannot use UNION clause (or something similar). So If you want to show the primarycontact/parentcustomer along with the connections, you're out of luck as you can only do one of them.

Hope this helps,
Andreas

Comments

Popular posts from this blog

SharePoint 2013 anonymous access add attachments to list item

CRM Plugin - Parent and Child Pipeline