Clone a record

There are some interesting things in the May 2006 Demo VPC that you might not have seen before. One of them is cloning a record. There's an addon written and supplied with the VPC that does take of cloning a contact. I've used it in some other projects and will be using it in my current project again. Ofcourse you can modify the code to match any entity.

I'll add the code here so that you dont have to download the complete VPC. There will be added a piece of code to the isv.config file and an additional file will need to be placed on the server.

Here is the piece that needs to be added in to the isv.config file:


<configuration version="3.0.0000.0">
<Root />
<Entities>
<Entity name="contact">
<ToolBar ValidForCreate="0" ValidForUpdate="1">
<Button Title="Clone Contact" ToolTip="Create a Copy of This Contact" Icon="/CloneContact/contactclone.gif" Url="/CloneContact/CloneContact.htm" WinMode="1" WinParams="dialogHeight:100px;dialogWidth:300px;"/>
</ToolBar>
</Entity>
</Entities>
</configuration>


This is the code that needs to be stored in the file as indicated in the isv.config file:

<html>
<title>Clone Contact</title>

<style>

BODY, TD
{
font-family: arial;
font-size: 12px;
}

TD.body
{
border-bottom: solid 1px #cccccc;
text-align: center;
}

</style>

<script language="javascript">

// Set global variable for the cloned contact window
var oClonedContact;

function window.onload()
{
// Open a new contact form
oClonedContact = window.open('/sfa/conts/edit.aspx','','menubar=0, status=1, width=1000, height=600');

// Set a timeout to wait for the new contact form to load
setTimeout('checkPageState()',100);
}

// Checks if the new contact form has completed loading
// When it completes, CloneContact will be called
// If it's not loaded, it will set a timeout and check again.
function checkPageState()
{
if (oClonedContact.document.readyState == 'complete')
{
CloneContact();
return;
}

setTimeout('checkPageState()',100);
}

function CloneContact()
{
// Get a pointer to the parent window
var oParent = window.dialogArguments;
var oSource = oParent.document.crmForm;

// With the target crmForm
with(oClonedContact.document.crmForm)
{
// Name fields
salutation.DataValue = oSource.salutation.DataValue;
firstname.DataValue = oSource.firstname.DataValue;
nickname.DataValue = oSource.nickname.DataValue;
lastname.DataValue = oSource.lastname.DataValue;
jobtitle.DataValue = oSource.jobtitle.DataValue;
parentcustomerid.DataValue = oSource.parentcustomerid.DataValue;

telephone1.DataValue = oSource.telephone1.DataValue;
telephone2.DataValue = oSource.telephone2.DataValue;
mobilephone.DataValue = oSource.mobilephone.DataValue;
fax.DataValue = oSource.fax.DataValue;
pager.DataValue = oSource.pager.DataValue;
emailaddress1.DataValue = oSource.emailaddress1.DataValue;

// Address fields
//address1_name.DataValue = oSource.address1_name.DataValue;
address1_line1.DataValue = oSource.address1_line1.DataValue;
address1_line2.DataValue = oSource.address1_line2.DataValue;
address1_line3.DataValue = oSource.address1_line3.DataValue;
address1_city.DataValue = oSource.address1_city.DataValue;
address1_stateorprovince.DataValue = oSource.address1_stateorprovince.DataValue;

address1_postalcode.DataValue = oSource.address1_postalcode.DataValue;
address1_country.DataValue = oSource.address1_country.DataValue;
//address1_telephone1.DataValue = oSource.address1_telephone1.DataValue;
//address1_addresstypecode.DataValue = oSource.address1_addresstypecode.DataValue;
//address1_shippingmethodcode.DataValue = oSource.address1_shippingmethodcode.DataValue;
//address1_freighttermscode.DataValue = oSource.address1_freighttermscode.DataValue;

// Professional Information fields
//department.DataValue = oSource.department.DataValue;
accountrolecode.DataValue = oSource.accountrolecode.DataValue;
managername.DataValue = oSource.managername.DataValue;
managerphone.DataValue = oSource.managerphone.DataValue;

assistantname.DataValue = oSource.assistantname.DataValue;
assistantphone.DataValue = oSource.assistantphone.DataValue;

// Personal Information fields
gendercode.DataValue = oSource.gendercode.DataValue;
familystatuscode.DataValue = oSource.familystatuscode.DataValue;
spousesname.DataValue = oSource.spousesname.DataValue;

all.birthdate.DataValue = oSource.all.birthdate.DataValue;
all.anniversary.DataValue = oSource.all.anniversary.DataValue;

// Description
//description.DataValue = oSource.description.DataValue;

// Internal Information fields
ownerid.DataValue = oSource.ownerid.DataValue;
originatingleadid.DataValue = oSource.originatingleadid.DataValue;

// Billing Information fields
//creditlimit.DataValue = oSource.creditlimit.DataValue;
//all.creditonhold.DataValue = oSource.all.creditonhold.DataValue;
//paymenttermscode.DataValue = oSource.paymenttermscode.DataValue;
//defaultpricelevelid.DataValue = oSource.defaultpricelevelid.DataValue;

// Contact Methods fields
preferredcontactmethodcode.DataValue = oSource.preferredcontactmethodcode.DataValue;
all.donotemail.DataValue = oSource.all.donotemail.DataValue;
all.donotbulkemail.DataValue = oSource.all.donotbulkemail.DataValue;
all.donotphone.DataValue = oSource.all.donotphone.DataValue;
all.donotfax.DataValue = oSource.all.donotfax.DataValue;
all.donotpostalmail.DataValue = oSource.all.donotpostalmail.DataValue;

// Marketing Information fields
all.donotsendmm.DataValue = oSource.all.donotsendmm.DataValue;
all.lastusedincampaign.DataValue = oSource.all.lastusedincampaign.DataValue;

// Service Preferences fields
preferredappointmenttimecode.DataValue = oSource.preferredappointmenttimecode.DataValue;
preferredappointmentdaycode.DataValue = oSource.preferredappointmentdaycode.DataValue;
preferredserviceid.DataValue = oSource.preferredserviceid.DataValue;
preferredequipmentid.DataValue = oSource.preferredequipmentid.DataValue;
preferredsystemuserid.DataValue = oSource.preferredsystemuserid.DataValue;
}

// Finally, close the dialog
window.close();
}

