using AJAX to update InfoBox

Good afternoon,

I know it is risky asking for assistance on a beautiful late-summer Friday afternoon…

I would like to update a InfoBox descriptions dynamically. Hannah Pinkos helped update a CZML entity’s description here (Updating a CZML ‘description’ upon opening the InfoBox). The challenge I’ve hit involves how to supply the return from an AJAX (or XMLhttpRequest) to “setInputAction(function(click)”.

I can get the setInputAction(function(click) to return information to a div or other element without trouble, but I want the result to end up with the "pickedObject.id.description’= “…” to be read in the javascript setInputAction(function(click) operation.

I began using the JQuery AJAX approach but ran into trouble with its Async-ness. Just to get something to work I tried Ssync-ing things with no luck. See the bottom component of this Sancastle (and temporary php):

var viewer = new Cesium.Viewer(‘cesiumContainer’);
var scene = viewer.scene;

var czml =
[{“id” : “document”,
“version” : “1.0”
},{“id” : “Boston”,
“label”:{“text”:“Boston”},
“position”:{“cartographicDegrees”:[-71.0589,42.3601,0]},
“description”:“Boston is a city…”,
},{“id” : “New York City”,
“label”:{“text”:“New York”},
“description”:“New York is a city…”,
“position”:{“cartographicDegrees”:[-74.0059,40.7127,0]},
}];

var promise = Cesium.CzmlDataSource.load(czml);
promise.then(function(dataSource) {
viewer.dataSources.add(dataSource);

var handlerA = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handlerA.setInputAction(function(click) {
var pickedObject = scene.pick(click.position);
if (Cesium.defined(pickedObject)) {
$.ajax({
async: false,
type: ‘GET’,
url: ‘InfoBox.php’,
data: (pickedObject.id.id).val(),
success: function(response) {
result (response);
}
});
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

`//------ create CZML ------
//------ Get the array of entities
var entities = dataSource.entities.values;
//------ Loop entities
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
var name = entity.label;
entity.label.translucencyByDistance = new Cesium.NearFarScalar(100000,1.0,500000,0.0);
}
}).otherwise(function(error){
//------ Display error
window.alert(error);
});

//------ Use JQuery/AJAX to update to current description`

<<InfoBox.php>> File (for simplicity’s sake):

<?php //MySQL search with 'placeholder' set to 'pickedObject.id.id' echo ("pickedObject.id.description='this is driving me crazy!';"); ?>

``

I have also tried a XMLhttpRequest as that can easily handle the Async-ness of the AJAX (with a callback) without pulling in another library for one function, but the challenge remains: these functions work for me in isolation but not within the setInputAction function.

Many thanks, and enjoy the weekend. Best, erik

Hello Erik,

What is this function doing?

    success: function(response) {
      result (response);
    }

You need to set the description client side, and I’m a little confused at what is happening here. What is result?

-Hannah

Looks like you are trying to send “javascript” from php that the client should execute. While that could work if you evaluating the send script after receiving it, it has a few downsides. Like what if another client uses it and do not use the variable name pickedObject?

My suggestion would be to return json form php. I just googled something, so you will have to check if it works.

<?php ``` header('Content-type: application/json'); ``` echo ("{'town':'boston', 'temp', 25}"); ?>

``

var handlerA = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handlerA.setInputAction(function(click) {
var pickedObject = scene.pick(click.position);
if (Cesium.defined(pickedObject)) {
$.ajax({
type: ‘GET’,
url: ‘InfoBox.php’,
data: (pickedObject.id.id).val(),
success: function(result) {
pickedObject.id.description = “The temperatur of " + result.town + " is " + result.temp + " degrees…”;
}
});
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

``

Hope it helps

Small typo,
echo ("{‘town’:‘boston’, ‘temp’, 25}");

``

should have been
echo ("{‘town’:‘boston’, ‘temp’: 25}");

``

Many thanks Poul and Hannah.

@Hannah:

To clarify, the sandcastle-ready example I provided is simplistic. See www.geo-animate.com or more directly to http://geo-animate.com/CesiumScripts/WorldWarII/WWIIanimation.php for the real project.

This animation outlines the movements of each army unit during the Battle for Normandy in 1944. The database includes references and notes for each movement of every unit. My challenge is to make these sources and notes available to the user.

I want to use the built-in InfoBox because it is tried-and-tested. Also, I felt (without any analysis) that downloading all of the notes along with all of the positions for each unit would take too long. For that reason I felt XMLhttpRequest or AJAX would be the right tool.

I became tripped up figuring out how to pass the pickedObject.id.id to the AJAX function, and then the format in which to put the response so that the pickedObject.id.description would be updated in the setInputAction(function(click) {… code.

@Poul:

I apologize if my simple sandcastle example was misleading. I see why you recommend JSON… that is simpler. Because the description update I’m seeking from the server database may have images, tables, etc, I will stay with javascript/HTML for the time being.

However, your code did include the magic I was seeking. I changed the success function to:

success: function(result) {
pickedObject.id.description = (result);
}

``

So the complete code for this is currently:

var handlerA = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handlerA.setInputAction(function(click) {
var pickedObject = scene.pick(click.position);
if (Cesium.defined(pickedObject)) {
$.ajax({
async: false,
type: ‘GET’,
url: ‘InfoBox.php’,
data: (pickedObject.id.id).val(),
success: function(result) {
pickedObject.id.description = (result);
}
});
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

``

I have more work to improve this. Most notably is changing the nature of the function back to asynchronous. Also changing the AJAX function to XMLhttpRequest to remove the need to download the JQuery library. But for the time being (and for my level of expertise) it has created something with which I can move ahead. You’ve made my weekend.

Cheers! erik

I remain, as always, happy to learn from other suggestions…