Ajax question

I want to hide a div when a form is sent using Ajax. The problem is that I’ve got around a hundred divs that are all called helpfulxxx (the xxx is the unique handler for each div). The problem is I’m not sure how to change just that div.

When a form is submitted I run this code:

            <script type="text/javascript">
$("#rate-yes").click(function(){
                $.ajax({
                  async: false, type: "POST", url: "/rate.php?rate=good",
					data: $("#rate-yes").serialize(),
                  success: function(data){
							$('#helpful"+#rate-no+"').fadeOut("fast", function(){
								$(this).before("<div class='rate'><strong>Thank you</strong></div>");
							});
						}
                });
                });
			
            $("#rate-no").click(function(){
                $.ajax({
                  async: false, type: "POST", url: "/rate.php?rate=bad",
					data: $("#form").serialize(),
                  success: function(data){
							$('#helpful"+#rate-no+"').fadeOut("fast", function(){
								$(this).before("<div class='rate'><strong>Thank you</strong></div>");
							});
						}
                });
                });
				</script>

but I don’t know how to change just the relevant div.

The code for the comments (and the form is):

    <div class="comment-list">
                            <div class="comment">
                  <div style="padding: 5px 0 5px 0;">
                    28th May 2015<br><br>
                    Well done!<br>
                    <div id="helpful570579">Was this comment helpful? <input id="rate-yes" type="image" src="/images/review_yes.png" value="570579" width="24" height="26" style="vertical-align: middle;"> (2) <input id="rate-no" type="image" src="/images/review_no.png" value="570579" width="24" height="26" style="vertical-align: middle;"> (1)</div>
                  </div>
                </div>
                            <div class="comment">
                  <div style="padding: 5px 0 5px 0;">
                    29th May 2015<br><br>
                    The best<br>
                    <div id="helpful569347">Was this comment helpful? <input id="rate-yes" type="image" src="/images/review_yes.png" value="569347" width="24" height="26" style="vertical-align: middle;"> (0) <input id="rate-no" type="image" src="/images/review_no.png" value="569347" width="24" height="26" style="vertical-align: middle;"> (0)</div>
                  </div>
                </div>

please show some examples of your html

Also, it looks like you might be using id’s wrong. All id’s should be unique on the page. There should only be 1 element with the id="rate-yes" and 1 with id="rate-no". If there are multiple elements, they should be classes. You can do a click event based on the class.

eg:

<button class="rate-yes">Yes</button>
<script>
    $('.rate-yes').click(function(e) {
        // do stuff
    });
</script>

Sorry I thought I had, it looks like it was removed. The code is:

<div class="comment-list">
                    <div class="comment">
          <div style="padding: 5px 0 5px 0;">
            28th May 2015<br><br>
            Well done!<br>
            <div id="helpful570579">Was this comment helpful? <input id="rate-yes" type="image" src="/images/review_yes.png" value="570579" width="24" height="26" style="vertical-align: middle;"> (2) <input id="rate-no" type="image" src="/images/review_no.png" value="570579" width="24" height="26" style="vertical-align: middle;"> (1)</div>
          </div>
        </div>
                    <div class="comment">
          <div style="padding: 5px 0 5px 0;">
            29th May 2015<br><br>
            The best<br>
            <div id="helpful569347">Was this comment helpful? <input id="rate-yes" type="image" src="/images/review_yes.png" value="569347" width="24" height="26" style="vertical-align: middle;"> (0) <input id="rate-no" type="image" src="/images/review_no.png" value="569347" width="24" height="26" style="vertical-align: middle;"> (0)</div>
          </div>
        </div>
1 Like

Yeah, you’re using id’s wrong. They should be unique to the page. You should also be using stylesheets or defining the styles elsewhere in the page.

<style>
.rate-yes {
    width: 24px;
    height: 26px;
    vertical-align: middle;
}
</style>
<input class="rate-yes" type="image" src="/images/review_yes.png" value="570579">

Same thing for the rate-no.

