22 Ocak 2011 Cumartesi

CRM 4.0 Enhancing Picklists presentation layer




Picklists are usually used to provide a short range of predefined options that further describe our data. To make them usable it?s suggestible to keep the number of Picklist options to a minimum. Although a Picklist presentation layer is functional data is not always that boring and deserves a better re-presentation.

I personally think that controls should convey more emotions and strengthen bond between what is showing and how it?s shown. Take for example a simple Picklist that has values 1-5 that describe the account rating or a Picklist of shipping methods with well known company names. No doubt presenting the following control to the user makes more sense than just selecting a number.



The concept used in this example can be developed further to support more advanced scenarios. The nice thing about it is that most of the bits that handle the actual show and hide of the Picklist menu can be reused. So if you find yourself needing to create a more complex Picklist you should center most of your effort by overriding the buildPopup function (see code).

The code exposes most of the styling attributes which means you don?t have to tear it apart if you feel like redecorating ;+).



In order to facilitate the construction of options and their respective images the code uses a simple technique that accepts an Image base URL and utilizes the picklist id to identify specific images folder. The image names represent their index i.e. 0.gif, 1.gif, 2.gif and so on. If need to use option?s value instead you must also change the code that constructs the image URL.


CRMWeb
| -- ISV
|-- IMGPL (this is the ImageBaseUrl)
|-- selected.gif (A small arrow that points to the selected option)
|-- gi_rating (This is the Picklist id)
|-- 0.gif (Empty option X image ? index 0)
|-- 1.gif (first option ? index 1)
|-- 2.gif (second option ? index 2 and so on..,)


Eventually the image URL is http://servername:port/iSV/IMGPL/gi_rating/1.gif
Feel free to comment.



String.prototype.Format = function( args )
{
return this.replace( /\{(\d{1})\}/ig , function match(){return args[arguments[1]];});
}

function ImagePicklist(picklistId)
{
var ipl = this;

if (!(ipl.Picklist = crmForm.all[picklistId]))
return alert("Picklist is missing");

if (ipl.Picklist.Disabled)
return;

ipl.ImageBaseUrl = "/ISV/IMGPL/";
ipl.HoverStyle = {Color: "#FFFFFF",Background: "#000000"}
ipl.HasEmptyOption = true;
ipl.Height = 213;
ipl.BackgroundColor = "#FFFFFF";
ipl.Scroll = true;

ipl.Picklist.ondblclick = function(){show();}
ipl.Picklist.onmousedown = function(){show();}
ipl.Picklist.onfocusout = function()
{
ipl.Picklist.Popup.document.body.innerHTML = "";
ipl.Picklist.Popup.hide();
}

function show()
{
ipl.Picklist.Disabled = true;
buildPopup();
var left = ipl.Picklist.Position.X;
var top = ipl.Picklist.Position.Y;
var width = ipl.Picklist.offsetWidth;
var height = ipl.Height
ipl.Picklist.Popup.show(left ,top ,width ,ipl.Height ,document.body);
setTimeout(function(){ipl.Picklist.Disabled = false;},100);
return false;
}

ipl.MouseOver = function(option)
{
option.style.backgroundColor = ipl.HoverStyle.Background;
option.style.color = ipl.HoverStyle.Color;
}

ipl.MouseOut = function(option)
{
option.style.backgroundColor = ipl.BackgroundColor;
option.style.color = "#000000";
}

ipl.Onclick = function(option)
{
ipl.Picklist.onfocusout();
ipl.Picklist.selectedIndex = option.index
ipl.Picklist.focus();
}

function getPosition(control)
{
var left = 0;
var top = control.offsetHeight;

do {
left += control.offsetLeft;
top += control.offsetTop;
} while (control = control.offsetParent);

return {X:left,Y:top}
}

function buildPopup()
{
ipl.Picklist.Position = getPosition(ipl.Picklist);
ipl.Picklist.Popup.document.body.style.backgroundColor = ipl.BackgroundColor;

var div = document.createElement("DIV");
div.style.cssText = "overflow-y:{0};height:{1}px;".Format([(ipl.Scroll?"scroll":"hidden"),(ipl.Height-13)]);

for (var i=(ipl.HasEmptyOption?0:1);i< ipl.Picklist.options.length;i++)
{
var option = ipl.Picklist.options[i];

var item = document.createElement("DIV");
item.index = i;
item.onmouseover = "document.ImagePicklist.MouseOver(this);";
item.onmouseout = "document.ImagePicklist.MouseOut(this)";
item.onclick = "document.ImagePicklist.Onclick(this)";
item.title = "Value = {0}".Format([option.value]);
item.style.lineHeight = "25px"
item.style.cursor = "hand";

var selItem = null;
if (option.selected)
{
selItem = document.createElement("IMG");
selItem.style.height = "16px";
selItem.style.width = "16px";
selItem.src = "{0}selected.gif".Format([ipl.ImageBaseUrl]);
selItem.align = "middle";
}
else
{
selItem = document.createElement("SPAN");
selItem.innerHTML = " ";
selItem.style.width = "16px";
}

item.appendChild(selItem);
item.appendChild(document.createTextNode(" "));

var img = document.createElement("IMG");
img.src = "{0}{1}/{2}.gif".Format([ipl.ImageBaseUrl,ipl.Picklist.id,i]);

item.appendChild(img);
var optText = null;
if (option.selected)
{
optText = document.createElement("B");
optText.innerText = " {0}".Format([option.innerText]);
}
else
{
optText = document.createTextNode(" {0}".Format([option.innerText]));
}
item.appendChild(optText);
div.appendChild(item);
}

ipl.Picklist.Popup.document.body.innerHTML = div.outerHTML;
}

{ //Initialize

ipl.Picklist.Popup = window.createPopup();
/* A reference from the window popup to ipl */
ipl.Picklist.Popup.document.ImagePicklist = ipl;

var popUpBodyStyle = ipl.Picklist.Popup.document.body.style;
popUpBodyStyle.border = "1px solid gray";
popUpBodyStyle.padding = 0;
popUpBodyStyle.margin = 5;
}
}

