I am having trouble because of django's app, that is smart select, it tries to load jquery by itself. I am already loading jquery by myself in head and after that I am loading JQuery UI related stuff. But as smartselect come in body it also load jquery again that cause problem for UI related stuff. I don't understand how can I stop smartselect jquery if it is already loaded.
Following is the code for widgets.py file of smart select app.
import django
from django.conf import settings
from django.forms.widgets import Select
from django.contrib.admin.templatetags.admin_static import static
from django.core.urlresolvers import reverse
from django.utils.encoding import iri_to_uri
from django.utils.safestring import mark_safe
from django.db.models import get_model
import locale
from smart_selects.utils import unicode_sorter
if django.VERSION >= (1, 2, 0) and getattr(settings,
'USE_DJANGO_JQUERY', True):
USE_DJANGO_JQUERY = True
else:
USE_DJANGO_JQUERY = False
JQUERY_URL = getattr(settings, 'JQUERY_URL', 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js')
class ChainedSelect(Select):
def __init__(self, app_name, model_name, chain_field, model_field, show_all, auto_choose, manager=None, *args, **kwargs):
self.app_name = app_name
self.model_name = model_name
self.chain_field = chain_field
self.model_field = model_field
self.show_all = show_all
self.auto_choose = auto_choose
self.manager = manager
super(Select, self).__init__(*args, **kwargs)
class Media:
if USE_DJANGO_JQUERY:
js = [static('admin/%s' % i) for i in
('js/jquery.min.js', 'js/jquery.init.js')]
elif JQUERY_URL:
js = (
JQUERY_URL,
)
def render(self, name, value, attrs=None, choices=()):
if len(name.split('-')) > 1: # formset
chain_field = '-'.join(name.split('-')[:-1] + [self.chain_field])
else:
chain_field = self.chain_field
if self.show_all:
view_name = "chained_filter_all"
else:
view_name = "chained_filter"
kwargs = {'app':self.app_name, 'model':self.model_name, 'field':self.model_field, 'value':"1"}
if self.manager is not None:
kwargs.update({'manager': self.manager})
url = "/".join(reverse(view_name, kwargs=kwargs).split("/")[:-2])
if self.auto_choose:
auto_choose = 'true'
else:
auto_choose = 'false'
empty_label = iter(self.choices).next()[1] # Hacky way to getting the correct empty_label from the field instead of a hardcoded '--------'
js = """
<script type="text/javascript">
//<![CDATA[
(function($) {
function fireEvent(element,event){
if (document.createEventObject){
// dispatch for IE
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt)
}
else{
// dispatch for firefox + others
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true ); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
}
}
function dismissRelatedLookupPopup(win, chosenId) {
var name = windowname_to_id(win.name);
var elem = document.getElementById(name);
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
elem.value += ',' + chosenId;
} else {
elem.value = chosenId;
}
fireEvent(elem, 'change');
win.close();
}
$(document).ready(function(){
function fill_field(val, init_value){
if (!val || val==''){
options = '<option value="">%(empty_label)s<'+'/option>';
$("#%(id)s").html(options);
$('#%(id)s option:first').attr('selected', 'selected');
$("#%(id)s").trigger('change');
return;
}
$.getJSON("%(url)s/"+val+"/", function(j){
var options = '<option value="">%(empty_label)s<'+'/option>';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].value + '">' + j[i].display + '<'+'/option>';
}
var width = $("#%(id)s").outerWidth();
$("#%(id)s").html(options);
if (navigator.appVersion.indexOf("MSIE") != -1)
$("#%(id)s").width(width + 'px');
$('#%(id)s option:first').attr('selected', 'selected');
var auto_choose = %(auto_choose)s;
if(init_value){
$('#%(id)s option[value="'+ init_value +'"]').attr('selected', 'selected');
}
if(auto_choose && j.length == 1){
$('#%(id)s option[value="'+ j[0].value +'"]').attr('selected', 'selected');
}
$("#%(id)s").trigger('change');
})
}
if(!$("#id_%(chainfield)s").hasClass("chained")){
var val = $("#id_%(chainfield)s").val();
fill_field(val, "%(value)s");
}
$("#id_%(chainfield)s").change(function(){
var start_value = $("#%(id)s").val();
var val = $(this).val();
fill_field(val, start_value);
})
})
dismissAddAnotherPopup = function(win, newId, newRepr) {
oldDismissAddAnotherPopup(win, newId, newRepr);
if (windowname_to_id(win.name) == "id_%(chainfield)s") {
$("#id_%(chainfield)s").change();
}
}
var oldDismissAddAnotherPopup = dismissAddAnotherPopup;
})(jQuery || django.jQuery);
//]]>
</script>
""" % {"chainfield":chain_field, "url":url, "id":attrs['id'], 'value':value, 'auto_choose':auto_choose, 'empty_label': empty_label}
final_choices = []
if value:
item = self.queryset.filter(pk=value)[0]
try:
pk = getattr(item, self.model_field + "_id")
filter = {self.model_field:pk}
except AttributeError:
try: # maybe m2m?
pks = getattr(item, self.model_field).all().values_list('pk', flat=True)
filter = {self.model_field + "__in":pks}
except AttributeError:
try: # maybe a set?
pks = getattr(item, self.model_field + "_set").all().values_list('pk', flat=True)
filter = {self.model_field + "__in":pks}
except: # give up
filter = {}
filtered = list(get_model(self.app_name, self.model_name).objects.filter(**filter).distinct())
filtered.sort(cmp=locale.strcoll, key=lambda x:unicode_sorter(unicode(x)))
for choice in filtered:
final_choices.append((choice.pk, unicode(choice)))
if len(final_choices) > 1:
final_choices = [("", (empty_label))] + final_choices
if self.show_all:
final_choices.append(("", (empty_label)))
self.choices = list(self.choices)
self.choices.sort(cmp=locale.strcoll, key=lambda x:unicode_sorter(x[1]))
for ch in self.choices:
if not ch in final_choices:
final_choices.append(ch)
self.choices = ()
final_attrs = self.build_attrs(attrs, name=name)
if 'class' in final_attrs:
final_attrs['class'] += ' chained'
else:
final_attrs['class'] = 'chained'
output = super(ChainedSelect, self).render(name, value, final_attrs, choices=final_choices)
output += js
return mark_safe(output)
D
I know how to check if jquery is already loaded in JS. But how to deal with it Django, don't know. Also sometime I think that stuff still works but sometime not. Don't understanding why it is happening. Above is what I have concluded after undefined $('.datepicker').datepicker()
and by inspecting from firebug. Also some time this code doesn't cause problem. I don't understand why.
Please tell if you guys have any idea. and please ask if I am not clear enough.
thanks
Updated
Here is how I loaded jquery and jquery ui :
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Kaasib.com</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="{{STATIC_URL}}css/style.css" />
<link rel="stylesheet" href="{{STATIC_URL}}css/ui-lightness/jquery-ui-1.8.23.custom.css" />
<script src="{{STATIC_URL}}js/libs/jquery-1.7.1.min.js"></script>
<script src="{{STATIC_URL}}js/libs/jquery-ui-1.8.23.custom.min.js "></script>
<script src="{{STATIC_URL}}js/main.js"></script>
</head>