I’m sure it’s generated content, but this looks generic enough to do this.

Anyway, to your question. Use the this keyword.

$(".rate-yes").click(function(e) {
    // "this" here corresponds to the button that was clicked
    // set to a "self" variable because it is a keyword and will lose scope later on
    var self = this; 
    // *note* self is not a keyword, just a variable name. you could name it "bob" if you'd like

    $.ajax({
        async: false,
        type: "POST",
        url: "/rate.php?rate=good", 
        data: $(self).serialize(), // self instead of the class
        success: function(data) {
            // wrap self in the jquery object $() to use jquery functions like .val()
            // just concat the value of the button to the id name
            $('#helpful' + $(self).val()).fadeOut("fast", function() {
                $(this).before("<div class='rate'><strong>Thank you</strong></div>");
            });
        }
    });
});

That should work.

Thank you so much, that works perfectly now!

1 Like

Thank you

I’m really sorry to be a pain but when I load more comments this stops working. I’ve tried to fix it myself but am not sure how to. I tried to change $(“.rate-no”).click(function(e) { to $(“.rate-no”).on(“click”,function(e) { but that didn’t work

This is the code that loads more comments:

<script type="text/javascript">
              var comments_offset=<?php echo $more ?>;
              function comments_load() {
                $.ajax({
                  url: "/comments-load.php?pid=<?php echo $id ?>&offset="+comments_offset+"&t="+Math.random(),
                  success: function(data){
                    if( data.substring( 0,5 )!="failed" ) {
                      bits=data.split( "==DSPLIT==" );
                      $(bits[1]).insertBefore( "#comments-control" );
                      comments_offset=bits[0];
                      if( comments_offset==0 ) { $("#comments-control").hide(); }
                    }
                  }
                });
              }
            </script>
            <div id="comments-control" <?php if( !$more ) { ?> style="display: none;"<?php } ?>>
              <br /><a class="input_button" onclick="comments_load();" href="javascript:void(0);">More comments</a>
            </div>

I’m sure you’ve moved on by now because this is a month and a half old, but I didn’t notice this. Sorry. Discourse only notifies someone if you click the little reply under their post, or quote them, or mention them (best way).

$(document).on('click', '.rate-no', function(e) {
   // stuff
});

Actually no I haven’t moved on!! I’m still trying to get this to work after someone clicks for more results. I’ll try that and let you know.

Thanks

The call to the database works so the code is being executed but the #helpful div isn’t being hidden and the .rate one isn’t being shown so somebody could click to rate it multiple times.

This is what I’ve got:

$(document).on(‘click’, ‘.rate-yes’, function(e) {
var self = this;

    $.ajax({
        async: false,
        type: "POST",
url: "/rate.php?rate=good&id=" + $(self).val(), 
        data: $(self).serialize(), // self instead of the class
        success: function(data) {
            $('#helpful' + $(self).val()).fadeOut("fast", function() {
                $(this).before("<div class='rate'><strong>Thank you</strong></div>");
            });
        }
    });
});

Because you’re not hiding #helpful until the response from the server comes back. Do that at the beginning. Don’t worry about a successful response unless you need the data.

Because if your code works, then the response should be good almost every time, so that means you should only need to handle the errors. The user doesn’t actually care if the response is good, that’s what’s supposed to happen. So why make them wait?

$(document).on('click', '.rate-yes', function(e) {
    var self = this;

    $('#helpful').fadeOut('fast', function() {
        $(this).before("<div class='rate'><strong>Thank you</strong></div>");
    });

    $.ajax({
        async: false,
        type: "POST",
        url: "/rate.php?rate=good&id=" + $(self).val(), 
        data: $(self).serialize(), // self instead of the class
        error: function(data) {
           // handle the error here
        }
    });
});

I changed the code but it still isn’t working for the comments that are loaded after the page is loaded.

So at the moment it works for the first 10 comments, but the others that are loaded using ajax the ‘thank you’ text isn’t being shown (although the code is being executed).

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.