You are on page 1of 18

2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

GetStarted

Solutions Support Training Community Developer Partner

About

Community / Blogs

AWebClientAgainstaRESTAPI
withJavaScriptandXML
January13,2013 | 271Views |
RdigerPlantiko
morebythisauthor

ABAPDevelopment
bsp | css | html | http | javascript | rest | sarissa | xml | xslt

Follow

WhyREST?
ASampleRESTService
TheApplication
Testing
TheJavaScript
WorkingWiththeResponseXMLData
TheFieldAbstraction
TheSelfActualizingDropDownBox
TheTableAbstraction
Summary

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 1/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

Inapreviousblog,IdescribedaverygeneralXMLformatforAjax.In
thisblog,Ishowhowthisformatcanbeusedtobuildawebclient
againstaRESTAPI.Forsimplicity,IdevelopedanAPIwhichallowsto
maintainasingledatabasetable.Althoughsimple,itshowstheessential
ideasandcanbethoughtasabuildingblockformorecomplex
applications.

ThewebclientconsistsofanHTMLpage,JavaScriptcode,andtwo
XSLTtransformationswhichareexecutedinthebrowser.Basically,
theseobjectscouldbehostedonanywebserver,itdoesnthavetobe
theSAPWebAS.ButwhenworkingwiththeSAPWebAS,Business
ServerPagesaretherightframeworkforthis:Weneedtorollourown
applicationspecificJavaScriptandHTMLcode,andwewantthefull
controlovereverysinglebytegoingouttotheclient.

WhyREST?

WhenenteringanURLinthebrowser,itdisplaysthewebcontentthat
correspondstothisURL.Thisisafunctionalcorrespondence:The
detailedcontentisafunctionofthatURLalone(atleastforstaticweb
pages,whichdonotchangeintime).Technically,thebrowserperforms
aGETrequestforthatURL,withemptyHTTPbody.

Thisfunctionalviewconsideringthecompleteressourceasa
functionoftheURL,ressource=f(URL)extendsinanatural
mannertoremoteobjects.AnURLcanbeseenasashortformofan
object.Thecompletedatadescribingtheobjectcanbecalledusingan
HTTPGETrequest.Frequently,theIDornumberofanobjectwillthen
bepartoftheURL,sothattheURLpathendswithareadable
expression,like/order/4711.

Inordertoremotelychange,create,ordeleteobjects,furtherHTTP
methodsapartfromGEThavetobeconsidered:Naturalchoicesare
PUTforcreateandchangeoperations,DELETEfordeletion,andPOST
foractionswhichchangestateonserverside,butcannotbeseenasan
operationonasingleobject.Foralltheseoperations,itmakessenseto
usetheHTTPrequestbodytocarryfurtherinformation:InthePUT
case,forexample,thebodymaycontaintherepresentationoftheobject
thatistobecreatedorchanged.

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 2/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

RESTbuildsonHTTPastransferprotocolandexploitsitinmoredetail
thanalternativeslikeSOAP.WhileinSOAPallthecontextofthe
operationiscarriedasenvelope,aspartoftheHTTPrequestbody,
RESTusesHTTPitselftoconveythiscontext:HTTPstatuscodes,
HTTPmethods,HTTPheaderfieldslikeAcceptareusedforthe
negotiationsbetweenclientandserver.RESTcanbeseenasanatural
applicationofHTTPforremoteobjectaccess.ItistiedtoHTTP,reusing
theHTTPfeatures(whichcanbeseenasadisadvantageaswell:Its
notpossibletouseRESTwithanotherprotocolthanHTTP).

ASampleRESTService

Everycomplexapplicationdecomposesintosimplebuildingblocks.Ifa
relationaldatabasesystemisusedformodelling,suchasimplebuilding
blockcouldberesponsibleforthemaintenanceofthedatacontainedin
oneparticulardatabasetable.Itismorethanwhatpeopleusuallycalla
DAO(DataAccessObject),becauseitnotonlytakescareaboutthe
databaseupdates,butalsoincorporatestherulesconnectedwiththese
data:consistencychecks,logic,mapping,anddependencieswithother
entitiesofthesystem.

