Sunday, August 21, 2005

Integrating AJAX with ArcGIS Server - IV

In this final part of Integrating AJAX with ArcGIS Server series, we will discuss how to customize javascript code for the custom magnifier tool. The most challenging part in this section is to integrate our custom tool in the existing toolbar managed by ArcGIS Server ADF. Java ADF manages the active tool through Map Control in the server side. The magnifier tool that we are developing, however, does not submit the request to ADF but to a separate servlet. So we need to develop our own mechanism to integrate this new tool to the existing toolbar. To solve this problem, we will add a JSF hidden input element to store the state (active or not) of the Magnifier tool and customize the javascript code to update the toolbar in client side. Since JSF components are stored in the server side, we will use this hidden input element to maintain the state of the magnifier tool between the postbacks.
With this introduction, lets discuss the code step by step.

1. We will be writing the javascript code in a separate file called ajax.js. So first thing we will do is add the reference to the js file in the mapviewer.jsp page:


<script language="Javascript" src="js/ajax.js">
</script>



(We will take a look at this file in a while.)

2. Add the magnifier tool right after the identify tool in the toolbar:


<td>
<IMG id="imgMagnifier"
name="imgMagnifier"
src="images/magnifier.gif"
alt="Magnifier"
title="Magnifier"
onmouseover="this.src='images/magnifierU.gif'"
onmousedown="this.src='images/magnifierD.gif';
MapPoint('Map0', 'Magnifier');
HighlightTool('Magnifier');"
onmouseout="ButtonOut('imgMagnifier', 'Map0',
'Magnifier', 'images/magnifier.gif',
'images/magnifierD.gif');" />
<jsfh:inputHidden id="btnMagnifierHidden" value="" />
</td>


The above code is similar to other tools except these 2 important differences:
a) In onmousedown event, we have called MapPoint function and passed our custom tool id called Magnifier. Since this is not the ADF managed tool but our own tool, we need to manage it through our custom javascript code.
We will discuss the javascript code just in a bit.
b) As mentioned before, we have added a jsf hidden input component to manage the status of the magnifier tool.

3. Save the following images in images folder of the web application as magnifier.gif, magnifierU.gif and magnifierD.gif respectively:




4. Find the identifyResult control tag and add the following code right after it:


<div id="magnifierDiv"
style="position:absolute;
overflow:auto;
z-index:9999;
left:0px;
top:0px;
background-color:White;
border-style:ridge;
visibility:hidden;">
<div id="mainImg">
<IMG id="magnifierDivImg" src="" />
</div>
<div id="closeImg"
style="position:absolute;left:180px; top:5px;">
<IMG id="magnifierCloseImg"
src="images/close.gif"
onmousedown="closeMagnifier();" />
</div>
</div>


In the above code, we have added a div element with 2 inner div elements. The first inner div element is to store the magnified image which would be obtained from our custom servlet. The second div element contains a close image which when clicked calls closeMagnifier() function to hide the magnifier div.

5. Toward the end of the jsp file, find the script tag and modify it as shown below:



<script language="JavaScript">
var fid = document.forms[docFormID].id;

var magnifierHidden = document.getElementById(fid+':btnMagnifierHidden');
var mval = magnifierHidden.value;
if(mval =="active"){
document.images["imgMagnifier"].src = "images/magnifierD.gif";
MapPoint('Map0', 'Magnifier');

} else {
HighlightTool(document.forms[docFormID].elements["Map0_mode"].value);
}
</script>



The above code checks the value of the hidden input element that we added. If its value is active (which means current active tool is magnifier), we will activate the magnifier tool. Otherwise it will behave in a normal manner.

6. In the HighlighTool function:
a) We need to add this line outside switch statement to unselect the magnifier tool:
document.images["imgMagnifier"].src = "images/magnifier.gif";
b) And this new case statement to select the magnifier tool:

case "Magnifier":
document.images["imgMagnifier"].src = "images/magnifierD.gif";
break;


7. Change the ButtonOut function to handle this new tool:



