﻿// JQuery Ajax Grid
// Author: Omer DUZYOL
// jQuery 1.2+
jQuery.fn.outerHTML = function() {
	return $('<div>').append( this.eq(0).clone() ).html();
};

;(function(){
	
var $$;

$$ = jQuery.fn.ajaxGrid = function(params) {

    // ajax grid base prototype
    var ajaxGrid = {
        totalRows:0,
        totalPages:0,
        pageSize:0,
        pageIndex:0,
        dataSource:null,
        targetGrid:this,
        sorters:null,
        parameters: params
    };
    
	if(ajaxGrid.targetGrid==null || params.Service == null)
	    throw new Error('params.Service');
    
    if(ajaxGrid.targetGrid.length==0)
        throw new Error('params.targetGrid');

    if(ajaxGrid.parameters.Columns == null || ajaxGrid.parameters.Columns.Keys == null)
        throw new Error('params.Columns');
    
    if(params.RowTemplate == null)
        throw new Error('params.RowTemplate');
            
    var sorters = params.Sort != null ? params.Sort : new Array();
    var sorterStr = ",'" + sorters.convertJSON() + "',";
    var wsArgs = params.ServiceArgs != null ? params.ServiceArgs: new Array();
    var wsArgsString = null;
    
    ajaxGrid.pageIndex = params.PageIndex !=null ? params.PageIndex : 1;
    ajaxGrid.pageSize = params.PageSize!=null ? params.PageSize : 10;
    
    function parseServiceArgs(){
        wsArgsString = wsArgs.length>0 ? "" : "''";    
        for(var i=0;i<wsArgs.length;i++){
            var currObj = $.JSON.stringify(wsArgs[i]);
            if(i!=wsArgs.length-1) currObj += ",";
            
            wsArgsString += currObj;
        }
        /*$.each(wsArgs,function(i){
            var currObj = this;
            if(typeof currObj == 'string')
                currObj = "'" + currObj + "'";
            
            if(i!=wsArgs.length-1) currObj += ",";
        });*/
    }
    parseServiceArgs();
    ajaxGrid.sorters = sorters;
        
    // extending ajaxGrid prototype with Reload() function
    $.extend(ajaxGrid,{
        Reload:function(newArgs){
            if(newArgs!=null){
                wsArgs = newArgs;
                // parse new service arguments
                parseServiceArgs();
            }
            
            if (params.onPreload != null)
                params.onPreload();
            
           // call service indirectly
           eval('params.Service(ajaxGrid.pageIndex,ajaxGrid.pageSize' + sorterStr + wsArgsString + ');');
        }
    });
    
    // extending ajaxGrid prototype with Sort() function
    $.extend(ajaxGrid,{
        Sort:function(column,direction){
            sorters = new Array();
            if(column!=null)
                sorters.push(column);
            if(direction!=null)
                sorters.push(direction);
                
            ajaxGrid.sorters = sorters;
            
            if(sorters.length>0)
                sorterStr = ",'" + sorters.convertJSON() + "',";
            else
                sorterStr = ",'" + new Array().convertJSON() + "',";
           
           // reload table
           ajaxGrid.Reload();        
        }
    });
    
    // extending ajaxGrid prototype with Page() function
    $.extend(ajaxGrid,{
        Page:function(newIndex){
            if(ajaxGrid.totalPages>0){
                ajaxGrid.pageIndex = newIndex;           
               // reload table
               ajaxGrid.Reload();
            }
        }
    });
   
    params.Service.Callback = function(wsResult){
        if(wsResult.Succeed){
            ajaxGrid.dataSource = wsResult.Response.DataSource;
            ajaxGrid.totalRows = wsResult.Response.TotalRows;

            var gw = $(ajaxGrid.targetGrid);
            gw.empty();
            gw.append(  '<thead></thead>' +
                        '<tbody class="rows"></tbody>' +
                        '<tfoot></tfoot>');
            
            // Creating pager
            gw.find('thead').append('<tr class="pagerTop">' + 
			            '<td colspan="' + params.Columns.Values.length + '">' +
			                '<table width="100%" cellpadding="0" cellspacing="0" border="0">' +
				                '<tr class="es_grid_header_top" height="25">' + 
					                '<th >&nbsp;</th>' + 
					                '<th colspan="6"><span id="recordsSummary"></span></th>' +
					                '<th colspan="2" class="algnRight">' + 
						                '<table cellpadding="0" cellspacing="0" border="0" class="pageNumbers"></table>' +
					                '</th>' +
				                '</tr>' +
			                '</table>' +
                        '</td>' +
		            '</tr>');           
            
            // Creating columns
            var jCols = $('<tr></tr>');
            jCols.addClass('columns');
            jCols.addClass(params.Columns.Class);
            
            //gw.find('thead').append(jCols);
            //jCols = gw.find('thead>tr.columns');
            
            $.each(params.Columns.Values,function(){
                if(this!=null)
                    jCols.append(this);
            });
            
            gw.find('thead').append(jCols);
            
            var gwRows = gw.find('tbody.rows');
            var summary = gw.find('thead span#recordsSummary');
            var pager = gw.find('thead .pageNumbers');
            var columns = ajaxGrid.parameters.Columns.Keys;
            var thColumns = gw.find('thead th[scope=col]');
            var evenRowTemplate = typeof params.RowTemplate == 'string' ? params.RowTemplate : params.RowTemplate.outerHTML().replace(/%7B/g,'{').replace(/%7D/g,'}');
            var oddRowTemplate = typeof params.RowTemplateAlternate == 'string' ? params.RowTemplateAlternate : params.RowTemplateAlternate.outerHTML().replace(/%7B/g,'{').replace(/%7D/g,'}');           
            
            var primaryKeyColumn = gw.attr('primarykey');
            
            //  Clear grid data
            gwRows.empty();
            
            if (ajaxGrid.dataSource.Rows != null) {
                    
                //  Datarow loop
                for ( var currentRow = 0; currentRow < ajaxGrid.dataSource.Rows.length; currentRow++ )
                {
                    //  Fetch record
                    var objRecord = ajaxGrid.dataSource.Rows[currentRow];
                    //  Even, odd row template
                    var currentRowTemplate = (currentRow % 2 == 0)? evenRowTemplate : oddRowTemplate;
                    var currentRowData = currentRowTemplate;
                    
                    //  Datacolumn loop
                    for(var colName in columns){
                        try{
                            var evaulator = columns[colName];
                            var format = null;
                            var formatPos = evaulator.indexOf(':');
                            if(formatPos>-1){
                                format = evaulator.substring(formatPos+1);
                                evaulator = evaulator.substring(0,formatPos);
                            }
                            
                            currentData = objRecord[colName];
                            try{
                                eval('currentData=Eval'+evaulator+'("' + currentData + '",format);');
                            } catch(ex){};
                            
                        } catch(ex){
                            currentData = '';
                        }
                        currentRowData = currentRowData.replace( eval('/{' + colName + '}/g'), currentData );
                    }
                               
                    //  Append row to grid
                    gwRows.append(currentRowData);
                }
                
                
                // bind sortings
                //  Datacolumn loop
                thColumns.each(function(){
                    var currColumn = $(this);
                    var currentColumnName = currColumn.attr('rel');
                    var isSortable = currColumn.attr('sortable');
                    var direction = (currColumn.attr('direction') == 'desc') ? 'desc' : 'asc';
                    if(isSortable != null && isSortable != '' && (isSortable == 'sortable' || isSortable == 'true'))
                    {
                        currColumn.find('a').unbind('click').bind('click',function(){
                            ajaxGrid.Sort(currentColumnName,direction);
                            if(direction == 'asc')
                                currColumn.attr('direction','desc');
                            else
                                currColumn.attr('direction','asc');
                        });
                    }
                });
                
                // Calc. total pages
                ajaxGrid.totalPages = Math.ceil(ajaxGrid.totalRows / ajaxGrid.pageSize );
            } else {
                ajaxGrid.totalPages = 0;
            }
            
            
            // create pager
            pager.empty();
            pager.append('<tbody><tr></tr></tbody>');
            pager = pager.find('tr');
            
            var pagerLength = 5;
            var pagerStart = ajaxGrid.pageIndex;
            if(pagerStart<=2)
                pagerStart = 1;
            else
                pagerStart = pagerStart -2;
            var pagerEnd = pagerStart+(pagerLength-1);
            if(pagerEnd>ajaxGrid.totalPages)
                pagerEnd = ajaxGrid.totalPages;
            
            pagerEnd++;
            
            //console.log('start:' + pagerStart + ' - end:' + pagerEnd + ' total:' + ajaxGrid.totalPages);
            
            var moveFirst = $('<td><a href="javascript:;"><<</a></td>');
            moveFirst.find('a').bind('click',function(){
                ajaxGrid.Page(1);
                //console.log('move first');
            });
            pager.append(moveFirst);
            
            var movePrevious = $('<td><a href="javascript:;"><</a></td>');
            movePrevious.find('a').bind('click',function(){
                var page2go = ajaxGrid.pageIndex-1;
                page2go = page2go<=0 ? 1:page2go;
                ajaxGrid.Page(page2go);
                //console.log('move previous');
            });
            pager.append(movePrevious);
            
            for(var i=pagerStart;i<pagerEnd;i++)
            {
                var pageLink;
                if(i==ajaxGrid.pageIndex){
                    pageLink = $('<td>' + i + '</td>');
                } else {
                    pageLink = $('<td><a href="javascript:;">' + i + '</a></td>');
                    pageLink.find('a').bind('click',function(){
                        ajaxGrid.Page(parseInt($(this).text()));
                        console.log('move to page ' + parseInt($(this).text()) );
                    });
                }   
                pager.append(pageLink);
            }
            
            var moveNext = $('<td><a href="javascript:;">></a></td>');
            moveNext.find('a').bind('click',function(){
                var page2go = ajaxGrid.pageIndex+1;
                page2go = page2go>=ajaxGrid.totalPages ? ajaxGrid.totalPages:page2go;
                ajaxGrid.Page(page2go);
                //console.log('move next');
            });
            pager.append(moveNext);

            var moveLast = $('<td><a href="javascript:;">>></a></td>');
            moveLast.find('a').bind('click',function(){
                ajaxGrid.Page(ajaxGrid.totalPages);
                //console.log('move last');
            });
            pager.append(moveLast);
            
            if(ajaxGrid.totalPages>0){
                // set summary
                // Record 1 to 20 of 416
                summary.text('Records ' + (ajaxGrid.pageIndex * ajaxGrid.pageSize - ajaxGrid.pageSize +1)  + ' to ' + ((ajaxGrid.pageIndex * ajaxGrid.pageSize) < ajaxGrid.totalRows ? (ajaxGrid.pageIndex * ajaxGrid.pageSize) : ajaxGrid.totalRows ) + ' of ' + ajaxGrid.totalRows);
            } else {
                summary.text('No records found');
            }
            
            if (params.onLoad != null)
                params.onLoad(wsResult.Response.DataSource);
            
        } else {
            if (params.onError != null)
                params.onError(wsResult.Exception);
        }
    };
        
    // reload table
    ajaxGrid.Reload();    
    
    return ajaxGrid;

};

})(jQuery);