Friday, November 20, 2009

Enforcing Leaf Node Selection in Select Subject Dialogue Box

Alright... it's been a while, I was planning something major and had to stop blogging, anyways now I am back[Hopefully with a bang] and here is a first scriptlet on CRM.

Recently one of my colleague was facing an issue with Subject Lookup dialogue box. The requirement was to enable selection of only leaf-nodes i.e. any node with a child node should not be selected as a Subject. After little R&D I came up with the following

Edit : \CRMWeb\_controls\lookup\lookupsubject.aspx
In function applyChange
just below the following statement
if currentSubject != ""
{
put this script…
try{
if(document.getElementById(currentSubject.Id).parentNode.parentNode.attributes['isExpanded'])
{
alert('saaary.. saary meri vajah se hai..');
return;
}
}
catch(e)
{
alert('Error in sadu logic of leaf node selection.' + e.message);
}

I was in strange mood so I've put some garbage text in messages, basically first message box notifies end user when S/He tries to select a non-leaf node and the second message box says there was some error with the script.

Seriously, I love CRM and the endless possibilities of unsupported customizations. :) I hope you got the message ... to make it clear, this is unsupported customization and if you end up with a dead fish please DO NOT blame me.

Sunday, July 19, 2009

CRM 4.0 Hide the date part of a DateTime field

So this is pretty easy but rare to face scenario. If you check DateTime field's format options, it says Date Only and Date And Time. But what if I want to have Time Only? This is what some one asked recently, and I thought, let me give this one a try. Again, unsupported and all that blah blah blah goes here, just get over with it and get to the good part.

function HidDatePart(targetFieldName)
{
crmForm.all[targetFieldName]DataValue = new Date();
document.getElementById(targetFieldName).childNodes[0].childNodes[0].style.display = "none";
document.getElementById(targetFieldName).childNodes[0].childNodes[1].style.display = "none";
}

just pass the targetFieldName parameter and you are good to go.

Remember you can't remove the date field using DOM operation, as it will start giving you errors.. Also by default time field is disabled, to enable it, it is necessary to add some value in Date Field.

Let me know if you need more help with this.

Removing Activities after entity has been created in CRM 4.0

Recently, I've started working on CRM bit seriously. Basically, my areas of interest includes .Net and DHTML and lot many other technologies. But CRM was never there in my list till last January. After taking a long break [Trust me anything beyond few hours away from computers, is LONG for me], in January, I realized, that I needed to give it a shot and since then the journey has been AWESOME!!! And here one of the problem I solved recently while helping out someone. If you have worked with CRM, you know how it makes your life really interesting some times. Like you can not disable the relationship between a custom made entity and notes/activities once you have created it. I am damn sure, it was some pressing dead line or/and regression testing would have shown some strange behavior on removal of the same so dev team might have decided to lock it permanently once it is created. And as usual sometimes you might wanna get rid of Activities from your custom relationship as a result of design change or maybe just for a challenge... in that case... here is a hack that might come handy. Only limitation is you will have to delete the entity and then recreate it after a few changes in the customization xml. So if you have any existing data, this is not what you should be doing[You should be looking for the guy or gal who designed your solution right?].

Standard ToCs applies and... yes.. you get me right... if something goes wrong I DO NOT Take any responsibility of any kind of damage that might occur due to this little hack.

Here is what I did to remove activities from my custom entity.
- Export the customization.
- Extract and open the customization xml.
- Open the xml file in Visual Studio or any other xml/text editor of your choice.
- Change
<HasRelatedActivities>True</HasRelatedActivities>
to
<HasRelatedActivities>False</HasRelatedActivities>
- Remove
<EntityMask>ActivityPointer</EntityMask>
- Remove ActivityPointerRegardingName from <DisplayMaskElement>
- Remove following <EntityRelationship> elements.
- _ActivityPointers
- _Appointments
- _Emails
- _Faxes
- _Letters
- _PhoneCalls
- _ServiceAppointments
- _Tasks

- Save the xml file.
- Import and publish the customization xml file.

Let me know how it goes, as I would love to hear whether it worked for you or not.

Monday, June 29, 2009

Adding a Custom Button to Advanced Find in CRM 4.0

