The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. January 07, 2009, 06:33:52 PM

Login with username, password and session length


Pages: [1] 2
  Print  
Author Topic: My first AJAX project, biting off way more than i can probably chew  (Read 941 times)
nutballs
Administrator
Lifer
*****
Online Online

Posts: 3525


View Profile
« on: July 26, 2008, 04:42:45 PM »

I have a question about methodology.

Assume a typical AJAX setup of a client and the server.
the client send requests to the server, and the server replies back with responses.

assume a simple ajax of, user enters a value, and the ajax server replies back with a value that updates an element on page. Like enter a zip code, and ajax server replies back with a weather icon, the temperature, and conditions text.

would you have the handler code on the client side, waiting for a reponse of just the icon,temp,conditions.
OR
would you send back the handler code, and have the client eval()?

I am thinking that sending back the handler code allows for managing all the functionality from the ajax server, instead of splitting it across two files, the client php and the server php. The downside is that the traffic is increased because every request results in a full chunk of JS, instead of just 3 small databits in this example.

Obviously this is related to a much more complicated system, but the weather thingy is a good example.
Logged
jammaster82
Expert
****
Offline Offline

Posts: 300

bloody hacker


View Profile WWW
« Reply #1 on: July 26, 2008, 05:25:02 PM »


Logged

Of course Big Brother exists, he is the embodiment of the party..... Does he exist in the same way I exist?....... You, do not exist.
vsloathe
vim ftw!
Global Moderator
Lifer
*****
Online Online

Posts: 679



View Profile
« Reply #2 on: July 26, 2008, 07:17:32 PM »

My rule is: offload as much processing as possible, wherever possible, to the client.

Save the serverside processing for stuff that's important, like when security of the application is concerned.
Logged

nutballs
Administrator
Lifer
*****
Online Online

Posts: 3525


View Profile
« Reply #3 on: July 26, 2008, 07:49:18 PM »

i agree. however, in either scenario the work is offloaded to the client.

the difference between the two is functions.

do I supply them, right away upon pageload with all the functions to manipulate the page, and then just process the bits I get back with those functions.
OR
do I supply them with only a basic set of comms, like perks ajax class, and then each time the page needs to be manipulated, send them a custom code chunk, just for that specific action, and if its repeated, the client will get a duplicate of that code, over and over.

Initially i thought that sending the code with each request would be simpler, because then I could send only what they need, when they need it. Also, because then all the code is managed from the PHP side. But like i said the downside is that communication gets a bit more bloated because im am sending code chunks, not just data.
On the flip side however.
All the functionality is sent down to the user, whether they ever use it or not. Plus that also means that code is now separated out from my core logic, into a JS file for example, even though they both need to play with each other at a fundamental level.

I think, keeping all the code serverside, and sending only what is needed to manipulate the page, when the user takes action, makes more sense. The only concern I had as well is if that open a security risk. "hey client, here is some code, run it, trust me..." But I really have no idea.
Logged
DangerMouse
Expert
****
Online Online

Posts: 177



View Profile
« Reply #4 on: July 27, 2008, 03:20:53 AM »

I've just started looking into developing an AJAX app for myself, and similarly feel like I've bitten off way more than I can chew!

My current plan is to setup using REST type architecture serving JSON responses and handle the rest client side, seems to be standard practice rather than sending back code to be handled by eval(). Only problem is I don't know javascript  Grin ...yet!

DM
Logged
jammaster82
Expert
****
Offline Offline

Posts: 300

bloody hacker


View Profile WWW
« Reply #5 on: July 27, 2008, 04:09:02 AM »

I love the coolness of the eval() idea, I'm gonna have to read up on REST and JSON, but without encryption i agree NB the security risk would be great to just blindly execute code.  Reminds me of the FoReM bbs for the atari 800.  It was all written in Basic, but when they ran out of ram they would print to the screen something like:

Code:
10001
10002
10003
10004
10005
GOTO 10006

then they would position the cursor over the first line and actually break the program,
after first starting off a machine language routine that just kept poking the keypress
buffer with a chr(13) so that it appeared to the atari that someone actually hit the
 break key, and typed all those numbers which in basic erased the line numbers,
 now line 10006 would do the same with the rest to be deleted and voila 3 more k.

So then line 10006 would open a file off the disk, copy the new code to be included
in the program (which could be your own code as well) to the screen reposition to the
top , restart the ML procedure to keep smacking the return key for you until last
line which stopped the return smacker and redirected basic to the line to start back
and an BOOM everything still there.

