Adding Chrome to browser identification list for Microsoft Ajax

Microsoft Ajax library can identify browser type and version for Firefox, Internet Explorer and Safari. Chrome is missing from this list and it seems Microsoft added Chrome to “init.js” but did not extend Microsoft Ajax. However, as Microsoft Ajax is not limited to SharePoint, you can add Chrome by adding the following code in another JavaScript file (be sure you load the file after Microsoft Ajax is loaded).

(function () {

    function execute() {
        Sys.Browser.Chrome = {};
        var a = navigator.userAgent.toLowerCase();
        if (a.toLowerCase().indexOf("chrome") != -1) {
            Sys.Browser.agent = Sys.Browser.Chrome;
            Sys.Browser.version = parseInt(a.substring(a.indexOf("chrome/") + 7));
        }
    }

    if (typeof (Sys) !== "undefined" && typeof (Sys.Browser) !== "undefined") {
        execute();
    }

})();

And now you can easily identify is browser is Chrome and what version is used.

// Check if browser is Chrome
if (Sys.Browser.agent === Sys.Browser.Chrome) {
    // Alert current Chrome version
    alert(Sys.Browser.agent);
}
Advertisements

Date type extensions in Microsoft Ajax library

I have to admit, Microsoft Ajax JavaScript library is not so well known and popular these days. But still if offers a lot of functionalities a developer might use doing some client side work. I believe can be very useful for SharePoint developers, as SharePoint, being a web forms based technology, use it.

For this article, my objective is to explain a little bit more about Ajax Date type extensions, which are a set of methods designed to extend JavaScript built-in Date object.

Format date as string

Converting a date object to a formatted string has never been easier. Ajax is adding a extension method to Date object called “format” which accepts a format string as parameter. As rule this string should contain the following placeholders to show different parts of the date:

  • yyyy – show full year
  • yy – show short format of year (only the last 2 numbers)
  • M – show short month number (doesn’t add leading zero if month number is under 10)
  • MM – show month
  • MMM – show month name, like Oct, Jan
  • MMM – show full month name, like October and January
  • d – show short day number (doesn’t add leading zero if day number is under 10)
  • dd – show day
  • ddd – show day name, like Sat, Sun….
  • dddd – show full day name, like Saturday or Sunday
  • hh- show hours
  • mm – show minutes
  • ss- show seconds
var dt = new Date();

// 2015-10-22T09:18:30Z
dt.format("yyyy-MM-ddThh:mm:ttZ") 

// 2015/10/22
dt.format("yyyy/MM/dd");

// 22-Oct-15
dt.format("dd-MMM-yy");

// Output Thu
dt.format("ddd");

// Output Thursday
dt.format("dddd");

// Output October
dt.format("MMMM");

You can play with this format string parameter and find more date formats. There is not rocket science here and it is straight format.

Convert a formatted string to Date

Let’s now discussed about the reverse process to convert a string to Date object. Microsoft implemented a static method for Date object called “parseInvariant”. It returns a date if string is a valid representation of it, otherwise returns null.

// @value = A string that represents a date.
// @format = A string provided the format information. For me an array of strings did not work, even  Microsoft says this is the correct parameter type
 var a = Date.parseInvariant(value, format);

You can see below some examples.

var dt;

// This is valid date and is 1st of december 2015. 
dt = "2015-12-01";
Date.parseInvariant(dt,"yyyy-MM-dd");
dt = "12/01/2015";
Date.parseInvariant(dt,"dd/MM/yyyy");
dt = "01 December 2015";
Date.parseInvariant(dt,"dd MMMM yyyy");

It seems for “parseInvariant” function we use the same placeholders like we used for “format” function.

The functions I have talked about do not depend on the culture, but there are also other two versions which are affected by it: “parseLocale” and “localeFormat”. Documentation about entire Date type extended methods can be found here. I have to admit Microsoft did not provide too much details about this, but I hope my findings will help you work smarter doing client side development on web forms based technology (not only, because Ajax is not depending on server side).

Create a hierarchical jQuery date pickers structure

A was working recently with a SharePoint custom form with contains a lot of textbox controls to server as date pickers. Of course, as many other developers, I choose jQuery date picker. So far, so good, but one the requests was to put a series of 4 or 5 controls in hierarchical structure. In other words, date selection of one control was not supposed to be less than previous control selection.