function OnCrmPageLoad()
{

window.ctcPicklist = new ImagePicklist("customertypecode");
ctcPicklist.ImageBaseUrl = "/ISV/IMGPL/";
ctcPicklist.HoverStyle = {Color: "gold",Background: "#FF3454"}
ctcPicklist.HasEmptyOption = false;

window.accPicklist = new ImagePicklist("accountcategorycode");
accPicklist.Height = 85;
accPicklist.Scroll = false;
accPicklist.BackgroundColor = "yellow";

window.graPicklist = new ImagePicklist("gi_rating");
graPicklist.Height = 165;
graPicklist.Scroll = false;
graPicklist.HoverStyle = {Color: "navy",Background: "#FFFFFF"}
}

OnCrmPageLoad();



online contact management |ms crm training |superoffice crm |dynamics ax |banking crm |

The choice of long distance Bluetooth Pocket PC.

Building a system which can communicate between Bluetooth enabled PPC and a Bluetooth enabled Server. The system requires a long communicate distance, but can't use WIFI. The server is 100 meters Bluetooth dongle which is long enough. However I haven't see any Pocket PC with 100 meters Bluetooth distance! After research, I found there are two choices to get this aim.

The first, setup a Bluetooth Access Point to extend the PPC's Bluetooth distance. By this way, the PPC and BAP connect via Bluetooth, all the information between PPC and Server will be routered by the BAP. The benefit of this structure is lower cost -Becasue the application will be done by WEB interface. The disadvantage is more response time.

The link here:
http://msmobiles.com/catalog/i.php/563.html


Or

