﻿/**************************************************
* 版权所有: 博华无限
* 文 件 名: MyAjax.js
* 文件描述: 
* 类型说明: 
*           MyAjax  Ajax类
* 授权声明:
*           本程序为自由软件；
*           您可依据自由软件基金会所发表的GPL v3授权条款，对本程序再次发布和/或修改；
*           本程序是基于使用目的而加以发布，然而不负任何担保责任；
*           亦无对适售性或特定目的适用性所为的默示性担保。
*           详情请参照GNU通用公共授权 v3（参见license.txt文件）。
* 版本历史: 
*           v1.0.2 黄嵩高 2010-08-25 修改MyAjax.decode()方法
*           
***************************************************/

/**
* MyAjax构造函数
*<parameters>
*   url: ajax调用的链接
*   method: HTTP请求方法
*   params: 调用参数，参数类型视contentType而定
*   contentType: 数据类型 
*   onload: 成功回调函数
*   onerror: 失败回调函数
*</parameters>
*/

var MyAjax = function (url, method, params, contentType, onload, onerror) {
    this.httpRequest = null;                                    //XMLHttpRequest对象
    this.onload = (onload) ? onload : MyAjax.defaultCallback;   //成功回调函数
    this.onerror = (onerror) ? onerror : MyAjax.defaultError;   //失败回调函数
    this._request (url, method, params, contentType);           //发送请求
}

MyAjax.rootURL = "/";
MyAjax.jsLoadDic = new Object();

/*
* 发起AJAX请求, 内部私有方法
*<parameters>
*   url: ajax调用的链接
*   method: HTTP请求方法
*   params: 调用参数，参数类型视contentType而定
*   contentType: 数据类型 
*</parameters>
*/
MyAjax.prototype._request = function(url, method, params, contentType) {
    if (!method)
        method = "GET"; //如果HTTP请求方式未指定,则默认为GET方式
    if (!contentType && method == "POST")
        contentType = MyAjax.ContentType.JSON;  //默认为JSON格式

    //创建XMLHttpRequest对象
    if (window.ActiveXObject) {  //ie浏览器
        this.httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else {                      //其他浏览器
        this.httpRequest = new XMLHttpRequest();
    }

    //发送请求
    if (this.httpRequest) {
        try {
            var ajax = this;
            this.httpRequest.onreadystatechange = function() {
                if (ajax.httpRequest.readyState == 4) {          //数据准备完毕
                    if (ajax.httpRequest.status == 200) {        //Ajax调用正常
                        ajax.onload.call(ajax.httpRequest);     //调用成功回调函数
                    }
                    else {                                      //Ajax调用失败
                        ajax.onerror.call(ajax.httpRequest);    //调用失败回调函数
                    }
                    ajax.httpRequest = null;
                }
            };
            
            //打开请求通道
            this.httpRequest.open(method, url, true);
            //设置请求头
            this.httpRequest.setRequestHeader("Cache-Control", "no-cache");
            this.httpRequest.setRequestHeader("Content-Type", contentType);
            this.httpRequest.setRequestHeader("Accept", contentType);

            //发送请求
            this.httpRequest.send(params);

        }
        catch (e) {
            alert("AJAX 调用失败:" + e);
            this.httpReqeust = null;
        }
    }
    else {
        alert("XMLHttpRequest对象创建失败!")
    }
}

//默认失败回调函数
MyAjax.defaultError = function() {
    alert("AJAX调用失败: \n\nreadyState: "+this.readyState+
                            "\nstatus: "+this.status+
                            "\nheaders: \n"+this.getAllResponseHeaders());
    alert("错误信息: \n"+this.responseText);
}

//默认成功回调函数
MyAjax.defaultCallback = function() {
    alert("AJAX调用成功, 返回数据为：" + this.responseText);
}

/*
* 发起AJAX请求
*<parameters>
*   url: ajax调用的链接
*   method: HTTP请求方法
*   params: 调用参数，参数类型视contentType而定
*   contentType: 数据类型 
*   onload: 成功回调函数
*   onerror: 失败回调函数
*</parameters>
*/
MyAjax.request = function(url, method, params, onload, onerror, contentType) {
    new MyAjax(url, method, params, contentType, onload, onerror);
}

//MyWebService.asmx的路径
MyAjax.myWebServiceURL = MyAjax.rootURL + "WebServices/MyWebService.asmx/";

/*
* 发起AJAX请求调用WEB服务Operator()、BatchOperator()
*<parameters>
*   className: 业务层中服务类含命名空间的类名
*   methodName: 服务方法名
*   data: 预操作的数据
*   onSuccess: 成功回调方法
*   onFail: 失败回调方法
*   isBatch: 是否进行批量操作
*</parameters>
*/
MyAjax.operator = function(className, methodName, data, onSuccess, onFail, isBatch) {
    var _params;
    
        _params = "{className:'"+className+"',methodName:'"+methodName+"',dic:"+((!data || data=='')?null:JSON.stringify(data))+"}";
    var _url = MyAjax.myWebServiceURL + (isBatch ? "BatchOperator" : "Operator");
    
    try
    {
        MyAjax.request(_url, "POST", _params, onSuccess,onFail);
    }
    catch(e)
    {
        alert(e);
    }
}

/*
* 发起AJAX请求调用WEB服务DatasetOperator
*<parameters>
*   className: 业务层中服务类含命名空间的类名
*   methodName: 服务方法名
*   data: 预操作的数据
*   onSuccess: 成功回调方法
*   onFail: 失败回调方法
*   isBatch: 是否进行批量操作
*</parameters>
*/
MyAjax.operator2 = function(className, methodName, data, onSuccess, onFail) {
    var _params;
    _params = "{className:'"+className+"',methodName:'"+methodName+"',arr:"+((!data || data=='')?null:JSON.stringify(data))+"}";
    MyAjax.request(MyAjax.myWebServiceURL+"DatasetOpertor", "POST", _params, onSuccess, onerror);
}

MyAjax.decode = function(sourceString) {
    eval("var returnObj = " + sourceString + ".d");
    for(var i=0;i<10;i++){
        try{
            eval("var returnObj= " + returnObj );
        }
        catch(e){
            return returnObj;
        }
    }
    return returnObj;
}

/*
* 将table标签对象转为JsonObject
*<parameters>
*   tableId:table表的id
*</parameters>
*/
MyAjax.TableToJsonObject = function(tableId){
    var GridView=document.getElementById(tableId);
    var s="[";
    for(var i=1;i<GridView.rows.length;i++)
    {
        s+="{";
        for(var j=0;j<GridView.rows[i].cells.length;j++)
        {
            var columnname=GridView.rows[i].cells[j].getElementsByTagName("input")[0].name;
            var columnvalue = GridView.rows[i].cells[j].getElementsByTagName("input")[0].value;
            if(typeof (columnvalue)=="string")
                s+=columnname.split('$')[2]+":'"+ columnvalue +"',";
            else
                s+=columnname.split('$')[2]+":"+ columnvalue +",";
        }
        s=s.substring(0,s.length-1)+"},";
    }
    s=s.substring(0,s.length-1)+"]";
    eval("var jsonObject = "+s);
    return jsonObject;
}

//几种数据类型
MyAjax.ContentType = new Object();
MyAjax.ContentType.XML = "text/xml";
MyAjax.ContentType.JSON = "application/json";
MyAjax.ContentType.TEXT = "text/plain";
MyAjax.ContentType.HTML = "application/X-www-form-urlencoded";
MyAjax.ContentType.SCRIPT = "application/javascript";



//Json

var JSON=JSON||{};(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+
partial.join(',\n'+gap)+'\n'+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());