But this was the first time I ever thought bout (and actually saw) programs writing programs and this
concept really makes A.I. and the possibilities just about endless you could even write
a pseudocompiler or your own natural language processor in php with this if you just tokenized everything and
resolved it to php code to be evaluated on the fly to simulate a runtime compiler...... wow that
really spun my gears hard this morning , pre coffee and all! Im gonna go see if i can dig it up!

 

Logged

Of course Big Brother exists, he is the embodiment of the party..... Does he exist in the same way I exist?....... You, do not exist.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5324


:sniffle: Humor was so much easier before.


View Profile
« Reply #6 on: July 28, 2008, 01:34:33 PM »

I'll jump in here tonight or tomorrow.

Wha... perk has an opinion on Ajax?   ROFLMAO ROFLMAO ROFLMAO
Logged

If I can't be Mr. Root then I don't want to play.
nutballs
Administrator
Lifer
*****
Online Online

Posts: 3525


View Profile
« Reply #7 on: July 28, 2008, 05:49:22 PM »

to just add to what I am thinking...

i did a quick POC for myself.
I have the php page that the client ends up landing on, the client page:
Code:
<html>
<head>
<script type="text/javascript" src="/inc_js/ajaxjunk.js"></script>
<script>
function init()
{
ajax1 = new ajaxRequestor()
ajax1.url = '/requests.php';
ajax1.postParam('method', 'init');
ajax1.onSuccess = handleAjax;
ajax1.execute();
}

function handleAjax(sender)
{
eval(sender.lastResponse);
}
</script>
</head>
<body onload="init();">
<div id="wrapper"></div>
</body>
</html>

and then my requests.php handles EVERYTHING, but for now the very stripped down example is:
Code:

test()

function test()
{
$content = <<<CONTENT
This is<br>
some updated text<br>
which should now be<br>
in the div.
CONTENT;
$content = str_replace('"','\"',$content); //escape double quotes for the JS
$content = str_replace("\r\n",' ',$content); //drop CRLFs for JS
//$out = 'document.getElementById("'.$_POST['id'].'").innerHTML="'.$out.'";';
$out =  'var p = document.getElementById("wrapper");';
$out .= 'var newdiv = document.createElement("div");';
$out .= 'newdiv.setAttribute("id","login");';
$out .= 'newdiv.innerHTML = "'.$content.'";';
$out .= 'p.appendChild(newdiv);';
return $out;
}

so basically, I am sending EVERYTHING back to the client, and the client EVALs that to build the on page elements.
I would start with a blank page, or at least a blank content area, and build from ajax, no elements exist when the page is first loaded, like the client page above shows.

Is this a viable way to do it? Or is evaling a problem?
Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5324


:sniffle: Humor was so much easier before.


View Profile
« Reply #8 on: July 29, 2008, 09:33:56 AM »

Hey NBs -

I rarely send JS back during an Ajax call because it complicates debugging and my notion of where all the code lies.

Most most often, I send back a JSON encoded array that contains any number of things: a great example is a donation management system I'm currently working on for a non-profit client. The surfer has a blank client area with a header and a footer. My intention is to put a table of donation information in the client area, and headers and totals in the header and footer. So in my PHP array I'll have both data and a complete HTML table ready to view on different indicies of the array. I'll json_encode it and ship it back to the client. Then I eval the ajaxxed string back into a JS array and kaboom, I'm ready to go on the client side.

I've tried sending just data and then building HTML client side and that gets too processing heavy at the client. I've tried sending all the HTML and that gets too server and comms heavy. And I've tried sending new code back to the client as they need it and, as sexy as it seems, it really complicated the overall process for me to the point of confusion.

My own personal standard now, is for a server file to be called module.[module's raison d'être].php and ajax.[module's raison d'être].php. So, module.donations.php and ajax.donations.php are what's going on in my example above. The ajax file does this: $request = $_POST['request'] and then does a switch statement for everything that <this> module expects - if I don't find it, there's either a bug or it's a hack attempt. The case statements in that switch then handle the request immediately or get it from a function at the bottom of the file if readbility is a problem. The most common form of ajax response I do looks like this:

(note that $db would have already been connected as my utility database handler earlier in the page-handling process)

Code:
<?php