The second, if the PPC supports USB-HOST, then that's a good idea. Many PPC from Toshiba supports USB-HOST, so it may connect a USB cable + 100 meters Bluetooth dongle, that's really cool. Microsoft Mobile 5 can support this USB-HOST as the MS native Bluetooth stack. So it costs more money to buy a latest device with WM5, alternatively upgrade the ROM for HTC Himalaya device is also considerable(http://www.clintonfitch.com/wm5/default.asp). However, the system can be build by WINDOWS interface and faster than the web access.





















These links here:
http://www.pocketpcthoughts.com/forums/viewtopic.php?p=367986&sid=d29669233fa83304bf99e115c42e588b
http://discussion.brighthand.com/showthread.php?s=&threadid=104328
http://www.johncruise.com/pocketpc/howto-usb-bt.php


crm features |erp |small business crm |healthcare crm |crm lead management |

CRM 4.0 : Check current user's security role using JavaScript

It's a common question about how to show/hide fields based on user's security roles.
Ronald Lemmen had a very popular post on his blog about how to use 'RemoteCommand' to achieve that in CRM 3.0. Because 'RemoteCommand' is for internal use and unsupported, it doesn't work in CRM 4.0.
Michael H?hne also had a great post about how to access web service using client-side JavaScript. Since CRM 4.0 web service EndPoint changed, some people get 401 authorization error.

Here's code which works great in CRM 4.0, the function UserHasRole("ROLE_NAME") returns true if the current has the role, returns false if it doesn't. GetCurrentUserRoles() function generated by Michael H?hne's tool with some changes. Thanks for Regan who point out that using GenerateAuthenticationHeader() instead of hard-coding the Organization's Name.



//check if the current user has the 'System Administrator' role
alert(UserHasRole("System Administrator"));

function UserHasRole(roleName)
{
//get Current User Roles, oXml is an object
var oXml = GetCurrentUserRoles();
if(oXml != null)
{
//select the node text
var roles = oXml.selectNodes("//BusinessEntity/q1:name");
if(roles != null)
{
for( i = 0; i < roles.length; i++)
{
if(roles[i].text == roleName)
{
//return true if user has this role
return true;
}
}
}
}
//otherwise return false
return false;
}

function GetCurrentUserRoles()
{
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>" +
" <RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" +
" <q1:EntityName>role</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>name</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Distinct>false</q1:Distinct>" +
" <q1:LinkEntities>" +
" <q1:LinkEntity>" +
" <q1:LinkFromAttributeName>roleid</q1:LinkFromAttributeName>" +
" <q1:LinkFromEntityName>role</q1:LinkFromEntityName>" +
" <q1:LinkToEntityName>systemuserroles</q1:LinkToEntityName>" +
" <q1:LinkToAttributeName>roleid</q1:LinkToAttributeName>" +
" <q1:JoinOperator>Inner</q1:JoinOperator>" +
" <q1:LinkEntities>" +
" <q1:LinkEntity>" +
" <q1:LinkFromAttributeName>systemuserid</q1:LinkFromAttributeName>" +
" <q1:LinkFromEntityName>systemuserroles</q1:LinkFromEntityName>" +
" <q1:LinkToEntityName>systemuser</q1:LinkToEntityName>" +
" <q1:LinkToAttributeName>systemuserid</q1:LinkToAttributeName>" +
" <q1:JoinOperator>Inner</q1:JoinOperator>" +
" <q1:LinkCriteria>" +
" <q1:FilterOperator>And</q1:FilterOperator>" +
" <q1:Conditions>" +
" <q1:Condition>" +
" <q1:AttributeName>systemuserid</q1:AttributeName>" +
" <q1:Operator>EqualUserId</q1:Operator>" +
" </q1:Condition>" +
" </q1:Conditions>" +
" </q1:LinkCriteria>" +
" </q1:LinkEntity>" +
" </q1:LinkEntities>" +
" </q1:LinkEntity>" +
" </q1:LinkEntities>" +
" </query>" +
" </RetrieveMultiple>" +
" </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/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);

var resultXml = xmlHttpRequest.responseXML;
return(resultXml);
}



Due to Bloger's format issue, I have rewrite the code, it should work for everyone now.:)


microsoft crm 3 |small business crm |crm magic quadrant |microsoft business solutions crm |crm tutorial |

A easy way to share files between HOST and VM in Microsoft Virtual Server 2005.

Microsoft Virtual Server 2005 provides the improved performance and functions than Virtual PC. However, for some reasons, it is not easy to share files between HOST and VM in Virtual Server. Generally, we have to setup a VPN access between HOST and VM, but sometimes it's not the best solution.

After some research, I found a easy to share files:
On your HOST, go to "run" "cmd", and type:
"net use X: \\192.168.1.11\C$"
And then login as administrator of VM.

In this case, my HOST IP address is: 192.168.1.2, the VM IP address is: 192.168.1.11, both of them share the same network adaptor and in the same LAN.

After the command, you will found a new "drive X" in your HOST computer.
The drive X is the mapping of the drive C of the VM . Now you may fully control the VM, and share files with it.

Enjoy! ;-)

for more information about Microsoft Virtual Server, please visit: http://www.microsoft.com/windowsserversystem/virtualserver/default.mspx


business crm software |hosted crm solutions |crm examples |call centre |crm software |

BroadTooth - the Bluetooth broadcasting system!

