|
|
Comments and Discussions
|
|
 |

|
from what I see the reference is injected dynamically into the Head section so you do not need to include it in the html
|
|
|
|

|
I want to pass more than one parameter. Is this possible with this framework?
If so, how would I do this?
Thanks
|
|
|
|

|
You could use a separated value list (such as "A|B|C").
|
|
|
|

|
I tried this and it removed the values past A
somewhere it is removing the items from | on ?
|
|
|
|

|
ie // Callback asynchronously employeeList.Attributes["onchange"] = GetAsyncCallbackEventReference ( Page.FindControl("Form1"), String.Format("document.getElementById('{0}').options[document.getElementById('{0}').selectedIndex].value|{1}", employeeList.UniqueID, "1"), "JSCallBackHandler", //txtEmployeeDetail.ClientID, txtEmployeeDetail.ClientID, "JSCallBackErrorHandler" ); When it generates the click event, it looks like this: 5|1 But when the public string RaiseClientCallbackEvent(string eventArgument) is called, the eventArgument is only 5 The 1 is getting dumped somewhere?
|
|
|
|

|
Just fyi as well, when I look at the source I see this:
onchange="javascript:WebForm_DoAsyncCallback('Form1',document.getElementById('employeeList').options[document.getElementById('employeeList').selectedIndex].value|1,JSCallBackHandler,txtEmployeeDetail,JSCallBackErrorHandler);
document.getElementById('employeeList').options[document.getElementById('employeeList').selectedIndex].value|1
but when I click on that, and look at the DoAsyncCallback, the |1 is removed?
|
|
|
|

|
You need to do:
String.Format("document.getElementById('{0}').options[document.getElementById('{0}').selectedIndex].value + '|' + {1}", employeeList.UniqueID, "1"),
The browse is interpreting 5|1 as the bitwise "or" operation which results in 5 (the bits of "1" are already contained by "5"):
00000101 | 00000001 = 00000101
|
|
|
|

|
ah excellent catch!
Thanks for your response!!!
|
|
|
|

|
Hello, to set if a request is a Callbak you look in the Request.QueryString, but if the lenght of the postData is greater than 2067 it´s used the post method to send data. So the request has no querystrings, wich isn´t detected as a callback.
There is a little problem there, because U do all the data treatment on the RaiseClientCallbackEvent. So the page posts, and nothing happens at best.
Solution: change in the OnInit and HandleClientCallback of PageTemplate from Request.QueryString to Request.Params. So even if it´s posted it will call the RaiseClientCallbackEvent, and your data will still be treated normally.
Yugo Watari
|
|
|
|
|

|
AJAX is a trendy name some people came up with to describe this technique.
|
|
|
|
|
|
|

|
I discovered a bug in PageEx.js - when the xml request is opened the async parameter is not set to the value of the async parameter being passed to WebForm_DoCallback.
I have uploaded the fix to my web site at http://mywebpages.comcast.net/shaul_ahuva/ScriptCallback.zip
Also, I have updated the code-behind to only render the controls that are needed to reduce server processing time.
|
|
|
|

|
This link is not working for me?
|
|
|
|

|
Hi,
I have suggestion and few questions.
- It's not bad idea to include textarea also in your pageex.js.
- In my opinion it is good to escape values too.
- I extend a little bit your solution using controlCollection as a Callback result, because there is situation where two or more grids work together, raising events and responding to events. What is your opinion?
--
My question is about onload event. When I open a page using callback and when this page has onload event in the body, I found that handler never executes.
What I'm doing wrong?
Thanks in advance
Darko
|
|
|
|

|
Hi,
Hear is an example.When I open this page using callback window_onload never executes. Everything is the same when using javaScript instead of vbscript.
<BODY bottomMargin="0" vLink="blue" link="blue" leftMargin="0" topMargin="0" rightMargin="0"
language="javascript" önload="return window_onload()">
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
<LINK href="Styles.css" type="text/css" rel="stylesheet">
<form id="Form1" method="post" runat="server">
</form>
<activereportsweb:WebViewer id="WebViewer1" runat="server" height="0px" width="0px" ViewerType="ActiveXViewer"
HtmlCharacterSet="UnicodeUtf8">
<script language="vbscript">
Sub WebViewer1_ActiveX_LoadCompleted()
document.all("WebViewer1_ActiveX").Object.PrintReport(false)
End Sub
</script>
</BODY>
Thanks in advance
D
|
|
|
|

