AJAX kicked my butt all day yesterday...

Permalink 1 user found helpful
And it did not get better this morning!

PROBLEM: When making an AJAX call from a block's view.php (to controller.php), the function returns the entire HTML for one of several dashboard pages???

If I set the datatype to "json" the function returns Error 200: "Unexpected token <" (But only because the returned data contains a bunch of raw HTML)

I tried to simplify the code (below) but still the same...

VIEW.PHP
function setSkills(ID){
  $.ajax({
    type: "POST",
    data: "&ID="+ ID,
    dataType: 'json',
    url: "<?php print str_replace("&","&",$this->action('getDefaults')); ?>",
    success: function(data){
      $('#wbMessage').html(data);
    },
    error:function (xhr, ajaxOptions, thrownError){
      $('#wbMessage').html(xhr.status+"<br/>"+thrownError);
    }
  });
}


CONTROLLER.PHP
public function action_getDefaults(){
    $ID = $_REQUEST['ID'];
    $result = "this is a test";
    echo json_encode($result);
    exit;
  }


Obviously it should be return "This is a test" (every time), but if I change the ID value, it returns different dashboard pages! (What up wit dat?)

It's very likely these the code samples will not help you, because I have the same code syntax used in several other blocks - without error. Meaning the real problem is lost somewhere in the code (not shown).

I'm hoping some has encountered this problem before and can just say... do "X"

rockface
View Replies: View Best Answer
guythomas replied on at Permalink Best Answer Reply
guythomas
I think you may have some syntax problems with your ajax request. I have not tested it, but it just doesn't look right to me.

When you test this, are you examining your request in firebug or similar, to ensure your post variables are being set properly?

Furthermore, while I have implemented ajax many times on c5 sites, I have NEVER gotten the mysterious "action" method to work properly..

My ajax work flow is to send an identifying function variable, as well as the required data to the controller, and sort it out there...

So, if I was adding an item to a list my ajax would send two variables

action: 'add' <-quoted string
itemname: itemname <-javascript variable representing item text

The request would be submitted to the basic URL of the page who's controller will handle the ajax.. In the VIEW, I do this like so:

$currentPage = Page::getCurrentPage();
Loader::helper('navigation');
$url_base = NavigationHelper::getLinkToCollection($currentPage, true);


$url_base can now be used as the url in your ajax

Finally, I perform the processing of the request in the controller like so.. In the CONTROLLER on_start() method I use the following:

if ($this->isPost()){
         switch ($this->post('action')){
         case "edit":
            $return_value['message'] = "Made it to Edit";
            $js = Loader::helper('json');
            $r = $js->encode($return_value);
            echo $r;
            break;
         case "add":
            $return_value['message'] = "Made it to Add";
            $js = Loader::helper('json');
            $r = $js->encode($return_value);
            echo $r;
            break;
         case "delete":


Finally, I like to use the .post, or .get jquery functions instead of the ajax function.. Here is an example:

var usersitemname = $(this).val();
$.post(<?php echo $url_base ?>, 
      {itemname: usersitemname, action: 'add'},
      function(r) {
         if (r.message){
            alert(r.message);
         }
      },'json');


I know this isn't what you were looking for, but I hope it helps.. If I had to give you a quick answer instead of a novel, I would tell you to examine your .ajax() commands url: and data: properties.. I'm pretty sure you do not need to add a $_GET like "&" in front of the variable name, and I'm not really sure what you are doing with the string replace in the URL..

-Guy
fastcrash replied on at Permalink Reply
fastcrash
did it still hurt?, your butt?
rockface replied on at Permalink Reply
rockface
yes it did!
rockface replied on at Permalink Reply
rockface
Thanks guythomas, this started working, only after moving the controller code into the "on_page_view()" function.

based on your example, I am switching over to this method!! I seems to work really well and offers an easy way of passing multiple variables in both directions!

Thank you SO much!
guythomas replied on at Permalink Reply
guythomas
Just a correction to the above post. This method is how I perform Ajax operations when building single pages, not blocks.

Today I built a block with action passthru methodology and it worked great.
nerdess replied on at Permalink Reply
nerdess
how do you make your ajax requests secure? do you check whether a user is logged in or check for a token or both? just need some best practise hint :-)
rockface replied on at Permalink Reply
rockface
Hi nerdess,
you can control security by placing the form on a page which is only viewable by users who are logged in.
1. Navigate to that page
2. click on Edit > Permissions
3. Uncheck the "Guest" under "Who can view this page?"

Or you can wrap the form in an if block...
Loader::model('user');
$u = new User();
$uID= $u->getUserID();
if (iID>'') {
  // My form 
}

Another security concern is SQL injection... that would be another topic (about how to have data, once you have it and want to write it to the database.
m3rg replied on at Permalink Reply
Probably not the best solution but I've used this:
if(!$_SESSION['uID'] && !in_array('Administrators', $_SESSION['uGroups']))
{
   echo t('Invalid credentials.');
   return;
}
a2mDeveloper replied on at Permalink Reply
a2mDeveloper
Thank you!! Works like a charm! :)