What is BroadTooth?
BroadTooth is the Bluetooth broadcasting system provided by LondonDev Limited.


What is BroadTooth marketing solution?

This innovative BroadTooth marketing solution uses standard Bluetooth technology with our own message management software. This enables you to send multiple advertisements and messages to passing phones and review the success of the broadcast in real time.

  • BroadTooth technology simply delivers your sales message into the hand of potential customers. Imagine the potential of your sales messages appearing on the phones & PDA's of passers-by who permit transmission by pressing the 'receive' button.

  • BroadTooth is the process of sending information with Bluetooth technology. The BroadTooth Software can send multimedia files, graphic advertisements and animated GIF Files to Bluetooth-enabled mobile Phones and PDA's to anyone up to 30 metres way.

  • BroadTooth offers mobile and fixed location use. This flexibility is most useful in high density audience situations. The software can be installed and run from a lap top computer with a Bluetooth dongle.

  • BroadTooth in high density audiences (e.g. sports and music events or mainline rail terminals) offers the ideal opportunity to send over 1000 messages an hour directly. To improve results further, circulating through the crowd provides an even wider audience for your advertisement to be received.

  • BroadTooth can transmit from any location near a source of potential customers. Retail opportunities for this form of 'proximity marketing' are almost limitless, including sales messages for in store offers, messaging to passing pedestrians and drivers of the 'offer of the day' or the teaser-ad approach to brand building. Other possibilities include catering, offices, transport, public information and all forms of sports & leisure events, concerts, public and trade exhibitions, and strategic corporate and shopping centre applications.

  • BroadTooth from multiple locations can be managed from a single location via a LAN, using different messages and campaign formats and timings, facilitating continuous test-marketing and immediate response to local market factors.

What is BroadTooth supported device?
BroadTooth software can send your customised message to all the Bluetooth-enabled mobile Phones and PDAs. The object system could be all the major mobile systems in the market: Symbian, Microsoft Windows Mobile, Palm, Linux etc. These almost include 95% mobile systems in the market.

What can I do next?
Please contact us for more information.




crm |crm features |microsoft crm partner |sales crm |free crm |

How to allow '&' in email address

CRM 3.0 doesn't allow '&' in email address ,however, it's a requirement to make it possible!
The file you need to change is located in: \_forms\controls\INPUT.text.eml.htc,
The idea is change the regular expression for email field:

/*
Allow '&' in email address
Need to edit htc file(HTML Components)
\_forms\controls\INPUT.text.eml.htc
*/
//var _validEmailRegexp = /^\w([-._'\w]*\w)?@\w([-._\w]*\w)?\.\w+$/;
var _validEmailRegexp = /^\w([&-._'\w]*\w)?@\w([-._\w]*\w)?\.\w+$/;



crm software reviews |crm evaluation |healthcare crm |customer relations |online contact management |

CRM 4.0 upgrade: There is already an object named 'AttributeTypes' in the database.

This week I was helping a customer to upgrade their CRM 3.0 system to CRM 4.0.
The upgrade pre-check looks fine with all passed, no errors, no warnings.
But during the upgrade process, it first alert an error regarding C360, then I fix the problem, click the "Retry" button, it then generates another error:

" Microsoft.Crm.Setup.Server.InstallDatabaseAction failed.
System.Data.SqlClient.SqlException: There is already an object named 'AttributeTypes' in the database. "

That's very strange. But finally I found it's a design lack of upgrade process: The 'Retry' doesn't actually do 'Retry'!
So I had to:
1. Stop the upgrade process and uninstall CRM 4.0;
2. Restore CRM 3.0 databases, then install CRM 3.0 with existing databases;
3. Fix the problem which generated the first error;
4. Re-run the CRM 4.0 upgrade.

I did know there are some complains about C360 add-ons stop the CRM upgrade process, these could be the reasons:
1. The C360 uninstall doesn't do a clean uninstall all the time, so you may still see C360 icons on the CRM form, but no function;
2. Some C360 products create tables inside the CRM database which is not a recommended method, and again once you uninstall the product, the tables are still there.
3. C360 has a cleanup tool which does cleanup the remained infomation in the onLoad, onSave, and isv.cofig.xml etc. However, it doesn't cleanup the database. And the tool is hard to find on C360 website.

C360 provides some great add-ons for MSCRM, but we wish it could be better!


act contact management |crm upgrade |crm software features |crm workflow |crm evaluation |