Adding additional values to duration fields

The following script adds the new option "42 Minutes" to the actualdurationminutes field in a task:

var duration = crmForm.all.actualdurationminutesSelect;

var tables = duration.getElementsByTagName("table");
var table = tables[1];

var row = table.insertRow();
var newOption = row.insertCell(-1);

var newValue = "42 Minutes";
newOption.setAttribute("val", newValue);
newOption.innerText = newValue;

Replacing the content of an IFRAME

If you really want to do some funny things in your CRM form, you can create an IFRAME serving as a placeholder for your real HTML code. Create an IFRAME in an entity and name it "IFRAME_TEST". In the Onload event put the following code:

crmForm.all.IFRAME_TEST_d.innerHTML ="Some HTML text";


Note the "_d" at the end of IFRAME_TEST. This single line replaces the whole IFRAME element with your own HTML.

Standard XmlHttpRequest using JScript

Example of standard xmlhttp request

Retrieve Method Using JScript

This sample shows how to use the CrmService.Retrieve method using the example provided in the following topic: CrmService.Retrieve method.

// Prepare variables for a contact to retrieve.
var contactid = "4696f8cb-9a1c-dd11-ad3a-0003ff9ee217";
var authenticationHeader = GenerateAuthenticationHeader();

// Prepare the SOAP message.
var xml = ""+
"" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+
authenticationHeader+
""+
""+
"contact"+
""+contactid+""+
""+
""+
"fullname"+
"
"+
"
"+
"
"+
"
"+
"
";
// Prepare the xmlHttpObject and send the request.
var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");
xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq.setRequestHeader("Content-Length", xml.length);
xHReq.send(xml);
// Capture the result.
var resultXml = xHReq.responseXML;

// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0)
{
var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
alert(msg);
}
// Display the retrieved value.
else
{
alert(resultXml.selectSingleNode("//q1:fullname").nodeTypedValue);
}

CrmService.Delete Method Using JScript

This sample shows how to use the CrmService.Delete method using the same example provided in the Server Programming Guide



// Identify the contact to delete.
var contactid = "57a4e111-7027-dd11-b452-0003ff9ee217";
var authenticationHeader = GenerateAuthenticationHeader();

// Prepare the SOAP message.
var xml = ""+
"" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+
authenticationHeader+
""+
""+
"contact"+
""+contactid+""+
"
"+
"
"+
"
";
// Prepare the xmlHttpObject and send the request,
var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Delete");
xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq.setRequestHeader("Content-Length", xml.length);
xHReq.send(xml);
// Capture the result,
var resultXml = xHReq.responseXML;

// Check for errors,
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0)
{
var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
alert(msg);
}
// Display confirmation message.
else
{
alert("Contact with id = "+contactid+" successfully deleted");
}

Counting the number of backslashes in a string

First method


var text = "hardware\\printers\\Epson";
var paths = text.split("\\");
alert(paths.length -1);



second method


var text = "hardware\\printers\\Epson";
var numBs = 0;
var index = 0;

while(index != -1) {
index = text.indexOf("\\", index);

if (index != -1) {
numBs++;
index++;
}
}

alert(numBs);

Composite

If you read through the section about the singleton pattern and thought, "well, that was simple," don't worry, I have some more complicated patterns to discuss, one of which is the composite pattern. Composites, as the word implies, are objects composed of multiple parts that create a single entity. This single entity serves as the access point for all the parts, which, while simplifying things greatly, can also be deceiving because there’s no implicit way to tell just how many parts the composite contains.

Structure of the composite

The composite is explained best using an illustration. In Figure 1, you can see two different types of objects: containers and galleries are the composites and images are the leaves. A composite can hold children and generally doesn't implement much behavior. A leaf contains most of the behavior, but it cannot hold any children, at least not in the classical composite example.

clip_image001

Figure 1. The structure of a composite

As another example, I'm 100% certain you’ve seen the composite pattern in action before but never really thought about it. The file structure in computers is an example of the composite pattern. If you delete a folder, all of its contents get deleted too, right? That's essentially how the composite pattern works. You can call a method on a composite object higher up on the tree and the message will be delivered down through the hierarchy.

Composite coding example

This example creates an image gallery as an example of the composite pattern. You will have just three levels: album, gallery, and image. The album and galleries will be composites and the images will be the leaves, just like in Figure 1. This is a more defined structure than a composite needs to have, but for this example, it makes sense to limit the levels to only being composites or leaves. A standard composite doesn't limit which levels of the hierarchy that leaves can be on, nor do they limit the number of levels.

To start things off, you create the GalleryComposite "class" used for both the album and the galleries. Please note that I am using jQuery for the DOM manipulation to simplify things.



var GalleryComposite = function (heading, id) {
this.children = [];

this.element = $('')
.append('

' + heading + '

');
}

GalleryComposite.prototype = {
add: function (child) {
this.children.push(child);
this.element.append(child.getElement());
},

remove: function (child) {
for (var node, i = 0; node = this.getChild(i); i++) {
if (node == child) {
this.children.splice(i, 1);
this.element.detach(child.getElement());
return true;
}

if (node.remove(child)) {
return true;
}
}

return false;
},

getChild: function (i) {
return this.children[i];
},

hide: function () {
for (var node, i = 0; node = this.getChild(i); i++) {
node.hide();
}

this.element.hide(0);
},

show: function () {
for (var node, i = 0; node = this.getChild(i); i++) {
node.show();
}

this.element.show(0);
},

getElement: function () {
return this.element;
}
}

There's quite a bit there, so how about I explain it a little bit? The add, remove, and getChild methods are used for constructing the composite. This example won't actually be using remove and getChild, but they are helpful for creating dynamic composites. The hide, show, and getElement methods are used to manipulate the DOM. This composite is designed to be a representation of the gallery that is shown to the user on the page. The composite can control the gallery elements through hide and show. If you call hide on the album, the entire album will disappear, or you can call it on just a single image and just the image will disappear.

Now create the GalleryImage class. Notice that it uses all of the exact same methods as the GalleryComposite. In other words, they implement the same interface, except that the image is a leaf so it doesn't actually do anything for the methods regarding children, as it cannot have any. Using the same interface is required for the composite to work because a composite element doesn't know whether it's adding another composite element or a leaf, so if it tries to call these methods on its children, it needs to work without any errors.



var GalleryImage = function (src, id) {
this.children = [];

this.element = $('')
.attr('id', id)
.attr('src', src);
}

GalleryImage.prototype = {
// Due to this being a leaf, it doesn't use these methods,
// but must implement them to count as implementing the
// Composite interface
add: function () { },

remove: function () { },

getChild: function () { },

hide: function () {
this.element.hide(0);
},

show: function () {
this.element.show(0);
},

getElement: function () {
return this.element;
}
}


Now that you have the object prototypes built, you can use them. Below you can see the code that actually builds the image gallery.

var container = new GalleryComposite('', 'allgalleries');
var gallery1 = new GalleryComposite('Gallery 1', 'gallery1');
var gallery2 = new GalleryComposite('Gallery 2', 'gallery2');
var image1 = new GalleryImage('image1.jpg', 'img1');
var image2 = new GalleryImage('image2.jpg', 'img2');
var image3 = new GalleryImage('image3.jpg', 'img3');
var image4 = new GalleryImage('image4.jpg', 'img4');

gallery1.add(image1);
gallery1.add(image2);

gallery2.add(image3);
gallery2.add(image4);

container.add(gallery1);
container.add(gallery2);

// Make sure to add the top container to the body,
// otherwise it'll never show up.
container.getElement().appendTo('body');
container.show();