Documentation of jQuery date picker range selection is limited to 2 controls. So to bypass this, I created an Ajax non visual control to integrate and extend this functionality to more date pickers. I will present the code below, which is not very complicated for someone who works with Microsoft Ajax controls.

/// <Reference Name="MicrosoftAjax.js" />

Type.registerNamespace('Sys');


Sys.HierarchicDatePickers = function () {
    /// <summary>Create an instance of Sys.HierarchicDatePickers class</summary>
    Sys.HierarchicDatePickers.initializeBase(this, []);


    this._id;
    this._datepickersIds = [];
    this._pickersOptions = {};
    this._dateChanged = null;
}


Sys.HierarchicDatePickers.prototype = {

    initialize: function () {

        var instance = this;

        // Overwrite format date option if specified (will be improve in the next version)
        instance._pickersOptions['dateFormat'] = 'yy-mm-dd';


        for (var i = 0; i < this._datepickersIds.length; i++) {

            var ctl = $get(this._datepickersIds[i]);
            var jCtl = jQuery('#' + this._datepickersIds[i]);

            // If date picker is initialized, change date format option to our standard
            if (Sys.UI.DomElement.containsCssClass(ctl, 'hasDatepicker') === true) {
                jCtl.datepicker('option', 'formatDate', 'yy-mm-dd');
            }

            // If date picker is not initialized, create date picker
            if (Sys.UI.DomElement.containsCssClass(ctl, 'hasDatepicker') === false) {
                jCtl.datepicker(instance._pickersOptions);
            }


            // Trigger change event when date picker is closed, we will keep and execute also first previous on close handler
            var prevOnClose = jCtl.datepicker('option', 'onClose');
            jCtl.datepicker('option', 'onClose', function (dt, inst) {
                if (prevOnClose !== null) prevOnClose(dt, inst);
                instance._triggerChange(ctl);
            });


            this._add_changeHandler(i);
        }

        this._setPickersMinDate();

    },

    dispose: function () {
        this._dateChanged = null;
        this._pickersOptions = null;
        Sys.HierarchicDatePickers.callBaseMethod(this, 'dispose');
    },


    _add_changeHandler: function (index) {
        /// <summary>Add change handler for control (internal method)</summary>
        /// <param name="index"></param>
        var instance = this;

        $addHandler($get(this._datepickersIds[index]), 'change', function (evt) {
            instance._setPickersMinDate();
            if (instance._dateChanged !== null) instance._dateChanged.apply(instance);
        });
    },

    _triggerChange: function (element) {
        /// <summary>Trigger change event</summary>


        if ("createEvent" in document) {
            var evt = document.createEvent("HTMLEvents");
            evt.initEvent("change", false, true);
            element.dispatchEvent(evt);
        }
        else {
            $get(element).fireEvent('onchange');
        }
    },

    _setPickersMinDate: function () {
        /// <summary>Set picker min date (internal method)</summary>

        var minDate = $get(this._datepickersIds[0]).value.toString().trim();
        for (var i = 1; i < this._datepickersIds.length; i++) {
            var prev = $get(this._datepickersIds[i - 1]).value.toString().trim();
            minDate = (prev === '') ? minDate : prev;
            jQuery('#' + this._datepickersIds[i]).datepicker('option', 'minDate', minDate);
        }
    },


    set_id: function (id) {
        /// <summary>Set id for current instance of Sys.HierarchicDatePickers class</summary>
        /// <param name="id" type="String" mayBeNull="false" optiona='false">Id</param>
        /// <returns type="Sys.HierarchicDatePickers" />
        var e = Function.validateParameters(arguments, [{ name: 'id', type: String, mayBeNull: false, optional: false }], true);
        if (e) throw e;

        this._id = id;
    },

    get_id: function () {
        /// <summary>Get id for current instance of Sys.HierarchicDatePickers class</summary>
        /// <returns type="String" />

        return this._id;
    },

    set_pickersOptions: function (options) {
        /// <summary>Set date pickers options</summary>
        /// <param name="options" type="Object" mayBeNull="false" optiona='false">Pickers options</param>
        /// <returns type="Sys.HierarchicDatePickers" />
        var e = Function.validateParameters(arguments, [{ name: 'options', type: Object, mayBeNull: false, optional: false }], true);
        if (e) throw e;

        this._pickersOptions = options;
        return this;
    },

    get_pickersOptions: function (options) {
        /// <summary>Get date pickers options</summary>
        return this._pickersOptions;
    },

    set_datepickersIds: function (ids) {
        /// <summary>Set date pickers controls id</summary>
        /// <param name="ids" type="Array" elementType="String" elementMayBeNull="false">Controls id</param>
        /// <returns type="Sys.HierarchicDatePickers" />

        var instance = this;
        for (var i = 0; i < ids.length; i++) {
            var id = ids[i];
            if ($get(id) !== null && $get(id).tagName === 'INPUT' && $get(id).type === 'text') {
                instance._datepickersIds.push(id);
            }
        }
        return instance;
    },

    get_datepickersIds: function () {
        /// <summary>Get date pickers id</summary>
        /// <returns type="Array" elementType="String" />

        var instance = this;
        return instance._datepickersIds;
    },

    add_dateChanged: function (handler) {
        /// <summary>Add handler for date changed event</summary>
        /// <param name="handler" type="Function" mayBeNull="false" optional="false">Handler function</param>
        /// <returns type="Sys.HierarchicDatePickers" />
        var e = Function.validateParameters(arguments, [{ name: 'handler', type: Function, mayBeNull: false, optional: false }], true);
        if (e) throw e;

        this._dateChanged = handler;
        return this;
    },

    remove_dateChanged: function () {
        /// <summary>Remove handler for date changed event</summary>
        this._dateChanged = null;
    }

};