|
Hi,
Hear is an example.When I open this page using callback window_onload never executes. Everything is the same when using javaScript instead of vbscript.
<BODY bottomMargin="0" vLink="blue" link="blue" leftMargin="0" topMargin="0" rightMargin="0"
language="javascript" önload="return window_onload()">
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
<LINK href="Styles.css" type="text/css" rel="stylesheet">
<form id="Form1" method="post" runat="server">
</form>
<activereportsweb:WebViewer id="WebViewer1" runat="server" height="0px" width="0px" ViewerType="ActiveXViewer"
HtmlCharacterSet="UnicodeUtf8">
<script language="vbscript">
Sub WebViewer1_ActiveX_LoadCompleted()
document.all("WebViewer1_ActiveX").Object.PrintReport(false)
End Sub
</script>
</BODY>
Thanks in advance
D
|
|
|
|

|
Hi,
Just have a quick question regarding Viewstate. If I implement the IClientCallbackEventHandler interface on a control and set a property server side - how can I update the ViewState to reflect the changes (obviously without posting back)? I've been playing around with the Page Template and I am finding that controls which have been modified on CallBack aren't maintaining state between postbacks. Thanks
Ben
|
|
|
|

|
Ben,
I actually have been looking at this issue, and I have a solution - always render the page during the callback and pull the viewstate out of the page source. Then, just update the viewstate client-side. This allows ASP developers to use AJAX concepts. In fact, the next logical step would be to create a generic ASP.NET AJAX engine for normal controls.
I'll be uploading the changes later tonight.
|
|
|
|

