Author | Topic: Something Yummy from Steffen's kitchen | |
---|---|---|
Bruce Anderson | Something Yummy from Steffen's kitchen on Wed, 04 Mar 2009 14:17:00 -0600 In mid February, Steffen showed a way to use the Prototype.js functions withWAA. It is, hands down, the easiest way to incorporate AJAX into a webpage. Here is an example I have developed. This shows both a repeating call to a function in a WAA dll and a simple pushbutton executed function call. Because the calls are to WAA functions, this gives us a simple way to put a window on the web page which is continously updated from the database. THIS IS THE BASIC PAGE... <html> <head> <title>TESTAJAX</title> <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Expires" CONTENT="-1"> <script src='/PROTOTYPE.js' type='text/javascript' ></script> <script language='JavaScript' type='text/javascript'> function MAGIC(){ var url = "/cgi-bin/waa1gate.isa"; var params = "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_INTRO"; var ajax = new Ajax.Updater( {success: 'ajaxstuff'}, url, {method:'post', parameters:params}); } function MORE_MAGIC(){ var url = "/cgi-bin/waa1gate.isa"; var params = "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_INTRO2"; var ajax = new Ajax.Updater( {success: 'ajaxstuff'}, url, {method:'post', parameters:params}); } </script> </head> <body onload="setInterval('MAGIC()', 1000);"> <div id="top" > <p>this is top text</p> </div> <div id="ajaxstuff" > <p>Item will load here...</p> </div> <div id="bottom" > <p>this is bottom text<br /> <input type="button" name="mButton" value="Do More Magic" onClick="MORE_MAGIC();" /></p> </div> </body> </html> THESE ARE THE WAA FUNCTIONS... FUNCTION STUFF_INTRO( oHtml, oContext ) LOCAL cTime := time() oHtml:put([<p>] + cTime + [</p>]) return (.T.) FUNCTION STUFF_INTRO2( oHtml, oContext ) LOCAL cDate := dtoc(date()) oHtml:put([<p>] + cDate + [</p>]) return (.T.) | |
Allen Lee | Something Yummy from Steffen's kitchen on Fri, 06 Mar 2009 18:55:45 -0800 Hi Bruce; It's exciting to see an uncomplicated AJAX implementation. Unfortunately, the demo needs the Prototype.js file to work. Would you mind posting it for us, please? | |
Bruce Anderson | Re: Something Yummy from Steffen's kitchen on Sat, 07 Mar 2009 09:42:35 -0600 That would be diminuitive of me. Here are your links. This is where you can get the file: http://www.prototypejs.org/. I simply shortened the name of the current version of the file. This is one of the better quick and dirty manuals I have stumbled onto: http://www.sergiopereira.com/articles/prototype.js.html. I found it when I went looking for the background on Ajax.Updater. Post some example when you plow ahead, please? | |
Allen Lee | Something Yummy from Steffen's kitchen on Tue, 10 Mar 2009 21:49:29 -0700 Hi Bruce; Your example works nicely! Let's say that you want to pass a variable to a new function named STUFF_INTRO3 1. So you add this to your header: function Gofindit(){ var searchfor = document.formsearch.findthis.value; var url = "/cgi-bin/waa1gate.isa"; var params = "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_INTRO3&WAA_VAR=" + searchfor ; var ajax = new Ajax.Updater({success:"ajaxstuff"},url,{method:"post",parameters:params}); { 2. And you add this to your body: <form name="formsearch" action=""> <p>Search inventory for: <input name="findthis" size="15" type="text"> <input type="button" value="Go Find It" onClick="Gofindit()"> </form> 3. And you add this to the WAA functions: function STUFF_INTRO3( oHtml, oContext ) local cVar := oHtml:getVar('WAA_PAR') if valtype(cVar)='U' oHtml:put([<p>The variable cVar is undefined</p>]) else oHtml:put([<p>The variable is ] + cVar + [</p>]) endif return (.T.) The result is that cVar is undefined. Without studying Prototype.js, will it allow you to pass variables? Bruce Anderson wrote: > In mid February, Steffen showed a way to use the Prototype.js functions > withWAA. It is, hands down, the easiest way to incorporate AJAX into a > webpage. Here is an example I have developed. This shows both a > repeating call to a function in a WAA dll and a simple pushbutton > executed function call. Because the calls are to WAA functions, this > gives us a simple way to put a window on the web page which is > continously updated from the database. > > THIS IS THE BASIC PAGE... > <html> > <head> > <title>TESTAJAX</title> > <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> > <META HTTP-EQUIV="Expires" CONTENT="-1"> > <script src='/PROTOTYPE.js' type='text/javascript' ></script> > > <script language='JavaScript' type='text/javascript'> > function MAGIC(){ > var url = "/cgi-bin/waa1gate.isa"; > var params = "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_INTRO"; > var ajax = new Ajax.Updater( {success: 'ajaxstuff'}, > url, > {method:'post', parameters:params}); > } > function MORE_MAGIC(){ > var url = "/cgi-bin/waa1gate.isa"; > var params = "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_INTRO2"; > var ajax = new Ajax.Updater( {success: 'ajaxstuff'}, > url, > {method:'post', parameters:params}); > } > </script> > </head> > <body onload="setInterval('MAGIC()', 1000);"> > <div id="top" > > <p>this is top text</p> > </div> > <div id="ajaxstuff" > > <p>Item will load here...</p> > </div> > <div id="bottom" > > <p>this is bottom text<br /> > <input type="button" name="mButton" value="Do More Magic" > onClick="MORE_MAGIC();" /></p> > </div> > </body> > </html> > > > THESE ARE THE WAA FUNCTIONS... > > FUNCTION STUFF_INTRO( oHtml, oContext ) > LOCAL cTime := time() > oHtml:put([<p>] + cTime + [</p>]) > return (.T.) > > FUNCTION STUFF_INTRO2( oHtml, oContext ) > LOCAL cDate := dtoc(date()) > oHtml:put([<p>] + cDate + [</p>]) > return (.T.) > > | |
Bruce Anderson | Re: Something Yummy from Steffen's kitchen on Wed, 11 Mar 2009 07:58:50 -0500 You have a typo. In the Ajax call, you name the passed var "WAA_VAR". In STUFF_INTRO3, you ask for "WAA_PAR". Correct this and it works. | |
Les C. Cseh (ASAP Checks) | Re: Something Yummy from Steffen's kitchen on Fri, 13 Mar 2009 17:42:22 -0400 Thanks for these great examples! I hope to experiment with this in the coming weeks. Les | |
Bruce Anderson | Re: Something Yummy from Steffen's kitchen on Sat, 14 Mar 2009 12:19:24 -0500 Here is one more example. This is a cascade of three <select> controls, country->customer->product, where the options can depend on the previous select, just insert the appropriate database coding. Bruce Anderson Graphical Database Programs TESTAJAX.2a.txt | |
Allen Lee | Something Yummy from Steffen's kitchen on Mon, 16 Mar 2009 09:14:28 -0700 Thank you, Bruce. I was working on the same implementation except using tables with buttons and onclick events on every row. However, your example is very impressive! I congratulate you, sir, for opening a new area of WAA developement. After a couple of futile years of casually researching ajax, I had not seen anything as elegant as your examples. How did you discover this? Bruce Anderson wrote: > Here is one more example. This is a cascade of three <select> controls, > country->customer->product, where the options can depend on the previous > select, just insert the appropriate database coding. > > Bruce Anderson > Graphical Database Programs #include "CDXDBE.CH" > #include "COLLAT.CH" > #include "COMMON.CH" > #include "DBFDBE.CH" > #include "DBSTRUCT.CH" > #include "DLL.CH" > #include "DMLB.CH" > #include "ERROR.CH" > #include "FILEIO.CH" > #include "FONT.CH" > #include "FOXDBE.CH" > #include "INKEY.CH" > #define CRLF chr(13)+chr(10) > > FUNCTION _register( oPackage ) > LOCAL oDlg > LOCAL oList > LOCAL oStat > LOCAL oStat2 > > oPackage:registerForm( "INTRO_TESTAJAX" ) > oPackage:registerForm( "STUFF_CUSTOMER" ) > oPackage:registerForm( "STUFF_PRODUCT" ) > oPackage:registerForm( "NOTDEF" ) > oPackage:registerForm( "SAVE_TESTAJAX" ) > > RETURN .T. > > FUNCTION _version() > RETURN "Version 2.5" > > FUNCTION _Copyright() > RETURN "Graphical Database Programs, (c) 2008. All rights reserved." > > FUNCTION INTRO_TESTAJAX( oHtml, oContext ) > LOCAL aCountries := { "", "England", "France", "Germany", "USA" } > LOCAL n > LOCAL cId > LOCAL cValue > > oHtml:put( strtran( doctype(), "$1$", procname())) > oHtml:put([<script language='JavaScript' type='text/javascript'>]) > > oHtml:put([function SET_CUSTOMER( country ){]) > oHtml:put([ var url = "/cgi-bin/waa1gate.isa";]) > oHtml:put([ var params = > "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_CUSTOMER&COUNTRY=" + country; ]) > oHtml:put([ var ajax = new Ajax.Updater( {success: 'customer'},]) > oHtml:put([ url, ]) > oHtml:put([ {method:'post', > parameters:params});]) > oHtml:put([ params = "WAA_PACKAGE=TESTAJAX&WAA_FORM=NOTDEF"; ]) > oHtml:put([ ajax = new Ajax.Updater( {success: 'product'},]) > oHtml:put([ url, ]) > oHtml:put([ {method:'post', > parameters:params});]) > oHtml:put([}]) > > oHtml:put([function SET_PRODUCT( customer ){]) > oHtml:put([ var url = "/cgi-bin/waa1gate.isa";]) > oHtml:put([ var params = > "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_PRODUCT&CUSTOMER=" + customer; ]) > oHtml:put([ var ajax = new Ajax.Updater( {success: 'product'},]) > oHtml:put([ url, ]) > oHtml:put([ {method:'post', > parameters:params});]) > oHtml:put([}]) > > oHtml:put([</script>]) > oHtml:put([</head>]) > oHtml:put([<body>]) > oHtml:put([<form name="fS" id="fS" onsubmit="return false" > ACTION="/cgi-bin/waa1gate.isa" METHOD=POST>]) > oHtml:put([<input type="hidden" name="WAA_PACKAGE" id="WAA_PACKAGE" > value="TESTAJAX" /> ]) > oHtml:put([<input type="hidden" name="WAA_FORM" id="WAA_FORM" > value="SAVE_TESTAJAX" />]) > > country select > oHtml:put([<div id="top" >]) > oHtml:put([Pick a Country ]) > oHtml:put([<select name="COUNTRY" id="COUNTRY" size="1" > onChange="SET_CUSTOMER( this.value );" >]) > for n := 1 to len( aCountries ) > cId := aCountries[n] > cValue := aCountries[n] > oHtml:put([<option value="] + cId + [">] + cValue ) > next > oHtml:put([</select>]) > oHtml:put([</div>]) > > customer select > oHtml:put([<div id="customer" >]) > oHtml:put([<p>Customer Select will display here...</p>]) > oHtml:put([</div>]) > > product select > oHtml:put([<div id="product" >]) > oHtml:put([<p>Product Select will display here...</p>]) > oHtml:put([</div>]) > > oHtml:put([<div id="bottom" >]) > oHtml:put([<input type="button" name="SAVE" id="SAVE" value="CONTINUE" > onClick="document.getElementById('fS').submit();" />]) > oHtml:put([</div> ]) > oHtml:put([</body>]) > oHtml:put([</html>]) > return (.T.) > > FUNCTION STUFF_CUSTOMER( oHtml, oContext ) this is the function > called by Ajax.Updater > LOCAL aCustomers > LOCAL cCountry > LOCAL cId > LOCAL cValue > LOCAL n > > cCountry := oHtml:getVar("COUNTRY" ) > aCustomers := { "AACME", "BACME", "CACME", "DACME"} > > oHtml:put([Now, pick a Customer from ] + cCountry + [ ]) > oHtml:put([<select name="CUSTOMER" id="CUSTOMER" size="1" > onChange="SET_PRODUCT( this.value );">]) > for n := 1 to len( aCustomers ) > cId := aCustomers[n] > cValue := aCustomers[n] > oHtml:put([<option value="] + cId + [">] + cValue ) > next > oHtml:put([</select>]) > return (.T.) > > FUNCTION STUFF_PRODUCT( oHtml, oContext ) this is the function > called by Ajax.Updater > LOCAL aProducts > LOCAL cCustomer > LOCAL cId > LOCAL cValue > LOCAL n > > cCustomer := oHtml:getVar("CUSTOMER" ) > aProducts := { "AWIDGET", "BWIDGET", "CWIDGET", "DWIDGET"} > > oHtml:put([Now, pick a Product for ] + cCustomer + [ ]) > oHtml:put([<select name="PRODUCT" id="PRODUCT" size="1" >]) > for n := 1 to len( aProducts ) > cId := aProducts[n] > cValue := aProducts[n] > oHtml:put([<option value="] + cId + [">] + cValue ) > next > oHtml:put([</select>]) > return (.T.) > > FUNCTION NOTDEF( oHtml, oContext ) > oHtml:put([<p>Product Select will display here...</p>]) > return (.T.) > > FUNCTION SAVE_TESTAJAX( oHtml, oContext ) > LOCAL aValues > LOCAL n > LOCAL cField > LOCAL cValue > oHtml:put( strtran( doctype(), "$1$", procname())) > oHtml:put([</head>]) > oHtml:put([<body>]) > aValues := oHtml:getAllVars() each element of aValues is { "var > name", {array of var values} } > for n := 1 to len( aValues ) > cField := aValues[n][1] > cValue := aValues[n][2][1] > oHtml:put([<p>] + cField + " = " + cValue + [</p>]) > next > oHtml:put([</body>]) > oHtml:put([</html>]) > return (.T.) > > FUNCTION DOCTYPE() > return ([<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"] > + CRLF + ; > ["http://www.w3.org/TR/html4/loose.dtd">] + CRLF + ; > [<html>] + CRLF + ; > [<head>] + CRLF + ; > [<link type='text/css' href='/TESTAJAX.css' rel=stylesheet>] + > CRLF + ; > [<title>$1$</title>] + CRLF + ; > [<META HTTP-EQUIV="Pragma" CONTENT="no-cache">] + CRLF + ; > [<META HTTP-EQUIV="Expires" CONTENT="-1">] + CRLF + ; > [<script src='/PROTOTYPE.js' type='text/javascript' ></script>] + > CRLF ) > > | |
Anand Kumar Gupta | Re: Something Yummy from Steffen's kitchen on Thu, 19 Mar 2009 12:39:50 +0530 Bruce Is there a possibility that you can host the demo as well ? I would love to see the demo as well. Since I have not worked on WAA at-all (other then playing with it when it was initially launched with 1.3 or so). Sorry for bothering you ! Anand "Bruce Anderson" <banderson@graphical-db.com> wrote in message news:7f34658a$76b8ec2c$e9e@news.alaska-software.com... > Here is one more example. This is a cascade of three <select> controls, > country->customer->product, where the options can depend on the previous > select, just insert the appropriate database coding. > > Bruce Anderson > Graphical Database Programs > | |
Bruce Anderson | Re: Something Yummy from Steffen's kitchen on Thu, 19 Mar 2009 09:10:41 -0500 I will work up something and put it on my server. Should not take too long. Stay tuned. | |
Boris Borzic | Re: Something Yummy from Steffen's kitchen on Wed, 01 Apr 2009 21:33:32 +0200 Bruce, Here is an Xb2.NET version of your simple AJAX sample: Assuming xb2.net webserver is running on same machine, url to react test function is: http://localhost/ajaxtest? PROCEDURE WEB_AjaxTest( nAction ) Static cHtml Local cResponse if cHtml == nil TEXT INTO cHtml TRIMMED <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Xb2.NET AJAX Test</title> <script src='prototype.js' type='text/javascript' ></script> <script language='javascript' type='text/javascript'> function ServerTime(){ var ajax = new Ajax.Updater({success: 'ajaxstuff'}, 'AjaxTest(1)?', {method:'get', parameters:''}); } function ServerDate(){ var ajax = new Ajax.Updater({success: 'ajaxstuff'}, 'AjaxTest(2)', {method:'post'}); } </script> </head> <body onload="setInterval('ServerTime()', 1000);"> <div id="top" ><br>this is top text</div> <div id="ajaxstuff" ><br>Ajax data will load here...</div> <div id="bottom" ><br>this is bottom text <input type="button" value="get server date" onclick="ServerDate()" /> </div> </body> </html> ENDTEXT endif do case case empty(nAction) .or. valtype(nAction) != "N" cResponse := cHtml case nAction == 1 cResponse := "<br>" + time() case nAction == 2 cResponse := "<br>" + dtos(date()) endcase ThreadObject():HTTPResponse:Content := cResponse Return Best regards, Boris Borzic http://xb2.net http://sqlexpress.net industrial strength Xbase++ development tools "Bruce Anderson" <banderson@graphical-db.com> wrote in news:7b652302$492fcae5$1ee@news.alaska-software.com: > In mid February, Steffen showed a way to use the Prototype.js > functions withWAA. It is, hands down, the easiest way to incorporate > AJAX into a webpage. Here is an example I have developed. This shows > both a repeating call to a function in a WAA dll and a simple > pushbutton executed function call. Because the calls are to WAA > functions, this gives us a simple way to put a window on the web page > which is continously updated from the database. > > THIS IS THE BASIC PAGE... ><html> ><head> ><title>TESTAJAX</title> ><META HTTP-EQUIV="Pragma" CONTENT="no-cache"> ><META HTTP-EQUIV="Expires" CONTENT="-1"> ><script src='/PROTOTYPE.js' type='text/javascript' ></script> > ><script language='JavaScript' type='text/javascript'> > function MAGIC(){ > var url = "/cgi-bin/waa1gate.isa"; > var params = "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_INTRO"; > var ajax = new Ajax.Updater( {success: 'ajaxstuff'}, > url, > {method:'post', parameters:params}); > } > function MORE_MAGIC(){ > var url = "/cgi-bin/waa1gate.isa"; > var params = "WAA_PACKAGE=TESTAJAX&WAA_FORM=STUFF_INTRO2"; > var ajax = new Ajax.Updater( {success: 'ajaxstuff'}, > url, > {method:'post', parameters:params}); > } ></script> ></head> ><body onload="setInterval('MAGIC()', 1000);"> ><div id="top" > ><p>this is top text</p> ></div> ><div id="ajaxstuff" > ><p>Item will load here...</p> ></div> ><div id="bottom" > ><p>this is bottom text<br /> ><input type="button" name="mButton" value="Do More Magic" > onClick="MORE_MAGIC();" /></p> ></div> ></body> ></html> > > > THESE ARE THE WAA FUNCTIONS... > > FUNCTION STUFF_INTRO( oHtml, oContext ) > LOCAL cTime := time() > oHtml:put([<p>] + cTime + [</p>]) > return (.T.) > > FUNCTION STUFF_INTRO2( oHtml, oContext ) > LOCAL cDate := dtoc(date()) > oHtml:put([<p>] + cDate + [</p>]) > return (.T.) | |
Phil Ide | Re: Something Yummy from Steffen's kitchen on Thu, 02 Apr 2009 17:49:11 +0100 Bruce, can I point out that using AJAX in xbHCL is extremely trivial, and the code is portable between WAA and Xb2.NET. Additionally, since the web page is created dynamically at runtime, you can change both the (static) contents of the page and the AJAX functions called by the page to suit the user (e.g. language, frequency of ajax refresh etc.). Since xbHCL incorporate the entire HTML v4.x syntax into Xbase++, plus allows you to code your jscript routines within your Xbase++ code, you can actually generate a bespoke jscript routine for individual users. All this and the same code runs without changes in WAA and Xb2.NET Regards, Phil Ide --------------------- www.xbhcl.com www.pbih.eu www.idep.nl --------------------- This Tagline for Sale | |
Brian L. Wolfsohn | Re: Something Yummy from Steffen's kitchen on Thu, 02 Apr 2009 21:28:29 +0200 Phil Ide <phil@pbih.eu> wrote in news:1q2m0uqo2wam3$.185r8u4f69wxq.dlg@40tude.net: > Bruce, can I point out that using AJAX in xbHCL is extremely trivial, > and the code is portable between WAA and Xb2.NET. Additionally, since > the web page is created dynamically at runtime, you can change both > the (static) contents of the page and the AJAX functions called by the > page to suit the user (e.g. language, frequency of ajax refresh etc.). > > Since xbHCL incorporate the entire HTML v4.x syntax into Xbase++, plus > allows you to code your jscript routines within your Xbase++ code, you > can actually generate a bespoke jscript routine for individual users. > > All this and the same code runs without changes in WAA and Xb2.NET Phil, It's really great to have you "back in the saddle" so to speak.. I've looked at your ajax stuff in the past, and we still have a need for it in our system. What's the status on pushing info only if it's needed i.e. only if the info has changed ?? best regards, Brian | |
Thomas Braun | Re: Something Yummy from Steffen's kitchen on Fri, 03 Apr 2009 09:47:28 +0200 Brian L. Wolfsohn wrote: > I've looked at your ajax stuff in the past, and we still have a need for > it in our system. What's the status on pushing info only if it's needed > i.e. only if the info has changed ?? I don't think this is something AJAX can be used for - "pushing" implies the server sending information to the browser without getting a request first... which is impossible with HTTP, as it is "stateless". The server gets a request, sends the answer and that's it. The user might have closed his browser meanwhile, even the IP address might have changed (yes, there are ISPs where the external IP changes while being connected) - let alone all kinds of problems with NATting routers and firewalls between your server and the client. So (with HTTP) there is no way how this probably could work. AJAX could be used in this context to periodically send a request from the browser to ask the server for changed data. There are even javascript frameworks where you can define that the intervals between polls is increased when no new data is received for a defineable period. (I hope it is clear what I mean regards thomas | |
Boris Borzic | Re: Something Yummy from Steffen's kitchen on Fri, 03 Apr 2009 15:21:24 +0200 Thomas Braun <spam@software-braun.de> wrote in news:16hwtzls81epj$.m4ghuimnvzi4.dlg@40tude.net: > I don't think this is something AJAX can be used for - "pushing" > implies the server sending information to the browser without getting > a request first... which is impossible with HTTP, as it is > "stateless". The server gets a request, sends the answer and that's > it. Yes, but there is nothing to say that you can't keep the "answer" coming. The trick is to not terminate the response, but rather keep sending small bits of data using chunked transfer encoding. There are two examples included with Xb2.NET showing how to do that. If you have Xb2.NET, run the sample WEBSERVE.EXE server and navigate to the following URL's: http://localhost/SendChunks? http://localhost/ProgressBar? > The user might have closed his browser meanwhile, even the IP address > might have changed (yes, there are ISPs where the external IP changes > while being connected) - let alone all kinds of problems with NATting > routers and firewalls between your server and the client. So (with > HTTP) there is no way how this probably could work. This is no problem. As long as the connection is kept active, the IP will not change. Firewalls are also no problem since this is standard HTTP. If the user closes his browser, pushes the stop button, unplugs the network cable, etc... then the Xb2.NET server will receive a socket error as soon as the next chunk is sent. This is your signal to stop sending chunks and terminate the worker thread. > AJAX could be used in this context to periodically send a request from > the browser to ask the server for changed data. This is the traditional way because it is difficult to continualy send chunked data in a ISAPI or CGI (not sure it's possible) type of application. With Xb2.NET, this is trivial because your application has a direct socket connection to the client. Here's the SendChunks sample: //------------------------ PROCEDURE WEB_SendChunks() Local i, cHtml, oResp get reference to current xbHTTPResponse object. ThreadObject() will return a reference to the current xbHTTPThread object oResp := ThreadObject():HTTPResponse TEXT INTO cHtml TRIMMED <html><head> <title>Xb2.NET - Sending Chunks</title> <link rel="stylesheet" type="text/css" href="Style.css"></head> <body> <b> This sample shows how to send dynamic content in discrete chunks.<br> The server will pause for one second after sending each chunk of data: </b> <br><br><ul> ENDTEXT add a transfer-encoding header field and set it to "chunked" oResp:TransferEncoding('chunked') send the message header (the content will be sent later) oResp:Send() send first chunk oResp:SendChunk(cHtml) for i := 1 to 10 if oResp:SendChunk('This is chunk # '+NTrim(i)+'<br>') == SOCKET_ERROR connection terminated Return endif pause for one second before sending the next chunk sleep(100) next oResp:SendChunk('</ul><br><hr>All done</body></html>') send an empty chunk to signal end of content oResp:SendChunk() Return Best regards, Boris Borzic http://xb2.net http://sqlexpress.net industrial strength Xbase++ development tools | |
Phil Ide | Re: Something Yummy from Steffen's kitchen on Tue, 14 Apr 2009 16:28:38 +0100 There you go, two different ways to do it, each with their own benefits. Incidentally, Boris' technique of using chunked transfers is particularly useful when viewing a scrolling 'window' of a dataset. Regards, Phil Ide --------------------- www.xbhcl.com www.pbih.eu www.idep.nl --------------------- What do you mean, you formatted the cat? |