Sys.HierarchicDatePickers.registerClass('Sys.HierarchicDatePickers', Sys.Component);

For the moment, there are some limitation I want to bypass in the future. One of them is I am using YYYY-MM-DD date format, because is easy to work with it as string. But with a little help of some contributors, this can be extended.

Now, let’s assume we have 4 textbox controls with following id properties: StartDate, MiddleDate, AfterMiddleDate, EndDate. The requests is, of course, to have always dates selection in ascending in order. To do this we need put them in an array in the order we want to be.

var datepickers = ['StartDate', 'MiddleDate', 'AfterMiddleDate', 'EndDate'];

We might also want to add options for jQuery date pickers initialization and add a handler for change event.

var datepickersOptions = {
  buttonImage: '/teams/dealsupport/images/calendar.gif',
  showOn: 'button',
  buttonText: 'Select Date'
}

var changedHandler = function() {
// Do something here
// You can reference to instance of Sys.HierarchicDatePickers with this keyword
}

And now, the only thing we need to do is to initialize the class using $create Ajax function, which make our object life cycle to be managed by Ajax framework.

$create(Sys.HierarchicDatePickers, { 'id': 'pickers', 'datepickersIds': datepickers, 'pickersOptions': datepickersOptions }, { 'dateChanged': 	changedHandler }, {}, null);

Is not the perfect solution, but you can improve it and extend it and make it better. In any case, I think is an easier solution than writing lines and lines of code each time you need to have this functionality. Inheriting Sys.Component class, the code is ready to be reusable.

Read SharePoint Online list from ASP.NET

Today, IT world is all about connecting systems, so to connect an ASP.NET Web Forms based website to SharePoint Online can be a usual task for developers. This approach is classic and you can say is old fashion. We can say Web Forms are deprecate, but this is not true and this will be another topic on my blog.

But, let’s start with the beginning and present the steps you need for this.

Add required libraries to site

To be able to connect to SharePoint Online, or on Premise as well, you need to import some libraries into your website, or project if you decide to go for an ASP.NET project. These can be found on Microsoft site under the name of “SharePoint Server 2013 Client Components SDK” and can be downloaded from this address. Just copy and page these libraries to Bin folder you will enable SharePoint client objects into your code.

Create class to perform data operations

As you have imported required libraries, you can perform operations against a SharePoint list anywhere in your code. However, as you probably want a little bit of code organization, I would suggest you to create a class dedicated for this. I have called it “SharePoint”, which is probably not the best name, as it can create confusion.

