views:

157

answers:

4

Can I use Jquery to call an action and then change the image when it success, just like stackoverflow's post voting function?

In my view, I'm using the following code, but I don't want to refresh the browser. Can anyone provide some code about this for me?

Many thanks.

<%if (!item.IsPrinted)
{ %>
     <%=Html.ImageLink("~/Content/images/web/delete.png", "printed", "MarkAsPrinted", "Order", item.TaskID, null, null)%>
 <%}
 else
  {%>
       <img src="~/Content/images/web/star.png" alt="printed" />                    
  <% }  %>
A: 

I'm not sure you fully understand exactly what ajax is or does.

The way requests are normally made without ajax is essentially this:

[browser request]->[server handles request]->[new page sent to browser]

The difference with ajax is that a request is sent to the server, and the response is received by javascript, without the page reloading or anything. It is then up to the javascript script to decide what to do once the request has been received.

What you'd do for this is send the request to 'vote.asp' or something, and then use javascript to change the image once you receive the response from the server.

Cam
@incrediman, thank you for the explanation. Do you have any sample code about this? I'm do not have much experience about this.
Daoming Yang
@Daoming Yang: Here is a complete tutorial for using Ajax with jQuery: http://api.jquery.com/jQuery.ajax/
Cam
+2  A: 

Generally you should call helper methods through ajax call for this purpose rather than calling your action through ajax. Then, in the helper method, update the value of the score (like storing the latest value to the databse etc) and in the success method of ajax display the appropriate image

Edit:

public string UpdateVoteScore(int postId, int value) {
     // store value to database

     return "success";
}

In JavaScript:

var UpdateScore = function(postId, newValue) {
   $.ajax({
           type: "POST",
           url: /YourController/UpdateVoteScore,
           data: { postId: postId, value: newValue },
           success: function(result) {
              // replace your image
              $("#MyImage" + postId).attr("src", "some new image path here");
           },
           error: function(req, status, error) {
           }
    });
}

In View:

<img id='<%= "MyImage" + post.Id %>' 
     src="some image path"
     onclick="UpdateScore(scoreValueHere);"></img>

Note: post will be changing as you do this in a loop, so the post.Id will be unique and thus makes the image id unique

Mahesh Velaga
@Mahesh Velaga, do you have any sample code about this?
Daoming Yang
@Daoming: Edited the answer with some code snippets
Mahesh Velaga
@Mahesh Velago, thank you for the solution, but it only works for the first click and first image , I have a list of these images which generated through foreach from database. I think it could be img tag ID's the problem, all of them are having the some image ID. Any ideas?
Daoming Yang
yup, your image ids need to be different for each entry, and may be you want to send the post/answer id to your helper method as well, and append this id to your image id to make them unique, I will update the code
Mahesh Velaga
Thank you very much Mahesh.
Daoming Yang
glad to help :)
Mahesh Velaga
+2  A: 

Yes you can use JQuery for this. For example by letting JQuery replace a part of you're HTML code based on what it get's back from the server script.

Sample:

<html>
  <head>
    <script type="text/javascript" src="jquery-1.3.1.js"></script>
    <script type="text/javascript" src="jquery.form.js"></script>
    <script>
      $(document).ready(function(){
        $('#response a').bind('click',function(event){
          event.preventDefault();
          $.get(this.href,{},function(response){
          if (response.indexOf("OK") >= 0) {
            $('#response').html("<img src="~/Content/images/web/star.png" alt="printed" /> ");
          }
          })    
        })
      });
    </script>
  </head>
  <body>
    ... the other things on you're page
    <div id="response">
      <%=Html.ImageLink("~/Content/images/web/delete.png", "printed", "MarkAsPrinted", "Order", item.TaskID, null, null)%>
    </div>
    ... more things on you're page...
  </body>
</html>

Make sure that the server script returns "OK" when it needs to replace what's in the "respone" div.

Kdeveloper
@Kdeveloper, this solution is quite good, but it will affect other links. is there something I could do call the action and replace the image without refresh the page.
Daoming Yang
@Daoming Yang: I updated the script so you don't have to hardcode the HTML in you're script. Not sure what you mean by other links, though. BTW, the click on the link will not result in a page refresh (see: "event.preventDefault();").
Kdeveloper
@Kdeveloper, thank you. "$('a').bind('click',function(event)" will stop all the links working on the page, any suggestions?
Daoming Yang
@Daoming Yang: Updated the script, the JQuery selector should now select only the links in the 'response' div.
Kdeveloper
A: 

You could probably do something like:

$('#vote_button').click(function() {
   $.ajax({
      type: "GET",
      url: "script_name.asp", //your script that talks to the database
      data: "id=" + some_var, //get arguments
      success: $("#image_to_be_changed").attr("src", "some new image path here");
});
vette982