I just followed django-autocomplete-light tutorial, and it works very well in local mode.
Only problem is, it shows this kind of error in browser:
Uncaught ReferenceError: jQuery is not defined select2.min.js:1
Uncaught TypeError: Cannot read property 'fn' of undefined autocomplete.init.js:8
Uncaught ReferenceError: jQuery is not defined select2.full.js:17
Uncaught TypeError: $ is not a function select2.js:3
Uncaught SyntaxError: Unexpected identifier :1
This is my base.html
<!DOCTYPE html>
<html>
<head>
<!-- Meta -->
<meta charset="utf-8">
<meta name="keywords" content="HTML5,CSS3,Template" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, maximum-scale=1, initial-scale=1, user-scalable=0" />
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
{% block custom_stylesheet %}
{% endblock %}
</head>
<body>
<!-- HEADER -->
{% include "skeleton/header.html" %}
<!-- /HEADER -->
<!-- MAIN -->
<section>
{% block content %}
{% endblock %}
</section>
<!-- /MAIN -->
<!-- FOOTER -->
{% include "skeleton/footer.html" %}
<!-- /FOOTER -->
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous">
</script>
{% block custom_js %}
{% endblock %}
</body>
</html>
This is my code where autocomplete applied:
{% extends "skeleton/base.html" %}
{% load static %}
{% block content %}
{% crispy form %}
{% endblock %}
{% block custom_js %}
{{ form.media }}
{% endblock %}
What's wrong with it?
Select2 needs jQuery to be loaded.
@jpic As you can see in base.html, jQuery already loaded..... <script src="https://code.jquery.com/jquery-2.2.3.min.js">
Select2 needs jQuery to be loaded first: http://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#using-autocompletes-outside-the-admin
Please define "local mode" and "in browser".
Please also remove everything we don't need from your issue (extra blocks and other stuff tht's irrelevant to the js error and so on), this will also make it easier to spot to the bug.
@jpic I should have placed jQuery script before body ! Now it doesn't show any errors! But I learned that it would be better javascript or jQuery load "AFTER" body is loaded. It doesn't matter?
Move {{ form.media }} after jquery.
@jpic As you can see the original code in detail, {{ form.media }} is located after jQuery... by block custom_js. Even though it shows an error, it works quite well, though.
A quick hint on the issue: The JavaScripts are rendered is loaded even without specifying {{ form.media }}
@rightx2 to properly control the dependancies you can use block.super see http://stackoverflow.com/a/16691811 . But this does not matter in this case - it is a bug with how the dal loads the scripts. Try omitting {{ form.media }} and you will notice scripts are still loaded. I'm quite sure this comes from the plug when calling {% crispy form %}
@felixcheruiyot Thanks for your reply but it also doesn't work when I omitted {{ form.media }}...
I can confirm this problem. It seems like jquery.init.js does not properly initialize the yl variable's jQuery property. I added breakpoints in select2.js and autocomplete.init.js and yl.jQuery is undefined when Firefox executes both.
I tried to add $(document).ready() around the initialization code in select2.js and autocomplete.init.js and use the globally defined $ variable. This change made my select2 autocomplete fields work, but without using the yl object. The modified autocomplete.init.js looks like this:
$(document).ready(function() {
$.fn.getFormPrefix = function() {
...
document.csrftoken = getCookie('csrftoken');
});
Maybe jQuery is not fully loaded/initialized when jquery.init.js tries to assign it to yl.jQuery due to some parallelity issue. I'm not sure what the purpose of the yl object is, so I'll not create a pull request before getting feedback from someone with more insight.
@rightx2 if you use crispy forms you can suppress rendering of form media in the <form> tag by setting the form helper's include_media to False:
def __init__(self, *args, **kwargs):
super(YourFormClass, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.include_media = False
IIRC all that was just to support both django admin and user-loaded jquery.
django i18n js catalog routines may conflict with autocomplete jquery init script.
We are getting this in the admin with django 1.11, select2 is available in the jQuery object but not in yl.jQuery or the django.jQuery. ~The issue here looks like the wrong jquery.init.js is loaded we are getting the ./autocomplete_light/jquery.init.js instead of ./admin/js/jquery.init.js.~
BTW i can't see how select2 can work on the django own jquery since it requires $ or jQuery which are undefined, any hint?
@xrmx this is supposed to make it wokrks, when it overrides the admin's version: https://github.com/yourlabs/django-autocomplete-light/blob/master/src/dal/static/admin/js/jquery.init.js
It's basically the same issue django has here: https://github.com/django/django/pull/6385#issuecomment-306031642
Did you try with master too ? We've had that recently: https://github.com/yourlabs/django-autocomplete-light/commit/a44a2edd4fae8fca3c309f404cbefebd94bf2859
I wish I had time to search a better solution for this !
The default date widget in the admin - AdminDateWidget - tries to load jQuery and breaks the order jQuery is loaded by dal. So I'm using SelectDateWidget instead which lacks pretty JS. In Django 2.0 I also get this warning:
MediaOrderConflictWarning: Detected duplicate Media files in an opposite order:
autocomplete_light/jquery.init.js
admin/js/admin/DateTimeShortcuts.js
which seems to be caused by Media.merge trying to merge two asset lists, one which has autocomplete_light's assets before admin's, and the other has admin's before autocomplete_light's.
I can confirm @daradib's finding: "The default date widget in the admin - AdminDateWidget - tries to load jQuery and breaks the order jQuery is loaded by dal. So I'm using SelectDateWidget instead which lacks pretty JS."
I had a similar issue to all this, with sortedm2m in Django 1.11 breaking because jQuery was not defined. Sorting back through my app I found a workaround which was to change dal/static/admin/js/jquery.init.js to
var django = django || {};
django.jQuery = jQuery || django.jQuery
var yl = yl || {};
yl.jQuery = django.jQuery
// this file also prevents django.jQuery.noConflict
// there's got to be a better way ...
the change being the linedjango.jQuery = jQuery changed to django.jQuery = jQuery || django.jQuery as it appears otherwise django.jQuery was undefined if jQuery was not already set, whereas django.jQuery was already defined. This was with DAL being loaded as the second app (after django.contrib.contenttypes)
This is a bit of a kludge, but it may help some others out. Really before django.jQuery is assigned here it should be tested where jQuery exists and set appropriately. I don't know Django internals for JS loading well enough to work that out just now, so my kludge stands
Hope it helps someone else out.
Now you can just use autocomplete_fields since django 2.0.
Try to add js media
'//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js',
'autocomplete_light/jquery.init.js',
'vendor/select2/dist/js/select2.full.js',
'vendor/select2/dist/js/i18n/en.js',
'autocomplete_light/autocomplete.init.js',
'autocomplete_light/forward.js',
'autocomplete_light/select2.js',
'autocomplete_light/jquery.post-setup.js',
Most helpful comment
The default date widget in the admin -
AdminDateWidget- tries to load jQuery and breaks the order jQuery is loaded by dal. So I'm using SelectDateWidget instead which lacks pretty JS. In Django 2.0 I also get this warning:which seems to be caused by
Media.mergetrying to merge two asset lists, one which has autocomplete_light's assets before admin's, and the other has admin's before autocomplete_light's.