taggit-selectize icon indicating copy to clipboard operation
taggit-selectize copied to clipboard

taggit-selectize in templates

Open c3959 opened this issue 6 years ago • 14 comments

hi

this library only works in admin? because when trying to use is a template it does not generate the field in the formual as shown in the image following the documentation.

c3959 avatar Mar 15 '18 15:03 c3959

works in the user's frontend. Didn't need to change anything!

andytwoods avatar Mar 19 '18 13:03 andytwoods

@andytwoods what version of django are you using and version of selectize? did you need to include any tags in html template ?

brianbola90 avatar Apr 06 '18 07:04 brianbola90

afraid I moved to taggit. Indeed, I am pondering whether to move from taggit to ArrayField!

andytwoods avatar Apr 06 '18 08:04 andytwoods

@c3959 see https://github.com/chhantyal/taggit-selectize/issues/17 for solution. Thanks to @andytwoods for the assistance.

brianbola90 avatar Apr 06 '18 10:04 brianbola90

I am using django 1.11.5 and taggit selectize 2.4.0. this message is from the browser console:

jQuery.Deferred exception: $(...).selectize is not a function TypeError: $(...).selectize is not a function at HTMLDocument.

I think it's because jquery is not loaded. this is without modifying anything as recommended above or importing anything in the template. jquery was also tried from the header of the document. jquery is loaded for other script and is available in the console.

c3959 avatar Apr 10 '18 21:04 c3959

I had this exact issue yesterday. I was using the widget in a django-filter, and a js and css file were not added to the page. I manually added these and it worked:

{% block javascript %}
  {{ block.super }}
  <script type="text/javascript" src="/static/taggit_selectize/js/selectize.js"></script>
{% endblock %}

{% block css %}
  {{ block.super }}
  <link href="/static/taggit_selectize/css/selectize.django.css" type="text/css" media="all" rel="stylesheet"/>
{% endblock %}

andytwoods avatar Apr 11 '18 05:04 andytwoods

thanks guys for your guide. has a solution as explained by @andytwoods. I did it by passing the form data to the context of the template.

{% block css %}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
{{ form_media }}

{% endblock css %}

but this patch solution I do not like at all. Now I have two jquery, one in the header and one in the end of the template. I think the problem goes through the input tag script:

Tags
        <script type="text/javascript">
            (function($) {
                $(document).ready(function() {
                    $("input[id=id_tags]").selectize({
                        valueField: 'name',
                        labelField: 'name',
                        searchField: 'name',
                        diacritics: true,
                        create: true,
                        persist: true,
                        openOnFocus: true,
                        hideSelected: true,
                        closeAfterSelect: true,
                        loadThrottle: 300,
                        preload: false,
                        addPrecedence: false,
                        selectOnTab: false,
                        delimiter: ',',
                        plugins: [],
                        render: {
                            option: function(item, escape) {
                                return '<div>' +
                                    '<span class="title">' +
                                        '<span class="name">' + escape(item.name) + '</span>' +
                                    '</span>' +
                                '</div>';
                            },
                            'item': function(item, escape) {
                                name = item.name.replace(/^\s*"|"\s*$/g, '');
                                return '<div class="item">' + escape(name) + '</div>';
                            }
                        },
                        load: function(query, callback) {
                            if (query.length < 2) return callback();
                            $.ajax({
                                url: '/taggit/?query=' + encodeURIComponent(query),
                                type: 'GET',
                                error: function() {
                                    callback();
                                },
                                success: function(res) {
                                    callback(res.tags.slice(0, 10));
                                }
                            });
                        }
                    }).parents('.form-row').css('overflow', 'visible');
                });
            })(jQuery || django.jQuery);
        </script>
    
                </div>

This script is executed when loading the page, so it asks that the libraries be loaded before in the header. would not it be better to load libraries and then load that script when using the input? or load it after jquery at the end of the document?

c3959 avatar Apr 11 '18 21:04 c3959

