1

I've seen this problem posted on Stack Overflow couple of times, but the solution I found is usually very old and talks about delegate method which is deprecated.

I am looking for a solution for jQuery 3.x. This is my AJAX call:

$.ajax({
  type: "get",
  url: "/content",
  data: {
    name: {{ name }}
  },
  success: function(data) {
    $("#appendsection").append(data);
  } 
});

Here I am appending the success data to a div called appendsection This appendsection div does not execute any javascript, it executes CSS, but no javascript and no jquery. I see this problem most of the time, any data I get from ajax call does not want to execute javascript.

This is the appended content

<div class="sortingbuttons">
        <select id="sort">
        Sort By
          <option value="name">Relevance</option>
          <option value="price">Cheapest</option>
          <option value="recommend">Recommended</option>
        </select>
</div>

The #sort id is executed on app.js

$('#sort').change(function(){
            $('.section').hide();
            $('#' + $(this).val()).show();
        });

So, the sorting does not work on the appended content, so the javascript is not working on the appended content.

Dhiraj
  • 2,687
  • 2
  • 10
  • 34
  • 5
    What do you mean by 'does not execute javascript'? If you mean that no event handlers fire on it, then you need to use a delegated event handler. A vanilla AJAX call will give you no difference in the result. – Rory McCrossan Dec 05 '17 at 15:16
  • The appended html content does not run javascript on it, so if there is a javascript code like `.button.hide();` ,it will not work on that – Dhiraj Dec 05 '17 at 15:17
  • 2
    When are you attempting to call those functions? – Rory McCrossan Dec 05 '17 at 15:18
  • You mean when there is JS c ode in the returned `data`? That never works like this in jQuery. – xander Dec 05 '17 at 15:18
  • On the appended content itself it calls those functions and I am looking for a way to call it automatically once the content is appended – Dhiraj Dec 05 '17 at 15:19
  • Possible duplicate of [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements). Wether the other questions are old or new, the answer is still the same. – Turnip Dec 05 '17 at 15:19
  • @xander Yes, that's correct. Can you guide me a way to correct it. – Dhiraj Dec 05 '17 at 15:19
  • Don't return JS code in the HTML of an AJAX response. Use delegated event handlers, or put the logic in namespaced functions and call those when the AJAX completes. – Rory McCrossan Dec 05 '17 at 15:20
  • I'm not sure there is a proper way if you load JS code dynamically you can of course use eval or some evil code, but better use another design. – xander Dec 05 '17 at 15:21
  • Possible duplicate of [Loading script tags via AJAX](https://stackoverflow.com/questions/1800585/loading-script-tags-via-ajax) – Danmoreng Dec 05 '17 at 15:21
  • You can use $(document) to select elements inside the appended html, like this: '$(document).find(‘#idIsindeNewHtml’)' – YouneL Dec 05 '17 at 15:25
  • I am not returning JS code on my response data, but there are classes which is called by JS on a separate JS file – Dhiraj Dec 05 '17 at 15:26
  • "I am not returning JS code on my response data"... ok, so when you said to xander "yes that's correct", you actually meant "no, that's not correct"? Please try and describe the situation clearly and accurately. If this latest scenario you've got is correct, then yeah you need to use delegated event handling to bind events to the new content. If you need to do something to the new content (e.g., I don't know, append tooltips or something) which was previously done on the old content by running some script, then simply you need to run that script again to do the same thing to the new content. – ADyson Dec 05 '17 at 15:29
  • If you still don't understand, or something doesn't work after you try to change your code, then show the code which you are referring to when you say "there are classes which is called by JS on a separate JS file" - we could do with seeing what it's _actually_ doing, as opposed to your (rather unclear) description of what it's doing. – ADyson Dec 05 '17 at 15:32
  • @ADyson Thank you, I have updated my question – Dhiraj Dec 05 '17 at 15:34
  • ` – ADyson Dec 05 '17 at 15:40

2 Answers2

4

the solution to your problem is still delegation but not the method delegate.

here is the structure for event delegation in jQuery 1.7+

$( elements ).on( events, selector, data, handler );

try this I hope it will work

$('body').on('change', '#sort', function(){
    $('.section').hide();
    $('#' + $(this).val()).show(); //do anything  
})
ishahadathb
  • 481
  • 2
  • 13
  • I still don't understand, I tried changing it to `body.on function` but it does not work, how will this work – Dhiraj Dec 05 '17 at 15:44
  • Hi, it should have worked, check this jsFiddle https://jsfiddle.net/adcf0qky/ . I tried to mimic the ajax append here with the markup as a string and it worked. Please try clearing the cache and reload. – ishahadathb Dec 05 '17 at 15:58
0

I apparently, solved this problem by running the necessary javascript code on the success function

$.ajax({
  type: "get",
  url: "/content",
  data: {
    name: {{ name }}
  },
  success: function(data) {
    $("#appendsection").append(data);
    //execute necessary javascript after this
    $('#sort').change(function(){
        $('.section').hide();
        $('#' + $(this).val()).show();
    });
  } 
});

This might be one of the ways to delegate the javascript, but I am sure that this is not the best way to do it. But for the moment, this is the only solution that worked for me.

Dhiraj
  • 2,687
  • 2
  • 10
  • 34