Showing posts with label clientside scripting. Show all posts
Showing posts with label clientside scripting. Show all posts

Passing clientside data to the server with AJAX

Sue wrote a post about mixing clientside and serverside Javascript in Webcrossing. I want to touch briefly on a related topic, which is passing data back and forth between client- and server-side. It can get confusing, especially when you're writing in essentially the same language throughout, to remember what context you're in and what you have access to and what you don't.

Where things can get really wacky is when you're using AJAX calls to change the contents of the browser window without a page refresh. Specifically, you have to remember that any local server-side variables you may have set outside of the AJAX'd content won't be there once you make an AJAX request. Here's a simple example, where I'll use WCTL to make it a bit easier to separate client from server.

First, let's assume your page has the following AJAX call on it. (This example uses jQuery, the Javascript framework with which I'm most familiar.)

function whenYouClick() {

  $.get("/someNewContent",,function(newText) {
    $('#newContentGoesHere').html(newText);
  });
};

If you're not familiar with jQuery, just take my word for it that this code will call the WCTL macro or WCJS command "someNewContent", and whatever it returns will replace the current contents of the DOM element with ID "newContentGoesHere".

Now, let's move down into the body of the page...

%% set initValue 25 %%
<div id="newContentGoesHere">
%% use someNewContent %%
</div>

And then, separate from this page macro, you have this macro:

%% macro someNewContent %%
%% set returnVal 2*initVal %%
%% returnVal %%
%% endmacro %%

It should be obvious what will happen when you first load this entire page. someNewContent will execute and evaluate to "50" which will become the content of the div. But now, what happens if the clientside function whenYouClick() makes the AJAX call? someNewContent will execute again, but outside of the context of the entire page, that local variable initVal is not defined. returnVal will be 0.

As long as you keep it straight in your head which data is available where, this problem is not difficult to avoid. Here are two common approaches:
  • You can store needed data in session variables. If you used session.initVal instead of the local variable, it would still be available inside the AJAX call (with some caveats that affect guest users who, depending on system settings, may not have a unique session).
  • Alternatively, you can pass the data as arguments in your clientside function (or put it inside a DOM element where your clientside code can retrieve it) and then through to your AJAX call. Once your AJAX code is executing, any arguments you pass will be part of the form object.
This is a very brief look at a rather challenging topic, but I hope it gives you some idea of the issues involved.

Code snippet: What's up, DOCTYPE?

In a previous post I mentioned using AJAX to call server-side functions and write dynamic content to the page. Here I introduce an easy workaround for one of the places where Webcrossing trips over its own flexibility.

There's a system setting to include a DOCTYPE in every page response for compliance with W3C standards. But once defined, this happens automatically for every request, including those which are not intended to be a full page of HTML, such as the response to an AJAX call. In order to avoid breaking your page, use this simple clientside Javascript function to remove the DOCTYPE:


function removeDoctype( txt ) {
return txt.replace(/<!DOCTYPE[^>]+>/g, "");
}

Implemented with a jQuery AJAX call, it looks like this:

$.get("/someNewContent",,function(newText) {
    $('#newContentGoesHere').html(removeDoctype(newText));
  });

A colleague of mine likes to say, "Every so often a programmer will determine that the best solution for a problem is a regular expression. Now she has two problems."