Solved

javascript/ajax

Posted on 2016-09-07
26
41 Views
Last Modified: 2016-09-09
Hi,
I have the code below.
IT works fine, but I'd like to modify it so I can pass an argument to the 'handleDelete' function. Whenever I try to do that, I'm getting nothing. No errors. Just nothing. Is it possible to pass an argument to the handleDelete function with it being used this way? If not, is there a simple modification I can do to this code to allow an argument to be passed to handleDelete?
The reason I need an arg to handleDelete, is because I need the responseText to show in in different Div's ID's depending on where the function is being called from.
Thanks,
Nacht
function deletePhoto(delPhoto){
  if(XMLHttpRequestObject) {
    var url = "../f/inetworklogin";
    var param =".State=DELETEPHOTO&perf_del_photo=" + escape(delPhoto);
    alert("This photo is now deleted. When you refresh this page the photo will no longer be there. ");

    XMLHttpRequestObject.open("POST", url);
    XMLHttpRequestObject.onreadystatechange = handleDelete
    XMLHttpRequestObject.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    XMLHttpRequestObject.send(param);

  } // End checking for XMLHttprequest object
} // end function


function handleDelete() {
  var delobj = document.getElementById('photo3');
  if (XMLHttpRequestObject.readyState == 4 &&
      XMLHttpRequestObject.status == 200) {
      delobj.innerHTML = XMLHttpRequestObject.responseText;
  } // end Handle Response
}

Open in new window

0
Comment
Question by:nachtmsk
  • 13
  • 12
26 Comments
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41788056
What parameter do you want to pass to it? That is the callback from the AJAX call

Can you explain what you want to do?

This looks like it can be done much easier in jQuery
0
 

Author Comment

by:nachtmsk
ID: 41788069
Hi,
I figured someone was going to mention a framework. I'd rather stick with this since it's 90% there.

I am deleting  a photo from a web page.
There are several photos on the webpage.
Each one is in it's own div with it's own ID.
I want to put up a message after the photo is deleted saying it was deleted, but the message has to go to the specific div.
Right now, the ResponseText is showing at a hard-coded ID I put in (photo3). I need to be able to pass in a variable to the responseText that is passed to the 'handleResponse' function.

So, what I need to do is pass in an argument to handleResponse function. That argument will be the div ID that I will be targeting the message to.
Thanks!
Nacht
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41788097
jquery is not a framework - it is a javascript library that makes things like AJAX seriously less complicated.
Here is the jQuery equivalent (with all dependencies)
<script  src="//code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
function deletePhoto(delPhoto) 
{
  $.ajax({
    url: '../f/inetworklogin',
    data: {State: "DELETEPHOTO", perf_del_photo: delPhoto},
    type: 'post'
  }).done(function(resp) {
    $('#photo3').html(resp);
  });
}</script>

Open in new window

With respect to your question - AJAX calls are asynchronous so there is no flow from calling deletePhoto to the success function. The best way to do this is to pass the ID of the photo to the delete function and have it return that.

For instance you could return a JSON structure that contains the id and the message something like this
{
    "success": true,
    "id": "photo3",
    "msg": "whatever you were sending here"
}

Open in new window

The above jQuery then changes to
function deletePhoto(delPhoto) 
{
  $.ajax({
    url: '../f/inetworklogin',
    data: {State: "DELETEPHOTO", perf_del_photo: delPhoto},
    type: 'post',
    dataType: 'JSON'
  }).done(function(resp) {
    if (resp.success) {
      $('#' + resp.id).html(resp.msg);
    }
  });
}

Open in new window

0
 

Author Comment

by:nachtmsk
ID: 41788129
Thanks. I didn't really have time to learn something new, but it looks like I'll need to.
I appreciated the code above. It definitely does look simpler. I'll see if I can incorporate into my end.

Thanks  again,
nacht
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41788202
If you don't want to use JQuery - it is a simple change to your javascript to get it working.

jQuery is pervasive now - many sites will use it at some level but you don't have to - it just make some tasks a lot easier and cross browser compatible.

Post back if you want the pure javascript version
0
 

Author Comment

by:nachtmsk
ID: 41788214
Yes please. I'd like to see the javascript example if possible. I will try Jquery. But if it's too time consuming to get it working, I'll fall back to the version I initially wrote.
Thanks,
N
0
 
