I have been working on quite a lot of small quick posts this last week but I’m also working on some more complex posts to put in the xRM development category.I hope these I’ll find …
Read the full story »This area is mostly about dev related stuff – tips, tricks, code snippets and more
System integration in xRM deployments is a key factor for user adoption – Intelligent integration makes is even more valuable
The Dynamics CRM Developer Group is intended to be the place for Dynamics CRM developers to network, discuss ideas and have fun!
News in the xRM world – and in the Danish xRM community!
Codesnippets and other stuff for download
When working on partner hosted Dynamics CRM deployments it is not possible to deploy assemblies on the server – so the solution does often involve JavaScript.
This solution is based on elements found round and about on different blogs and some ideas of my own.
This solution displays a picture on the account form saved attached to a note (annotation).
First the Fetch sentence to retrieve the annotationid
1: function getAccountLogoAnnotationId() {
2: var fetchXml = '';
3: fetchXml += '<fetch mapping="logical" count="50" version="1.0">';
4: fetchXml += '<entity name="annotation">';
5: fetchXml += '<attribute name="annotationid" />';
6: fetchXml += '<filter>';
7: fetchXml += '<condition attribute="filename" operator="eq" value="logo.png" />';
8: fetchXml += '<condition attribute="isdocument" operator="eq" value="1" />';
9: fetchXml += '<condition attribute="objecttypecode" operator="eq" value="1" />';
10: fetchXml += '<condition attribute="objectid" operator="eq" value="'+crmForm.ObjectId+'" />';
11: fetchXml += '</filter>';
12: fetchXml += '</entity>';
13: fetchXml += '</fetch>';
14: fetchXml += '';
15:
16: /* Make the fetch and retrieve xml result */
17: var resxml = Fetch(fetchXml);
18: /* Create an ObjTree Object */
19: var xotree = new XML.ObjTree();
20: /* Objectize xml result */
21: var tree = xotree.parseXML(resxml);
22: return (tree.resultset.result.annotationid);
23:
24: }
Notice the xotree object – it’s a method to kind of create a JS object in this case a annotation object, but it could be any CRM entity – for more information have a look here: Objectizing Ajax (XML) results.
My code is copy pasted from Adi Katz blog post – i’ll repost it here:
1: if ( typeof(XML) == 'undefined' ) XML = function() {};
2:
3: // constructor
4:
5: XML.ObjTree = function () {
6: return this;
7: };
8:
9: // object prototype
10: XML.ObjTree.prototype.xmlDecl = '<?xml version="1.0" encoding="UTF-8" ?>\n';
11: XML.ObjTree.prototype.attr_prefix = '';
12:
13: // method: parseXML( xmlsource )
14: XML.ObjTree.prototype.parseXML = function ( xml ) {
15: var root;
16: if ( window.ActiveXObject ) {
17: xmldom = new ActiveXObject('Microsoft.XMLDOM');
18: xmldom.async = false;
19: xmldom.loadXML( xml );
20: root = xmldom.documentElement;
21: }
22: if ( ! root ) return;
23: return this.parseDOM( root );
24: };
25:
26: // method: parseDOM( documentroot )
27: XML.ObjTree.prototype.parseDOM = function ( root ) {
28: if ( ! root ) return;
29:
30: this.__force_array = {};
31: if ( this.force_array ) {
32: for( var i=0; i<this.force_array.length; i++ ) {
33: this.__force_array[this.force_array[i]] = 1;
34: }
35: }
36:
37: var json = this.parseElement( root ); // parse root node
38: if ( this.__force_array[root.nodeName] ) {
39: json = [ json ];
40: }
41: if ( root.nodeType != 11 ) { // DOCUMENT_FRAGMENT_NODE
42: var tmp = {};
43: tmp[root.nodeName] = json; // root nodeName
44: json = tmp;
45: }
46: return json;
47: };
48:
49: // method: parseElement( element )
50: XML.ObjTree.prototype.parseElement = function ( elem ) {
51: // COMMENT_NODE
52: if ( elem.nodeType == 7 ) {
53: return;
54: }
55:
56: // TEXT_NODE CDATA_SECTION_NODE
57: if ( elem.nodeType == 3 || elem.nodeType == 4 ) {
58: var bool = elem.nodeValue.match( /[^\x00-\x20]/ );
59: if ( bool == null ) return; // ignore white spaces
60: return elem.nodeValue;
61: }
62:
63: var retval;
64: var cnt = {};
65:
66: // parse attributes
67: if ( elem.attributes && elem.attributes.length ) {
68: retval = {};
69: for ( var i=0; i<elem.attributes.length; i++ ) {
70: var key = elem.attributes[i].nodeName;
71: if ( typeof(key) != "string" ) continue;
72: var val = elem.attributes[i].nodeValue;
73: if ( ! val ) continue;
74: key = this.attr_prefix + key;
75: if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
76: cnt[key] ++;
77: this.addNode( retval, key, cnt[key], val );
78: }
79: }
80:
81: // parse child nodes (recursive)
82: if ( elem.childNodes && elem.childNodes.length ) {
83: var textonly = true;
84: if ( retval ) textonly = false; // some attributes exists
85: for ( var i=0; i<elem.childNodes.length && textonly; i++ ) {
86: var ntype = elem.childNodes[i].nodeType;
87: if ( ntype == 3 || ntype == 4 ) continue;
88: textonly = false;
89: }
90: if ( textonly ) {
91: if ( ! retval ) retval = "";
92: for ( var i=0; i<elem.childNodes.length; i++ ) {
93: retval += elem.childNodes[i].nodeValue;
94: }
95: } else {
96: if ( ! retval ) retval = {};
97: for ( var i=0; i<elem.childNodes.length; i++ ) {
98: var key = elem.childNodes[i].nodeName.replace("#","");
99: if ( typeof(key) != "string" ) continue;
100: var val = this.parseElement( elem.childNodes[i] );
101: if ( ! val ) continue;
102: if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
103: cnt[key] ++;
104: this.addNode( retval, key, cnt[key], val );
105: }
106: }
107: }
108: return retval;
109: };
110:
111: // method: addNode( hash, key, count, value )
112: XML.ObjTree.prototype.addNode = function ( hash, key, cnts, val ) {
113: key = this.key_qualify(key);
114: if ( this.__force_array[key] ) {
115: if ( cnts == 1 ) hash[key] = [];
116: hash[key][hash[key].length] = val; // push
117: } else if ( cnts == 1 ) { // 1st sibling
118: hash[key] = val;
119: } else if ( cnts == 2 ) { // 2nd sibling
120: hash[key] = [ hash[key], val ];
121: } else { // 3rd sibling and more
122: hash[key][hash[key].length] = val;
123: }
124: };
125:
126: XML.ObjTree.prototype.key_qualify = function( key ){
127: return key.replace(/\W/gi,"");
128: }
129: // method: xml_escape( text )
130: XML.ObjTree.prototype.xml_escape = function ( text ) {
131: return String(text).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
132: };
133:
134: /*
135: Copyright (c) 2005-2006 Yusuke Kawasaki. All rights reserved.
136: This program is free software; you can redistribute it and/or
137: modify it under the Artistic license. Or whatever license I choose,
138: which I will do instead of keeping this documentation like it is.
139: */
140:
So there you have it – it’s actually pretty easy – and using Stunnware Javascript Factory it’s manageable in spite of the many lines of code.
Take care
One of my customers wanted to create Quote templates we had to figure out how it should be done – we thought about using opportunities as templates when choosing an opportunity as leading opp it …
At Microsoft Partner Conference the MS CRM Team took the challenge of creating a xRM application in 24 hours. The team to fulfill this was Barry Givens, Nikhil Hasija, Reuben Krippner and Bryan Nelson.
To decide …
Integration with Dynamics CRM is not the most popular task to do. But it can actually be done very easy and within a reasonable budget.
With the Rapidi Online integration solution you can easily hook up …