xms xms - 4 months ago 14
jQuery Question

jQuery and replacing hyperlink with HTML code loaded from the server

My HTML code has about 100 divs and hyperlinks which are almost identical:

<div><a href="#" onclick="load_edit(1, 1);" class="painike">Edit 1</a></div>
<div><a href="#" onclick="load_edit(1, 2);" class="painike">Edit 2</a></div>


My jQuery code should load load_edit.php from the server and replace the hyperlink which called the function. Anyway, my code does not replace a hyperlink with HTML code, and I do not know the reason. What is wrong?

function load_edit(kaavio, ottelu) {
$.post( "load_edit.php", { kaavio: kaavio, ottelu: ottelu } )
.done(function( data ) {
alert( "Data Loaded: " + data );

$(this).replaceWith(data); // this does not work
});
}


On the other hand, because I have about 100 hyperlinks which are calling the same function, it would be nice to hear, how this could be done better. I would like to get rid of my inline JavaScript code and improve the function.

Answer

In your code, $(this) doesn't refer to the DOM element that was clicked.
For more information, see What context is the jQuery.post callback function invoked in?

When you create an anonymous function, it will hold onto all local variables in the same scope, but not this, which is set by JavaScript itself (to the global object) or overridden when called.
Yehuda Katz

I suggest binding a click handler to all links with the appropriate class. Then, define a reference to the clicked element before making your AJAX call. This local variable will then be available in the anonymous "done" function.

I also suggest using data attributes to define variables per link. This data can be retrieved from the DOM by using jQuery's data() method.

jQuery('.painike').on('click', function(e) {
  
  e.preventDefault();

  var $this = $(this),
      kaavio = $this.data('kaavio'),
      ottelu = $this.data('ottelu');

  jQuery.post("//posttestserver.com/post.php", {
      kaavio: kaavio,
      ottelu: ottelu
    }).done(function(data) {
      $this.replaceWith(data);
    });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div><a href="#" class="painike" data-kaavio="1" data-ottelu="1">Edit 1</a></div>
<div><a href="#" class="painike" data-kaavio="1" data-ottelu="2">Edit 2</a></div>

Here's another seemingly relevant post, though it's not exactly a duplicate:
Uncaught TypeError: Cannot read property 'createDocumentFragment' of undefined