Have you ever observed how powerful Advanced Find dialogue can be in the right hands? Well apart from looking at the customized result set and providing total control to filter the data Advanced Find can be used for some really cool tricks. Recently, I had to face a situation where I needed to turn Advanced Find into some bit simpler find by removing some functionalist and by adding a simple button on the Grid Toolbar.

I managed it somehow in few hours and thought to share it with you, just in case you also fall in the same trap some day. So here it goes, just note that, modifying Advanced Find is NOT at all supported and I DO NOT take any responsibility what so ever if you follow the steps I've mentioned below and end up with any kind of damage[mental\physical\financial\social\...].

Here are steps to add a button to advanced find window
1. Go to CRM Installation directory and navigate to \CRMWeb\AdvancedFind\. Mostly you will have to go to C:\Program Files\Microsoft Dynamics CRM\CRMWeb\AdvancedFind.
2. Take a back up of AdvFind.aspx.
3. Open AdvFind.aspx in any text editor. [Visual Studio is recommended though].
4. locate the first </form> tag.
5. Copy-paste the following line : <input type="button" onclick="Alert('Hey!!!... I am in Advanced Find Window...')" value="Click Me!!!" />
6. Save and Close the file.
7. Go to CRM and click on Advanced Find... Dialogue. You will see a long ugly button on top. Click on it to see the message.
This is a simple approach I've followed. There can be tons of things you can do. You can skin it to look like the real CRM buttons and then replace the alert message with some really useful and complex logic.

Anyways, I took it little further and added the following script and removed the button from the previous step.

<script language="javascript" type="text/javascript">
function DoIt() {
var template = document.getElementById("btnEditProperties");
var newNode = document.createElement(template.tagName);
newNode.setAttribute("class", "ms-crm-Menu");
newNode.setAttribute("tabIndex", "-1");
newNode.setAttribute("title", "Visit Metrix...");
var magic = "<SPAN class=ms-crm-Menu-Label><A class=ms-crm-Menu-Label tabIndex=-1 onclick='return false;' href='javascript:onclick();' target=_self><IMG class=ms-crm-Menu-ButtonFirst tabIndex=-1 alt='Visit Metrix....' src='/_imgs/vieweditor/16_viewProps.gif'><SPAN class=ms-crm-MenuItem-TextRTL tabIndex=0>http:\\\\
metrix.blogspot.com</SPAN></A></SPAN>";
newNode.insertAdjacentHTML("afterBegin", magic);
template.parentNode.appendChild(newNode);
}
DoIt();
</script>

and I got this :

Also you might want to add a little delay in the execution of the script by using window.setTimeout method otherwise it will give error in case the grid is not loaded by the time script is called.

Monday, June 22, 2009

Hide Elements on OnLoad in CRM 4.0/CRM 3.0

I know it is pretty simple to do but I see there are posts popping up here and there for the same. So here it is, a very simple script to hide form elements in CRM during page load. You can call the function from any where any time once you have put it on OnLoad event of the page.

document.HideElement = function(elementId) {
if (document.getElementById(elementId))
document.getElementById(elementId).style.display = 'none';
}

And here how you can use this function to hide various elements when CRM form loads

document.HideElement("_MBcrmFormSave"); // Hides Save button
document.HideElement("_MBcrmFormSaveAndClose"); // Hides Save And Close button

to hide an element say for example : AccountValue, following will be the code snippet

document.HideElement("skynet_AccountValue_c");
document.HideElement("skynet_AccountValue_d");
document.HideElement("skynet_AccountValue");

Wednesday, June 17, 2009

Will The Real GAC Folder Structure Please Show Up?

Just in case the above mentioned blogpost is gone, here is the command to 'mount' GAC as a drive.
subst x: "c:\windows\assembly\gac"
It solves the universal problem for the developers who wants to dissemble .net assemblies which are registered in GAC. Enjoy!!!

Tuesday, June 16, 2009

Disable Page Close Confirmation in CRM 4.0

If you have worked with CRM, then you must have observed an annoying popup message whenever you try to close a form once you have made any changes to it. In certain cases, you might like to avoid showing that dialogue. In one of the recent engagements, I had to change some values on the form when it loads but then users started complaining that even if they don't change anything they are presented with the dialogue box asking to save the record. And then what I had to put a crmForm.Save(); statement after I've changed the values[That's lame I know...]. However, I stumbled upon on this unsupported and undocumented function that helps you get rid of that irritating popup. Use it wisely and you will be good to go :

crmForm.detachCloseAlert()

Wednesday, June 03, 2009

Scrolling Announcements on Home Page for CRM 4.0

Lately, I've started looking into problems people face when dealing with CRM. Well it is a part of my job and provides me a great learning opportunity.

A day or two before I got this requirement : The end user wanted to scroll Announcements[CRM entity : newsarticle] on top of home page. I made a simple script which can be used. This one fetches all Announcements so you might want to set some filters like expiry date or active on date.

Here are the steps to scroll announcement on CRM Home page. Kindly note that I do not take any responsibility if something goes wrong with this approach.
1. Go to CRMWeb\_root\ and take backup of bar_top.aspx and keep it safe somewhere. In case things goes wrong, you will need it to restore things back.
2. Open bar_top.aspx in Visual Studio
3. Add the following code snippet at the end of the file.

<!-- SCRIPT BEGIN : Scroll Announcements -->

<script type="text/javascript" language="javascript">
window.attachEvent('onload', ScrollAnnouncement);

function ScrollAnnouncement() {
var xml = "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"
http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
+ GenerateAuthenticationHeader()
+
" <soap:Body>" +
" <Execute xmlns=\"
http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <Request xsi:type=\"RetrieveMultipleRequest\" ReturnDynamicEntities=\"true\">" +
" <Query xmlns:q1=\"
http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" +
" <q1:EntityName>businessunitnewsarticle</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>articletitle</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Distinct>false</q1:Distinct>" +
" </Query>" +
" </Request>" +
" </Execute>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");

xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction", "
http://schemas.microsoft.com/crm/2007/WebServices/Execute");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);

var resultXml = xmlHttpRequest.responseXML;

var entityNode = resultXml.selectNodes("//BusinessEntities")[0];
var marqueeHTML = "<marquee class='ms-crm-MastHead-SignIn-User'>";
for (var i = 0; i < entityNode.childNodes.length; i++) {
if (i == 0) {
marqueeHTML += entityNode.childNodes[i].childNodes[0].childNodes[0].text
} else {
marqueeHTML += "&nbsp; &nbsp; " + entityNode.childNodes[i].childNodes[0].childNodes[0].text;
}
}
marqueeHTML += "<marquee>";

var headerTD = document.getElementById("tdLogoMastHeadBar");
headerTD.innerHTML += marqueeHTML;
}
</script>

<!-- SCRIPT END : Scroll Announcements -->


4. Check on home page.
You will see a scrolling marquee of the announcements title on CRM Header.

Monday, June 01, 2009

Hiding Menu Items from top menu bar in CRM 4.0

Here is a little script which you can call to hide menu item from top menu.
Put this script on page load or on any other event where you would like it.
You might also wanna add it as document.HideMenuItem = new function(targetMenu, targetMenuItem) {//code goes here};

function HideMenuItem(targetMenu, targetMenuItem) {
var menuLIs = document.getElementById("mnuBar1").getElementsByTagName("LI");
for (var i = 0; i < menuLIs.length; i++) {
if (menuLIs[i].title && menuLIs[i].title.indexOf(targetMenu) > -1) {
var targetDivs = menuLIs[i].getElementsByTagName("DIV");
for (var j = 0; j < targetDivs.length; j++) {
var targetLIs = targetDivs[j].getElementsByTagName("LI");
for (var k = 0; k < targetLIs.length; k++) {
if (targetLIs[k].innerHTML.indexOf(targetMenuItem) > -1) {
targetLIs[k].style.display = "none";
return;
}
}
}
}
}
}

All you have to do is call it with two parameters first parameter is the text without space so if you have root menu named Sub Test, you should call it SubTest. And the second parameter is the whole text of the menu item you need to hide.

HideMenuItem("ISV.NEW", "Coming Soon...");
HideMenuItem("SubTest", "Test Sub 1");
HideMenuItem("ISV.NEW", "Web Only");

Let me know if you need any more info on the same.
PS: Thanks to Andrew, there was a bug in the previous version of script, which didn't work with all the menus but now it has been fixed.

Friday, May 29, 2009

Hiding Notes Section from Notes tab from CRM Form

If you hit this post, then most probably you were looking to hide Notes Section/Notes Tab. However there is a CRM limitation of having only 8 tabs per form[It can be overridden though].
So sometimes you might want to use that notorious Notes tab but then you don't want users to see Notes field in there.
So here is a one line of code which takes care of it. Just copy paste it on the Form Load of your entity form and it should do the rest
document.getElementById("notescontrol_d").parentNode.parentNode.parentNode.parentNode.style.display
= "none";

Thursday, May 28, 2009

Removing System Locked Section from CRM Form

This is one interesting and as usual unsupported solution that will help you to remove a system locked section from CRM form. Kindly note that I do not take any responsibility if something goes wrong with this approach.

Please take backup of your customization before you try this. Here is a step by step guide to remove a system locked section.

1. Export Service Appointment entity.[Take a backup of the zip file you just exported].
2. Extract content of the zip file -> customization.xml.
3. Open the xml in your favourite xml editor. You can use Notepad or Visual Studio to keep it simple.
4. locate the following section "scheduling information"
<section name="scheduling information" showlabel="true" showbar="true" locklevel="1" id="<GUID>" IsUserDefined="0" layout="varwidth" columns="11">change locklevel 1 to 0.
5. Once you have done it, import the customization back to CRM.
6. Open the Form.
7. Move Start Time and End Time to a choice of your section. You can Duration and All Day Event as well.
8. Remove the section.
9. Preview and Test.

In case things do not work as expected, use the backup and restore the entity.

Tuesday, March 03, 2009

Dependent Picklist for CRM 4.0

It's been a while since I posted anything on this blog and there are good reasons for that. Lately I've been quite busy with an integration project which involves a WCF Proxy and a lot of troubleshooting here and there. It's definitely fun but then I don't get time nor I've energy to do anything once I am home.

Anyways today I could steal some time 'cause of a request to share the code of Dynamic or chained Picklists in CRM 4.0 There is not much rocket science in here just easy to use scriptlets and pure DHTML fun.

I have uploaded it here : https://cid-b6a90e5b5092759c.skydrive.live.com/self.aspx/BlogStore/Chained%20Picklists.zip

The zip has the script file and a helper excel that will make it easier for you to create the Picklist arrays.

If you give it a try kindly let me know how it goes for you.

Monday, January 19, 2009

Dirty Fox... heading the risky business apps list

Ah... I thought I will give company to Mrinal.. and here it is.. a link to the article... check it out ... http://www.insidetech.com/news/articles/3605-firefox-heads-risky-business-app-list oh.. hi.. L(inux)users... where are yo?

VS2008SP1 on Win7

As you all know.. Win7 is out.. and my god it is.. faster beyond my expectations.. and definitely.. faster than my XPSP3(Oh I was so proud... about it :(). And just yesterday, I installed VS2008 SP1 on it nad it works like a charm.. not a single glitch in compiling my existing code and on top of that it looks better than Vista. It has got soft UI elements and somehow.. I felt really comfortable working with them when compared to Vista. Check out the sample running a demo WPF application.

And no matter... what they are saying, it was piece of cake to install VS2008 it took less than 10 minutes and YES I don't want to talk about how long it took to install SP1(I was running some heavy processes in background.. eh.. :P)

Sunday, January 18, 2009

Microsoft .NET Framework 2.0 Service Pack 2

Link:
Download Overview:
The .NET Framework 2.0 Service Pack 2 provides cumulative roll-up updates for customer reported issues found after the release of the .NET Framework 2.0. In addition, this release provides performance improvements, and prerequisite feature support for the .NET Framework 3.5 Service Pack 1.

Please review the supported operating systems for this deployment package in the System Requirements section. The corresponding updates for Windows Vista and Microsoft Windows 2008 are deployed via the full .NET Framework 3.5 service pack 1.
Just be careful, there is a follow up update patch - KB959209 needed, once you install .Net Framework 2.0 SP2.

Saturday, January 17, 2009