using System;
using System.Collections.Generic;
using System.Security;
using System.Linq;
using System.Web;
using Microsoft.SharePoint.Client;

/// <summary>
/// Summary description for SharePoint
/// </summary>
public class SharePoint : IDisposable
{
    string username;
    SecureString password;
    string url;
    ClientContext context;

	public SharePoint(string url, string username, string password)
	{
        this.url = url;
        this.password = password.ToSecureString();
        this.username = username;
        this.context = new ClientContext(this.url);
        this.context.Credentials = new SharePointOnlineCredentials(this.username, this.password);
	}

  

   /// <summary>
   /// Get list items (method overloaded)
   /// </summary>
   /// <param name="listName">List name</param>
   /// <returns></returns>
    public Microsoft.SharePoint.Client.ListItemCollection GetListItems(string listName)
    {
        return this.GetListItems(listName, CamlQuery.CreateAllItemsQuery());
    }

    /// <summary>
    /// Get list items (method overloaded)
    /// <param name="listName">List name</param>
    /// <param name="camlQuery">CAML query</param>
    /// <returns></returns>
    public Microsoft.SharePoint.Client.ListItemCollection GetListItems(string listName, string camlQuery)
    {
        var oQuery = new CamlQuery();
        oQuery.ViewXml = camlQuery;
        return this.GetListItems(listName, oQuery);
    }

    /// <summary>
    /// Get list items (method overloaded)
    /// </summary>
    /// <param name="listName">List name</param>
    /// <param name="camlQuery">CAML query</param>
    /// <returns></returns>
    public Microsoft.SharePoint.Client.ListItemCollection GetListItems(string listName, CamlQuery camlQuery)
    {
        Web oWeb = context.Site.RootWeb;
        List oList = oWeb.Lists.GetByTitle(listName);
        Microsoft.SharePoint.Client.ListItemCollection oItems = oList.GetItems(camlQuery);
        context.Load(oItems);
        context.ExecuteQuery();
        return oItems;
    }
    
    void IDisposable.Dispose()
    {
        this.context.Dispose();
    }


    public static string GetFieldValue(object field = null)
    {
        if (field == null)
            return "";
        
        var fieldType = field.GetType().ToString();
       
    
        // user field
        if (fieldType  == "Microsoft.SharePoint.Client.FieldUserValue")
        {
            return ((Microsoft.SharePoint.Client.FieldUserValue)field).LookupValue;
        }
        // int32
        else if (fieldType == "System.Int32")
        {
            return Convert.ToString(field);
        }
        // string
        else if (fieldType == "System.String")
        {
            return Convert.ToString(field);
        }
        // Lookup field value
        else if (fieldType == "Microsoft.SharePoint.Client.FieldLookupValue") {
            return Convert.ToString(((Microsoft.SharePoint.Client.FieldLookupValue)field).LookupValue);
        }
        // date time
        else if(fieldType == "System.DateTime")
        {
            return Convert.ToDateTime(field).ToLongDateString();
        }
        else if (fieldType == "Microsoft.SharePoint.Client.ContentTypeId") {
            return ((Microsoft.SharePoint.Client.ContentTypeId)field).StringValue;
        }
        else
        {
            // return Convert.ToString(field);
            return fieldType;
        }   
    }
}

The class contains an overloaded method called “GetListItems” and a static method used for converting field values into string based on their types. There is a lot you can improve here, but it doesn’t fall under this post subject. Also we are not going to use for this example all signatures of “GetListItems” method, but for future use you can keep this method overloading.

Create Ajax enabled WCF service to communicate with SharePoint

What you need now is WCF service to communicate with SharePoint. I choose an Ajax enabled one because I wanted to use it through script manager. But if you prefer, you can use a non-Ajax enabled one to consume it using jQuery.

When you actually execute a query against a SharePoint list, you obtain a ListItemCollection object. As far as I know it cannot be de-serialized by default, so you will need to implement this. So you can create following classes to serve as data contract for the web service.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.Runtime.Serialization;


/// <summary>
/// Represent list item in a collection returned by WCF service
/// </summary>
[CollectionDataContract(Name = "SharePointListItem")]
public class SharePointListItem : Dictionary<string, string>
{
  
}