function ButtonOut(id, control, tool, flatimage, downimage)
{
var f = document.forms[docFormID];
var m = control + "_mode";
var mode = f.elements[m].value;
var imgsrc = flatimage;
var magVal = document.getElementById(f.id+':btnMagnifierHidden').value;
if(magVal =="active"){
if(tool == "Magnifier") imgsrc = downimage;
}else if (mode == tool) {
imgsrc = downimage;
}
var imgObj = document.getElementById(id);
if(imgObj != null) imgObj.src = imgsrc;
}



8. In map_functions.js file, find mapSetTool function and add this new variable right before
this function:

var isMagnifier = false;


Add this new code at the top of the mapsetTool function:



var ff = document.forms[docFormID];
var hid = document.getElementById(ff.id+':btnMagnifierHidden');
if(mode=="Magnifier") {
//set the value of hidden input element
//to active
isMagnifier = true;
hid.value="active";
//change the cursor to crosshair
cursor="crosshair";
}
else {
isMagnifier = false;
//set empty value for hidden input element
hid.value="";
}



In the above code, we are checking if Magnifier tool is activated. If so, we will set the value
of isMagnifier to true and that of hidden input element to active. If any other tool has been selected, we set the value of isMagnifier to false and that of hidden input element to an empty value.

9. Modify the mapPointClick function as shown below:



function mapPointClick(e) {
if (isLeftButton(e)) {
getXY(e);
getMapDiv(e);
adjustMapCoords();
if(isMagnifier){
//call the custom function
sendMagnifierRequest (zleft, ztop);
}
else {
//post back the form
divObj.style.cursor = "wait";
var f = document.forms[docFormID];
f.minx.value=zleft;
f.miny.value=ztop;
postBack(Maps[divIndex].controlname, 'point');
//alert(divObj.id + "\n" + zleft + "," + ztop);
}
}
return false;
}



Here, we are calling our custom function (that we will be looking soon) instead of posting
back the form if the magnifier tool is active.

10. Now lets take a look at the ajax.js file:



var appName = "AjaxTest";

function getHTTPObject() {
var xmlhttp;
//mozilla
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
// IE
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}

//XMLHttpRequest object
var req ;

//variables to store x/y location
var ajx, ajy;

//this function sends the request
function sendMagnifierRequest(xx,yy) {
req = getHTTPObject();
ajx = mouseX;
ajy = mouseY;

//for IE, i needed to subtract 2 pixels
//to center the map more accurately
if(isIE){
xx -= 2;
yy -= 2;
}
var url = "/" + appName + "/AgsServlet?x=" + xx + "&y=" + yy;
if (req != null) {
req.open("GET", url, true);
req.onreadystatechange = getResponse;
req.send(null);
}
}

//this function processes the response
function getResponse(){

if (req.readyState == 4) {
if (req.status == 200) {

var result = req.responseText;
//alert(result);
//position the div element
var mDiv = document.getElementById('magnifierDiv').style;
mDiv.left = ajx-100;
mDiv.top = ajy-100;
//specify the image returned as a src
var magImg = document.getElementById('magnifierDivImg');
magImg.src = result;
//show the div
mDiv.visibility = "visible";

}
}

}
//this function hides the div
function closeMagnifier(){
var mDiv = document.getElementById('magnifierDiv').style;
mDiv.visibility = "hidden";
}



First we have specified the application name in a variable appName. Make sure to change
this variable with your web application name.

Function getHTTPObject creates and returns a new XMLHttPRequest object. Notice the difference in creating this object between IE and Mozilla.
Function sendMagnifierRequest is responsible for submiting the user click point (x/y values) to our custom servlet. In this function, we first got a new XMLHttpRequest object called req and opened a "GET" connection to our custom Servlet. We have passed the x/y values to the servlet by appending the argument value pair to the url. The following line specifies that getReponse function will be called every time he state of XMLHttpRequest object is changed:
req.onreadystatechange = getResponse;

Remember that one of the key features in Ajax is to send requests asynchronously, i.e. we won't be sitting there and waiting for the response once we submit the request. That is why we have specified the above function that will track the state of the XMLHttpRequest object and processes the response when ready.

