Coding CRM Lookup Fields - مسافر بره مصر حتى وانا جواها مسافر

Coding CRM Lookup Fields

A Lookup is a reference or a pointer to another record (GUID) in crm. As opposed to other crm types, lookups are handled differently in many aspects. One “interesting” aspect which I relate to here is how a lookup DataValue is assigned when used in JavaScript.

The lookup DataValue is actually an array which holds a “lookup item” object or objects. Each lookup item exposes a set of properties we need to address in code for crm to acknowledge
its value. In reality an entity with a lookup is comprised of 3 table columns, so for example the primary contact lookup field on the account entity is actually a combination of primarycontactid (guid “{1234…}”) , primarycontactidname (name “Adi Katz”) and primarycontactiddesc columns in the database.

Now, crm only cares about GUIDs so until we start calling our selves by GUID (and not by NAME) we need to bridge that gap. Ms does relate to this gap, but only from the UI / End user perspective (auto complete feature). Unfortunately this ability is not exposed through code in any supported way and we need to build that bridge (automate the process) our selves using custom Ajax calls.

In the simplest scenario the lookup DataValue requires only a GUID (id) and entity name(typename). For example:


01.var LookupItem = new Object();
02.LookupItem.name = “Crm only cares about GUIDs (pls Save...)”;
03.LookupItem.id = “{D04D44AD-36D0-DC11-AA32-0003FF33509E}”;
04.LookupItem.typename = “contact”;
05.crmForm.all..DataValue = [LookupItem];

The problem is that we usually don’t know the entity id (GUID) only its name e.g.
01.var LookupItem = new Object();
02.LookupItem.name = “Adi Katz”;
03.LookupItem.id = “”;
04.LookupItem.typename = “contact”;
05.crmForm.all..DataValue = [LookupItem];

And of course this won’t work unless we lookup “Adi Katz” GUID by name and assign
it to the LookupItem.id.

The following “LookupHelper” class facilitates / automates the process by providing
the following features:

If “Adi Katz” does not exist then a clean lookup dialog is opened.
If “Adi Katz” exists more then once a lookup dialog is opened with the name “Adi Katz” inside the search box.
If one “Adi Katz” exists then the lookup is assigned a valid DataValue

The Lookup Helper works with all lookup types e.g. (single entity, customer, regarding and party lookup).

In all lookups, setting the entity name will set the lookup defaulttype property so when you open the lookup dialog the entity being searched is set in advance.

The OnCrmPageLoad bellow describes the How-to and possibilities you might encounter
in your daily “lookup programming”.