|
I have a working sample (using Northwind database) which displays the functionality of the code posted by shaul_ahuva.
If you would like it, please email me at tim@timyee.com.
Features:
1. Uses a custom datagrid (which has client-side paging and sorting and also column dragging, taken from msdn cutting edge article). The paging event uses the callback framework. The sorting event i used the msdn version which sorts only the records that are currently displayed, but not the whole datatable. I am going to test out sorting using the callback framework later.
2. Uses a dynamic client side drop down list population (with a loader message....displaying "Loading Drop Down List...". This uses the callback framework.
Note: There are a few "hacks" that I had to do to make it work. Maybe you can find a better way, but it works for me. Let me know if you do.
Another Note: within the code the names of the components are not exactly those consistent with Northwind, as I am integrating this code into my own project.
If you have any questions feel free to ask.
Hope you find this helpful, and thankyou shaul_avuna for posting your solution.
Regards,
Tim
|
|
|
|

|
Does anyone know why this is so?
When I use an xml file which is under 2KB, there is no problem. When I use an xml which is over 2KB the code in Employee.ascx, more specifically function ShowEmployeeErrorHandler(responseText, context), gets called instead of function ShowEmployeeDetailHandler(responseText, context) which should be called when everything is normal.
I traced the code in ScriptCallback.js, more specifically the function WebForm_DoSyncCallback(eventTarget, eventArgument, eventCallback, context, errorCallback),
if (pageUrl.length + postData.length + 1 > 2067) {
usePost = true;
}
if (usePost) {
xmlRequest.open("POST", pageUrl, false);
xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlRequest.send(postData);
}
else
{
if (pageUrl.indexOf("?") != -1) {
xmlRequest.open("GET", pageUrl + "&" + postData, false);
}
else {
xmlRequest.open("GET", pageUrl + "?" + postData, false);
}
xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlRequest.send();
}
which determines whether to do a POST or a GET depending on the size of the data. Obviously the GET works, but the POST for some reason just does not work.
Does anyone have any idea how I would fix this? I am very excited about these pieces of code and would like to use them in my program.
Thankyou!!!!
Tim
tim@timyee.com
|
|
|
|

|
Never mind. I didn't see the next page of posts. Someone had the exact same problem. Solved! Thanks.
|
|
|
|

|
You need to Pass the "__SCRIPTCALLBACKID" ID & and its value AS Bellow
then it will work fine.
if (usePost) {
xmlRequest.open("POST", pageUrl + "&__SCRIPTCALLBACKID=" + eventTarget + "&__SCRIPTCALLBACKPARAM=" + escape(eventArgument).replace(re, "%2B"), true);
xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlRequest.send(postData);
}
Regards,
Rajkumar.S
|
|
|
|

|
Hi There!
Great Article!! I'm gonna adpot your technique to my web apps very soon. But just one question, since Client side JavaScript can be inspected by the end-user, do you think that exposing the JavaScript call backs functions on the client would allow an attacker to gain knowledge of the business logic on the server?
Thanks!!!
|
|
|
|

|
I don't think it would be a problem; the only danger would be the same danger inherent in all web development - undesired/malicious data coming across in the request. This can easily be protected against with data validation.
|
|
|
|

|
Hi There!
Fantastic example...it's really cool.
Is there a way to get rid of the status codes at the bottom of the screen? (the 200, etc.)
Thanks!
|
|
|
|

|
I don't know if it was done intentially , but one of variables that was used to get the coming back result is named which matches with window.status. Just add declaration in Javascript and replace with newly declared variable.
Thank you
|
|
|
|

|
A co-worker of mine really liked this idea and starting using it. He was using the client-side paging datagrid from msdn, but I thought a better way would be to modify the datagrid to work like the new GridView control. In order to do this, I had to get the paging/sorting events to be called through the callback framework. I made the following changes:
1) WebForm_InitCallback is broken:
Checkboxes are added into the form/querystring regardless of their state (this problem is also in .NET 2.0 -- see http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackId=5c115f35-d7d7-47c0-9e2f-262c3cccdec2".
If trying to pass an event through the framework, the last button processed will kick off it's event and not the value of __EVENTARGET because all buttons are added to the form/querystring. This problem is fixed in .NET 2.0.
2) Created an enhanced version of __doPostBack called __doPostBackEx. This function sets up the post to pass an event through the callback framework. Any events that go through the callback framework must use this function.
3) Changed the return value of IClientCallbackEventHandler.RaiseClientCallbackEvent to "object" and changed how the return value was handled so that a control's entire html markup could be returned to the client and updated dynamically.
4) Added code to allow the Page class to implement the IClientCallbackEventHandler.
There's probably other changes, but I think those are the major ones.
I included a sample (just a code snippet) of how I got the DataGrid to pass it's events through the callback framework.
I made some breaking changes (removed un-needed status codes, changed interface/method names to match .NET 2.0), so if you use this merge the changes carefully!
You can get the updated files from http://mywebpages.comcast.net/shaul_ahuva/scriptCallback.zip
|
|
|
|

|
Nice work!
I have a couple of questions:
1) Is your enhanced framework working correctly with Firefox?
2) Could you expand on the checkbox problem
3) Did you managed to fix it for 1.1 ?
Thanks!
|
|
|
|