In the getResponse function, we will check the state of the XMLHTTPRequest object and if it's value is 4 (i.e. completed) and the HTTP status of the response is 200 (OK), we will then process the response.
Remember from our previous discussion, the custom servlet simply sends back the url of the output image in a simple text format. So we will get this url from responseText property of the req object and set the url as a source to an image in a div element. We will center this DIV element at the click location and finally make it visible.

11. Finally, save the ajax.js file in the js folder of your web application.
Thats it. You are all set to test this new tool. Enjoy!!!

20 Comments:

At 7:45 AM, Anonymous Anonymous said...

Hello Kafle

I appreciate your effort in keeping all this info in the blog. I really got some ideas regarding what I'm doing after seeing your blog.

Keep writing

Thanks
Addy

 
At 11:25 PM, Blogger Surya said...

Hello Kafle,
that is really excellent.
I am asking you question.
I want to replace webapp in the areaDivName(name of the div element of the map over the browser) with the image generated over the magnifier window.

What can i do??

Thanx
UmaSurya S.

 
At 4:13 PM, Anonymous Anonymous said...

Who can help me with .httpaccess ?
where i can fined full information about .httpaccess file syntaxis?

 
At 11:58 AM, Anonymous Anonymous said...

Who knows where to download XRumer 5.0 Palladium?
Help, please. All recommend this program to effectively advertise on the Internet, this is the best program!

 
At 9:57 AM, Anonymous furniture repair service said...

Hello KafleI appreciate your effort in keeping all this info in the blog. I really got some ideas regarding what I'm doing after seeing your blog.Keep writingThanksAddy

 
At 7:41 PM, Anonymous true school sex stories said...

My boss. Get yourselfsome, of course.
animal and wemon sex stories
xxx mom blows son stories
male bestiality sex stories
erotic sex stories about little girls
adult baby diaper lover stories
My boss. Get yourselfsome, of course.

 
At 4:08 PM, Anonymous miami broadband said...

And as it is written in Java.. it will have more options to get better gadgets.. tools.. everything

 
At 2:28 AM, Blogger hibeyond said...

black boots

Chocolate boots

sand boots

Chestnut boots

gray boots

pink boots

grey boots

pink boots

 
At 10:20 AM, Anonymous zithromax price usa said...

Wow, nice post,there are many person searching about that now they will find enough resources by your post

 
At 4:56 AM, Anonymous pepa prase igre said...

I'm so excited. Keep up your excellent work.
bojanke
bojanke za printanje
gledanje u solju

 
At 5:00 AM, Anonymous cinema arts said...

I'm really enjoyed reading this article and whole website, thanks a lot for this informations!

 
At 6:12 AM, Anonymous get girlfriend give head said...

I will bookmark this site and visit again. It is very informative. Thanks for sharing.

 
At 4:48 AM, Anonymous arabic letters said...

I'm really enjoyed reading this article and whole website, thanks a lot for this informations!
Islamic quotes
Arabic quotes

 
At 9:06 AM, Anonymous cunnilingus said...

I will bookmark this site and visit again. It is very informative. Thanks for sharing.
how to finger a girl
cunnilingus video
how to eat a girl out

 
At 10:11 AM, Anonymous loperamide dosage said...

Thank you very much, you just saved my life.

 
At 9:28 AM, Anonymous Viagra said...

Thank you so much for sharing this tutorial!

 
At 5:18 PM, Anonymous price per head bookmaking said...

I really appreciate it, I visit more often for updates, keep up the great work!

 
At 8:36 PM, Anonymous Anonymous said...

Yes, you can find for all those peoples-class Buy GW2 Gold combinations of various possibilities of an individual story. Since the D3 Gold moves on, you can even provide more info of your figure.

 
At 5:59 PM, Blogger Kzaxcpnd Molluskxbny said...

When the aerials are down, and your spirit is covered with snows of cynicism and the ice of Runescape Gold pessimism, then you are grown rs gold old, even at 20, but as long as your aerials are up, to catch waves of optimism, there is Runescape Money hope you may die young at 80.

 
At 6:03 PM, Blogger Kzaxcpnd Molluskxbny said...

Promises are often like the rs2 gold butterfly, which disappear after Runescape2 Gold beautiful hover. Fading is true while flowering is past. Love ,promised between the RS Gold fingers

 

Post a Comment

<< Home