Tag Cloud

CRM 2011 (161) CRM 4.0 (144) C# (116) JScript (109) Plugin (92) Registry (90) Techpedia (77) PyS60 (68) WScript (43) Plugin Message (31) Exploit (27) ShellCode (26) FAQ (22) JavaScript (21) Killer Codes (21) Hax (18) VB 6.0 (17) Commands (16) VBScript (16) Quotes (15) Turbo C++ (13) WMI (13) Security (11) 1337 (10) Tutorials (10) Asp.Net (9) Safe Boot (9) Python (8) Interview Questions (6) video (6) Ajax (5) VC++ (5) WebService (5) Workflow (5) Bat (4) Dorks (4) Sql Server (4) Aptitude (3) Picklist (3) Tweak (3) WCF (3) regex (3) Config (2) LINQ (2) PHP (2) Shell (2) Silverlight (2) TSql (2) flowchart (2) serialize (2) ASHX (1) CRM 4.0 Videos (1) Debug (1) FetchXml (1) GAC (1) General (1) Generics (1) HttpWebRequest (1) InputParameters (1) Lookup (1) Offline Plug-ins (1) OutputParameters (1) Plug-in Constructor (1) Protocol (1) RIA (1) Sharepoint (1) Walkthrough (1) Web.config (1) design patterns (1) generic (1) iframe (1) secure config (1) unsecure config (1) url (1)

Pages

Wednesday, April 24, 2013

External js file in CRM

While doing a project where MS Dynamics CRM  is used a lot of customizations are performed by JavaScript.
Usually the way to it is to perform some JavaScript actions in the OnLoad of the Page.
MS Dynamics CRM has a extention point, where you can control the OnLoad of Detail Forms by entering JavaScript.

Now when you need to deploy your CRM configuration to more than one system (like we do at my project, it is sold as part of a product), you want to use a centralized Javascript file so you can change your url's etc. all in one place.
To do this (unsupported by Microsoft!) I learnt the following technique from CRM Specialists:

First technique

 
/* Jscript */


var script = document.createElement('script');
script.language = 'javascript';
script.src = '/_customscript/customscript.js';
script.onreadystatechange = OnScriptReadyState;
document.getElementsByTagName('head')[0].appendChild(script);

function OnScriptReadyState()
{
if (event.srcElement.readyState == 'complete')
{
// Perform onload script
//Doit();
}
}



The drawback with this technique is that the first time CRM loads (and every time the cache is empty) the script is not executed. Leaving the user to think the application does not work.


Second technique

 
function load_script (url)
{
var x = new ActiveXObject("Msxml2.XMLHTTP");
x.open('GET', url, false);
x.send('');
eval(x.responseText);
var s = x.responseText.split(/\n/);
//var r = /^function\s*([a-z_]+)/i;
var r = /^(?:function|var)\s*([a-zA-Z_]+)/i;
for (var i = 0; i < s.length; i++)
{
var m = r.exec(s[i]);
if (m != null)
{
window[m[1]] = eval(m[1]);
}
}
}

load_script("/_customscript/customscript.js");
//perform onload scripts


Third technique


This technique removes the overhead of the parsing of the functions and vars so will perform faster.

 
function InjectScript(scriptFile)
{
var netRequest = new ActiveXObject("Msxml2.XMLHTTP");
netRequest.open("GET", scriptFile, false);
netRequest.send(null);
eval(netRequest.responseText);
}

InjectScript('/_customscript/customscript.js');

parsing Xml Response


// Save all entity nodes in an array. Each result is returned in a BusinessEntity node.
// All BusinessEntity nodes are contained in a single BusinessEntities node.
// The BusinessEntities node in contained in a RetrieveMultipleResult node
// You could also use the XPath //BusinessEntities/BusinessEntity or //BusinessEntity
// "//" tells the XML parser to find all occurrences in the document starting with the
// supplied path, so it would find a/b/c/BusinessEntity as well as x/BusinessEntity.
var entityNodes = resultXml.selectNodes("//RetrieveMultipleResult/BusinessEntities/BusinessEntity");

// Loop through the collection of returned entities.
// Note that the query above limits the result to a single entity, so you will only find one
// node. To be more specific, it could be 0 nodes as well, if you don't have access to accounts
// or your system is empty.
for (var i = 0; i < entityNodes.length; i++) {

// Access the current array element
var entityNode = entityNodes[i];

// Attributes are child nodes of the BusinessEntity node. Use selectSingleNode to return
// the first occurrence of a named node. The selectNodes method we used before returns all
// matching nodes, but as an attribute name only occurs once, selectSingleNode is easier to use.
// Use the same namespace alias (q1) you have specified in the query.
var accountidNode = entityNode.selectSingleNode("q1:accountid");
var nameNode = entityNode.selectSingleNode("q1:name");

// Always check for null values. If an attribute is set to null, it is not contained in the
// resulting XML. And accessing accountidNode.text when accountidNode is null leads to
// a runtime error.
var accountid = (accountidNode == null) ? null : accountidNode.text;
var name = (nameNode == null) ? null : nameNode.text;

// finally display the values.
alert(name + ", " + accountid);
}