|
1) I don't know if it works with FireFox - I would assume not if the original code doesn't work. I guess I can take a look at it once I get to work today
2) Basically, a checkbox should not be added to the POST's form (or the GET's querystring) unless it is checked. Both the CheckBox WebControl and HtmlInputCheckBox HtmlControl check to see if they get any post data during Page.ProcessPostData(). If they have a value (it doesn't matter what it is), they infer that they should be checked.
What thens happens is that EVERY single checkbox reads as "Checked=True" during a callback, regardless of their true state on the client.
This happens because the WebForm_InitCallback method just rips through all input elements and adds them to the form/querystring without regard for the fact that different types of input elements should handled differently.
3) Yes, I did get it fixed. I also fixed a problem with how .NET 1.1 handles postback events so that the events could get passed through the callback framework (again, a problem with WebForm_InitCallback) - this problem doesn't exist in .NET 2.0 because they changed the way the framework handles events.
To see for yourself, get copy of Reflector (http://www.aisto.com/roeder/dotnet/) and look at the Page.ProcessRequestMain and Page.ProcessPostData methods as well as the CheckBox.LoadPostData and HtmlInputCheckBox.LoadPostData implementations.
|
|
|
|

|
I'm assuming that the code is breaking on this line:
selectChild = element.children.length;
If it is, just replace it with the following:
selectCount = (element.children == null) ? 0 : element.children.length;
Evidently, FireFox sets children to "null" while IE sets children to a valid collection with 0 elements.
Hope this helps...
Hmmm...just reflected .NET 2.0 and saw that the problem exists there as well. Oh well, this is why we have betas and CTPs.
|
|
|
|

|
Hi,
First of all thank you for your update!
I have a suggestiong and few questions.
A full funcional example would be great.
I do not understand what PrepareDataGridEx means? Is it your server side code where your accomplish databinding?
What does controlSource variable mean?
What does ncsi in following statement mean
= new streamReader([Assembly].GetExecutingAssembly().GetManifestResourceStream("Ncsi.PageEx.js")) Do you put PageEx in resx file or what?
Please help.
|
|
|
|

|
Going in the order they are accessed:
controlSource is just a string containing the control's HTML source (obtained by creating my own HtmlTextWriter with a StringWriter and calling "MyBase.Render / base.Render"). In the example given, I simply replace any __doPostBack calls in the first and last table rows with updated __doPostBackEx calls.
PrepareDataGridEx is the JS function called just prior to an event being raised through the callback framework. If you look at the signature of __doPostBackEx you'll notice that the fourth argument (preCallBackHandler) is called just prior to rebuilding the form. This gives your control a chance to update any elements with current data (in this case I just keep the previous page number in a hidden element since the DataGrid keeps it in viewstate).
When retrieving embedded resources from an assembly, you must prefix the resource name with the namespace it is in. You can add files as embedded resources by setting the "Build Action" property to "Embedded Resource" for the file(s).
While I can't give a more comprehensive example (mostly due to time right now), I can point out what I have done to extend a control so events can be passed through the callback framework:
1) Create a hidden element during CreateChildControls and append it to the Controls collection. I don't know if this is the best place or not, but I also load the hidden element's value from the request's form. I think there was a specific reason why I chose to do it in CreateChildControls, but the reason escapes me right now.
2) Register a function to be called prior to the callback being posted. Again, this function prepares any current data that you'll need.
3) Render the control and replace __doPostBack calls with __doPostBackEx calls as needed.
4) Implement the IPostBackClientEventHandler (IClientCallbackEventHandler in the original code) interface and return "this/Me" as the return value.
That's really about it; the rest of the code is in PageEx and PageEx.js. What will happen is something akin to the following:
1) The user clicks on something that calls __doPostBackEx. This calls your pre-callback handler if one exists, updates the form and posts the callback.
2) ASP.NET will create all of your controls and load them with data from viewstate. The hidden control I detailed above will also be created at this time.
3) ASP.NET will find the control to get the event in the __EVENTTARGET form value and call the RaisePostBackEvent). In the case of my DataGrid, it is a DataGridLinkButton; the event for the button is bubbled to the DataGrid, which figures out which event delegate needs to be called and calls it.
4) After you handle the event and control returns to ASP.NET, the Render method is called on PageEx.
5) The callback is handled at this time. In this scenario, the control's RaiseCallbackEvent is called and returns a reference to itself.
6) PageEx determines what type of data was returned (either a class descending from System.Web.UI.Control or anything else), and renders the response appropriately.
7) The response is received by the client, which updates the innerHTML property of the context. I changed this recently in my own code since it was a bad idea; all controls are now responsible for updating themselves.
That's pretty much it. I'll try to find time to get a working sample up at some point in the near future.
|
|
|
|

