1

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.

xms
  • 429
  • 5
  • 24

2 Answers2

1

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

Community
  • 1
  • 1
showdev
  • 28,454
  • 37
  • 55
  • 73
  • Thanks a lot! How about using href="#" on my hyperlink. Better ways? – xms Jul 22 '16 at 17:28
  • I think the `#` is fine, but there are [varying opinions](http://stackoverflow.com/questions/134845/which-href-value-to-use-for-javascript-links-or-javascriptvoid0). You might want to cancel the default action of the links by using [`preventDefault()`](https://api.jquery.com/event.preventdefault/) or `return false;`. If you really want to be accommodating, you could link to a page that explains that JavaScript is required. – showdev Jul 22 '16 at 17:33
  • I had to add $(document).ready(function(){ (do not know the reason) and after that your code works perfectly! Thank a lot. – xms Jul 22 '16 at 17:57
  • Sounds good. If your JavaScript loads before the DOM, you may need to use [`$(document).ready()`](https://learn.jquery.com/using-jquery-core/document-ready/) to wait for the DOM to load before binding your click handler. See [Why document.ready is used in jQuery](http://stackoverflow.com/questions/30753333/why-document-ready-is-used-in-jquery). – showdev Jul 22 '16 at 18:04
  • If I want to use style – xms Jul 22 '16 at 18:08
  • It doesn't appear that adding another class will affect your JavaScript. That is, unless there is some other conflicting JavaScript bound to the "muokattavaksi" class. – showdev Jul 22 '16 at 18:11
1

Inside your .done() callback, this does not refer to the clicked element. Instead, you can pass the element reference into load_edit().

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

function load_edit(kaavio, ottelu, element) {
    $.post("load_edit.php", { kaavio: kaavio, ottelu: ottelu })
        .done(function (data) {
            $(element).replaceWith(data);
        });
}
Slippery Pete
  • 3,051
  • 1
  • 13
  • 15