if (!$request $_POST['request']) die('Hack Attempt');
switch(
$request)
{
case 'refresh':
$db->query("select * from donations");
while ($db->fetchAssoc$outArr[] = $db->row;
echo json_encode($outArr);
break;

...

?>


Although I am pretty much with VS on the "push as much as you can to the client" I have found, personally, that pushing the processing to the most appropriate entity is better... for example, when creating a rather intense table for the client to view, it's better to use a HEREDOC style php code with the above loop to create the HTML I want to display, then place it onto a node in that array, encode it and send it back than to try and dynamically build the table with JS on the client side (which I've done a whole lot of as well).

With the exception of events tied to HTML that I send back to the client (think onClick="doFunction(this)") I try to have all the code for each side of processing stable and established before the page gets rolling. This really helps me think for the perspective of two autonomous entities communicating, rather than the server being a crutch for the client.

Hope that helps... I do have a lot of experience with this one if you want to go deeper.

/perk
Logged

If I can't be Mr. Root then I don't want to play.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5324


:sniffle: Humor was so much easier before.


View Profile
« Reply #9 on: July 29, 2008, 09:37:04 AM »

Forgot to mention - the primary decider on where code belongs (for me) is speed. If it's going to blow doors to create the HTML server side and ship it back, the server gets it. If the client clicks and the answer it right there because it can all be done client side, well, there you go. It's all about the user's perception of the speed of the app for me.

Because I believe in the user.  ROFLMAO
Logged

If I can't be Mr. Root then I don't want to play.
nutballs
Administrator
Lifer
*****
Online Online

Posts: 3525


View Profile
« Reply #10 on: July 29, 2008, 10:54:57 AM »

ok. i guess Im a bit confused then.

in my particular project, I have a grid or unknown number of rows.
only 1 row will be updated at a time, and actually, only 1 field specifically, at any point in time.

My thought was the scenario of code above which i posted. but now, i am thinking I might be able to slim this down to bones via another methodology.

Just out of curiousity, when you build an ajax site, what is the process of creation?
Normally, when I build a traditional client/server/refreshall application, I build out the visual framework first, then plug in the functionality. This is partly a result of my project types, which are usually very plan-on-the-fly.
Does that same philosophy make sense in an ajax app?

The example is a todo list.
You have 10 items in your list.
you could update an item.
you could delete an item, removing its row from the table
you could add an item, adding a row to the table
you could have no items, meaning no table yet exists, though i guess it could have a blank row.

do I build it out in HTML then "apply" an ajax layer to it?

this is way out of my comfort zone. But only this first step. after that its a non-thing. I am just stuck on the how-the-hell-to-start step.
Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5324


:sniffle: Humor was so much easier before.


View Profile
« Reply #11 on: July 29, 2008, 12:04:45 PM »

I'll recap our telco discush for anyone else following this thread.

@ handling an unknown number of rows in a table being viewed/edited by the user:
The best way that I have found is to rely on the DOM as your storage and "stack navigation" mechanism. In other words, why put something into variables if the DOM is, in fact, one big stack waiting for you to walk it?

If I have a really complicated table of information that I want to display to the user, I have really 3 choices: A) build a whole new page and ship it out, B) AJAX back the data alone and build the HTML client side or C) build the HTML server side and AJAX it back and display it client side.

Obviously, A is unsuitable for this discussion because we want an AJAX app.

B is reasonable, and I've done it quite a bit. However, depending on the complexity of the table or thing you are building, this can weigh heavy on local processing time. Also, you just handed the perception of the application's snappiness to the browser's implementation of JS. There are also idiosyncrasies you'll need to deal with when building tables and multiple browsers. This is why I built my tableManager class, which allows me to programmatically build a table in JS that works for any browser. All that said, if I pass back 500 rows and build 10 cells per row, I've got a lot of client-side processing to do and the app will feel sluggish at best.

C is the right choice in this case - build the HTML serverside and simply node.innerHTML = (the packet) and kerpow, client application updated. Snappy, pretty. However, there are some problems with this: the original page has no idea about what data is now sitting in the innerHTML of that target node. This is where I use the dom. Consider:

Code:
<table>
<tr id="row_id_12345">
<td>Some Data</td>
<td>Some More Data</td>
<td><input type="button" value="Click Me To Edit This Row" onClick="editRow(this)"></td>
</tr>
<tr id="row_id_45678">
<td>Some Data</td>
<td>Some More Data</td>
<td><input type="button" value="Click Me To Edit This Row" onClick="editRow(this)"></td>
</tr>
</table>

Now consider that I have a handling function:
Code:
function editRow(sender)
{
var target = sender;
while(target.nodeName != 'TR') target = target.parentNode;
alert('The ID I'm looking for is: ' + target.id;
}

So what I'm doing here, is when I created the HTML in PHP I made the row have the unique database ID of the actual DB row I'm editing. The button calls a function that <we> already know about - it was sent with the original page load, called "editRow." It calls that function with a parameter of itself: "this." The handling function then receives the node that called it and walks up the DOM tree until it finds a TR (row) node, at which point I know that I've found what I am looking for (Note: Of course this is not exactly how I do it because I can make this WAY more efficient, but I've written it this way for readability). In this way, the DOM has become one big blob of data that I can navigate and retrieve from at will. So I now no longer need to know about anything that's in the innerHTML, because I can get it when I need it. Follow?