|
I have a working sample (using Northwind database) which displays the functionality of the code posted by shaul_ahuva.
If you would like it, please email me at tim@timyee.com.
Features:
1. Uses a custom datagrid (which has client-side paging and sorting and also column dragging, taken from msdn cutting edge article). The paging event uses the callback framework. The sorting event i used the msdn version which sorts only the records that are currently displayed, but not the whole datatable. I am going to test out sorting using the callback framework later.
2. Uses a dynamic client side drop down list population (with a loader message....displaying "Loading Drop Down List...". This uses the callback framework.
Note: There are a few "hacks" that I had to do to make it work. Maybe you can find a better way, but it works for me. Let me know if you do.
Another Note: within the code the names of the components are not exactly those consistent with Northwind, as I am integrating this code into my own project.
If you have any questions feel free to ask.
Hope you find this helpful, and thankyou shaul_avuna for posting your solution.
Regards,
Tim
|
|
|
|

|
Hi, I downloaded and tried your code. Very nice work!
I could not make the employee control work in Firefox. I started debugging it and the server is binding the XML correctly but the problem seem to be in the client script.
Since Im not a Javascript saavy I wanted to ask, does someone made it work?
|
|
|
|

|
Nice code. Demo works nicely.
But, I'm lost on how to use it for the treeview.
Basically, I want the nodes to be added when the plus sign is clicked.
When the node (without children) is clicked, I add the node value to listbox.
Any suggestion is greatly appreciated.
Thanks,
Sam.
|
|
|
|

|
I posted updated code that allows controls to be returned (the entire markup, not specific elements).
Assuming that the code I wrote is being used, you could do this one of two ways:
1) Modify/extend the TreeView to replace any __doPostBack calls with __doPostBackEx calls so that the event gets passed through the framework. Then, if it's a callback render just the nodes that are needed and return them to a post-event js function. I haven't tried it, but the eventCallback function could probably be used for this.
2) In the RaiseCallbackEvent, return the entire TreeView. This approach would require passing the needed data in via the eventArgument parameter.
Hope this helps...
|
|
|
|

|
Currently, when you use XMLHttpRequest object, system cashes all you calls and if GET string is the same it loads page from the cash. It is not always what is required. Simplest solution is to make GET string every time different. I have change this framework a little bit to add this feature. For interested people I am passing solution beneath.
|
|
|
|

