Skip to content

Commit

Permalink
Merge branch 'release/1.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
crucialfelix committed Sep 5, 2016
2 parents b93f459 + 81b6cab commit 2625814
Show file tree
Hide file tree
Showing 27 changed files with 529 additions and 173 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ htmlcov
.coverage
docs/_build
example/ajax_select
example/ajax_selects_example
example/ajax_selects_example_db
dist
MANIFEST
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ sudo: false
env:
- TOX_ENV=py27-flake8
- TOX_ENV=py34-flake8
- TOX_ENV=py27-dj15
- TOX_ENV=py27-dj16
- TOX_ENV=py33-dj15
- TOX_ENV=py33-dj16
- TOX_ENV=py27-dj17
- TOX_ENV=py27-dj18
- TOX_ENV=py27-dj19
- TOX_ENV=py27-dj110
- TOX_ENV=py34-dj17
- TOX_ENV=py34-dj18
- TOX_ENV=py34-dj19
- TOX_ENV=py34-dj110
# - TOX_ENV=py35-dj18
# - TOX_ENV=py35-dj19
install:
Expand Down
19 changes: 18 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Change Log

## [1.5.0](https://github.com/crucialfelix/django-ajax-selects/tree/1.5.0) (2016-09-05)
[Full Changelog](https://github.com/crucialfelix/django-ajax-selects/compare/1.4.3...1.5.0)

- Added Support for Django 1.10
- Dropped Django 1.5

**Closed issues:**

- ValueError in Django 1.10 [\#177](https://github.com/crucialfelix/django-ajax-selects/issues/177)
- Django 1.10 did add popup [\#174](https://github.com/crucialfelix/django-ajax-selects/issues/174)
- Example not Working [\#161](https://github.com/crucialfelix/django-ajax-selects/issues/161)

**Merged pull requests:**

- Fix documentation to format code properly [\#165](https://github.com/crucialfelix/django-ajax-selects/pull/165) ([joshblum](https://github.com/joshblum))
- install.sh not working [\#162](https://github.com/crucialfelix/django-ajax-selects/pull/162) ([hdzierz](https://github.com/hdzierz))

## [1.4.3](https://github.com/crucialfelix/django-ajax-selects/tree/1.4.3) (2016-03-13)
[Full Changelog](https://github.com/crucialfelix/django-ajax-selects/compare/1.4.2...1.4.3)

Expand Down Expand Up @@ -214,4 +231,4 @@
## [1.1.0](https://github.com/crucialfelix/django-ajax-selects/tree/1.1.0) (2010-03-06)


\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Assets included by default
Compatibility
-------------

- Django >=1.5, <=1.9
- Django >=1.6, <=1.10
- Python >=2.7, 3.3-3.5


Expand Down
1 change: 0 additions & 1 deletion ajax_select/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from ajax_select.helpers import make_ajax_form, make_ajax_field # noqa
from ajax_select.lookup_channel import LookupChannel # noqa


try:
# django 1.7+ will use the new AppConfig api
# It will load all your lookups.py modules
Expand Down
57 changes: 32 additions & 25 deletions ajax_select/fields.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from __future__ import unicode_literals
import json
from ajax_select.registry import registry
from django import forms
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from django.db.models.query import QuerySet
try:
from django.forms.utils import flatatt
except ImportError:
Expand All @@ -15,7 +17,6 @@
from django.utils.safestring import mark_safe
from django.utils.six import text_type
from django.utils.translation import ugettext as _
import json


as_default_help = 'Enter text to search.'
Expand Down Expand Up @@ -49,10 +50,10 @@ def __init__(self,
channel,
help_text='',
show_help_text=True,
plugin_options={},
plugin_options=None,
*args,
**kwargs):
self.plugin_options = plugin_options
self.plugin_options = plugin_options or {}
super(forms.widgets.TextInput, self).__init__(*args, **kwargs)
self.channel = channel
self.help_text = help_text
Expand Down Expand Up @@ -90,9 +91,10 @@ def render(self, name, value, attrs=None):
'func_slug': self.html_id.replace("-", ""),
'add_link': self.add_link,
}
context.update(plugin_options(lookup, self.channel, self.plugin_options, initial))
templates = ('ajax_select/autocompleteselect_%s.html' % self.channel,
'ajax_select/autocompleteselect.html')
context.update(make_plugin_options(lookup, self.channel, self.plugin_options, initial))
templates = (
'ajax_select/autocompleteselect_%s.html' % self.channel,
'ajax_select/autocompleteselect.html')
out = render_to_string(templates, context)
return mark_safe(out)

Expand Down Expand Up @@ -162,15 +164,15 @@ def __init__(self,
channel,
help_text='',
show_help_text=True,
plugin_options={},
plugin_options=None,
*args,
**kwargs):
super(AutoCompleteSelectMultipleWidget, self).__init__(*args, **kwargs)
self.channel = channel

self.help_text = help_text
self.show_help_text = show_help_text
self.plugin_options = plugin_options
self.plugin_options = plugin_options or {}

def render(self, name, value, attrs=None):

Expand All @@ -182,20 +184,18 @@ def render(self, name, value, attrs=None):

lookup = registry.get(self.channel)

# eg. value = [3002L, 1194L]
if value:
# |pk|pk| of current
current_ids = "|" + "|".join(str(pk) for pk in value) + "|"
if isinstance(value, QuerySet):
objects = value
else:
current_ids = "|"
objects = lookup.get_objects(value)

objects = lookup.get_objects(value)
current_ids = pack_ids([obj.pk for obj in objects])

# text repr of currently selected items
initial = []
for obj in objects:
display = lookup.format_item_display(obj)
initial.append([display, obj.pk])
initial = [
[lookup.format_item_display(obj), obj.pk]
for obj in objects
]

if self.show_help_text:
help_text = self.help_text
Expand All @@ -213,7 +213,7 @@ def render(self, name, value, attrs=None):
'func_slug': self.html_id.replace("-", ""),
'add_link': self.add_link,
}
context.update(plugin_options(lookup, self.channel, self.plugin_options, initial))
context.update(make_plugin_options(lookup, self.channel, self.plugin_options, initial))
templates = ('ajax_select/autocompleteselectmultiple_%s.html' % self.channel,
'ajax_select/autocompleteselectmultiple.html')
out = render_to_string(templates, context)
Expand Down Expand Up @@ -344,7 +344,7 @@ def render(self, name, value, attrs=None):
'extra_attrs': mark_safe(flatatt(final_attrs)),
'func_slug': self.html_id.replace("-", ""),
}
context.update(plugin_options(lookup, self.channel, self.plugin_options, initial))
context.update(make_plugin_options(lookup, self.channel, self.plugin_options, initial))
templates = ('ajax_select/autocomplete_%s.html' % self.channel,
'ajax_select/autocomplete.html')
return mark_safe(render_to_string(templates, context))
Expand Down Expand Up @@ -394,10 +394,9 @@ def _check_can_add(self, user, related_model):
ctype = ContentType.objects.get_for_model(related_model)
can_add = user.has_perm("%s.add_%s" % (ctype.app_label, ctype.model))
if can_add:
self.widget.add_link = reverse('add_popup', kwargs={
'app_label': related_model._meta.app_label,
'model': related_model._meta.object_name.lower()
})
app_label = related_model._meta.app_label
model = related_model._meta.object_name.lower()
self.widget.add_link = reverse('admin:%s_%s_add' % (app_label, model)) + '?_popup=1'


def autoselect_fields_check_can_add(form, model, user):
Expand All @@ -411,7 +410,7 @@ def autoselect_fields_check_can_add(form, model, user):
form_field.check_can_add(user, db_field.rel.to)


def plugin_options(lookup, channel_name, widget_plugin_options, initial):
def make_plugin_options(lookup, channel_name, widget_plugin_options, initial):
""" Make a JSON dumped dict of all options for the jQuery ui plugin."""
po = {}
if initial:
Expand All @@ -429,3 +428,11 @@ def plugin_options(lookup, channel_name, widget_plugin_options, initial):
'plugin_options': mark_safe(json.dumps(po)),
'data_plugin_options': force_escape(json.dumps(po))
}


def pack_ids(ids):
if ids:
# |pk|pk| of current
return "|" + "|".join(str(pk) for pk in ids) + "|"
else:
return "|"
4 changes: 4 additions & 0 deletions ajax_select/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class LookupChannelRegistry(object):
_registry = {}

def load_channels(self):
"""
Called when loading the application. Cannot be called a second time,
(eg. for testing) as Django will not re-import and re-register anything.
"""
self._registry = {}
try:
from django.utils.module_loading import autodiscover_modules
Expand Down
61 changes: 35 additions & 26 deletions ajax_select/static/ajax_select/js/ajax_select.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

(function($) {
'use strict';

$.fn.autocompleteselect = function(options) {
return this.each(function() {
Expand Down Expand Up @@ -134,26 +134,20 @@

function addAutoComplete (inp, callback) {
var $inp = $(inp),
html_id = inp.id,
prefix_id = html_id,
opts = JSON.parse($inp.attr('data-plugin-options')),
prefix = 0;

/* detects inline forms and converts the html_id if needed */
if (html_id.indexOf('__prefix__') !== -1) {
// Some dirty loop to find the appropriate element to apply the callback to
while ($('#' + html_id).length) {
html_id = prefix_id.replace(/__prefix__/, prefix++);
}
html_id = prefix_id.replace(/__prefix__/, prefix - 2);
// Ignore the first call to this function, the one that is triggered when
// page is loaded just because the 'empty' form is there.
if ($('#' + html_id + ', #' + html_id + '_text').hasClass('ui-autocomplete-input')) {
return;
}
opts = JSON.parse($inp.attr('data-plugin-options'));
// Do not activate empty-form inline rows.
// These are cloned into the form when adding another row and will be activated at that time.
if ($inp.attr('id').indexOf('__prefix__') !== -1) {
// console.log('skipping __prefix__ row', $inp);
return;
}

if ($inp.data('_ajax_select_inited_')) {
// console.log('skipping already activated row', $inp);
return;
}
// console.log('activating', $inp);
callback($inp, opts);
$inp.data('_ajax_select_inited_', true);
}

// allow html in the results menu
Expand Down Expand Up @@ -187,14 +181,28 @@
}
});

/* the popup handler
requires RelatedObjects.js which is part of the django admin js
so if using outside of the admin then you would need to include that manually */
window.didAddPopup = function (win, newId, newRepr) {
/* Called by the popup create object when it closes.
* For the popup this is opener.dismissAddRelatedObjectPopup
* Django implements this in RelatedObjectLookups.js
*/
var djangoDismissAddRelatedObjectPopup = window.dismissAddRelatedObjectPopup || window.dismissAddAnotherPopup;
window.dismissAddRelatedObjectPopup = function(win, newId, newRepr) {
// This may be called for ajax-select inputs or for other inputs.
// Call the original which sets the input (just the pk)
// calls input.trigger('changed') if >= 1.10
// and closes the window.
if (djangoDismissAddRelatedObjectPopup) {
djangoDismissAddRelatedObjectPopup(win, newId, newRepr);
} else {
win.close();
}
var name = window.windowname_to_id(win.name);
$('#' + name).trigger('didAddPopup', [window.html_unescape(newId), window.html_unescape(newRepr)]);
win.close();
};
// newRepr is django's repr of object
// not the Lookup's formatting of it.
$('#' + name).trigger('didAddPopup', [newId, newRepr]);
}
// Django renamed this function in 1.8
window.dismissAddAnotherPopup = window.dismissAddRelatedObjectPopup;

// activate any on page
$(window).bind('init-autocomplete', function() {
Expand Down Expand Up @@ -228,6 +236,7 @@
// if dynamically injecting forms onto a page
// you can trigger them to be ajax-selects-ified:
$(window).trigger('init-autocomplete');
// When adding new rows in inline forms, reinitialize and activate newly added rows.
$(document)
.on('click', '.inline-group ul.tools a.add, .inline-group div.add-row a, .inline-group .tabular tr.add-row td a', function() {
$(window).trigger('init-autocomplete');
Expand Down
5 changes: 1 addition & 4 deletions ajax_select/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,5 @@
urlpatterns = [
url(r'^ajax_lookup/(?P<channel>[-\w]+)$',
views.ajax_lookup,
name='ajax_lookup'),
url(r'^add_popup/(?P<app_label>\w+)/(?P<model>\w+)$',
views.add_popup,
name='add_popup')
name='ajax_lookup')
]
Loading

0 comments on commit 2625814

Please sign in to comment.