Just out of curiousity, when you build an ajax site, what is the process of creation?
Normally, when I build a traditional client/server/refreshall application, I build out the visual framework first, then plug in the functionality. This is partly a result of my project types, which are usually very plan-on-the-fly.
Does that same philosophy make sense in an ajax app?
Absolutely. The methods for building a good application are the same, regardless of comm mechanics under the hood. I choose to ship out everything that the client will need to know with the original page load, because the surfer is already expecting a delay - and then ship only what is really necessary during application run time. This offers a problem: if you have lots and lots of code to ship out to the client, how do you manage it (from a developer's perspective)?

The phpMyIDE app is an example of how I choose to manage it. At the moment a surfer calls for the app, it does not exist. The main.php includes all of the modules that should be used to construct it. These modules all contribute to a wide variety of string arrays: CSS I will need to include, initialization JS, functional JS, HTML and so forth. The main routine, having included all of the modules, will now have a big'ol array filled with all of the stuff that should be in the output. I'll implode the CSS array into a single string, then put that in the header of the output: I'll implode the functional JS array and include that in the header: I'll implode the initialization JS and include that in the body of the output: I'll implode the HTML into a string and include that in the body of the output and so on and so forth.

In this way, I can look at code JUST for <this> module at any given time and I can keep my brains unconfused (a more and more dicey proposition as I age LOL) - and I can include/exclude modules with a single comment character (ie., in the main.php I simply DONT include a particular module and nothing about it will be included in the output to the surfer). Hope that makes sense... that one took quite a while for me to figure out and implement.


The example is a todo list.
You have 10 items in your list.
you could update an item.
you could delete an item, removing its row from the table
you could add an item, adding a row to the table
you could have no items, meaning no table yet exists, though i guess it could have a blank row.
do I build it out in HTML then "apply" an ajax layer to it?
The temptation here is to "fire and forget" ajax calls that send a DB update but do the client-side GUI work without interacting with the DB or waiting for it. This looks good on paper, but you are setting yourself up to be out of sync with the server, consider this: let's say someone adds 3 todos to the system. The GUI is updated and all looks good. But unbeknownst to them, their cable modem is down and they have no comms with the server. They think they've added todos but the DB has done nothing.

My personal fix is to always respond with this on success (for a simple update like request) : echo json_encode(array('OK')); then on the client side I'll do this:

Code:
function handleUpdate(sender)
{
try {
var arr = eval('(' + sender.lastResponse + ')');
} catch (e) {
alert('Error: ' + e.message);
}
if (arr[0] != 'OK')
alert("Warning: " sender.lastResponse);
}
Very quickly, I know if the server has done what I asked. The reason I did it this way, is that if MySQL pops back something like "Warning: $res is not a valid result set" or something, eval will bomb and presto, I get my error from PHP. This is a vital trick, because debugging AJAX apps is another thing that took me quite a while to get my arms around so that I could be efficient. In fact, it sucks horribly at first.


this is way out of my comfort zone. But only this first step. after that its a non-thing. I am just stuck on the how-the-hell-to-start step.
You'll do well because at the core it works the way you think. It's a bastard to start out tho, believe me I understand. Hope all this helps.

/p
« Last Edit: July 29, 2008, 01:03:35 PM by perkiset » Logged

If I can't be Mr. Root then I don't want to play.
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5324


:sniffle: Humor was so much easier before.


View Profile
« Reply #12 on: July 29, 2008, 12:05:38 PM »

ROFLMAO Yeah, I have "10 minutes"  ROFLMAO ROFLMAO ROFLMAO Anything to avoid real work mang )
Logged

If I can't be Mr. Root then I don't want to play.
nutballs
Administrator
Lifer
*****
Online Online

Posts: 3525


View Profile
« Reply #13 on: July 29, 2008, 12:57:39 PM »

lol perk. I seriously meant just 10 minutes. I know the feeling. I have done nothing today...
Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Online Online

Posts: 5324


:sniffle: Humor was so much easier before.


View Profile
« Reply #14 on: July 29, 2008, 01:02:46 PM »

I was laughing at me NBs, not you ... no worries mate Wink
Logged

If I can't be Mr. Root then I don't want to play.
Pages: [1] 2
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!