Fortestpurposes,IhavewrittenalittleHTTPserviceforhandlingan
imaginarytableofaBatchJobManagementsystem.Imaginean
applicationforplanningallthebatchjobsrunninginthesystem.

Well,wehaveSM36andSM37,youmightsay

ButwemaywantsomeadditionalinformationbeyondtheSM37data:
Foreachjob,wewantnotonlytoknowthevariantandreportnameto
bestarted,butalsoacontactperson,atextforshortnotes,apriority
(howimportantisitthatthisjobruns?),andtheinfowhetherthisjob
cansimplyberestartedafterafailure.

ThesejobattributesarekeptindatabasetableZJOBS,witha4digitID
askey.TheserviceundertheURL

http://bsp.mits.ch/buch/job/attributes/

acceptsGET,PUTandDELETErequests(andaspecialPOSTrequest).
Asresponse,itsendsXMLdatabacktotheclient,intheAjaxResponse
formatdescribedinmyearlierblog.

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 3/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

AsingleentityarowinthedatabasetableisdescribedbytheseXML
data:

<jobid="0001">
<descr>Outputallsalesorderconfirmations</descr>
<repid>RSNAST00</repid>
<varid>UXPD_KUBE_KV</varid>
<prio>2</prio>
<restart>X</restart>
<contact>RainerZufall</contact>
</job>

TheIDofthejobinquestionmaybeappendedtotheURLpath,ifthe
operationrequiresanidentifiedobject.So,forexample,theHTTP
request

DELETEattributes/0001

denotestherequesttodeletethejobwiththeID0001.

Additionally,thistestserviceoffersaspecialPOSTrequest,

POSTattributes/reset

whichrestoresthetestdata.

TheserviceiswrittenasanABAPrequesthandler.Inaforthcomingblog
IwillgivesomedetailsonwritingRESTservicesinABAP.

Thefocusinthepresentblogisonhowtowritewebapplicationsbased
onsuchservices.

TheApplication

IhavewrittenademoBSPapplication,accessibleundertheURL
http://bsp.mits.ch/buch/zz_jobs/jobs.htm.Hereishowitlooks(thebutton
andtabledesignisshamelesslystolenfromtheSAPRetailStore
design):

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 4/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

Youseethattheapplicationiscomposedoffourparts:

Amessagearea,reservedforthedisplayofsinglemessagelines,
Aninputarea,consistingofinputtextfields,listboxes,
checkboxes,forchangingtheattributesofasinglejob
Abuttonarea,presentingthedifferentchoicesofuser
commands,
Atablearea,displayingtheactualcontentofthejobtable.

TheHTMLcodeandtheJavaScriptcodeshouldreflectthisvisible
structure.Beforegoingintomoredetails,Iwanttotalkaboutoneofthe
mostimportantpartsofanydevelopment:

Testing

Whentheapplicationisinbeing,itsthebesttimetostartwithtests.
Usedatanearlystage,testshelptodiscoverbugsattheroot
immediatelywhentheyareproduced.Thisearly,theyareeasyto
analyzeandtofix.Duringdevelopment,Icanaddscenarioafter
scenariotoanautomatedtestsuite,ensuringalltheprocessesare
performedproperly.

Inaverypopularbrowsercomparison,Firefoxisaccusedforits
numerousplugins.Also,Firefoxclearlydoesntwinthebrowserspeed
contest.Theremaybesometruthinthesecritiques,buttherearetwo
pluginsthatIfindparticularlyusefulandthatmakeFirefoymyfavorite
browserfordevelopingwebapplications:TheSeleniumIDE,and
Firebug.Withtheseplugins,itbecomesveryeasytodetectbugsandto
keepthefunctionalitystableduringdeveloping.Hereisascreenshotof
sometestsinaction(clicktoenlargetheimage):

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 5/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

