One of the shortcomings of lookup controls in CRM 2011 and 2013 is that you can’t disable the View Picker once you enter a new custom view. Although you can set it as default and put it first on the list, users can still select records related to other views.
When 2011 was introduces it seemed that this missing SDK ability was no more than a glitch.
Unfortunately it’s still an issue in 2013 and yet again we are required to find undocumented features to enforce this type of business rule.
Luckily both 2011 and 2013 has this feature built into the product. We just needed to find a way to activate it without hindering existing CRM functionality.
In order to handle all the lookup internals, supported and unsupported, I’ve created an XrmLookupField wrapper. The wrapper enables me to manipulate the control with ease and I suggest you do the same in your code.
There is one thing you need to remember about this feature. Once you disable the View Picker you can’t add custom views to it. You must enable the View Picker before you add new customs views and disable it again if you so require.
If you take a closer look at the AddLockedView method in the code sample you’ll notice that this is exactly what I’m doing before adding a new custom view.
i.e. EnableViewPicker(); > AddCustomView() > DisableViewPicker()
This is how we did it in 2011
Note: This XrmLookupField example only includes methods that are relevant to this post.
//SDK wrapper for lookup field 2011 function XrmLookupField(sId) { var xlf = this; //control instance xlf.Ctl = Xrm.Page.getContorl(sId); //dom instance xlf.Dom = document.getElementById(sId); //jquery instance xlf.$ = $(xlf.Dom); //use that to disable the view picker xlf.DisableViewPicker = function () { xlf.SetParameter("disableViewPicker", "1"); } //use that to enable the view picker xlf.EnableViewPicker = function () { xlf.SetParameter("disableViewPicker", "0"); } //set undocumented attributes xlf.SetParameter = function (sName, vValue) { xlf.$.attr(sName, vValue); } //add locked view xlf.AddLockedView = function (sViewId, sEntityName, sViewDisplayName, sFilterXml, sFilterLayout) { //first enable the view picker xlf.EnableViewPicker(); //add the custom view (last parameter set the view as default) xlf.Ctl.addCustomView(sViewId, sEntityName, sViewDisplayName, sFilterXml, sFilterLayout, true); //lock the view picker xlf.DisableViewPicker(); } //create new guid xlf.NewGuid = function () { var d = new Date().getTime(); var guid = '{xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx}'.replace(/[xy]/g, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16); }); return guid; } }
And here is a usage example. Note that I’m using the dynamic FetchXml builder to construct my Layouts and FetchXml queries.
You can read more about it here or use regular xml in your code.
//entity onload js var myLookup1; //call this function from OnLoad handler function OnCrmPageLoad() { myLookup1 = new XrmLookupField("new_lookup1"); myLookup1.AddLockedView( //sViewId myLookup1.NewGuid() , //sEntityName "account", //sViewDisplayName "My Locked Custom View", //sFilterXml fetch() .entity("account") .attribute("name") .filter() .condition("name" , fetch.op.Eqaul, "My Company") .toString(), //sFilterLayout layout(1, "name", "accountid") .column("name", 200) .toString() ); }
CRM 2013 introduced some interesting changes. Controls now have a double layout state, one for printing or a read-only state and another for inline editing.
This also means that the built-in feature that controls the View Picker changed.
Luckily, now that we have our XrmLookupField wrapper, we only need to make slight modification in order to make this feature work again and apply it in all our forms.
Following are the required XrmLookupFIeld additions for 2013
I added a comment above each addition to make it noticeable
//SDK wrapper for lookup field 2013 function XrmLookupField(sId) { var xlf = this; //control instance xlf.Ctl = Xrm.Page.getContorl(sId); //dom instance xlf.Dom = document.getElementById(sId); //jquery instance xlf.$ = $(xlf.Dom); /* 2013 addition --- Inline Control instance --- */ xlf.$i = $("#" + sId + "_i"); //use that to disable the view picker xlf.DisableViewPicker = function () { /* 2013 addition --- The attribute capitalization changed */ xlf.SetParameter("disableviewpicker", "1"); } //use that to enable the view picker xlf.EnableViewPicker = function () { /* 2013 addition --- The attribute capitalization changed */ xlf.SetParameter("disableviewpicker", "0"); } //set undocumented attributes xlf.SetParameter = function (sName, vValue) { xlf.$.attr(sName, vValue); /* 2013 addition --- Also change the inline contorl value */ xlf.$i.attr(sName, vValue); } //add locked view xlf.AddLockedView = function (sViewId, sEntityName, sViewDisplayName, sFilterXml, sFilterLayout) { //first enable the view picker xlf.EnableViewPicker(); //add the custom view (last parameter set the view as default) xlf.Ctl.addCustomView(sViewId, sEntityName, sViewDisplayName, sFilterXml, sFilterLayout, true); //lock the view picker xlf.DisableViewPicker(); } //create new guid xlf.NewGuid = function () { var d = new Date().getTime(); var guid = '{xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx}'.replace(/[xy]/g, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16); }); return guid; } }
And finally , the usage is exactly the same as above saving us a tone of work
Fill free to comment
Cheers,
Adi
Hi Adi,
ReplyDeletedo you have a tip for me, why to disable the viewPicker is not working under crm 2016 online Wave 1?
Here my script:
function disableViewPicker () {
var lookup = Xrm.Page.getControl("lookup_WorkTags");
if (lookup) {
var id = "{E57F5DE2-7764-E611-80DD-C4346BAC0E68}"; // Tag lookup view for work
var defaultView = lookup.getDefaultView();
if (defaultView != id) { lookup.setDefaultView(id); }
lookup.SetParameter("disableViewPicker", "1"); //setDisabled(true);
}
setTimeout( function () { disableViewPicker(); } , 1000);
}
Frank