/// <summary>
/// Represents a collection of SharePoint list items returned by WCF service
/// </summary>
[CollectionDataContract(Name = "SharePointListItemCollection")]
public class SharePointListItemCollection : List<SharePointListItem>
{

}

Implementation of WCF service is simple. In our case, not to complicate the explanations too much, I have created only one method called “GetListItems”, which will get all items for specified list.

using System;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
using System.Xml;
using System.Web.Script.Serialization;
using Microsoft.SharePoint.Client;

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ListData
{
	// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
	// To create an operation that returns XML,
	//     add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
	//     and include the following line in the operation body:
	//         WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";



    [WebGet(ResponseFormat=WebMessageFormat.Json)]
    public SharePointListItemCollection GetListItems(string listName)
    {
        string url = ConfigurationManager.AppSettings["spUrl"];
        string username = ConfigurationManager.AppSettings["spUsername"];
        string password = ConfigurationManager.AppSettings["spPassword"];
        SharePointListItemCollection results = new SharePointListItemCollection();
        using(SharePoint sp = new SharePoint(url,username, password))
        {
        
            Microsoft.SharePoint.Client.ListItemCollection items = sp.GetListItems(listName);
            foreach (ListItem item in items)
            {
                SharePointListItem r = new SharePointListItem();
                foreach (KeyValuePair<string, object> field in item.FieldValues)
                {
                    // SharePointItemField f = new SharePointItemField();
                    // f.FieldName = field.Key;
                    // f.FieldValue = SharePoint.GetFieldValue(field.Value);
                    r.Add(field.Key, SharePoint.GetFieldValue(field.Value));
                }
                results.Add(r);
            };
          
           
        }
        return results;
    }


}

As you noticed, SharePoint class is initialized with 3 parameters, and we are taking these from application settings. To you need to add them in web.config.

  <appSettings>
    <add key="spUsername" value="username" />
    <add key="spPassword" value="password" />
    <add key="spUrl" value="https://url" />
  </appSettings>

Add reference to the WCF service

As the WCF service is Ajax enabled, you need to add a reference to it script manager tag. This will generate a JavaScript for you and will eliminate time waste for writing Ajax calls to the service.

    <asp:ScriptManager runat="server" EnablePartialRendering="true" LoadScriptsBeforeUI="false" EnablePageMethods="true">
        <Services>
            <asp:ServiceReference Path="~/_Services/ListData.svc" />
        </Services>
     </asp:ScriptManager>

Getting the data

And this is the last step, getting the data from SharePoint list. This will take place when page loads to prevent performance issues rendering the mark-up.

function pageLoad(source, args) {
    var service = new ListData();
    service.GetListItems('List name',
        // Success
        function (response) {
            // Do something with JSON response
        },
        // Fail
        function (response) {
            alert(args.get_message());
        });
}

The response is JSON type, so it is up to you what you are going to do with it. My suggestion is to use JavaScript template engine to display it on the page.

A simple JavaScript observable array

Working with JavaScript is very popular in SharePoint enviroment today. Unfortunately, people are looking in other external libraries to achieve functionality they already have, but they are not aware of it. Today, I have decided to present how a SharePoint programmer can make an observable array by using what any web forms based technology already has.
I will take as an example an array containing my names. Initially I will include only two names in it and I will add the other in an observable manner also executing in the same time a handler I will attach to change event.

var arr = ['Andrei', 'Popescu'];

After I have declared my array, is time to make it observable. And of course, as there is no point to make it observable without executing an action when is modified, I will attach a handler to collection change event.

var obsvervableArr = Sys.Observer.makeObservable(arr);
Sys.Observer.addCollectionChanged(obsvervableArr, function(target) {
alert(target);
});

And now, here comes the magic. To add an item to my array in an observable manner, I simply need to call static method “add” of the same Sys.Observable object.

// This will alert my array after new item was added. 
// For complex logic add complex handler to collection changed event
Sys.Observer.add(obsvervableArr,'Vlad');

There are more other method you can use with observable arrays: Sys.Observer.remove, Sys.Observer.removeAt, Sys.Observer.addRange, Sys.Observer.insert and Sys.Observer.clear. All of these are documented on Microsoft website, though not very much details are provided. However, you can use this functionality very easy and create advanced logic, without making use of other libraries. Is all about Microsoft Ajax JavaScript library and it is still the base for SharePoint client side functionality (even on SharePoint 2013).