TheJavaScript

Orderedfrommostabstracttomostspecific,Iusethefollowing
JavaScriptressources(eachofthemsmallinsize):

AminimalisticJavaScriptlibraryminlib.js(whichispartofthe
global.jsofmyBSPframework),thecoderequiringabout7KB.
Thisisnotanessentialingredientoftheapplication.Itonlyhelps
writingshorterJavaScript,byprovidingshortcutsandbrowser
independentfunctionsforthemostcommonJavaScriptcalls.For
example,thefunctionbyId()simplyisashortcutfor
document.getElementById().Also,thefunctiondoRequest()isa
crossbrowserabstractionoftheXMLHttpRequestobject.
Sarissa.jswhichhelpshandlingXSLTtransformationsandXML
Documentsinthebrowser.Needs12KB.
globalAjax.jsasetofobjectsforconnectingXMLdatawithweb
objectsliketablesorinputfields.Needs3.5KB.
ApplicationspecificJavaScriptcode.Thisisthespecific,non
reusablepartofthecodeforservingthisparticularapplication.It
requires10KB.IleftitinthesourcecodeoftheHTMLpagefor
easyinspection.Usually,thiscodewillbeanownfilebelongingto
theMIMEobjectsofanapplication.

Ontopofallthecodearetheuseractions,triggeringthefollowup
actions.Forexample,thereisaSavebutton,definedintheBSPlayout
withthehelpofaBSPextensionelement:

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 6/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

<z:buttonfcode="SAVE"
onClick="saveJob();"
text="<%=otr(Z_MVC_EXAMPLE/SICHERN)%>"/>

Thisrendersthebutton

andattachesthefunctionsaveJob()asclickhandler(puristsmayargue
thataDOMlevel2registrationwouldbebetterhereandtheyare
right.Butthisisadetail.)Whentheuserhitsthebutton,thefunctionwill
becalled.Ithasto

takeactiononlyifthereisatleastareportnamespecifiedinthe
inputarea,
takethedatafromtheinputareaandputthemintoajobXML
structure,
callthePUTmethodoftheJobAttributesAPI,withthatXML
documentintheHTTPbody,
displayapotentialmessage,andupdatetherowinthejobtable,
assoonastheAPIcomesback.

Thisisthefunctionwhichaffordsallthis:

functionsaveJob(){
if(notEmpty("repid")){
callJobAttributes("PUT",function(){
jobTable.updateRows(this.responseXML);
});
}
}

Similarly,thedeleteJob()functionlookslikethis:

functiondeleteJob(){
if(notEmpty("id")){
callJobAttributes("DELETE",function(){
jobTable.deleteRows(this.responseXML);
resetInput();
});

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 7/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs
}
}

WorkingWiththeResponseXMLData
ThecommonfunctioncallJobAttributes()isresponsibleforcallingthe
JobAttributesAPI.ItcollectstheinputareaintoanXMLdocument,
attachesittotheHTTPbodyofarequest,sendsthisrequestasAjax
request,registeringahandlerforcallbackwhentheresponsecomesin.

