Tuesday, September 16, 2008

Cloning an entity Part 2 - Addressable Forms

As you know crm 4.0 has a new feature called addressable forms. This allows you to fill a new entity Form from scratch by sending Named (Field Names) parameters inside the Query String e.g. /edit.aspx?fieldname1=value1&fieldname2=value2 .


The reason I decided to write about this is I thought this could be a more supported replacement to my “cloning an entity with javascript” post which uses the opener to get the cloning entity information. This approach is not without limitations since the amount of data you can pass in the query string is restricted to 2083 characters.


I found ms sdk somewhat missing! For example, Ms states you need to pass a DateTime field “text” as a valid value. The problem is ms don’t expose any supported property that returns that text so I ended using the {DateTime Field}.InnerText instead. (On second thought I have the feeling that this is what they meant).


Although the owner lookup is a single lookup it needs the entity typename (“systemuser”), didn’t see any reference about that in the sdk.
You might find other issue which I missed.


The AddressableForm object is a nice wrapper which makes it easy to use this feature.
The object has an AddField method which accepts a Field ID to be passed to the new window. If you don’t specify any fields the class will try to clone the entire field set. Finally use the open method to complete the job.


In the following example i simply created a condition in the OnCrmPageLoad to test this. You should create an isv.config button that calls the CloneEntity function.


function OnCrmPageLoad()
{
if( crmForm.FormType == 2 )
CloneEntity();
}

function CloneEntity()
{
var addrForm = new AddressableForm();
//Optional , if you don't specify any field all fields that are not null are cloned
addrForm.AddField("firstname");
addrForm.AddField("ownerid");
addrForm.AddField("defaultpricelevelid");
addrForm.Open();
}

function AddressableForm()
{
var Instance = this;
var url = location.pathname + "?";
var search = "";

Instance.Fields = [];
Instance.AddField = function( fieldId )
{
var field = document.getElementById( fieldId );
if( field ) Instance.Fields[Instance.Fields.length] = field;
}

Instance.Open = function()
{
var list = Instance.Fields.length > 0 ? Instance.Fields : crmForm.all;

for( var i = 0 ; i < list.length ; i++ )
{
if( list[i].req && list[i].DataValue )
FillAddressableParameter(list[i]);
}

url = url + search.replace(/&$/gi,"");

var features = "toolbars=0,top=" + screenTop + ",";
features += "left=" + screenLeft + ",";
features += "width=" + document.body.offsetWidth + ",";
features += "height=" + document.body.offsetHeight;
window.open( url , "" , features );
}

function FillAddressableParameter( element )
{
var elementId = element.id;
var elementDv = element.DataValue;

switch( element.tagName )
{
case "IMG": //lookup
search += elementId + "=" + elementDv[0].id + "&";
search += elementId + "name=" + elementDv[0].name + "&";
/*
Special Cases
Condition1 - checks if this is a customer lookup
Condition2 - checks if this is an owner lookup
*/
if( element.lookuptypes.indexOf(',') != -1 || element.lookuptypes == "8")
search += elementId + "type=" + elementDv[0].typename + "&";
break;
case "TABLE": // datetime
search += elementId + "=" + element.InnerText + "&";
break;
default:
search += elementId + "=" + elementDv + "&";
break;
}
}
}

window.CloneEntity = CloneEntity;

OnCrmPageLoad();

No comments: