jazzband / django-smart-selects

chained and grouped selects for django forms
https://django-smart-selects.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.12k stars 352 forks source link

django-smart-select not populating secondary dropdown #258

Closed smitty1788 closed 6 years ago

smitty1788 commented 6 years ago

Checklist

Put an x in the bracket when you have completed each task, like this: [x]

Steps to reproduce

models.py

class State(models.Model):

    id = models.AutoField(

    state_name = models.CharField(
        _('State Name'),
        max_length = 46,
        blank = True,
        null = True,
    )

    def __str__(self):
        return u'%s' % (self.state_name)

class CBSA(models.Model):

    id = models.AutoField(
        primary_key = True
    )

    cbsa_title = models.CharField(
        _('CBSA Title'),
        max_length = 46,
        blank = True,
        null = True,
    )

    def __str__(self):
        return u'%s' % (self.cbsa_name)

# CBSA/State Connection Table. CBSA's can span several states    
class CBSAState(models.Model):

    id = models.AutoField(
        primary_key = True
    )

    state = models.ForeignKey(
        State,
        verbose_name=_('State'),
        on_delete=models.CASCADE,
        null = True,
        blank = True,
    )

    cbsa = models.ForeignKey(
        CBSA,
        verbose_name=_('CBSA'),
        on_delete=models.CASCADE,
        null = True,
        blank = True,
    )

    def __str__(self):
        return u'%s' % (self.cbsa)

class econ_writeups(models.Model):

    id = models.AutoField(
        primary_key = True
    )

    project_name = models.CharField(
        _('Project Name'),
        max_length = 255,
        blank = True,
        null = True,
        help_text = _('Full name of the project'),
    )

    state = models.ForeignKey(
        State,
        verbose_name=_('State'),
        on_delete=models.CASCADE,
        null = True,
        blank = True,
    )

    msa = ChainedForeignKey(
        CBSAState,
        chained_field="state",
        chained_model_field="state",
        show_all=True,
        auto_choose=False,
        sort=True,
        verbose_name=_('MSA'),
    )

    body_text = models.TextField(
        _('Body of Text'),
        blank=True,
        null=True,
        max_length = 4000,
    )

    date_submitted = models.DateTimeField(
        editable = False, 
        auto_now_add = True
    )

    def __str__(self):
        return u'%s' % (self.project_name) 

forms.py

class econ_writeupsForm(forms.ModelForm):

    class Meta:
        model = econ_writeups
        exclude = ('date_submitted',)

    project_name = forms.CharField(
        max_length=255,
        required=True,
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        label=_('Project Name'),
        help_text=_('Full name of the project'),
    )

    body_text = forms.CharField(
        widget=forms.Textarea(attrs={'class': 'form-control'}),
        required=True,
        label=_('Body of Text'),
    )

views.py

def econ_writeups_add(request):
    if request.method=="POST":
        form = econ_writeupsForm(request.POST)

        if form.is_valid():

            msa = CBSAState.objects.get(id=int(request.POST.get('msa')))
            state = State.objects.get(id=int(request.POST.get('state')))

            econ_writeups = form.save(commit=False)
            econ_writeups.project_name = request.POST.get('project_name')
            econ_writeups.state = state
            econ_writeups.msa = msa
            econ_writeups.body_text = request.POST.get('body_text')

            econ_writeups.save()
            return HttpResponseRedirect(reverse('econ_novo'))
    else:
        form = econ_writeupsForm
    return render(request,'econ_writeups.html',{'form':form})

base.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

{% block header %}
{% load static %}
<html lang="en">

<head>

     <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    <script src='{% static "smart-selects/admin/js/chainedfk.js" %}'></script>

    <meta name="google" value="notranslate">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <!-- <link rel="icon" href=""> -->
    <link rel="shortcut icon" href="{% static "dl/favicon.ico" %}" type="image/x-icon">
    <title>Novocore</title>
    <!-- Bootstrap core CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
    <link href="{% static "css/sticky-footer-navbar.css" %}" rel="stylesheet">

    {% block scripts %}{% endblock %}

    <!-- Custom styles for this site -->
    <style type="text/css">
        body {
            padding-top: 5rem;
        }

        .starter-template {
            padding: 3rem 1.5rem;
            text-align: center;
        }

        .wrapper {
            width: 100%;
            height: 600px;
            margin: 0 auto;
            background: #CCC
        }

        .h_iframe {
            position: relative;
        }

        .h_iframe .ratio {
            width: 50%;
            height: 600px;
        }

        .h_iframe iframe {
            width: 100%;
            height: 600px;
        }

        .footer {
            position: fixed;
            bottom: 0;
            width: 100%;
            /* Set the fixed height of the footer here */
            height: 60px;
            line-height: 60px;
            /* Vertically center the text there */
            background-color: #f5f5f5;
        }
    </style>

</head>

<body>
    <nav class="navbar navbar-expand-md navbar-dark fixed-top" style="background-color: #162f7f;"> <a class="navbar-brand" href="" style="color:#dc9f36;font-weight:bold">NOVOCORE</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button>
        <div class="collapse navbar-collapse" id="navbarsExampleDefault">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item active"> <a class="nav-link" href='{% url '' %}'>Home <span class="sr-only">(current)</span></a> </li>
                <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">GIS</a>
                    <div class="dropdown-menu" aria-labelledby="dropdown01">
                        <a class="dropdown-item" href='{% url 'leaflet' %}'>PMA Creator</a>
                        <a class="dropdown-item" href="GIS/">Demo Request</a>
                        <a class="dropdown-item" href='{% url 'ticket_search' %}'>Demographic Search</a>
                        <a class="dropdown-item" href='{% url 'ticket_stats' %}'>Demo Request Trends</a>
                    </div>
                </li>
                <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Training and Guides</a>
                    <div class="dropdown-menu" aria-labelledby="dropdown01">
                        <a class="dropdown-item" href='{% url 'howto' %}'>How-To Guides</a>
                        <a class="dropdown-item" href="{% url 'writeups' %}">Inserts</a>
                        <a class="dropdown-item" href="">Videos - Under Construction</a>
                        <a class="dropdown-item" href='BT/'>Super Workbook Bug Tracker</a>
                    </div>
                </li>
                <li class="nav-item"> <a class="nav-link" href="{% url 'worktemplate' %}">Templates</a> </li>
                <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">OPEX</a>
                    <div class="dropdown-menu" aria-labelledby="dropdown01">
                        <a class="dropdown-item" href="{% url 'opex' %}">OPEX Overview</a>
                        <a class="dropdown-item" href="{% url 'opex_national' %}">National</a>
                        <a class="dropdown-item" href="{% url 'opex_unit_size' %}">By Unit Size</a>
                        <a class="dropdown-item" href="{% url 'opex_unit_type' %}">By Unit Type</a>
                        <a class="dropdown-item" href="{% url 'opex_age' %}">By Age</a>
                        <a class="dropdown-item" href="{% url 'opex_region' %}">By Region</a>
                        <a class="dropdown-item" href="{% url 'opex_category_definitions' %}">Category Definitions</a>
                    </div>
                </li>
<!--                <li class="nav-item"> <a class="nav-link" href="http://goval.novoco.com/" target="_blank">LIHTC Allocations</a> </li>-->
                <li class="nav-item"> <a class="nav-link" href="http://valuation.novoco.com/valuation/home.m" target="_blank">Rent Valuation Toolkit</a> </li>
                <li class="nav-item"> <a class="nav-link" href="https://ric.novoco.com/tenant/rentincome/calculator/z1.jsp" target="_blank">Rent and Income Calculator</a> </li>
                <li class="nav-item"> <a class="nav-link" href="http://valuation.novoco.com/jobtrack/login.jsp" target="_blank">JobTrack</a> </li>
            </ul>
        </div>
        <ul class="navbar-nav ml-auto">
            <li class="nav-item"> <a class="nav-link" href="https://www.novoco.com/" target="_blank">novoco.com</a> </li>
        </ul>
    </nav>
    {% endblock %}

 {% block content %}{% endblock %}

{% block footer %}        
<footer class="footer">
    <div class="container">
        <span class="text-muted">&copy; Novogradac & Company LLP</span>
    </div>
</footer>

<!-- /.container -->
<!-- Bootstrap core JavaScript
    ================================================== -->
<!-- Placed at the end of the document so the pages load faster -->

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>

<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script>
        (function () {
            'use strict'
            if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
                var msViewportStyle = document.createElement('style')
                msViewportStyle.appendChild(document.createTextNode('@-ms-viewport{width:auto!important}'))
                document.head.appendChild(msViewportStyle)
            }
        }())
    </script>
</body>

</html>
{% endblock %}

econ_writeups.html

{% extends "base.html" %} 
{% load static %}

{% block content %}
<!-- Begin Page content  -->
<div style="height:2000px;width:50%; padding: 15px;margin: auto;">
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            <h3>Submit Econ Writeups</h3>
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            <p>Unless otherwise stated, all fields are required. Please provide as descriptive a title and description as possible.</p>
                            <form method='post' action='./' enctype='multipart/form-data'>
                                <fieldset class='col-xs-8'>
                                    {% comment %}{{ form|bootstrap }}{% endcomment %}
                                    {% for field in form %}
                                        {% if field.is_hidden %}
                                            {{ field }}
                                        {% else %}
                                            <div class="form-group">
                                                <dt><label for='id_{{ field.name }}'>{{ field.label }}</label>{% if not field.field.required %} <span class='form_optional'>(Optional)</span>{% endif %}</dt>
                                                <dd>{{ field }}</dd>
                                                {% if field.errors %}<dd class='error'>{{ field.errors }}</dd>{% endif %}
                                                {% if field.help_text %}<dd class='form_help_text help-block'>{{ field.help_text }}</dd>{% endif %}
                                            </div>
                                        {% endif %}
                                    {% endfor %}

                                    <div class='buttons form-group'>
                                        <button type="submit" class="btn btn-primary btn-sm btn-block"><i class="fa fa-send"></i>&nbsp;Submit Data</button>
                                    </div>
                                </fieldset>
                            {% csrf_token %}</form>
                            <!-- /.form -->
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
            </div>