//Callthe"jobattributes"API
//"action"=HTTPaction:OneofPUT,POST,GET,DELETE,OPTIONS
functioncallJobAttributes(action,handler,suffix){
varid=getText("id");
varurl=ajaxBaseURL+
"/attributes/"+
(suffix===undefined?id:suffix);
varjobDOM=xmldocFromInputFields("repid,varid,prio,descr,restart,contact"
byTagName("job",jobDOM)[0].setAttribute("id",id);
sendAjaxRequest(url,handler,jobDOM,action);
}

Atthispoint,weareintheglobalAjax.jslayer:Thefunctions
xmldocFromInputFields()andsendAjaxRequest()aregeneralinnature
notspecifictothisapplication.Therefore,theyareimplementedin
globalAjax.js.

//SendanAjaxrequest,handlemessageelementinresponse
//Dofollowupactiononlyiftherewasnoerror
functionsendAjaxRequest(url,handler,data,action){
doRequest(url,function(){
if(!this.responseXML){
throw"NoresponsetoHTTPrequest"+url;
}
checkMessage(this.responseXML);
if(handler&&!errorOccurred())handler.call(this);
},data,action,
{"ContentType":"text/xml;charset=ISO88591"});//still...
}

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 8/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

Here,doRequest()istheblankXMLHttpRequestfunctionitself(located
inthemostgenerallayer,intheJavaScriptframeworkminlib.js).

IftheContentTypeoftheresponseisttext/xml,thedatabrowserwill
parsethedataoftheresponseintoanXMLdocument,accessibleas
attributeresponseXMLoftheXMLHttpRequestobject.Itcanbe
evaluatedwithDOMfunctions.Forexample,themethod
checkMessage()looksfortheexistenceofa<message>elementand,if
so,rendersthemessagewiththegiventextandmesssagetype.Ifthere
are<field>childelements,thenthosewillberenderedaserrorfields:

//CheckswhetherthepassedDOMobjectcontainsa<message>element
//Ifso,themessagetextisplacedintotheapplication'smessagearea
//andgiventhestyleaccordingtoitstype
//Also,erroneousinput<field>saremarked
varmsgClass={E:"error",W:"warning",I:"info",S:"success"
functioncheckMessage(xmlNode,theMsgId){
varmsgId=theMsgId||"msg";
resetMessage(msgId);
byId(msgId).className="";
byTagName("input").each(resetError);
byTagName("message",xmlNode).each(function(msg){
varmsgType=msg.getAttribute("type");
setMessage(msgId,msg.getAttribute("text"),msgClass[msgType]);
if(msgType.match(/[EAX]/)){
byTagName("field",msg).each(function(field){
setErrorField(field.getAttribute("name"));
});
}
throw$break;//Thereisonlyonemessageelement
});
}

TheFieldAbstraction
Whenfillingcontrolelementslikeinputfields,checkboxes,listboxesor
textareaswithdatafromtheserver,itisofadvantagetohaveaunified
interfaceforsettingandgettingdatafromit.Sometimes,onlythevalue
attributehastobefilledlikeforinputfields.Forcheckboxes,theABAP
flagvalueXshouldcorrespondtosettingthecheckedattribute.For
listboxes,apreprocessingshouldbeperformedtoadjustthesetof
availableoptions.Allthesefunctionsshouldbeaddressedbyan
identicalinterface.

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 9/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

ThiscanbeperformedwiththeFieldabstraction.ThecallofField([id])
retrievesorcreatesanobjectinstancewithaset(value)andaget()
function.

Consider,forexample,thestatement

Field("restart").get();

Thisshouldquerythestateofthecheckboxrestart.Ifitischecked,the
callshouldreturnanXifnot,.Similarly,thefollowingstatements
setsthecheckedattribute:

Field("restart").set("X");

Duetotheunifiedinterface,thecheckboxcanbetreatedlikeanyother
inputfieldwhendataarepassedtoorretrievedfromtheserver.

Anotherexample:

Field("varid").set("test");

Thisshouldnotonlysettheselectedoptionofthevariddropdown
fieldtotest:Beforethishappens,ithastoverifythatthecurrentsetof
variantsstillcorrespondstothecurrentreportid.Ifnot,thenewvariants
havetoberetrievedfromtheserver,andonlyafterthat,thevaluehasto
beset.

Letsstartwithaninstancemanagement,attachingobjectstoids:

functionField(idOrNode){
varfield=getElement(idOrNode);
varf=Field.functions[field.id];
if(!f){
f=Field.setNew(field);
}
returnf;
}Field.functions={};

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 10/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

Bydefault,thereissomestandardbehaviour,dependingontheelement
nameanditstypeattribute:

Field.setNew=function(field){
vartype=(field.nodeName=="INPUT")?field.type:field.nodeName
varf;
switch(type){
case"checkbox":
f=newCheckboxField(field);
break;
case"SELECT":
case"TEXTAREA":
case"text":
f=newInputField(field);
break;
default:
f=newSpanTextField(field);
}
return(Field.functions[field.id]=f);
}

Now,thestandardInputFieldobjecttypeisdefinedquitestraightforward:

functionInputField(field){
this.field=field;
}
InputField.prototype.set=function(value){this.field.value=value
InputField.prototype.get=function(){returnthis.field.value;}

Forcheckboxes,thereisalittlebitmorelogic:

functionCheckboxField(field){
this.field=field;
}
setAttributes(CheckboxField.prototype,{
set:function(value){this.field.checked=(value=="X");},
get:function(){returnthis.field.checked?"X":"";}
});

(Here,theminlibframeworkfunctionsetAttributes(left,right)copiesall
membersoftherightobjecttotheleftobject.)

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 11/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

TheSelfActualizingDropDownBox

AsthefinalField()example,hereisthelogicforalistboxwithautomatic
actualizionofitsoptionsetthemostcomplexFieldinstancetype.

Thedropdownboxforvariantsobviouslydependsonthecontentofthe
inputfieldcontainingtheprogram.

Theoptionsaretobereselectedwhenevertheprogramnameis
changed.WithaGETrequest,thenewoptionscanberetrievedfrom
theserver:

Asinmorecomplexcases,alittlestylesheettobeexecutedontheclient
willtransformthesedataintoHTMLelements.Theresulting<option>
elementswillthenbethenewcontentofthedropdownfield.

<xsl:stylesheetxmlns:xsl="http://www.w3.org/1999/XSL/Transform"version
<xsl:templatematch="report">
<select>
<xsl:applytemplates/>
</select>
</xsl:template>
<xsl:templatematch="variant">
<optionvalue="{@name}">
<xsl:valueofselect="@text"/>
</option>
</xsl:template>
</xsl:stylesheet>

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 12/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

Thedropdownboxhastobeinitializedonceatpageloading,bycalling
newSelect().Oncethisisdone,theField(varid).set()methodworks
asexpected:Onchangeofrepid,thenewvariantswillbereselected
beforethevalueisset.

variantsSelect=
newSelect("varid",
function(){
returnajaxBaseURL+"/variants?repid="+getText
},
"xslt/variants.xsl");

HereistheimplementationofthosedropdownFields.Theconstructor
needs

theIDoftheselectbox
afunctiongetOptionsURL()returningtheURLwhichcanbeused
toretrievethecurrentsetoflistboxvalues
astringtransformOptionsURLpointingtoanXSLT,transforming
theXMLresponseofthegetOptionscallintoalistofHTML
<option>elements.

Observethattheimplementationisgeneric.Itcontainsnothingspecial
tooursampleapplication.Selectobjectsforselfactualizingdropdown
boxescanbereusedinanyotherwebapplication,andtherecanbe
multipleinstances,i.e.multipledropdownboxesperpagehandledin
thismanner.

//Anabstractionfordropdownfieldswhichareactualizedby
//XMLdocumentsfromtheserver
functionSelect(selectElement,getOptionsURL,transformOptionsURL){
this.selectElement=getElement(selectElement);
this.getOptionsURL=getOptionsURL;
this.transformOptionsURL=transformOptionsURL;
this.transformer=null;
this.lastURL="";

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 13/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs
varselectObject=this;//Fortheclosure...
if(this.selectElement.id){
//Specialruleforputtingavalueintothelistbox
//Determinetheproperselectionsbeforesettingthevalue
Field(this.selectElement.id).set=function(value){
selectObject.actualizeAndSetValue(value);
};
}
}
setAttributes(Select.prototype,{
//Asynonym,forbetterreadabilityoftheclientcode
actualizeAndSetValue:function(setValue){
this.actualize(setValue);
},
//Usethismethodwithoutargumentifyouonlywanttoupdatethelistbox
actualize:function(setValue){
varselect=this;
varnewURL=this.getOptionsURL();
if(this.lastURL!=newURL){
if(this.transformer){
doRequest(newURL,function(){
checkMessage(this.responseXML);
Sarissa.clearChildNodes(select.selectElement);
vardom=select.transformer.transformToDocument(this.responseXML
byTagName("option",dom).each(function(opt,i){
varoption=newOption(
opt.firstChild.data,
opt.getAttribute("value")
);
select.selectElement.options[i]=option;
});
if(typeofsetValue=="string")select.selectElement.value
select.lastURL=newURL;
});
}
else{
doRequest(this.transformOptionsURL,function(){
select.transformer=newXSLTProcessor();
select.transformer.importStylesheet(this.responseXML);
select.actualize(setValue);
});
}
}
else{
if(typeofsetValue=="string")select.selectElement.value=setValue
}
}
});

TheTableAbstraction

Letscomebacktotheexampleofthesavebutton:Whentheuserhits
it,thefollowingfunctionistriggered:

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 14/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

functionsaveJob(){
if(notEmpty("repid")){
callJobAttributes("PUT",function(){
jobTable.updateRows(this.responseXML);
});
}
}

TheupdateofthevisibledatatablefromtheresponseXMLdatacoming
backfromtheserver,isperformedwiththemethodupdateRows()ofthe
jobTableobject.Ittransformstheresultintoacollectionof<TR>
elementsandcopiesthemintothepage.Thisisaninstanceofanother
abstractiontheTableabstraction.

Whenthepageisloaded,thetableobjecthastobecreatedand
providedwith

acontainerelementofthepage,designedascarrierofthetable,
and
theURLofthepostprocessingXSLTtransformationwhichmaps
theAjaxresultintoHTMLelementdata:

jobTable=newTable("jobTableArea","xslt/tableTransformer.xsl");

Oncetheobjectiscreated,methodslikeupdateRows(xmldoc)and
deleteRows(xmldoc)canbecalledintheAjaxcallback,usingthe
xmlResponsedocumentasargument.Onlyrequirementforthistowork
isthattheHTMLtablerows(the<TR>elements)shouldhaveanID.
Thisisnecessarysincethetableperformsaperrowupdateanddelete,
makingitpossibletotransferonlysubsetsoftherows.

//Anabstractionfordynamictables,whichareactualizedby
//XMLdocuments,tobetransformedintoHTMLwitha"rowtransformer"
functionTable(tableArea,rowTransformerURL){
this.tableArea=getElement(tableArea);
this.table=null;//willbefilledlater
this.body=null;//willbefilledlater
this.rowTransformer=null;//willbeloadedwhenrequired
this.rowTransformerURL=rowTransformerURL;
}
setAttributes(Table.prototype,{
buildInitial:function(xmldoc){

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 15/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

vartableArea=this.tableArea;
vartable=this;
Sarissa.clearChildNodes(tableArea);
this.transform(xmldoc,function(){
Sarissa.moveChildNodes(this,tableArea);
table.table=byTagName("table",table.tableArea)[0];
table.body=byTagName("tbody",table.tableArea)[0];
},true);
},
transform:function(xmldoc,callback,with_title_row){
vartable=this;
if(this.rowTransformer){
this.rowTransformer.setParameter(null,"with_title_row",!!with_title_row
callback.call(table.rowTransformer.transformToDocument(xmldoc
}
else{
//LoadXSLTtransformationfortablerows
doRequest(this.rowTransformerURL,function(){
table.rowTransformer=newXSLTProcessor();
table.rowTransformer.importStylesheet(this.responseXML);
table.transform(xmldoc,callback,with_title_row);
});
}
},
updateRows:function(xmldoc){
vartable=this;
this.transform(xmldoc,function(){
varresult=this;
varrows=byTagName("tr",result);
rows.each(function(row){
varid=row.getAttribute("id");
if(!byId(id)){
//Rowdoesnotexistyetcreate
table.table.insertRow(1).id=id;
table.actualizeZebraStripes();
}
//Rowexistsfillwithdata
table.updateCellData(row);
});
});
},
deleteRows:function(xmldoc){
vartable=this;
this.transform(xmldoc,function(){
byTagName("tr",this).each(function(row){
table.body.removeChild(byId(row.getAttribute("id")));
});
table.actualizeZebraStripes();
});
},
updateCellData:function(xmlrow){
if(!xmlrow)return;
vartarget=byId(xmlrow.getAttribute("id"));
Sarissa.copyChildNodes(xmlrow,target);
},
actualizeZebraStripes:function(xmldoc){
varrows=byTagName("tr",this.body);
rows.each(function(row,i){
row.className="zebra"+(i%2+1);
});
},
https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 16/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

getCellsForRow:function(id){
varcells=byId("row_"+id).cells;
//Makeita"real"array,withallarraymethodsaccessible:
returnArray.prototype.slice.call(cells,0);
}
});

ObserveagainthatTable(),likeField(),isarealabstraction.Itdoesnt
containanyapplicationspecificcodeandisthereforelocatedin
globalAjax.js.Thetimetoimplementitisspentonlyonce.Inaparticular
application,thereisonlyasmallXSLTtransformationnecessaryto
adaptthedatafromtheXMLresponseformattoHTML.Fromthere,
theycanbeimportedintotheHTMLdocument.

Summary

Inthisblog,Ihaveshownhowtoimplementawebapplicationasclient
foraRESTAPI,usingXMLastransferlanguage(whichoncewasthe
intendedformatforAjax).Fortestpurposes,IexposedasampleREST
servicehttp://bsp.mits.ch/buch/job/attributes/andanapplication
http://bsp.mits.ch/buch/zz_jobs/jobs.htmworkingagainstthisservice.

Idiscussedthedifferentareasoftheuserinterfacethemessagearea,
theinputarea,thebuttonareaandthetablearea.Ishowedhowto
connectthemwitheachother,andhowtoletthemcommunicatewith
theserver.ThebasicideaistouseanXSLTenabledJavaScript
frameworklikeSarissaforpostprocessingtheresponseXMLdocuments
intoHTMLfragments.Thosefragmentscanthenbesplicedintothe
currentHTMLpageusingmethodslikeSarissa.copyChildNodes().By
separatingtheconcreteapplicationalcodefromabstractionslikethe
FieldabstractionortheTableabstraction,thelattercanbereusedin
similartasks.

AlthoughthewebapplicationhasbeenwrittenasBSP,thereisnolineof
ABAPcodeinvolved.TheBSPonlyservesascontainerforHTML,CSS,
JavaScriptandXSLTressources.Thisisnomust,ofcourse.There
maybepresentationlogicwhichcouldbecomfortablyimplementedwith
thehelpofABAP.Buttheseparationbetweenpresentationlogicand
businesslogicistheRESTAPI.

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 17/18
2/8/2017 AWebClientAgainstaRESTAPIwithJavaScriptandXML|SAPBlogs

AlertModerator

Bethefirsttoleaveacomment
YoumustbeLoggedontocommentorreplytoapost.

Share & Follow


Privacy TermsofUse LegalDisclosure Copyright Trademark Sitemap Newsletter

https://blogs.sap.com/2013/01/13/awebclientagainstarestapiwithjavascriptandxml/ 18/18

You might also like