// Anthem.js // Updated Sep 18, 2007 // Anthem.Manager.GetScripts: false function Anthem_Encode(s){ if (typeof encodeURIComponent == "function") { // Use JavaScript built-in function // IE 5.5+ and Netscape 6+ and Mozilla return encodeURIComponent(s); } else { // Need to mimic the JavaScript version // Netscape 4 and IE 4 and IE 5.0 return encodeURIComponentNew(s); } } // Primarily used by Anthem.Manager to add an onsubmit event handler // when validators are added to a page during a callback. function Anthem_AddEvent(control, eventType, functionPrefix) { var ev; eval("ev = control." + eventType + ";"); if (typeof(ev) == "function") { ev = ev.toString(); ev = ev.substring(ev.indexOf("{") + 1, ev.lastIndexOf("}")); } else { ev = ""; } var func; if (navigator.appName.toLowerCase().indexOf('explorer') > -1) { func = new Function(functionPrefix + " " + ev); } else { func = new Function("event", functionPrefix + " " + ev); } eval("control." + eventType + " = func;"); } function Anthem_GetXMLHttpRequest() { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else { if (window.Anthem_XMLHttpRequestProgID) { return new ActiveXObject(window.Anthem_XMLHttpRequestProgID); } else { var progIDs = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]; for (var i = 0; i < progIDs.length; ++i) { var progID = progIDs[i]; try { var x = new ActiveXObject(progID); window.Anthem_XMLHttpRequestProgID = progID; return x; } catch (e) { } } } } return null; } // This array is used to keep track of clientCallBack functions when using // an IOFrame to handle callbacks. var callbackFrames = new Array(); // This function is called by the onload event of the IOFrame after the // callback response is received. The function parses the response, updates // the page, and invokes the clientCallBack function. function Anthem_HandleIOFrameResponse(frameid) { var iframe = document.getElementById(frameid); if (iframe != null) { var doc = Anthem_ExtractIFrameDocument(iframe); if (doc.getElementsByTagName("textarea").length > 0) { // Extract the response var response = { responseText: doc.getElementById("response").value.replace(/<\/anthemarea>/, "") }; if (typeof(Anthem_DebugResponseText) == "function") { Anthem_DebugResponseText(response.responseText); } // Parse the response var result = Anthem_GetResult(response); if (result.error) { if (typeof(Anthem_DebugError) == "function") { Anthem_DebugError(result.error); } if (typeof(window.Anthem_Error) == "function") { Anthem_Error(result); } } // Update the page Anthem_UpdatePage(result); // Run the client scripts Anthem_EvalClientSideScript(result); // Run the custom post callback function for (var index in callbackFrames) { var frame = callbackFrames[index]; if (frame != null && frame.id == frameid) { callbackFrames.splice(index, 1); frame.clientCallBack(result, frame.clientCallBackArg); break; } } // Run the common post callback function if (typeof(window.Anthem_PostCallBack) == "function") { Anthem_PostCallBack(); } } setTimeout("document.body.removeChild(document.getElementById(\"" + frameid + "\"))", 10); } } // Returns the iframe document function Anthem_ExtractIFrameDocument(iFrameEl) { var doc = null; if (iFrameEl.contentDocument) { // For NS6 doc = iFrameEl.contentDocument; } else if (iFrameEl.contentWindow) { // For IE5.5 and IE6 doc = iFrameEl.contentWindow.document; } else if (iFrameEl.document) { // For IE5 doc = iFrameEl.document; } else { //alert("Error: could not find iFrame document"); return null; } return doc; } // Returns the form that is posted back using AJAX function Anthem_GetForm() { var form = document.getElementById(Anthem_FormID); return form; } // Returns the URL for callbacks function Anthem_GetCallBackUrl() { var form = Anthem_GetForm(); var action = form.action + (form.action.indexOf('?') == -1 ? "?" : "&") + "Anthem_CallBack=true"; return action; } function Anthem_CallBack(url, target, id, method, args, clientCallBack, clientCallBackArg, includeControlValuesWithCallBack, updatePageAfterCallBack) { if (typeof(window.Anthem_PreCallBack) == "function") { var preCallBackResult = Anthem_PreCallBack(); if (!(typeof preCallBackResult == "undefined" || preCallBackResult)) { if (typeof(window.Anthem_CallBackCancelled) == "function") { Anthem_CallBackCancelled(); } return null; } } var encodedData = ""; if (target == "Page") { encodedData += "&Anthem_PageMethod=" + method; } else if (target == "MasterPage") { encodedData += "&Anthem_MasterPageMethod=" + method; } else if (target == "Control") { encodedData += "&Anthem_ControlID=" + id.split(":").join("_"); encodedData += "&Anthem_ControlMethod=" + method; } if (args) { for (var argsIndex = 0; argsIndex < args.length; ++argsIndex) { if (args[argsIndex] instanceof Array) { for (var i = 0; i < args[argsIndex].length; ++i) { encodedData += "&Anthem_CallBackArgument" + argsIndex + "=" + Anthem_Encode(args[argsIndex][i]); } } else { encodedData += "&Anthem_CallBackArgument" + argsIndex + "=" + Anthem_Encode(args[argsIndex]); } } } if (updatePageAfterCallBack) { encodedData += "&Anthem_UpdatePage=true"; } // Anthem will normally use an XmlHttpRequest to communicate with the server. // But if an Anthem.FileUpload control is discovered on the page, then Anthem // will use a hidden IFRAME instead. This hidden IFRAME is often called an IOFrame // by AJAX library authors, so that is the name we use here. var useIOFrame = false; // Scan the controls on the form and extract their values. if (includeControlValuesWithCallBack) { var form = Anthem_GetForm(); if (form != null) { for (var elementIndex = 0; elementIndex < form.length; ++elementIndex) { var element = form.elements[elementIndex]; if (element.name) { var elementValue = null; if (element.nodeName.toUpperCase() == "INPUT") { var inputType = element.getAttribute("type").toUpperCase(); if (inputType == "TEXT" || inputType == "PASSWORD" || inputType == "HIDDEN") { elementValue = element.value; } else if (inputType == "CHECKBOX" || inputType == "RADIO") { if (element.checked) { elementValue = element.value; } } else if (inputType == "FILE") { // If the FILE element has a value (the path to the file), then an // IOFrame will be used to handle the callback. useIOFrame = useIOFrame | !(element.value == null || element.value.length == 0); } } else if (element.nodeName.toUpperCase() == "SELECT") { if (element.multiple) { elementValue = []; for (var i = 0; i < element.length; ++i) { if (element.options[i].selected) { elementValue.push(element.options[i].value); } } } else if (element.length == 0) { elementValue = null; } else { elementValue = element.value; } } else if (element.nodeName.toUpperCase() == "TEXTAREA") { elementValue = element.value; } if (elementValue instanceof Array) { for (var i = 0; i < elementValue.length; ++i) { encodedData += "&" + element.name + "=" + Anthem_Encode(elementValue[i]); } } else if (elementValue != null) { encodedData += "&" + element.name + "=" + Anthem_Encode(elementValue); } } } // ASP.NET 1.1 won't fire any events if neither of the following // two parameters are not in the request so make sure they're // always in the request. if (typeof form.__VIEWSTATE == "undefined") { encodedData += "&__VIEWSTATE="; } if (typeof form.__EVENTTARGET == "undefined") { encodedData += "&__EVENTTARGET="; } } } if (encodedData.length > 0) { encodedData = encodedData.substring(1); } if (typeof(Anthem_DebugRequestText) == "function") { Anthem_DebugRequestText(encodedData.split("&").join("\n&")); } // Send the callback request to the server. Use an IOFrame if there is a file upload, // otherwise use an XmlHttpRequest. if (useIOFrame) { // To allow multiple requests at the same time, all of the Anthem parameters are // passed to the server via the querystring var action = Anthem_GetCallBackUrl(); action = action + "&Anthem_IOFrame=true"; if (updatePageAfterCallBack) { action = action + "&Anthem_UpdatePage=true"; } // We could generate an anonymous function on the fly to handle the clientCallBack // and assign that to the iframe onload event (in fact this is how XmlHttpRequests are // handled). But that makes it very hard to debug the callback response. Instead // we will stuff the clientCallBack function and args into an array and then hard code // the onload event handler. The handler will find the appropriate callback info in // the array and handle the clientCallBack. var id = "f" + new String(Math.floor(9999 * Math.random())); // Generate frame number if (typeof(clientCallBack) == "function") { var frame = { "id":id, "clientCallBack":clientCallBack, "clientCallBackArg":clientCallBackArg }; callbackFrames.push(frame); } // Create a new, invisible iframe to handle the io. var ioframe = null; if (window.ActiveXObject) { ioframe = document.createElement("