01.var curLookup;
02.function OnCrmPageLoad()
03.{
04./*
05.- Both GUID (id) and name are known
06.- entity name is taken from the lookup
07.*/
08.curLookup = new LookupHelper( "transactioncurrencyid" );
09.curLookup.SetValue( "US Dollar" , "{944038FC-65C1-DC11-B67A-0003FFBB057D}" );
10.
11./*
12.- Search Mode
13.- Open the lookup dialog window
14.*/
15.curLookup = new LookupHelper( "transactioncurrencyid" );
16.curLookup.SetValue("");
17./*
18.- only GUID (id) is known (usually not the case)
19.- name is a temporary text until you save the record
20.*/
21.curLookup = new LookupHelper( "transactioncurrencyid" );
22.curLookup.SetValue( "" , "{944038FC-65C1-DC11-B67A-0003FFBB057D}");
23./*
24.- only name is known, the id is fetched from crm
25.- must provide PrimaryField of the lookup entity in this case currencyname
26.*/
27.curLookup = new LookupHelper( "transactioncurrencyid" , "currencyname" );
28.curLookup.SetValue( "US Dollar" );
29.//OR
30.curLookup = new LookupHelper( "transactioncurrencyid" );
31.curLookup.PrimaryField = "currencyname";
32.curLookup.SetValue( "US Dollar" );
33./*
34.- Customer Lookup
35.- Change from account to contact entity
36.- the id is fetched form crm
37.*/
38.curLookup = new LookupHelper( "customerid" );
39.curLookup.SetEntity( "contact" , "fullname" , "Adi Katz" );
40.//is the same as
41.curLookup = new LookupHelper( "customerid" );
42.curLookup.SetEntity( "contact" );
43.curLookup.PrimaryField = "fullname";
44.curLookup.SetValue( "Adi Katz" );
45./*
46.- getting the actual lookup field
47.*/
48.curLookup = new LookupHelper( "customerid" );
49.alert(curLookup.Lookup.DataValue[0].name); //assuming datavalue exists.
50.}
51.
52./*
53.Parameters:
54.
55.lookupId - Mandatory, The lookup schema name.
56.primaryField - Optional, Required for fetch. can be set here or later
57.entity - Optional, Taken from the lookup control
58.*/
59.function LookupHelper( lookupId , primaryField , entity )
60.{
61.//Lookup Reference
62.this.Lookup = document.getElementById( lookupId );
63.//Checks if the lookupId is valid
64.if(isUndefined(this.Lookup))
65.return alert('lookup ' + lookupId + ' is undefined');
66.
67.
68./* Private Fields */
69.
70.var Instance = this;
71.var data = this.Lookup.lookuptypenames.split(',')[0].split(':');
72.var Entity = isUndefined(entity)? data[0]:entity;
73.var PK = Entity + "id";
74.
75./* Public Fields */
76.
77.//Holds the lookup text e.g. Adi Katz
78.this.Text = "Value Selected (Save...)";
79.//Holds the default operator for the fetchxml condition e.g. 'fullname eq "Adi Katz"'
80.this.Operator = "eq";
81.//Holds the lookup entity primary field e.g. contact = fullname , account = name
82.this.PrimaryField = primaryField;
83.
84./*public Functions
85.
86.Descrition:
87.
88.Sets the Entity and PrimaryKey - Required For Fetch
89.Sets the Primary Field - Required For Fetch
90.Sets the Default Lookup Type - Feature for lookup popup window
91.If the text is supplied then the id is Fetched from crm
92.
93.Parameters:
94.
95.entity - Mandatory, Required For Fetch
96.primaryField - Mandatory (unless supplied in the ctor),Required For Fetch
97.text - Optional
98.*/
99.
100.this.SetEntity = function( entity , primaryField , text )
101.{
102.Entity = entity;
103.PK = entity + "id";
104.
105.if(!isUndefined(primaryField))
106.Instance.PrimaryField = primaryField;
107.
108.var regDefType = new RegExp(entity + ":(\\d+)","gi");
109.regDefType.exec(Instance.Lookup.lookuptypenames);
110.Instance.Lookup.defaulttype = RegExp.$1;
111.
112.if(!isUndefined(text))
113.Instance.SetValue(text);
114.}
115.
116./*
117.Description:
118.Sets The lookup DataValue
119.
120.if text is undefined and guid is supplied then
121.use default text e.g. 'Value Selected (Save...)'
122.else
123.use supplied text
124.
125.if guid is supplied then
126.set the lookup datavalue
127.else if text is undefined then
128.open clean lookup dialog
129.else
130.fetch for lookup item id
131.if 1 record is returned then set datavalue
132.else
133.open lookup dialog with specified search condition
134.
135.Parameters:
136.guid - record id - global unique identifier
137.text - name displayed inside the lookup
138.*/
139.this.SetValue = function( text , guid )
140.{
141.if(!isUndefined(text))
142.Instance.Text = text;
143.
144.if(!isUndefined(guid))
145.{
146.var LookupItem = new Object();
147.LookupItem.name = text;
148.LookupItem.id = guid;
149.LookupItem.typename = Entity;
150.Instance.Lookup.DataValue = [LookupItem];
151.}
152.else if(isUndefined(text)) Search( "" );
153.else LookupValue( text );
154.}
155.
156./* Clear Lookup Value - DataVale = null */
157.this.Clear = function()
158.{
159.Instance.Lookup.DataValue = null;
160.}
161.
162./* Private Functions
163.
164.builds a valid Fetchxml for the current lookup type
165.fetch value and ( set datavalue or open lookup dialog )
166.*/
167.function LookupValue( text )
168.{
169.var xmlHttp = CreateXmlHttp();
170.var xml = " 171.xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"
172.xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
173.xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
174.
175.xml += GenerateAuthenticationHeader();
176.xml += "";
177.xml += " 178.xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">";
179.xml += "";
180.
181.var fetchxml = "";
182.
183.fetchxml += "";
184.fetchxml += "";
185.fetchxml += "";
186.fetchxml += "";
189.fetchxml += "
";
190.fetchxml += "
";
191.fetchxml += "
";
192.
193.xml += _HtmlEncode(fetchxml);
194.xml += "
";
195.xml += "";
196.xml += "
";
197.xml += "";
198.
199.xmlHttp.open("POST", "/mscrmservices/2007/crmservice.asmx", false );
200.xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
201.xmlHttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
202.xmlHttp.send(xml);
203.
204.var resultDoc = loadXmlDocument(xmlHttp.responseXML.text);
205.var resultRecords = resultDoc.selectNodes("//" + PK );
206.
207.if( resultRecords.length == 1 )
208.{
209.var guid = resultRecords[0].text;
210.Instance.SetValue( Instance.Text , guid );
211.}
212.else
213.{
214.Search( Instance.Text );
215.}
216.}
217.
218./* Fill search
219.condtion and open lookup dialog */
220.
221.function Search( text ){
222.Instance.Lookup.AddParam("search" , text );
223.Instance.Lookup.click();
224.}
225.
226./* Checks object definition */
227.function isUndefined(obj){
228.return obj == null || typeof(obj) == "undefined" || obj == "";
229.}
230.}
231.
232.OnCrmPageLoad();