That script waits for the page to load? Via $(document).ready(function() ... Although it might be wise to use a pure JS way to detect when all the libraries are loaded, including jquery. E.g. document.addEventListener("DOMContentLoaded", function(event){ // your code here });

andytwoods avatar Jul 22 '18 11:07 andytwoods

OK, I tried swapping out $(document).ready(function() { with document.addEventListener("DOMContentLoaded", function(event){ (and loading jquery outside of the HEAD) but there's a whole lot of code within selectize.js that now complains about there being no Jquery. Seems best to load jquery in the HEAD and not to bother swapping those 'detect when everything is loaded' listeners.

andytwoods avatar Jul 23 '18 08:07 andytwoods

Could anyone use it outside the admin ? I have tried almost all the methods here and on #17 but couldn't do it.

uditvashisht avatar Aug 15 '18 15:08 uditvashisht

Yes, I have it working on a form (django 2.1, taggit, bootstrap 4):

  • Installed taggit-selectize with pip install git+https://github.com/chhantyal/taggit-selectize.git@4cca119f9f0839bdc6bbe9fd0e4fe927f6949a3a (this is only required with Django 2.1, otherwise the pip install taggit-selectize is enough) - Then I followed the instructions on the README.md of this repository
  • myproject/myproject/urls.py: path('taggit/', include('taggit_selectize.urls')) - (curl http://localhost:8000/taggit/?query=mytag must be working)
  • Replaced TaggableManager with the version from this package on my models.py
  • On forms.py (on my ModelForm) I added the widget:
from taggit_selectize import widgets as tag_widget

class PolicyForm(forms.ModelForm):

    class Meta:
        model = Policy

        fields = [
            'name', 'type', 'tags'
        ]

        widgets = {
            'tags': tag_widget.TagSelectize(attrs={'placeholder': 'Tags'}),
        }
  • Loaded jQuery on head, selectize.js and selectize.django.css on the button of the page.
  • Loaded selectize.js and selectize.django.css on the form page
  • My django generic class based view is working without any issue!

aventrax avatar Sep 05 '18 18:09 aventrax

@aventrax FYI, I released latest from master.

pip install taggit-selectize==2.6.0

chhantyal avatar Sep 06 '18 07:09 chhantyal

I had this problem and thanks to @andytwoods I solved it somehow (I looked through this chat - https://chat.stackoverflow.com/rooms/176541/discussion-between-andyw-and-sandor-des)

I'm using taggit-selectize in form This is what my head tag looks like.

<head>
...
  {% block css %}
  <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
  {% endblock %}
  {% block javscript %}
    <script src="{% static 'jquery.min.js' %}"></script>
    <script src="{% static 'umd/popper.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
  {% endblock %}
  {% block static %}{% endblock %}
...
</head>

and added this code at the bottom of the form page

{% block javascript %}   
  {{ block.super }}  
  <script type="text/javascript" src="/static/taggit_selectize/js/selectize.js"></script> 
{% endblock %}  
{% block css %}   
  {{ block.super }}   
  <link href="/static/taggit_selectize/css/selectize.django.css" type="text/css" media="all" rel="stylesheet"/> 
{% endblock %}

and it worked!

this is my model

from taggit_selectize.managers import TaggableManager

class Document(models.Model):
  ...
  tags = TaggableManager(verbose_name='태그', blank=True)

and this is my form

from taggit_selectize.widgets import TagSelectize

class DocumentForm(forms.ModelForm):

  class Meta:
    widgets = {
    ...
      'tags': TagSelectize(attrs={'placeholder': '태그'}),
    }

FYI Django 2.1 django-taggit 0.23.0 taggit-selectize 2.6.0 "jquery": "^3.3.1"

hope it helps

jmpark6846 avatar Sep 06 '18 13:09 jmpark6846

credits to @jmpark6846 for me I only had to add the below 2 lines and it worked!

adhg avatar Nov 02 '18 21:11 adhg