</script>

<body>

<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0" align>
<tr valign="middle">
<td class="body" align="center">
<div style="font-size= 10pt; font-family= Tahoma;">Cloning Contact...</div>
</td>
</tr>
</table>

</body>

</html>


It's just a free addon from Microsoft, so use it if you can :)

18 comments:

Anonymous said...

In de outlook client krijg ik een document error.
'document is leeg of geen object' in de web versie werkt het wel;
gebruikde stadaard clone functi uit cursus 8285

MR

Ronald Lemmen said...

MR,

The error you're getting, is that in the online or offline client? I expect the online client to easily work. The offline client may fail indeed. You'll need to play around a bit to figure out why this fails and how to solve it.

Jaber said...

Hi Ronald
I am trying to use it for the Account entity to clone accounts is it possible with this add-on
Or i need to modify it.
Regards
Jaber

Ronald Lemmen said...

Hi Jaber,

You can use the same approach, but you will need to change the schema names of the attributes to copy. Make sure that you have all the attributes on your screen in the list for the copy.

Kind regards,

Ronald

Aad said...

Hi Ronald,

Ik heb dit script geprobeerd te gebruiken maar krijg telkens de fout dat 'oSource.ticketnumber.DataValue not valid' is. Ik heb de hele regel uit de clonecase.htm gehaald maar hij blijft er toch over struikelen..? Hellup! Aad.van.der.velden@gmail.com

Jeff said...

Worked like a charm. Thanks for posting this.

Mehul512 said...

Hi Roanld,

excellent work, man. Keep it up. By the way is there any alternate method as well to access the parent forms data into child form while calling child form from parent forms toolbar button.

thanks,
MEHUL

Ronald Lemmen said...

Could you please try to explain that again Mehul?

Anonymous said...

Ronald, I'm using an Online version of CRM and when I add the piiece to the isv.config file nothing seams to happen. Is there somthing different when using the online version?

Thanks

Ronald Lemmen said...

Hi Anonymous,

Have you checked if the customizations are enabled? This can be denied in user roles or in the system settings.

Hope this helps,
Ronald

Adam Jewell said...

Mr. Lemmen,
Nice tweak.
Do you think that this might also work for cloning a Quote Product that is already associated with a Quote?
My goal would be to configure the clone functionality to allow users to add a copy of an existing quote product to the quote with the click of a button.

Cheers,
- Adam

Ronald Lemmen said...

Hi Adam,

I don't see a reason why you wouldn't be able to clone a quote product. As long as it is just a single entity which you want to clone you can use this technique. If you want to clone a quote with all related products, then you will need to make something serverside, but if I understand your question correctly, then this is not the case in your situation.

Feel free to post your solution here if you managed to get that working. Maybe somebody else can use that :)

Kind regards,
Ronald

CRM.Mark said...
This comment has been removed by the author.
Anonymous said...

Hi Ronald,
I want to clone an order with all related products, how would I do that with this code, you mentioned something about serverside, what would that code be?

Ronald Lemmen said...

Hi,

If you want to clone a record including associated records, like products, then you'll need to use the crm webservices to do this. Have a look in the crm sdk to find out how to do that. Especially look at the retrieve and create methods, that's what you'll need.

Kind regards,
Ronald

Anonymous said...

Ronald,

There is alot of information in the isv.config file, so where do you place this code (at the top, bottom, where)?

Ronald Lemmen said...

Hi,

The isv.config code is showing the setup of the complete document. The most important thing, is to copy the button line into the isv config file. Once you export the isv.config file, have a look at how this file is set up, what each line means and you'll be able to understand how to place the code snippet.

Kind regards,
Ronald

nav said...

hi i upgraded the crm from 3 to 4 and your clone functionality is not working. i have a html page on click wich takes the name for clone and called a service. after update the button is not doing any thing. isv.config in _resouce dir have no entry for button but i can see the button on tool bar.
thanks