by Gustaf Westerlund | Sep 13, 2007
Using isv.config customizations you can add buttons to the menybar above a grid (next to “More Actions”). A special technique has to be used to fetch the selected records and Ronald Lemmen wrote some about it this summer, here: http://ronaldlemmen.blogspot.com/2007/06/fetching-selected-records-in-grid.html . I had reason to try it and ran into problems when the url of the file containing the javascript was on a different server (different tcp-port has the same characteristics as a different server from an IE viewpoint). The window.dialogArguments was null. I tried to modify the settings in IE but found no way of getting around the problem except for setting up a virtual directory bellow the CRM-site containing the html-file.
So, if you run into similar problems, try moving the html-file to a directory on the same server (from an IE standpoint).
Gustaf
by Gustaf Westerlund | Sep 7, 2007
Developing CRM solutions that are environment independent is not trivial. By just adding a webservice you are making your code dependant on the CRM customization of that system. If you move the solution/dll:s to another system you will be running a risk of your code not working. This is especially problematic for ISVs since they never know what system their product will be installed on. However, there is a good way to handle it. The best way is to first use a plain out-of-the-box CRM system and use the program
C:Program FilesMicrosoft Visual Studio .NET 2003SDKv1.1Binwsdl /out:c:tempmyCRMProxyClass.cs http://localhost:5555/mscrmservices/2006/crmservice.asmx?wsdl
This will create a file called myCRMProxyClass.cs is c:temp.
Add this to your project. This is in essence the same this as adding a web reference and adding “using CRMSDK” or whatever you named it. Hence you can access all the CRM webservice classes.
Then create the service-instance and set the url by using the registry-key added during the installation of Microsoft CRM. Have a look here if you want to know how. http://ronaldlemmen.blogspot.com/2007/08/creating-environment-independent.html
If you have other environment specific data, it should be placed in the web.config / appsettings (if using a normal web-site/virtual directory) or you can use the AssemblySettings.dll (has to be downloaded, not from Microsoft) to create a assembly specific config-file, alternatively, add you own keys to the registry.
I hope I have given you a few hints on how this is done. Happy coding!
Gustaf
by Gustaf Westerlund | Sep 7, 2007
Workflows are a great tool. They are quite simple to create, even non-programmers can actually create them and they are flexible. However, there are some problems with workflows in CRM 3 (how workflows are handled in Titan/CRM 4 will be interesting to see) for instance, a workflow cannot be activated when an entity is updated, only when it is created, when it changes status, when it changes owner and of course, manually.
Mitch Milam has written an interesting post on his blog concerning how to activate a workflow using javascript. You can read about it here: http://blogs.infinite-x.net/2007/06/15/launching-a-workflow-rule-from-javascript/.
A bit of caution is however advised. I would actually prefer to have the workflow being activated by a PostUpdate-callout instead, to make sure that it is only run once. Activating a workflow on the on-change event can be a bit hazardous since it is very possible that the event is triggered several times on the same form before it has been saved.
Never the less, it is a good posting and can probably give you an idea or two about how to programmatically activate CRM workflows. If I wasn’t block from using my own virtual directory or website with my own aspx-files, I would also prefer to trigger the workflow from an aspx-page and call the aspx-page using AJAX. Have a look at the class ExecuteWFProcessRequest in the CRMSDK as it enables you to execute a workflow using the web service.
Gustaf
by Gustaf Westerlund | Sep 5, 2007
SQL Reporting Services is a great tool. It allows you to create flexible and exportable (to pdf etc) reports. However, things sometimes get a bit complicated and a normal problem that you face is the problem of columns containing null-values that you want to use for calculations. For this there is a nice function called COALESCE which replaces null with the value directed.
For example:
SELECT firstname, lastname, age FROM contacts;
Might return the list:
firstname lastname age
John Smith 5
Peter Jacks null
If you want to use the age-column to do some calculations or you just don’t want it to be null, just change your SELECT-statement to:
SELECT firstname, lastname, COALESCE(age, 0) As NewAge, COALESCE(age, 0) * 2 As DoubleAge FROM contacts;
This will give you the result:
firstname lastname NewAge DoubleAge
John Smith 5 10
Peter Jacks 0 0
A useful and simple functions, to get you out of some nasty trouble when doing for instance LEFT OUTER JOIN, RIGHT OUTER JOIN or FULL OUTER JOIN when the risk of returning null is great.
Gustaf
Humandata AB
by Gustaf Westerlund | Sep 1, 2007
Since we’re on the subject of javascript I might as well add some more stuff. First of all, how to define you own functions, then how to programmatically bind a function to an event, for instance, onchange of a field.
This mainly concerns Microsoft CRM but the technique can also be used in SharePoint, although javascripts aren’t as common.
First off, how to define a function.
There are actually several different ways, for instance the normal:
function myfunc1(param1, param2)
{
alert(“myfunc1”);
}
And the one with a weird sort of syntax:
var myfunc2 = function(param1, param2)
{
alert(“myfunc2”);
}
In CRM 3, these can actually be defined within the onLoad, hence creating some ways of code reuse. These functions will be available for all event in the page since they have been declared in the onload.
This leads me to another point, that a function has to be defined before it can be used. Hence, in the example above, myfunc2 can call myfunc1, but not the other way around. If you try, you will get strange error messages saying stuff like “null is not ‘null'”.
Secondly, you can bind events to functions using code. There are several ways of doing this as well (what did you think!?) and they mainly differ based on which browser you are using. If you want to read some more on the subject, if you want some more info on event binding in javascript, please have a look at this very instructive page: http://developer.apple.com/internet/webcontent/eventmodels.html
First the simple method by just setting the onchange attribute.
crmForm.all.ext_myfield.onchange = myfunc2;
or
document.getElementById(“objectid”).onchange = myfunc2;
This has the advantage of a quite simple syntax and, if you want it, the override of previous events.
The second way of doing this is using the attachEvent method. As far as I’ve read, there are some differences with syntax between browsers, but since neither MS CRM nor SharePoint work in any acceptable way in anything but IE, this is not a big issue. Here is some example syntax:
crmForm.all.ext_myfield.attachEvent(“onchange”, myfunc2);
or
document.getElementById(“objectid”).attachEvent(“onchange”, myfunc2);
The main advantage of this method is that you can attach several functions to one event, hence, not overriding other handling.
Bellow is an example html-file which demonstrates this:
<html
xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<script
type=”text/javascript”>
var myfunc1 = function()
{
alert(“myfunc1”);
}
var myfunc2 = function()
{
alert(“myfunc2”);
}
var loading = function()
{
alert(“running”);
document.getElementById(“btTest”).attachEvent(“onclick”, myfunc1);
document.getElementById(“btTest”).attachEvent(“onclick”, myfunc2);
}
</script>
</head>
<body
onload=”loading();”>
<button
id=”btTest”>Click me</button>
</body>
</html>
If you copy this to a file called test.htm and test it, you will see that when clicking the button, myfunc2 will be executed first and then myfunc1.
So, all put together, this can be used to a great extent in MS CRM 3, where you can now put all code in one place, the onLoad script, define some functions and then bind the onchange event of all the attributes you like in the same code. Remember to define the functions before you attach the events.
I havn’t seen CRM 4 / Titan yet, and I don’t know what features it will have in this aspect, but if it includes the feature to be able to add a global javascript file that will be included on all pages, this would be very very useful when using techniques like this.
And remember, javascript is an ugly beast, but it is very useful! J
Gustaf Westerlund
Humandata AB
Recent Comments