The reason why the client uses dhtml is mainly to achieve remote, simply put it as a refresh-free effect.
File: study.htm
<!doctype html public -//w3c//dtd html 4.0 transitional//en >
<html>
<head>
<title></title>
<meta name=generator content=microsoft visual studio 7.0>
</head>
<script language=jscript>
var otblmain ;//Main table
var strhtml = ;//Temporarily use global variables
var bsavestatus = true ;//Is the save successful?
var icallid ;//The unique number that calls the webservice
//Get all items through webservice
//Then format the output through the callback function ongetitems
function getitems()
{
//Calling the getitems method of the webservice
service.myservice.callservice(ongetitems, getitems) ;
}
//Webservice callback function
function ongetitems(result)
{
if(result.error)
{
alert(result.errordetail.code + : + result.errordetail.string ) ;
return ;
}
bbxml.loadxml(result.raw.xml);
var sxml = bbxml.transformnode(bbxsl.xmldocument);
if (bbxml.parseerror.reason == )
{
strhtml = sxml;
}
else
{
strhtml = bbxml.parseerror.reason;
}
}
//Page initialization
function onload()
{
//Preparing for using webservice
service.useservice(study.asmx?wsdl, myservice);
//Define the record table object
otblmain = document.getelementbyid(tblmain);
}
//Add a new record
//The function is to add a new row to the table and define 3 td styles and event
function onadd()
{
var row = otblmain.insertrow();
row.bgcolor = #ffffff ;
var cellid = row.insertcell();
cellid.innerhtml = otblmain.rows.length - 1;
cellid.onclick = function(){onidclick(this);} ;
cellid.style.cursor = hand ;
cellid.title = selected record;
var cellitem = row.insertcell();
cellitem.style.cursor = crosshair;
cellitem.onclick = function(){onitemclick(this);} ;
var celldemo = row.insertcell();
celldemo.style.cursor = help ;
celldemo.onclick = function(){ondemoclick(this);} ;
}
//td item click event
//The function is to pop up a layer and then obtain all items through the getitems method
//After formatting as innerhtml as this new layer
function onitemclick(cell)
{
getitems() ;
var odiv = document.createelement(div);
odiv.zindex = 1 ;
odiv.style.position = absolute;
odiv.style.height = 200 ;
odiv.style.width = 300;
odiv.style.left = cell.style.left;
odiv.style.top = cell.style.top;
odiv.style.backgroundcolor = #99eeff;
odiv.style.border = '0.1cm groove blue' ;
odiv.style.overflow = auto ;
odiv.innerhtml = strhtml;
//document.body.appendchild(odiv);
cell.appendchild(odiv);
}
//td item selection event
function onitemselected(cell)
{
var otr = cell.parentelement;
var otable = otr.parentelement;
var otbody = otable.parentelement;
var odiv = otbody.parentelement;
odiv.style.display = none ;
var ocell = odiv.parentelement ;
ocell.removechild(odiv);
ocell.innertext = cell.innertext;
odiv = null ;
}
//Selected record
function onidclick(cell)
{
var tr = cell.parentelement;
if(tr.bgcolor == #99ccff)
{
tr.bgcolor = #ffffff ;
}
else
{
for(var i = 0 ; i < otblmain.rows.length ; i ++)
{
otblmain.rows[i].bgcolor = #ffffff ;
otblmain.rows[i].cells[0].title = selected record;
}
tr.bgcolor = #99ccff ;
cell.title = Unselect;
}
}
//Delete button click event
//Delete the row selected by the user and renumber the row
function ondelete()
{
var i = getselectedindex() ;
if( i == 0)
{
alert(No record to be deleted is selected!);
return false ;
}
else
{
otblmain.deletero(i);
for(var j = 1 ; j < otblmain.rows.length ; j ++)
{
otblmain.rows[j].cells[0].innertext = j ;
}
}
}
//Get the line selected by the user
function getselectedindex()
{
for(var i = 0 ; i < otblmain.rows.length ; i ++)
{
if(otblmain.rows[i].bgcolor == #99ccff)
{
return i ;
}
}
return 0 ;
}
//The click time of demo td in the table
//The function is to pop up a patterned window and the user enters multiple values
function ondemoclick(cell)
{
//alert(cell.innertext) ;
var odemo = window.showmodaldialog(demo.htm,cell.innertext, dialogwidth:200px;dialogheight:200px;resizeable:no;status:no;scroll:no) ;
if(odemo != undefined)
{
cell.innertext = odemo.name + - + odemo.amount;
}
}
//How to click on the save button
//The current method is to call the webservice to save each record in turn.
//Then clear the saved records through the callback function onsaverecords(result)
function onsave()
{
if(otblmain.rows.length < 2)
{
alert(no record can be saved!);
return false ;
}
for(var i = 1 ; i < otblmain.rows.length&& bsavestatus ; i ++)
{
var stritemname ;
var strdemoname;
var intdemoamount ;
stritemname = otblmain.rows[i].cells[1].innertext;
var arr = otblmain.rows[i].cells[2].innertext.split(-) ;
if(arr.length != 2)
{
alert (Every record must be filled in);
return false ;
}
else
{
strdemoname = arr[0] ;
intdemoamount = arr[1] ;
//alert(stritemname + , + strdemoname + , + intdemoamount) ;
window.status = ;
icallid = service.myservice.callservice(onsavercords , savevercord , stritemname , strdemonname , parseint(intdemoamount , 10)) ;
window.status = Saving + i + record... ;
}
}
}
//Save the record
function onsavercords(result)
{
if(result.error)
{
alert(result.errordetail.code + : + result.errordetail.string ) ;
bsavestatus = false ;
return ;
}
else
{
if(result.value)
{
window.status = window.status + Success! ;
otblmain.deletero(1);
}
else
{
bsavestatus = false ;
alert(Save failed due to unknown reasons!);
window.status = window.status + Failed! Terminate save! ;
}
}
}
</script>
<body onload=onload();>
<div id=service style=behavior:url(webservice.htc)>
<xml id=bbxml></xml>
<xml id=bbxsl src=item1.xsl></xml>
<br>
<h3 align=center>webservice example</h3>
<br>
<br>
<table width=600 align=center id=tblmain bgcolor=#000000 cellpacing=1>
<tr bgcolor=#ffffff>
<td width=50>Number</td>
<td width=200>item</td>
<td>demo</td>
</tr>
</table>
<p align=center>
<input type=button value=add onclick=onadd()> <input type=button value=delete onclick=ondelete()>
<input type=button value=Save onclick=onsave()>
</p>
</body>
</html>
The above htm is used to access the webservice soap through Microsoft's webservice.htc. It is encapsulated very well. The work we have to do is to parse the passed back xml. I used xsl for parsing it. The following is the content of this file
File item1.xsl
<?xml version=1.0 encoding=utf-8?>
<xsl:stylesheet version=1.0 xmlns:xsl=http://www.w3.org/1999/xsl/transform xmlns:soap=http://schemas.xmlsoap.org/soap/envelope/ xmlns:xsi=http://www.w3.org/2001/xmlschema-instance xmlns:xsd=http://www.w3.org/2001/xmlschema>
<xsl:output method=html/>
<xsl:template match=/>
<xsl:apply-templates select=//soap:body/>
</xsl:template>
<xsl:template match=soap:body>
<xsl:apply-templates select=*[local-name() = 'getitemsresponse']/*[local-name() = 'getitemsresult']//>
</xsl:template>
<xsl:template match=*[local-name() = 'getitemsresult']>
<html>
<body>
<table border=1>
<tr>
<th>name</th>
<th>value</th>
</tr>
<xsl:for-each select=*[local-name() = 'anytype' and @xsi:type='item']>
<xsl:apply-templates select=./>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template match=*[local-name() = 'anytype' and @xsi:type='item']>
<tr>
<td style=cursor:hand onclick=onitemselected(this);>
<xsl:text disable-output-escaping=yes> </xsl:text>
<xsl:value-of select=*[local-name() = 'name']/>
</td>
<td>
<xsl:text disable-output-escaping=yes> </xsl:text>
<xsl:value-of select=*[local-name() = 'value']/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
The above example is very simple, the main difficulty lies in those dhtml. But if you expand it, you can complete a lot of functions that you had to implement with activex before.