Link to home
Start Free TrialLog in
Avatar of nachtmsk
nachtmskFlag for United States of America

asked on

javascript/ajax

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

Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

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
Avatar of nachtmsk

ASKER

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
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

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
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
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
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
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.
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
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)
User generated image
Sorry, posted before looking at your screen grab.

If you don't see the post there then try the Network tab.
Thanks for all the help!
 Might not get back to this until later today or in the morning tomorrow. Will respond then.
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);
    }
  });
}
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
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
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.
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.
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.
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
}
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.
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
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.
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.
You are welcome.