I think that this is a great idea as it allows readers to easily find and engage with people reading the same books and it also provides a way for the author to get involved and to show up at the conversations that their books are provoking.

There seemed to be a couple of issues with this approach though:

How do you find the "official" hashtag for each book? (Assuming that the author/publisher hasn't thought to mention it somewhere in the book)

Twitter search only returns Tweets from the last few days so the tail end of the conversation is soon lost

For those reasons I have created bookhashtags.com. The site acts as a place where readers can come and find the "official" hashtag for their book and also as a place that displays the entire conversation going on around each book hashtag that has been indexed.

What do you think? Is this side conversation a useful addition to your enjoyment of a book? Which books/hashtags would you like to be added? If you have a book/hashtag to add you can add it here.

If you want to change the properties of the data connection that your InfoPath form is using on submit you can do this in code. You might want to do this if you have lots of sites that use the same structure and each site contains a library that holds a certain type of form. Eg. A project site contains a library for project changes that are submitted using an InfoPath form. Each project site has a project changes library but you don't want to have to create a new project change form with a different submit connection for every site.

One of the great new features in SharePoint 2010 is the "My Newsfeed" section of My Site.

This is similar to the wall on Facebook and allows you to see the activities of your colleagues such as comments they are making and items they are tagging.

After installing SharePoint 2010 I added a load of colleagues and then sat back in anticipation of a steady stream of activity but nothing happened. Instead the message, "There are no activities in your newsfeed. Stay connected by adding colleagues and interests." kept on staring back at me.

It turns out there is a timer job that needs to be enabled in order for the news feed to be populated.

When picking a product on a CRM entity like quote product or order product the user also has to pick a unit of measure for the product. Wouldn't it be useful if CRM filled in the unit of measure field for the user based on the default unit for the product? Of course it would, but it doesn't do this out of the box.

My solution for this involves using a generic handler to get the default unit for a specific product and some JavaScript to call the handler asynchronously.

The JavaScript that is placed in the onchange event of the productid field looks like this:

var lookupItem = new Array;

// Get the lookup for the primarycontactid attribute on the account form.

The call to a generic handler in the post Using generic handlers in Dynamics CRM seemed to only be firing once. The alert was being displayed to say that the code had run successfully but I could see that after the first call it wasn't copying the entity as it should have.

It turns out this was because the xmlhttprequest was being cached and the fix was fairly simple. By adding an extra parameter to the url called by the request we can trick it into thinking that a completely new call is being made which prevents the cached result from being used.

Simply add the following to the query string: "bustCache=" + Math.random();

The result of this is that you now have a button on the Quote form called Copy Quote. When this button is clicked the JavaScript calls the .ashx file which copies the quote and then sends a message back to the JavaScript to let the user know if the operation has been successful.

When editing attributes on CRM entities it is often necessary to pass that attribute through to the entity in the next stage in the sales process.

For example you add a contact name to the quote entity and you want that contact to be passed through to the order that is created from the quote.

To do this for standard fields it is simply a case of opening the customisation screen for the entity, adding a new attribute and then adding a new mapping to the relevant relationship. In the case of quotes and orders this would be the N:1 quote to order relationship.

Where things become a little bit trickier is if you want to create a mapping between two entities for an attribute that is a lookup. This is because it is not possible to simply add a lookup field as an attribute.

To do this for the case of the contact lookup being passed from quote to order do the following:

Create a new N:1 relationship on the order entity. The Primary Entity for the realtionship will be Contact.

Give it a display name of Contact and leave all the other fields as default.

Click Save and Close - this will have created a new attribute called Contact which we can now use to map the Quote Contact attribute to.

Edit the Quote to Order 1:N relationship and add a new mapping between Contact in the source and target entities.

Click OK.

Now you can add Contact to the forms and views where it needs to be visible.

This is a blog that is usually about SharePoint and SharePoint development but recently I have been starting to do some work with Microsoft Dynamics CRM 4.0. Initially this work was about integrating SharePoint document libraries with CRM but has now gone beyond that into actual customisation and development of CRM itself.

CRM 4.0 has been around for a while now and many companies who have CRM will also have a SharePoint deployment so although it is a bit off topic I'm sure there are plenty of SharePoint people who will find a bit of CRM information helpful.

As with SharePoint there are lots of options for customising CRM. The first option is customisation of existing entities and forms. This allows you to add attributes to the various objects in CRM such as customers or orders. It is also possible to add JavaScript to the forms to add logic, validation or additional calculations into the forms and this is what this post will take a look at. Finally it is possible to add aspx pages or use ashx handlers in conjunction with the CRM web services to create virtually any extra complex business logic or functionality that is required - later posts will deal with this.

When customising CRM forms it is possible to easily add JavaScript to the on load and on save events of each form or to the on change event of any field.

A few hints and tips:

To reference an attribute on a form use crmForm.all.attributename.

If the attribute is not a string use .DataValue to return the value held in the attribute. e.g. crmForm.all.attributename.DataValue.

DataValue should also be used when creating comparison statements. E.g. if(crmForm.all.isapproved.DataValue == true)

If you have a calculated field that is set to read only on the form then you will need to make sure that it is set to ForceSubmit = true otherwise it will not be saved. To do this use the following - crmForm.all.attributename.ForceSubmit = true;

To hide a field or menu item use crmForm.all.attributname.style.display = "none";

To disable a field use - crmForm.all.attributename.Disabled = false; or use true; to disable the field.

It is possible to set the default for a lookup field. The following example script sets a default price list for the price list field:

if(crmForm.all.pricelevelid.DataValue == null)
{
//Create an array to set as the DataValue for the price list lookup control.
var lookupData = new Array();
//Create an Object add to the array.
var lookupItem= new Object();
//Set the id, typename, and name properties to the object.
lookupItem.id = '{0049EC3B-1257-DF11-8A46-00155D025108}';
lookupItem.typename = 'pricelevel';
lookupItem.name = 'Test Price List';
// Add the object to the array.
lookupData[0] = lookupItem;
// Set the value of the lookup field to the value of the array.
crmForm.all.pricelevelid.DataValue = lookupData;
}

Use the following JavaScript to call CRM web services to return information on the current user - this is then used to set a user lookup field to be the current user:

Using JavaScript is a great way to customise CRM as any script you add is saved as part of the form so when you come to deploy them they are included in the export customisations file. In my customisation of CRM I have tried to use this approach wherever possible but sometimes what you want to achieve cannot be done without cracking open Visual Studio and this is what I plan on taking a look at in my next post.