Singleton pattern using Microsoft Ajax JavaScript library

Microsoft Ajax JavaScript library is one the powerful libraries on the market, even is not so popular any more. More and more developers are going into jQuery direction, but I still continue to use on daily basis, as I am working in SharePoint environment.
For today, I have created a very simple example of singleton pattern based on this library. In essence, is not different at all than pure JavaScript, but the purpose of this is to show to other Microsoft Ajax enthusiastic developers how can integrate this pattern into their code.

/// <Reference Name="MicrosoftAjax.js" />

Type.registerNamespace('NS');

NS.Singleton = function () {
    /// <summary>Constructor for our singleton class</summary>
    if (NS.Singleton._instance !== null) {
        throw "An instance of NS.Singleton already exists"
    }
    NS.Singleton._instance = this;
};

// Stores the instance of Singleton class
NS.Singleton._instance = null;

NS.Singleton.get_instance = function () {
    /// <summary>Return single instance of NS.Singleton</summary>
    if (NS.Singleton._instance === null) {
        return new NS.Singleton();
    }
    else {
        MS.Singleton._instance;
    }
};

NS.Singleton.prototype = {
    firstMethod: function () {
        alert('This is first method');
    },
    secondMethod: function () {
        alert('This is second method');
    }
};

NS.Singleton.registerClass('NS.Singleton');

So, we have a class called “Singleton”, included into “NS” namespace, and we want to have only one instance of this class in the application. For this I have created a static property “_instance” of this class where we store the instance. I used “_” in the name as, by convention, private properties or method should start with this sign in the absence of access modifiers in JavaScript. Visual Studio is quite good on the intellisense and won’t trigger the auto complete for private properties.

Besides this, we need also a static method called “get_instance” to create an instance or return existing one.

var instance_one = NS.Singleton.get_instance();
instance_one.firstMethod();
var instance_two = NS.Singleton.get_instance();
instance_two.secondMethod();

In this example, instance_one and instance_two variable contains the same reference to the instance of NS.Singleton.

It might appear for you a little bit different than classical examples, but in essence is doing the same thing. In any case, if you decide to use Microsoft Ajax library, this is a working example.

Use MicrosoftAjax.js from custom location

MicrosoftAjax.js represent the base of ASP.NET Ajax client side development. It is a library developed by Microsoft which is automatically placed in your page if you include asp:ScriptManager control.  The file is taken from server resources and you cannot change it or add new code to it if you do not place it into a custom location.

But how do I specify the custom location for this file? First let’s start with the beginning and see how asp:ScriptManager is handling JavaScript files.

JavaScript files are added within Scripts tag inside asp:ScriptManager by specifying name or path to the file.

<asp:ScriptManager runat="server" LoadScriptsBeforeUI="false" ID="JSManager">
<Scripts>
       <asp:ScriptReference Name="MicrosoftAjax.js" />
       <asp:ScriptReference Name="MicrosoftAjaxWebForms.js" />
       <asp:ScriptReference Path="/Scripts/Framework.js" />
</Scripts>
</asp:ScriptManager>

Code posted above includes “MicrosoftAjax.js” and “MicrosoftAjaxWebForms.js” files from default location (those two files should be used together) and a custom JavaScript file from “Scripts” directory called “Framework.js”.

Now is time to create a copy of ASP.NET Ajax files and move them to “Scripts” directory near my custom code file.  By adding path near name attribute,  asp:ScriptManager will look for the location I specified, despite official documentation (please drop me a note if I am wrong).

<asp:ScriptManager runat="server" LoadScriptsBeforeUI="false" ID="JSManager">
<Scripts>
       <asp:ScriptReference Name="MicrosoftAjax.js" Path="/Scripts/MicrosoftAjax.js" />
       <asp:ScriptReference Name="MicrosoftAjaxWebForms.js" Path="/Scripts/MicrosoftAjaxWebForms.js" />
       <asp:ScriptReference Path="/Scripts/Framework.js" />
</Scripts>
</asp:ScriptManager>

Making this modifications I am now able to change built-in code and adapt it to new non-supported browsers like Chrome.