34 Responses to “Coding CRM Lookup Fields”

  1. Does anybody has the latest Lady Gaga indian song video. It is so nice but I can’t find it online anymore, nybe it is in songs pk

  2. Jim says:

    Hello. This is kind of an “unconventional” question , but have other visitors asked you how get the menu bar to look like you’ve got it? I also have a blog and am really looking to alter around the theme, however am scared to death to mess with it for fear of the search engines punishing me. I am very new to all of this …so i am just not positive exactly how to try to to it all yet. I’ll just keep working on it one day at a time Thanks for any help you can offer here.

  3. andyw says:

    After reading you blog, Your blog is very useful for me .I bookmarked your blog!
    Wishes your valentine day to be joyful!

  4. payday loans says:

    I want to thank the blogger very much not only for this post but also for his all previous efforts. I found feckra.com to be very interesting. I will be coming back to feckra.com for more information.

  5. Nice Website. You should think more about RSS Feeds as a traffic source. They bring me a nice bit of traffic.

  6. I don’t usually reply to posts but I will in this case. WoW

  7. Hi, Very interesting article you have there. I actually run a couple of blogs on this topic, and since I have found some of your articles very informative I definatelty think that my members would enjoy reading them. With that said I would like to place a link to some of your articles on my blogs since they are more detailed than the information posted on my blogs. Thanks for your help!

  8. ZAREMA says:

    Thanks the author for article. The main thing do not forget about users, and continue in the same spirit.

  9. gualetar says:

    The subject is fully clear but why does the text lack clarity? But in general your blog is great.

  10. Vusiatara says:

    i actually enjoy all your writing choice, very unique,
    don’t quit and also keep penning considering the fact that it just simply very well worth to follow it.
    impatient to browse through more of your own well written articles, kind regards ;)

  11. Unlike many posts on the internet, this was fun to read and gave me some valuable input. I will have to put a backlink on my website. Regards. J

  12. I found your site from bing and it is magnificent. Thankx for supplying such an amazing blog post…

  13. I found your site from bing and it is magnificent. Thankx for supplying such an amazing blog post…

  14. Sorry for my bad english. Thank you so much for your good post. Your post helped me in my college assignment, If you can provide me more details please email me.

  15. Pennie Hoak says:

    Your header is a bit wonky in Opera, mate.

  16. free trial says:

    Good share,you article very great, very usefull for us…thank you

  17. Hmm thanks for the share, do you have any other sources?

  18. Dude.. I am not much into reading, but somehow I got to read lots of articles on your blog. Its amazing how interesting it is for me to visit you very often.

  19. Yes… i also really like to visit new place, your idea is good.

  20. I thought it was going to be some boring old post, but I’m glad I visited. I will post a link to this page on my blog. I am sure my visitors will find that very useful.

  21. Really good sharing this.

  22. Hi…… post good :)

  23. Thank you for your help!

  24. nice share, good

    article, very usefull for me…thank you

  25. Thanks For This Post, was added to my bookmarks.

  26. MarkSpizer says:

    great post as usual!

  27. Killing no murder.

  28. Awesome Blog. I add this Blog to my bookmarks.

  29. This Blog is very nice.

  30. One again, your idea is very

    good.thank you!very much.

  31. You certainly have some agreeable opinions and views. Your blog provides a fresh look at the subject.

  32. beauty says:

    Thank you admins.

  33. Thanks for

    making my morning a little bit better with this great article!!

  34. thank! for this news it’s a good infomation !

Leave a Reply

See also: