Kyrre Kyrre - 3 months ago 15
Ajax Question

jQuery library "not a function" when called in a click event

I'm trying to apply the jQuery Text Editor library to a P tag which is populated by an Ajax call, inside a modal. This is part of a somewhat old and Ajax heavy site with many different jQuery versions being loaded, but running

$.fn.jQuery


in the JS console at any point returns "2.1.4".

I know the libraries do load to the page, as applying ".jqte()" to an existing/"static" element on the page transforms it as intended. This is before the modal is loaded/visible in the flow of the program.

$(document).ready(function(){
$(".odd").jqte();
});


The above snippet does turn all ".odd" elements into little text editors.

$("#showScraper").click(function(){
$(".editor").jqte();
});


The above is what is causing me pain.

I'm having a hard time discerning why the error

Uncaught TypeError: $(...).jqte is not a function


appears only when

$(".myClass").anyLibrary();


is called inside my click event. This also applies to IDs.

Any idea what could cause this? jQuery version conflict?
This question seems similar, and suggests that it could be a version conflict

Is it possible that somehow the html imports aren't read when the Ajax call is done? Or do I not understand scope?

Any help is greatly appreciated!

Some code:

PHP generating the HTML and content to be placed inside the modal:

echo '<div id="scrapedText"><p class="editor" name="text1">';
foreach ($matchContent['about']['p'] as $key => $value) {
echo $value , "<br /><br />";
}
echo '</p></div><br/>';


The link that opens the modal:

$button = '<p><a href="/my/ajax/path" id="showScraper" rel="modal:open">Show me the stuff</a></p>';


My imports:

<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<link rel="stylesheet" type="text/css" href="/css/jquery.modal.css" />
<script type="text/javascript" src="/scripts/jquery.modal.js"></script>
<link rel="stylesheet" type="text/css" href="/static/jQuery-TE_v.1.4.0/jquery-te-1.4.0.css" />
<script type="text/javascript" src="/static/jQuery-TE_v.1.4.0/jquery-te-1.4.0.min.js"></script>

Answer

You've said your site is loading jQuery more than once (multiple different versions). That's not shown in the list of script tags you included in the question, but I assume it is actually true.

That means you're only adding the plugin to the version of jQuery that controlled the jQuery variable as of when you loaded the plugin. So for instance:

<script src="jquery-1.7.2.js"></script>
<script>
$(document).ready(function($) {
// Note -------------------^
    $(".selector1").click(function() {
        $(this).niftyPlugin();
    });
});
</script>
<!-- ... -->
<script src="jquery-2.1.4.js"></script>
<script src="nifty-plugin.js"></script>
<script>
$(document).ready(function($) {
// Note -------------------^
    $(".selector2").click(function() {
        $(this).niftyPlugin();
    });
});
</script>

In the code above, clicks on .selector1 element will throw an error because they're using jQuery 1.7.2 and niftyPlugin isn't installed on your copy of jQuery 1.7.2. Clicks on .selector2 will work, because the plugin is installed on the other copy of jQuery, 2.1.4. When the second copy was loaded, both $ and jQuery were updated to point to it; but the code inside the ready callback is using the argument ($) it receives, which is a reference to the jQuery object that is making that ready call (in the first case, v1.7.2; in the second case, v2.1.4).

The best answer to making this work is not to use multiple copies of jQuery.

The second-best answer is to always be aware of which version of jQuery a given bit of code is using as $ or jQuery.

Comments