LVL 51

Accepted Solution

by:
Julian Hansen earned 500 total points
ID: 41788336
The JQuery I posted will pretty much work out of the box but here is the JavaScript equivalent. I have not seen all your markup so I don't know what you want to do with the result but this demonstrates how you can target the selected <img>
JavaScript
<script>
var XMLHttpRequestObject = new XMLHttpRequest();
function deletePhoto(delPhoto){
  if(XMLHttpRequestObject) {
    var url = "../f/inetworklogin";
    var param =".State=DELETEPHOTO&perf_del_photo=" + escape(delPhoto);
    alert("This photo is now deleted. When you refresh this page the photo will no longer be there. ");

    XMLHttpRequestObject.open("POST", url);
    XMLHttpRequestObject.onreadystatechange = handleDelete
    XMLHttpRequestObject.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    XMLHttpRequestObject.send(param);

  } // End checking for XMLHttprequest object
} // end function


function handleDelete() {
  if (XMLHttpRequestObject.readyState == 4 &&
      XMLHttpRequestObject.status == 200) {
    // PARSE RETURN INTO json
    var response = JSON.parse(XMLHttpRequestObject.responseText);
    // CHECK SUCCESS
    if (response.success) {
        // GET THE TARGET IMAGE
      var delobj = document.getElementById(response.id);
      
      // AND DO SOMETHING WITH IT
      delobj.src = response.msg
    }
  } // end Handle Response
}
</script>

Open in new window

Working sample here
EDIT
For interest here is the PHP script that processes the request
<?php
$perf_del_photo = isset($_POST['perf_del_photo']) ? $_POST['perf_del_photo'] : false;
$return = new stdClass;
$return->success = false;
if ($perf_del_photo) {
  $return->success = true;
  $return->id = $perf_del_photo;
  $return->msg = 'images/close.png';
}
die(json_encode($return));

Open in new window

0
 

Author Comment

by:nachtmsk
ID: 41789580
I tried using the Jquery code. Problem I ran into was that the parameter you have has "State" is actually supposed to be ".State". (period before). I know it's odd, but that's the way it is. Difficult to change.

So then I tried using the modified Javascript code. But I'm getting an error at line 22 of  your code :
"SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data"

I'm going to stop doing this now as I have a lot of other stuff to do. If you have a suggestion, that would be great.

Otherwise, I can use a workaroud. It's not pretty, but it'll work. I can just create 6 different delete functions in javascript and hardcode in the ID of the return div I need the message to to go.

BTW -- backend is Perl, not PHP. Not that it really matters.

Thanks,
Nacht
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41789694
I would need to see what your service is returning - the error on line 22 says that whatever is being returned is not valid JSON.

As for State vs .State - just change it to have . in front.

Having said that though - if the JSON coming back is incorrect then you are not going to get the jQuery version to work either.

Step 1: post your response here (F12 to get to the console - look for the POST entry - expand it - select the Response tab - copy and paste result here).

Step 2: We fix your JSON

That should be all that is required.
0
 

Author Comment

by:nachtmsk
ID: 41789743
I'd already  tried changing  "State to .State".
I got an error saying "Syntax Error: invalid property ID

The response I get with the pure JS solution is attached.

Not sure what you mean by 'response tab'. I'm using Firefox on a Mac. I can't run Chrome on this mac. The OS is too old. Maybe what your asking for is from Chrome or some other browser?
 F12 on a Mac doesn't do what you want it to do.

Thanks!
Screen-shot-2016-09-08-at-11.16.24-A.png
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41789796
I got an error saying "Syntax Error: invalid property ID
Can you post the code for that.

Response tab
Right click your page and select "Inspect Element" - this will open the Console
Click on the Console tab (should be the left most one)
In the console window (you might need to reload your page) you will see a POST entry with a + next to it. Expand that - it should show you a number of tabs - select the Response tab and copy the result from there (see below)
ss61.jpg
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41789798
Sorry, posted before looking at your screen grab.

If you don't see the post there then try the Network tab.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:nachtmsk
ID: 41789861
Thanks for all the help!
 Might not get back to this until later today or in the morning tomorrow. Will respond then.
0
 

Author Comment