</div>

{% endblock %}

urls.py

urlpatterns = [
    ...
    url(r'^chaining/', include('smart_selects.urls')),
]

Actual behavior

I trying to use django-smart-select to have a user select a state in the first dropdown and have the secondary dropdown populate with all Metro Statistical Area(CBSAs) within that state. Currently, when I select a state no options populate.

enter image description here

However, if I specify show_all=True in the ChainedForeignKey, it will populate with the options (only a few test options below). enter image description here

My question is why wont the show_all=False update my MSA(CBSA) dropdown to only show chained records? I have inspected the page in chrome when running the development server and no JS errors are present.

Expected behavior

If a state is selected, only the MSA(CBSAs) that are within that state will populate in the MSA dropdown. Example: DC would populate "Custom Area". Delaware would populate "Custom Area" and "Philadelphia MSA".

smitty1788 commented 6 years ago

I used the JS adjustments made in the JS Lint branch. That branch seems to have solved the issues and the smart select is working as intended.

eriktelepovsky commented 5 years ago

+1

emilyzzz commented 4 years ago

I installed "JS Lint branch" using pip install git+https://github.com/jazzband/django-smart-selects.git@js-unlinting-fixes, now smart selects works in my Admin page

diego1996 commented 1 year ago

Buenas!, esto me sigue pasando incluso usando la ultima version :c