Alert() from an Ajax loaded page?

Hey SP,

I’m trying to make it so I can call a function when an ajax script is loaded, this seems like it should work but it doesn’t. What am I missing here?

When this script runs it should alert() but doesn’t, even though it is outputting $updated

<?
if($_GET['m'] == 'imgupdate')
{
  # Update this image
  $query = 'update user_images set 
    image_permission = "' . $_GET['image_permission'] . '",
    image_caption = "' . $_GET['image_caption'] . '"
  WHERE
    user_id = "' . $_SESSION['user']['user_id'] . '" AND
    image_id = "' . $_GET['image_id'] . '"';
  
  $result = mysqli_query($tnt['sql_link'], $query);
  if($result)
  {
    $updated = 'Updated.';
  }else {
    $updated = 'Failed to Update';
  }
  
  $img['image_permission'] = $_GET['image_permission'];
  $img['image_caption'] = $_GET['image_caption'];
}
?>

<div id="image.<?=$img['image_id']?>" style="margin-top:10px;">
  <div style="padding-bottom:5px;">
    <select id="image_permission.<?=$img['image_id']?>" style="padding:2px; width:165px;">
      <option value="0" <?if($img['image_permission']==='0'){?>selected<?}?>>Private</option>
      <option value="1" <?if($img['image_permission']==='1'){?>selected<?}?>>Public</option>
    </select>
    
    <input type="button" value="Update" onclick="var url = 'index.submit.php?m=imgupdate&image_id=<?=$img['image_id']?>&image_permission=' + document.getElementById('image_permission.<?=$img['image_id']?>').value + '&image_caption=' + document.getElementById('image_caption.<?=$img['image_id']?>').value; ajax('image.<?=$img['image_id']?>',url,'GET')" />
  </div>
  
  <input type="text" id="image_caption.<?=$img['image_id']?>" style="width:90%;" value="<?if($img['image_caption']){echo $img['image_caption'];}else{?>(none)<?}?>"/>
  
  <?
  if($updated)
  {
    ?>
    <div id="updated"><?=$updated?></div>
    
    <script>
    alert('test');
    </script>
    <?
  }
  ?>
</div>

Where is the ajax() function defined?

I think here:

 <input type="button" value="Update" onclick="var **url =** 'index.submit.php?m=imgupdate&image_id=<?=$img['image_id']?>&image_permission=' + document.getElementById('image_permission.<?=$img['image_id']?>').value + '&image_caption=' + document.getElementById('image_caption.<?=$img['image_id']?>').value; ajax('image.<?=$img['image_id']?>',url,'GET')" />

Not sure if that will work, though.

:slight_smile:

that’s where it’s called, not where it’s defined.

It’s defined in the Head of the HTML page.

This ajax call works, it will update the permission and the caption of the image correctly. The issue I’m having is that Alert() won’t run after the script updates. Why is that? Is it not possible to have new javascript come in with an ajax load?

Maybe you’re thinking of JSONP ?

In any case, I think what you should do is not to try and send script along with the JSON, but instead have the alert already in place and only fire it if the JSON returns a specified value.

No idea what JSONP is.

I guess my issue boils down to one simple question.

Can an Ajax loaded script bring new JavaScript into the already loaded DOM? I’m guessing no.

That would be a security risk and AFAIK most if not all browsers don’t allow that.

You should however, be able to have the JavaScript in the page already, and use or not use it depending on what the JSON returns without much trouble.

So how would I have an Ajax loaded script trigger a function already loaded inside of the DOM? For example, lets say I wanted it to alert(‘Image has been updated’), if the loaded script can’t trigger an alert, how can it trigger any other function in the DOM?

What does your ajax function look like? The key is to call the alert function from within the success portion.

  function ajax(div,url,method)
  {
    var ajax=new XMLHttpRequest();
    
    ajax.onreadystatechange=function() 
    {
      if (ajax.readyState==4 && ajax.status==200) 
      {
        document.getElementById(div).innerHTML=ajax.responseText;
      }
      else
      {
        document.getElementById(div).innerHTML='<img src="/_css/_defaults/throbber.gif" />';
      }
    }
    ajax.open(method,url,true);
    ajax.send();
  }

Thanks, try this. Somewhere in the page (probably the head) wrap the alert in a function. eg.

<script>
  function fire_alert(msg) {
    alert(msg);
  }
</script>

then in your ajax function, call it. eg.

      if (ajax.readyState==4 && ajax.status==200) 
      {
        fire_alert("4 and 200");
        document.getElementById(div).innerHTML=ajax.responseText;
      }
      else
      {
        fire_alert("else");
        document.getElementById(div).innerHTML='<img src="/_css/_defaults/throbber.gif" />';
      }
1 Like

You don’t even need an ajax call to load a new script into the page. All you need to do is to insert the script tag into the DOM.

1 Like

Thanks. I’m disappointed though. That seems like an incredibly cumbersome way to have object like functionality.

What is the big security issue here? Why can’t an Ajax loaded script fire new javascript code?

How would I insert the script tag into the DOM?

Here’s a simple function for adding scripts to the page so that you can add as many scripts as you like by calling that function as shown in the last line simply by supplying the filename (and path if there is one).

var addJS = function(nm) {
  var s = document.createElement('script');
  s.type='text/javascript';
  s.src=nm;
  document.getElementsByTagName('body')[0].appendChild(s);
}

addJS('newScript.js');

See also http://www.felgall.com/jstip128.htm which at the bottom gives an example where scripts dynamically replace one another so that which one runs depends on when you call it.

Ok, so here is what I’ve got.

Contents of test.php:

   <!DOCTYPE html>
    
    <html lang="en">
    
    <head>
    
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta charset="UTF-8">
    
    <script type="text/javascript">
    
      function ajax(div,url,method)
      {
        var ajax=new XMLHttpRequest();
        
        ajax.onreadystatechange=function() 
        {
          if (ajax.readyState==4 && ajax.status==200) 
          {
            document.getElementById(div).innerHTML=ajax.responseText;
          }
          else
          {
            document.getElementById(div).innerHTML='<img src="/_css/_defaults/throbber.gif" />';
          }
        }
        ajax.open(method,url,true);
        ajax.send();
      }
    
    </script>
    
    <body>
    
    <input type="button" value="Click" onclick="ajax('box','test2.php','GET');">
    
    <div id="box"></div>
    
    </body>
    </html>

And here is the contents of test2.php:

<!DOCTYPE html>

<html lang="en">

<head>

<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta charset="UTF-8">

<body>

Alert Test
<script>alert('test');</script>

</body>
</html>

Now, can anyone tell me why this doesn’t do the alert on test2.php after it’s been ajax loaded?

And how could I modify my ajax function so I could easily pass javascript that I need to run on the new script?

A significant problem is that you have both a function and a variable with the same name.

When the onreadystatechage function is triggered, which of the ajax function or variable will it call? Give them different names and you will not have any confusion there.

I never considered that.

The function works as intended minus the alert() not working. I will go adjust and report back.

Update. No changes. test2.php still loads but does not fire the alert event.

You are also loading an entire web page inside of an innerHTML. so the resultant page will be completely broken.

Your test2.php should only contain the HTML that you want loaded into the innerHTML.

JavaScript loaded into innerHTML doesn’t necessarily run either. If you want to make sure JavaScript added to the page and runs then simply add the script tag to the page directly from the JavaScript (no ajax call required).