|
I tried to leave most implication intact like conformance to ASP.NET 2.0. However, I have changed a lot javascript for my convience, so I am passing all javascript and related parts from PageTemplate
script:
var __callbackList = new Array(); // Holds the asynchronous callback handler
// Add the Callback Handler to array list
function addToCallbackList(cb) {
__callbackList[__callbackList.length] = cb;
}
var pageUrl = ""; // Post Back URL
var __theFormPostData = ""; // Form Data
function WebForm_InitClientCallback(cbUrl) {
pageUrl = cbUrl;
var theForm = document.forms[0]; // ASP.NET currently support single form PostBack only
count = theForm.elements.length;
var element;
re = new RegExp("\\x2B", "g");
for (i = 0; i < count; i++) {
element = theForm.elements[i];
if (element.tagName.toLowerCase() == "input") {
__theFormPostData += element.name + "=" + element.value.replace(re, "%2B") + "&";
}
else if (element.tagName.toLowerCase() == "select") {
selectCount = element.children.length;
for (j = 0; j < selectCount; j++) {
selectChild = element.children[j];
if ((selectChild.tagName.toLowerCase() == "option") && (selectChild.selected == true)) {
__theFormPostData += element.name + "=" + selectChild.value.replace(re, "%2B") + "&";
}
}
}
}
}
//Create request object
function getXMLHttpRequest() {
var xmlhttp;
if (window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
try{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
//Make the last try to get
else {
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
//Helper fuctions
function prepareFormPostback(eventTarget, eventArgument, disableCash)
{
re = new RegExp("\\x2B", "g");
var strData = ""
if (!disableCash) {
var date = new Date();
strData = date.toString();
//strData += " " + date.getTime();
}
postData = __theFormPostData +
"__SCRIPTCALLBACKID=" + eventTarget +
"&__SCRIPTCALLBACKPARAM=" + escape(eventArgument).replace(re, "%2B");
if ( !disableCash && strData != null && strData.length > 0){
postData += "&__DATEHASH="+escape(strData);
}
return postData
}
//Create request object, send data using it and return object
function sendData(xmlRequest ,postData)
{
usePost = false;
if (pageUrl.length + postData.length + 1 > 2067) {
usePost = true;
}
if (usePost) {
xmlRequest.open("POST", pageUrl, true);
xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlRequest.send(postData);
}
else {
if (pageUrl.indexOf("?") != -1) {
xmlRequest.open("GET", pageUrl + "&" + postData, true);
}
else {
xmlRequest.open("GET", pageUrl + "?" + postData, true);
}
xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlRequest.send(null);
}
return xmlRequest;
}
// Callback asynchronously
function WebForm_DoAsyncCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, disableCash) {
try
{
var postData = prepareFormPostback(eventTarget, eventArgument, disableCash)
var xmlRequest = new getXMLHttpRequest();
xmlRequest.onreadystatechange = WebForm_OnClientCallbackComplete;
sendData(xmlRequest, postData);
var __callbackObject = new Object();
__callbackObject.xmlRequest = xmlRequest;
__callbackObject.eventTarget = eventTarget;
__callbackObject.eventArgument = eventArgument;
__callbackObject.eventCallback = eventCallback;
__callbackObject.context = context;
__callbackObject.errorCallback = errorCallback;
addToCallbackList(__callbackObject);
}
catch(e)
{
if (errorCallback != null)
errorCallback(e.message, context);
else
{
// For Testing Purposes
//alert(e.message);
}
}
}
// Callback Synchronously
function WebForm_DoSyncCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, disableCash) {
try
{
var postData = prepareFormPostback(eventTarget, eventArgument, disableCash);
var xmlRequest = getXMLHttpRequest()
sendData(xmlRequest, postData)
response = xmlRequest.responseText;
status = xmlRequest.getResponseHeader("__SCRIPTCALLBACKSTATUS");
if (status == "200")
{
if (eventCallback != null)
eventCallback(response, context);
}
else
{
if (errorCallback != null)
errorCallback(response, context);
else
{
// For Testing Purposes
//alert(response);
}
}
}
catch(e)
{
if (errorCallback != null)
errorCallback(e.message, context);
else
{
// For Testing Purposes
//alert(e.message);
}
}
}
// Asynchronous Callback Completed
function WebForm_OnClientCallbackComplete()
{
for(var i = 0; i < __callbackList.length; i++)
{
var __cbObject = __callbackList[i];
if (__cbObject != null && __cbObject.xmlRequest.readyState == 4)
{
try
{
xmlText = __cbObject.xmlRequest.responseXML;
response = __cbObject.xmlRequest.responseText;
status = __cbObject.xmlRequest.getResponseHeader("__SCRIPTCALLBACKSTATUS");
if (status == "200")
{
if (__cbObject.eventCallback != null)
__cbObject.eventCallback(response, __cbObject.context);
}
else
{
if (__cbObject.errorCallback != null)
__cbObject.errorCallback(response, __cbObject.context);
else
{
// For Testing Purposes
//alert(response);
}
}
}
catch(e)
{
if (__cbObject.errorCallback != null)
__cbObject.errorCallback(e.message, __cbObject.context);
else
{
// For Testing Purposes
//alert(e.message);
}
}
finally
{
__cbObject.xmlRequest = null;
__cbObject = null;
__callbackList[i] = null;
}
}
}
}
and PageTemplate:
public static string GetAsyncCallbackEventReference(
System.Web.UI.Control control,
string args,
string cbHandler,
string context,
string errHandler,
bool disableCash) {
if (control == null)
throw new ArgumentNullException("control");
if (cbHandler == null || cbHandler == String.Empty)
throw new ArgumentException("Client Callback Handler is required.", "cbHandler");
if (args == null || args == String.Empty)
args = "null";
if (context == null || context == String.Empty)
context = "null";
if (errHandler == null || errHandler == String.Empty)
errHandler = "null";
string strDisbCashed = disableCash ? "true" : "false";
return String.Format("javascript:WebForm_DoAsyncCallback('{0}',{1},{2},{3},{4}, {5});",
control.ID,
args,
cbHandler,
context,
errHandler,
strDisbCashed);
}
public static string GetAsyncCallbackEventReference(
System.Web.UI.Control control,
string args,
string cbHandler,
string context,
string errHandler)
{
return GetAsyncCallbackEventReference(control, args, cbHandler, context, errHandler, false);
}
public static string GetSyncCallbackEventReference(
System.Web.UI.Control control,
string args,
string cbHandler,
string context,
string errHandler,
bool disableCash) {
if (control == null)
throw new ArgumentNullException("control");
if (cbHandler == null || cbHandler == String.Empty)
throw new ArgumentException("A Callback Handler is required.", "cbHandler");
if (args == null || args == String.Empty)
args = "null";
if (context == null || context == String.Empty)
context = "null";
if (errHandler == null || errHandler == String.Empty)
errHandler = "null";
string strDisbCashed = disableCash ? "true" : "false";
return String.Format("javascript:WebForm_DoSyncCallback('{0}',{1},{2},{3},{4}, {5});",
control.ID,
args,
cbHandler,
context,
errHandler,
strDisbCashed);
}
public static string GetSyncCallbackEventReference(
System.Web.UI.Control control,
string args,
string cbHandler,
string context,
string errHandler)
{
return GetSyncCallbackEventReference(control, args, cbHandler, context, errHandler, false);
}
I hope it would be useful for somebody.
I have checked it with IE, Mozilla and Opera. However, Opera is not working correctly even current Beta version
Also I have not checked async calls but they should work. If not, let me know I will fix it.
Besides, thanx Elvin you did a great work.
|
|
|
|

|
Code looks ugly
Also you could change from date.toString() to date.getTime() in the script.
|
|
|
|

|
The solutions to the caching problem.
1.Add xmlRequest.setRequestHeader("Cache-Control","no-cache"); in the JS File
2.Add Response.AddHeader("Cache-Control","no-cache"); in the finally block of the HandleClientCallback Method in the PageTemplate.cs
You can use one or both of the above mentioned solutions.
Promise only what you can do & then deliver more than what you promised.
|
|
|
|

|
Thanx Raja, for me it is just in time note for some how something is not working nice with Mozilla.
Thanks a lot.
|
|
|
|

|
Yes, this the right way how this has to be handled.
I have read RFC. It says that "no-cache" can be applied to both request and response.
However, for me is not clear what happens if caching is applied to request and not to response?
Could someone enlight on this?
|
|
|
|

|
Hi! I have just experienced a problem when using Firefox and sending a SyncCallback with more than 2KB. I got the following exception: Error: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIXMLHttpRequest.send]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://localhost/crm/Javascript/ScriptCallback.js :: WebForm_DoSyncCallback :: line 137" data: no] To solve the problem I used the same piece of code that is used for the IE browser. In ScriptCallback.js I changed the following code (starting at line 131) if (pageUrl.indexOf("?") != -1) { xmlRequest.open("GET", pageUrl + "&" + postData, false); } else { xmlRequest.open("GET", pageUrl + "?" + postData, false); } xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlRequest.send(null); With this code (similar to the one used of the IE Browser): if (pageUrl.length + postData.length + 1 > 2067) { usePost = true; } if (usePost) { alert('post'); xmlRequest.open("POST", pageUrl, false); xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlRequest.send(postData); } else { if (pageUrl.indexOf("?") != -1) { xmlRequest.open("GET", pageUrl + "&" + postData, false); } else { xmlRequest.open("GET", pageUrl + "?" + postData, false); } xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlRequest.send(null); } I thought I just mention it... - Cheers, Øyvind
|
|
|
|

|
This is very informative.
However I am experiencing some difficulties.
I have created a composit control that Adds Some other controls in a override
for the createChildControls method.
Now on postback this works fine and the onload events of the child controls fire without an issue. However on the callback the onload override is never called. This happens even thought the controls are added to the Control Collection of the custome composite control.
Does Anyone have any idea why the onload method will not be called?
Thanks
Jaco
|
|
|
|

|
I had a problem when using a control that has a control inside. To replicate the issue just put employee.ascx (sample) into a new control and put that onto a page.
you get the error "Unable to find the specified Control".
You can solve the problem by changing GetAsyncCallbackEventReference and GetSyncCallbackEventReference: from control.ID to control.UniqueID.
I enjoy using your code
Mathias
|
|
|
|

|
I was looking to start developing some web apps using this technology and I recalled reading about this in MSDN magazine. However, the implementation provided was lacking just about everything I wanted (especially the similarities to the postback model). Your implementation is far more complete and comprehensive. Great work!
-Steven
|
|
|
|

|
I don't know if it is too late to ask!!
but if I want to place a decrease button as well, what should I do!!
I tried just creating the button and pass different data, but for some reason it does not want to work!!
could anyone pleas provide a simple example?
tahnsk in advance!
Simon
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
It allows calls to server events from client script code without causing the page to post back and refresh.
| Type | Article |
| Licence | |
| First Posted | 2 Aug 2004 |
| Views | 295,064 |
| Bookmarked | 123 times |
|
|