Show cool things you have done with our products


Post by mgerow »

At Mats' request I'm offering a few ideas for how to integrate Ext Gantt with SharePoint task lists. This is not to say my approach is the only, or even the best, way to do so, but might help others get started.

The approach we used is to create an ASP.NET page that returns the JSON expected by Ext Gantt. The ASP.NET page queries a given SharePoint task list to gather the data. Here's a snippet of JavaScript from gantt.js showing how the call looks (see line referencing "GanttCallback.aspx"):
    createGrid: function() {
        var start = new Date('5/1/2010');

        end = start.add(Date.MONTH, 10);

        var store = new Ext.ux.maximgb.tg.AdjacencyListStore({
            defaultExpanded: true,
            autoLoad: true,
            //autoLoad : false,
            proxy: new Ext.data.HttpProxy({
                //url : 'tasks.json',
                url: 'GanttCallback.aspx?mode=getsp&s=' + siteUrl + '&w=' + webName + '&type=task&l=' + listName + '&v=' + viewName,
                method: 'GET'
            }),
            reader: new Ext.data.JsonReader({ idProperty: 'Id' }, [
            // Mandatory fields
     	            {name: 'Id' },
                    { name: 'Name', type: 'string' },
                    { name: 'StartDate', type: 'date', dateFormat: 'c' },
                    { name: 'EndDate', type: 'date', dateFormat: 'c' },
                    { name: 'PercentDone' },
                    { name: 'ParentId', type: 'auto' },
                    { name: 'IsLeaf', type: 'bool' },

            // Your task meta data goes here
                    {name: 'Responsible' },
                    { name: 'EstHours' },
                    { name: 'ContentType' }
                ]
            )
        });
The querystring parameters are:

* mode - getsp to retrieve data, putsp to save it
* siteUrl - url of site collection containing task list
* webName - web name of site containing task list
* listName - name of the source/target task list

Saving the code is also handled by a call to the web page, passing back the tasks. This time it's handled by JavaScript attached to a button embedded in gantt.html, as shown in the following snippet:
var putUrl = 'GanttCallback.aspx?mode=putsp&s=' + siteUrl + '&w=' + webName + '&l=' + listName;

function saveIt() {
    // Write document back to disk w/help of ASP.NET APP
    var json = getJason();
    try { 
        xmlHttp = new XMLHttpRequest();
        xmlHttp.open('POST', putUrl, true); 
        xmlHttp.onreadystatechange = saveItHandler;
        xmlHttp.send(json); 
        
   } catch(e) {
        alert ('1: '+e);
   } 
}

function saveItHandler (response) {
    //readyState of 4 or 'complete' represents 
    //that data has been returned 
    if (xmlHttp.readyState == 4 || 
        xmlHttp.readyState == 'complete')
    {
        // Text of web page is returned
        var response = xmlHttp.responseText; 
        //eval (response);
        window.location = loc;
    }
}

Post by mgerow »

I forgot one important function, required by the callback to save the gantt data back to SharePoint:
function getJason() {
    // Create JSON for Tasks
    var json = "[";
    var rowCount = 0;
    for (var i=0; i < App.Scheduler.grid.store.data.items.length; i++) {
        row = App.Scheduler.grid.store.data.items[i];
        if (row.dirty) {
            if (rowCount > 0)
                json += ',';
            json += '{"EndDate" : "' + row.data.EndDate.dateFormat('c') + '",';
            json += '"Id" : ' + row.data.Id + ',';
            json += '"IsLeaf" : ' + row.data.IsLeaf + ',';
            json += '"Name" : "' + row.data.Name + '",';
            json += '"ParentId" : ' + row.data.ParentId + ',';
            json += '"PercentDone" : ' + row.data.PercentDone + ',';
            json += '"Responsible" : "' + row.data.Responsible + '",';
            json += '"StartDate" : "' + row.data.StartDate.dateFormat('c') + '"';
            json += '}';
            rowCount++;
        }
    }
    json += "]";
    
    // Create JSON for Dependencies
    json += "~";
    json += "[";
    rowCount = 0;
    for (var i=0; i < App.Scheduler.grid.dependencyStore.data.items.length; i++) {
        row = App.Scheduler.grid.dependencyStore.data.items[i];
        if (row.dirty || true) {
            if (rowCount > 0)
                json += ',';
            json += '{"From" : ' + row.data.From + ',';
            json += '"To" : ' + row.data.To + ',';
            json += '"Type" : ' + row.data.Type + ',';
            json += '"Id" : ' + row.data.Id;
            json += '}';
            rowCount++;
        }
    }
    json += "]";
    return json;    
}

Post by sonisick »

Can you tell me how to install EXT JS in SharePoint?

Post by mats »

You shouldn't have to install anything afaik as there is only JavaScript. No DLL's etc...

Post by mats »

Additional piece of advice, you could simplify a lot of the code posted by mgerow by using the functionality in Ext JS:

Iterating a store and encoding its data to JSON:
var buf = [];

store.each(function(record) {
   buf.push(Ext.encode(record.data));
});

console.log(buf.join(','));
The saveIt function should use an Ext.Ajax.request call instead, for a much simpler solution. Even simpler would be to use a JsonWriter, if used you wouldn't need any of the code above :)

Post by sonisick »

What does the page GantCallback.aspx look like?

Post by sonisick »

Continuing On--we've managed to get our ProjectList from SharePoint with all the data in JSON format. How can we take a JSON string variable and get it loaded into the store variable: var store = new Ext.ux.maximgb.tg.AdjacencyListStore({...........}); :shock: :o ;) :) :roll: :roll: :lol:

Post by mats »

If you define your store like this:
var store = new Ext.ux.maximgb.tg.AdjacencyListStore({
            defaultExpanded : false,
    	    autoLoad : true,
            proxy : new Ext.data.HttpProxy({
                url : 'PATH-TO-YOUR-WEBSERVICE',
                method:'GET'
            }),
		    reader: new Ext.data.JsonReader({idProperty : 'Id'}, [
                    // Mandatory fields
     	            {name:'Id'},
                    {name:'Name', type:'string'},
                    {name:'StartDate', type : 'date', dateFormat:'c'},
                    {name:'EndDate', type : 'date', dateFormat:'c'},
                    {name:'PercentDone'},
                    {name:'ParentId'},
                    {name:'IsLeaf', type: 'bool'},

                    // Your task meta data goes here
                    {name:'Responsible'}
                ]
            )
        });
Then you should only have to replace the URL to point to the webservice on your server that is serving the data. The rest will be handled by the component automatically. :). Does your JSON look something like the below:
[ { "EndDate" : "2010-02-02T00:00:00",
    "Id" : 1,
    "IsLeaf" : false,
    "Name" : "Planning",
    "ParentId" : null,
    "PercentDone" : 40,
    "Priority" : 1,
    "Responsible" : "",
    "StartDate" : "2010-01-18T00:00:00"
  }
]

Post by sonisick »

Mats,

I'm trying to use Ext.data.MemoryProxy(data). I'm getting data from JQuery SPServices. I know that my JQuery is returning data to my data variable--I can see it in the debugger.

/* From JQuery */
var fields = [
	{name: 'Name'},
	{name: 'StartDate'},
	{name: 'EndDate'},
	{name: 'PercentDone'},
	{name: 'Responsible'},
	{name: 'Duration'},
	{name: 'Id', type: 'int'},
	{name: 'ParentId', type: 'int'},
	{name: 'IsLeaf', type: 'bool'}
];
*/
//data variable was loaded from JQuery Spservices
//I've confirmed that there is data in the data variable





	var store = new Ext.ux.maximgb.tg.AdjacencyListStore({
		autoLoad : true,
		leaf_field_name: "IsLeaf",
		parent_id_field_name: "ParentId",		
		proxy: new Ext.data.MemoryProxy(data),
		reader: new Ext.data.JsonReader({
				idProperty: 'Id', 
				root: 'rows',
				fields: fields
		})
		
});

debugger

---Debugger statement stops but there is no data in store. It has a length of 0. The gantt chart graph displays with no errors.

Thanks for your help.

Post by mats »

How does your data look? Your code looks ok to me.

Post Reply