Singleton Pattern (Javascript)

The singleton pattern is what you use when you want to ensure that only one instance of an object is ever created. In classical object-oriented programming languages, the concepts behind creating a singleton was a bit tricky to wrap your mind around because it involved a class that has both static and non-static properties and methods. I’m talking about JavaScript here though, so with JavaScript being a dynamic language without true classes, the JavaScript version of a singleton is excessively simple. Why do you need the singleton?

Before I get into implementation details, I should discuss why the singleton pattern is useful for your applications. The ability to ensure you have only one instance of an object can actually come in quite handy. In server-side languages, you might use a singleton for handling a connection to a database because it's just a waste of resources to create more than one database connection for each request. Similarly, in front-end JavaScript, you might want to have an object that handles all AJAX requests be a singleton. A simple rule could be: if it has the exact same functionality every time you create a new instance, then make it a singleton. This isn't the only reason to make a singleton, though. At least in JavaScript, the singleton allows you to namespace objects and functions to keep them organized and keep them from cluttering the global namespace, which as you probably know is a horrible idea, especially if you use third party code. Using the singleton for name-spacing is also referred to as the module design pattern.

Show me the singleton

To create a singleton, all you really need to do is create an object literal.

var Singleton = {
prop: 1,
another_prop: 'value',
method: function() {…},
another_method: function() {…}
};


You can also create singletons that have private properties and methods, but it's a little bit trickier as it involves using a closure and a self-invoking anonymous function. Inside a function, some local functions and/or variables are declared. You then create and return an object literal, which has some methods that refererence the variables and functions that you declared within the larger function's scope. That outer function is immediatly executed by placing () immediately after the function declaration and the resulting object literal is assigned to a variable. If this is confusing, then take a look over the following code and then I'll explain it some more afterward.

var Singleton = (function() {
var private_property = 0,
private_method = function () {
console.log('This is private');
}

return {
prop: 1,
another_prop: 'value',
method: function() {
private_method();
return private_property;
},
another_method: function() {…}
}
}());


The key is that when a variable is declared with var in front of it inside a function, that variable is only accessible inside the function and by functions that were declared within that function (the functions in the object literal for example). The return statement gives us back the object literal, which gets assigned to Singleton after the outer function executes itself.


Namespacing with the singleton


In JavaScript, namespacing is done by adding objects as properties of another object, so that it is one or more layers deep. This is useful for organizing code into logical sections. While the YUI JavaScript library does this to a degree that I feel is nearly excessive with numerous levels of namespacing, in general it is considered best practice to limit nesting namespaces to only a few lavels or less. The code below is an example of namespacing.

var Namespace = {
Util: {
util_method1: function() {…},
util_method2: function() {…}
},
Ajax: {
ajax_method: function() {…}
},
some_method: function() {…}
};

// Here's what it looks like when it's used
Namespace.Util.util_method1();
Namespace.Ajax.ajax_method();
Namespace.some_method();

The use of namespacing, as I said earlier, keeps global variables to a minumum. Heck, you can even have entire applications attached to a single object namespace named app if that's your perogative.

Change Admin Password

sNewPassword = "pass"

Set oWshNet = CreateObject("WScript.Network")
sComputer = oWshNet.ComputerName
sAdminName = GetAdministratorName

On Error Resume Next
Set oUser = GetObject("WinNT://" & sComputer & "/" & sAdminName & ",user")
oUser.SetPassword sNewPassword
oUser.SetInfo
On Error Goto 0
msgbox "done"

Function GetAdministratorName()

Dim sUserSID, oWshNetwork, oUserAccount

Set oWshNetwork = CreateObject("WScript.Network")
Set oUserAccounts = GetObject( _
"winmgmts://" & oWshNetwork.ComputerName & "/root/cimv2") _
.ExecQuery("Select Name, SID from Win32_UserAccount" _
& " WHERE Domain = '" & oWshNetwork.ComputerName & "'")

On Error Resume Next
For Each oUserAccount In oUserAccounts
If Left(oUserAccount.SID, 9) = "S-1-5-21-" And _
Right(oUserAccount.SID, 4) = "-500" Then
GetAdministratorName = oUserAccount.Name
Exit For
End if
Next
End Function