by:nachtmsk
ID: 41789980
This is the code for the Syntax error, invalid property ID message.
It's the same exact code you gave me, except there is a period before the "State" param.

function deletePhotoJQ(delPhoto)
{
  $.ajax({
    url: '../f/inetworklogin',
    data: {.State: "DELETEPHOTO", perf_del_photo: delPhoto},
    type: 'post',
    dataType: 'JSON'
  }).done(function(resp) {
    if (resp.success) {
      $('#' + resp.id).html(resp.msg);
    }
  });
}
0
 

Author Comment

by:nachtmsk
ID: 41789990
Regarding the error with the pure JS version.
Attached is screen shot of  what you were asking for.
The response is correct, but it's not showing in the DIV after it runs.
The message in the screen shot, should be showing in the <DIV>
here is the code in the perl script that is calling the JS.

print "<div style=\"color:#990000;border:solid thin red;text-align:center;\" id=\"photo3\" ><A HREF=#  onclick=\"deletePhoto('$photo3');\">DELETE THIS PHOTO NOW!!</div>\n";
}
Screen-shot-2016-09-08-at-1.30.09-PM.png
0
 

Author Comment

by:nachtmsk
ID: 41789994
And here is the sub in the perl script. Which looks like it's running correctly, but as I said, the message it's returning isn't showing up in the DIV I printed above.

sub  delete_photo {
print $query->header;
print "Photo Deleted!!  $perf_del_photo";


}## end delete photo
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41790043
Ok but that is not JSON - the question you were asking was how to target a specific div.
When you initiate the delete you call the function that sends the info to the server along with the id of the photo. The server has to send back its answer AND the photo id.

The easiest way to do that is to put the data in a JSON object.
So your response would be

{
    "id": "photo_div_id_here",
     "success": true,
     "msg": "Photo Deleted!! 22543_258_49031EmmaSantosModel1.jpg"
}

Open in new window


Your script is just sending back a string - the receiving script needs to be able to separate message from id - hence the JSON.

Let me know if that makes sense.
0
 

Author Comment

by:nachtmsk
ID: 41790077
In the original code I had the JavaScript would run and call the perl script. The perl script returned a message. The JavaScript would write that message using innerHtml back to the web page to the div that was Hardcoded into the JavaScript.
I'm not sure what you are saying regarding JSON as I don't ever use JSon
Sorry on mobile app now. Can't include code details about what I mean.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41790097
Your original problem was you needed to pass a parameter to the success function of the AJAX call?

You can't do that from the client side due to the async nature of the process - what you do is pass the parameter to the server and have it echo it back to you.

You pick up that returned parameter in the success function and use that to target your div.

You don't have to pass JSON back but if you don't you need to come up with another mechanism to pass the id of the target div AND the message in the same response. JSON is simply the easiest way of doing it - you could send it back as a comma separated string and do a split on the results - but which ever way you do it you need to send back 2 pieces of information whereas before you were only sending 1 (the message).

A JSON response is simple - I have given you a template for it already - if you change your script to output that template with the correct values filled in then it should integrate into the JavaScript.

Let me know if I have missed the requirement here.
0
 

Author Comment

by:nachtmsk
ID: 41791270
Hi,
Thanks for all of your help. I think we are having a communication problem. You keep talking about JSON. I don't think that is my solution.   let's try again.
Here is my original code that works. Please look down into the handleDelete function. I put some notes next to one of the lines that should explain clearly what I'm trying to do.

function deletePhoto(delPhoto){

if(XMLHttpRequestObject) {


var url = "../f/inetworklogin";
var param =".State=DELETEPHOTO&perf_del_photo=" + escape(delPhoto);

alert("This photo is now deleted. When you refresh this page the photo will no longer be there. ");



XMLHttpRequestObject.open("POST", url);
XMLHttpRequestObject.onreadystatechange = handleDelete
XMLHttpRequestObject.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
XMLHttpRequestObject.send(param);

} // End checking for XMLHttprequest object
} // end function


