Clone/Copy Existing Record Using JavaScript

Recently I needed to create a clone functionality using JavaScript for CRM 2013. I wanted to make it so that by clicking a ribbon button on an existing CRM record, a new “create form” would open up that fills in all the values from the previous record.

There are couple of useful blogs out there that demonstrate how you can achieve this:

Clone Record From JavaScript

Clone Record Via JavaScript CRM 2011

However, either they need a self referencing relationship or they create a new record on the click of a ribbon button. My requirement was not to save the data already. If a user chose not to save the record, so be it. I tried to open a blank form from an existing record using parameters passed to Xrm.Utility.openEntityForm(“account”, null, params).

The problem? When the querystring grows beyond a certain length, CRM throws an exception. This made me come up with a different approach.

So, here is the concept: Assuming you want to do this on Account entity — go to edit account form, open Form Properties and navigate to Parameters. Add a new parameter and name it “param_copyfromaccountid” and set its type as UniqueId. Save and publish the form.

Add a new JavaScript web resource with the following functions and place it on the account form. Add OnLoad event from the same web resource to your account form.

function SetLocalAttributesFromEntity(entity, attributesToSkip)
{
for (var property in entity)
{
var propertyName = property.toLowerCase();

if (property != "__metadata" && attributesToSkip.indexOf(propertyName) == -1)
{
if (Xrm.Page.getAttribute(propertyName) != null && entity[property] != null)
{
var attributeToSet = Xrm.Page.getAttribute(propertyName);

switch (attributeToSet.getAttributeType())
{
case "optionset":
if (entity[property].Value != null)
{
attributeToSet.setValue(entity[property].Value);
}

break;

case "money":
if (entity[property].Value != null)
{
attributeToSet.setValue(Number(entity[property].Value));
}

break;

case "decimal":
case "double":
if (entity[property] != null)
{
attributeToSet.setValue(Number(entity[property]));
}

break;

case "datetime":
if (entity[property] != null)
{
attributeToSet.setValue(new Date(parseInt(entity[property].substr(6))));
}

break;

case "lookup":
if (entity[property].Id != null)
{
var lookupValue = [];
lookupValue[0] = {};
lookupValue[0].id = entity[property].Id;
lookupValue[0].entityType = entity[property].LogicalName;
lookupValue[0].name = entity[property].Name;

attributeToSet.setValue(lookupValue);
}

break;

default:
Xrm.Page.getAttribute(propertyName).setValue(entity[property]);
}
}
}
}
}

function account_Onload()
{
if (Xrm.Page.ui.getFormType() == 1)
{
var queryParams = Xrm.Page.context.getQueryStringParameters();
var parentAccountId = queryParams["param_copyfromaccountid"];

if (parentAccountId != null)
{
// get parent account using CRM REST Kit helper
// http://crmrestkit.codeplex.com/

var entityName = "Account";
var columns = new Array("*");

var parentOrder = CrmRestKit.Retrieve(entityName, parentAccountId, columns);

var columnsToSkip = new Array("statecode", "statuscode", "name",
 "accountnumber", "address1_addressid", "primarycontactid");

SetLocalAttributesFromEntity(parentOrder, columnsToSkip);
}
}
}

function CloneButtonClicked()
{
var params = {};

params["param_copyfromaccountid"] = Xrm.Page.data.entity.getId().substring(1, 37);

Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(), null, params);
}

Add a new ribbon button, “Clone,” and set its Action to call CloneButtonClicked from the web resource that you created above. Make sure to Save and Publish All.

Hope this helps. Also, please let me know in the comments if you come across a better way to do this, or if it can be improved upon.

2 Responses to “Clone/Copy Existing Record Using JavaScript”

  • carmenza says:

    ok

  • Bubba Mcneel says:

    What am I looking for ?

Leave a Comment