diff --git a/README.md b/README.md index 7c1cddf..4315307 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ A simple django widget that appends a character count to a text input which is d ## Installation The package can be installed via: - + pip install git+https://github.com/timmyomahony/django-charsleft-widget.git - + ## Usage @@ -20,9 +20,7 @@ class Song(models.Model): title = models.CharField(max_length=100) ``` -then create a custom model form that uses the custom widget class. **Note that it's important -to include the `maxlength` attribute manually when making use of the widget, as it will not -be pulled in automatically from your model field.** +then create a custom model form that uses the custom widget class. ```python from django import forms @@ -31,7 +29,7 @@ from charsleft_widget.widgets import CharsLeftInput from .models import Song class SongForm(forms.ModelForm): - name = forms.CharField(widget=CharsLeftInput(attrs={'maxlength': 100})) + name = forms.CharField(widget=CharsLeftInput()) class Meta: model = Song @@ -51,4 +49,11 @@ from .forms import SongForm @admin.register(Song) class SongAdmin(admin.ModelAdmin): form = SongForm -``` \ No newline at end of file +``` + + +You can optionally toggle off the color changing feature by initialising the widget (from the example above) with: + +```python + name = forms.CharField(widget=CharsLeftInput(attrs={'change_color': False})) +``` diff --git a/charsleft_widget/__init__.py b/charsleft_widget/__init__.py index fa8c8af..da4c8f8 100644 --- a/charsleft_widget/__init__.py +++ b/charsleft_widget/__init__.py @@ -1 +1 @@ -VERSION = ("0","1","0") \ No newline at end of file +VERSION = ("0","1","1") \ No newline at end of file diff --git a/charsleft_widget/static/charsleft-widget/js/charsleft.js b/charsleft_widget/static/charsleft-widget/js/charsleft.js index d1dadb1..d1685ab 100644 --- a/charsleft_widget/static/charsleft-widget/js/charsleft.js +++ b/charsleft_widget/static/charsleft-widget/js/charsleft.js @@ -1,34 +1,38 @@ -(function($){ +(function($){ $.fn.charsLeft = function(options){ - var defaults = { + var defaults = { 'source':'input', 'dest':'.count', } var options = $.extend(defaults, options); - - var calculate = function(source, dest, maxlength){ + + var calculate = function(source, dest, maxlength, changeColor){ var remaining = maxlength - source.val().length; dest.html(remaining); - /* Over 50%, change colour to orange */ - p = (100 * remaining) / maxlength; - if(p < 25){ - dest.addClass('orange'); - }else if(p < 50){ - dest.addClass('red'); - }else{ - dest.removeClass('orange red'); + + if (changeColor) { + /* Over 50%, change colour to orange */ + p = (100 * remaining) / maxlength; + if(p < 25){ + dest.addClass('orange'); + }else if(p < 50){ + dest.addClass('red'); + }else{ + dest.removeClass('orange red'); + } } }; - + this.each(function(i, el) { var maxlength = $(this).find('.maxlength').html(); var dest = $(this).find(options.dest); var source = $(this).find(options.source); + var changeColor = source.attr('change_color') !== undefined; source.keyup(function(){ - calculate(source, dest, maxlength) + calculate(source, dest, maxlength, changeColor) }); source.change(function(){ - calculate(source, dest, maxlength) + calculate(source, dest, maxlength, changeColor) }); }); }; @@ -38,5 +42,4 @@ 'dest':".count", }); }); -})(django.jQuery); - +})((typeof django !== 'undefined' && django.jQuery) || window.jQuery || jQuery); diff --git a/charsleft_widget/templates/charsleft_widget/input.html b/charsleft_widget/templates/charsleft_widget/input.html new file mode 100644 index 0000000..a9f90a4 --- /dev/null +++ b/charsleft_widget/templates/charsleft_widget/input.html @@ -0,0 +1,8 @@ +{% load i18n %} + + + + {{ current_count }}{% trans 'characters remaining' %} + {{ widget.attrs.maxlength }} + + \ No newline at end of file diff --git a/charsleft_widget/widgets.py b/charsleft_widget/widgets.py index a02ab44..80a420e 100644 --- a/charsleft_widget/widgets.py +++ b/charsleft_widget/widgets.py @@ -18,7 +18,9 @@ from charsleft_widget.utils import compatible_staticpath -class CharsLeftInput(forms.TextInput): +class CharsLeftInput(forms.TextInput): + template_name = 'charsleft_widget/input.html' + type = 'text' class Media: css={ @@ -26,42 +28,19 @@ class Media: } js=(compatible_staticpath("charsleft-widget/js/charsleft.js"), ) - def render(self, name, value, attrs=None, **kwargs): - if value is None: - value = '' - - extra_attrs = { - 'type': self.input_type, - 'name': name, - 'maxlength': self.attrs.get('maxlength') - } - - # Signature for build_attrs changed in 1.11 - # https://code.djangoproject.com/ticket/28095 - if VERSION < (1, 11): - final_attrs = self.build_attrs(attrs, **extra_attrs) - else: - final_attrs = self.build_attrs(attrs, extra_attrs=extra_attrs) - - if value != '': - final_attrs['value'] = force_str(self._format_value(value)) - - maxlength = final_attrs.get('maxlength', False) - if not maxlength: - return mark_safe(u'' % flatatt(final_attrs)) - - current = force_str(int(maxlength) - len(value)) - html = u""" - - - - %(current)s %(char_remain_str)s - %(maxlength)s - - """ % { - 'attrs': flatatt(final_attrs), - 'current': current, - 'char_remain_str': _(u'characters remaining'), - 'maxlength': int(maxlength), - } - return mark_safe(html) + def __init__(self, attrs=None): + """ + Override init to initialise change_color attribute + """ + if attrs is None: + attrs = {} + # If change_color present in widget attrs use the value, otherwise it's True by default + attrs.setdefault('change_color', True) + super().__init__(attrs) + + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + context['widget']['type'] = self.input_type + maxlength = int(context['widget']['attrs'].get('maxlength', attrs.get('maxlength', 0))) + context['current_count'] = force_str(maxlength - len(value)) if value else '0' + return context