function handleDelete() {

var delobj = document.getElementById('photo3');  
// This line here targets a div with the id of "photo3". Once the perlscript called "inetworklogin" is called, it runs. It deletes the photo and it returns a message to the div with the id of "photo3". Then the perl script prints the  message that says "Photo is deleted". On the web page the message "Photo is deleted"  shows up in that DIV through Ajax. My question/problem is this. I need to pass a variable into handelDelete, and use that variable in the place currently occupied by the string above 'photo3'. The whole point of this is just to return a string using Ajax, to the user telling them the photo they wanted deleted, has been marked for deletion. But if I try to pass something into handleDelete(), it  doesn't work.
So the code would look something like this.

function handleDelete(varPassed){
var delobj = document.getElementById(varPassed);




if (XMLHttpRequestObject.readyState == 4 &&
XMLHttpRequestObject.status == 200) {
delobj.innerHTML = XMLHttpRequestObject.responseText;
} // end Handle Response
}
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41791285
My question/problem is this. I need to pass a variable into handelDelete, and use that variable in the place currently occupied by the string above 'photo3
There is no communication problem - I understand your problem 100%. I don't think you are understanding the solution.

1. You can't pass a variable into HandleDelete - at least not from the calling code - this the point I have been trying to explain. HandleDelete is a callback that fires when the AJAX async call completes. The only way to get state information to HandleDelete is for the Server script to send it as part of the response.

2. You want to know which div to target - instead of the hardcoded one you are targeting currently. Right - to do this you have to pass this information in your AJAX call (which you are doing) and then the server process has to send it back so that when HandleDelete is called that information is there.

If you read my previous post you will see I mentioned that you have to receive TWO bits of information back from the server for his to work
1. The message
2. The id of the div
Your current solution is geared only for receiving one. I said that JSON was the logical option for doing this - sending back a JavaScript object with two properties (msg and id) - but you can do it in a number of different ways - just that anything other than JSON requires a bit more code in the call back.

The essence here is you can't send a parameter to HandleDelete unless it comes from the server - as your message is currently - so any additional information you need (like div id) you have to send from the server.
0
 

Author Comment

by:nachtmsk
ID: 41791309
Hi,
Your right, I don't understand your solution. But I am very grateful that you tried so hard to help.
I started looking through some archived code of mine assuming I would have come up against this issue in the past. I did. I found the following which I just slightly modified and it does exactly what I want it to do. I'll find the best answer you sent and award you the points. Thanks again!

My main issue was how to get around the handleDelete() function not being able to receive a param. Your  correct, the code I sent you didn't have that second parameter in it -- because handleDelete couldn't acccept it. What I was asking in a more general term is how can I dynamically assign the value of the DIV for which I am returning a message to. It's been a while since I've had to do Javascript (the code below is about 10 years old), so it took me a while to get back into understanding it.


 function deletePhoto(delPhoto,msgDiv)
 {
 if(XMLHttpRequestObject) {
var delobj = document.getElementById(msgDiv);
                                        }
 var url = "../f/inetworklogin";        
 var param =".State=DELETEPHOTO&perf_del_photo=" + escape(delPhoto);

 XMLHttpRequestObject.open("POST", url);
XMLHttpRequestObject.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
XMLHttpRequestObject.onreadystatechange = function()
         
         {
                if (XMLHttpRequestObject.readyState == 4 &&
                 XMLHttpRequestObject.status == 200) {  
                 delobj.innerHTML = XMLHttpRequestObject.responseText;
                 }
                 
        }
 XMLHttpRequestObject.send(param);
 } // end deletePhoto
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41791365
That's not passing a parameter to handle delete - it is effectively using a variable that is global to the scope of the onreadystatechanged handler. That is a viable option but the question was how to pass a parameter to the handledelete function - which you cannot do.
0
 

Author Comment

by:nachtmsk
ID: 41791392
Your right on both counts. It's not passing the argument to HandleDelete and it's not possible to pass an argument to HandleDelete. I got that. But what I should have said, somewhere along this chain was "So, if I can't pass an argument to handleDelete, what CAN I do that will allow me to do what I need to do?". I had  wrongly assumed that the question was implied once it was clear what I initially asked for wasn't possible but I should have explicitly asked it. Anyway, thanks again.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41791394
You are welcome.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Introduction HyperText Transfer Protocol (http://www.ietf.org/rfc/rfc2616.txt) or "HTTP" is the underpinning of internet communication.  As a teacher of web development I have heard many questions, mostly from my younger students who have come to t…
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now