Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependent field does not work in formset #136

Open
rez0n opened this issue Apr 17, 2022 · 3 comments
Open

Dependent field does not work in formset #136

rez0n opened this issue Apr 17, 2022 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@rez0n
Copy link

rez0n commented Apr 17, 2022

Describe the bug
Hi, dependent fields functionality does not work in the formset.
I debugged this and found an issue in django_select2.js file, I added the description as a comment.

var dependentFields = $element.data('select2-dependent-fields')
          if (dependentFields) {
            dependentFields = dependentFields.trim().split(/\s+/)
            $.each(dependentFields, function (i, dependentField) {
              // dependentField variable contains field name "fieldname"
              // but actually this field have name: form_prefix-0-fieldname
              result[dependentField] = $('[name=' + dependentField + ']', $element.closest('form')).val()
            })
          }

I fixed this on my side by overriding this part by dirty hack

              result[dependentField] = $('[name$=' + dependentField + ']', $element.closest('.card-body')).val()

name$= - $ symbol means wildcard selector
$element.closest('.card-body') - because my formset forms framed by div with class card-body

Actually I have no good idea how to solve this issue in a good way, maybe better to use some randomly generated data attribute on the dependent field to pick its value or so?

@rez0n rez0n added the bug Something isn't working label Apr 17, 2022
@codingjoe
Copy link
Owner

Hi @rez0n, thanks for you the detailed description. Since you are already so invested, maybe you want to also provide a patch? I am currently very busy on other projects and would probably take me a little while until I get time to fix this. Best Joe!

@sgeorgiev1995
Copy link

Overriding the form field and the widget worked for me. It's not the ideal solution, but it seems better than modifying
django_select2.js, at least in my case.

for form in formset:
    form_prefix = form.prefix
    form.fields['model'] = forms.ModelChoiceField(
        queryset=MyModel.objects.all(),
        widget=MyModelSearchableSelect(
        dependent_fields={f'{form_prefix}-dependent-field': 'dependent-field'}
    ))

@asqarsakenov
Copy link

asqarsakenov commented Feb 27, 2024

@sgeorgiev1995 could you please support on inline formsets? In my case, I add the form to the inline formset. And I receive errors 404.

# view.py

def invoice_line_create_view(request, pk):
    InvoiceLineFormSet = inlineformset_factory(Invoice2, InvoiceLine2, form=LineForm, extra=10)
    invoice = get_object_or_404(Invoice2, pk=pk)

    formset = InvoiceLineFormSet(instance=invoice)
    if request.method == 'POST':
        # print(f"{get_cache_key(request)} kod")
        formset = InvoiceLineFormSet(request.POST, instance=invoice)
        if formset.is_valid():
            formset.save()
            # Инвалидация кэша после сохранения формы
            # cache.delete(get_cache_key(request))


            return redirect('invoice_detail', pk=invoice.pk)

    context = {
        'invoice': invoice,
        'formset': formset,
    }

    return render(request, './invoice/invoice_line_new.html', context)
# froms.py

class LineForm(forms.ModelForm):
    class Meta:
        model = InvoiceLine2  
        # fields = ["name", "type_field"]
        fields = "__all__"
    name = forms.ModelChoiceField(
        queryset=Name2.objects.all(),
        label="Наименование",
        widget=s2forms.ModelSelect2Widget(
            model=Name2,
            search_fields=['name__icontains'],
            attrs={
                "data-minimum-input-length": 0,
                "data-placeholder": "Выберите Наименование",
                "data-close-on-select": "true",
                "data-allow-clear" : "true",
            },
            # dependent_fields={'type_field': 'types'},

        )
    )

    type_field = forms.ModelChoiceField(
        queryset=Price2.objects.all(),
        label="Тип",
        widget=s2forms.ModelSelect2Widget(
            model=Price2,
            search_fields=['type_field__icontains'],
            attrs={
                "data-minimum-input-length": 0,
                "data-placeholder": "Выберите Тип",
                "data-close-on-select": "true",
                "data-allow-clear" : "true",

            },
            dependent_fields={'name': 'name'},
            max_results=500,
        )
    )
<!-- template.html -->
{% extends 'base.html' %}

{% block script %}
{% comment %} Фильтры по ключевикам {% endcomment %}
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

{% comment %} Select2 {% endcomment %}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
{% endblock script %}

{% block content %}
{% if user.is_authenticated %}
{% load crispy_forms_tags %}

  {% comment %} <p>Введите ключевое слово (ввод не зависит от регистра, но слова должны быть корректно написаны).</p> 
  <p>Одновременно можно фильтровать по нескольким критериям (до 5)</p> {% endcomment %}
  {% comment %} <input class="form-control" id="myInput1" type="text" placeholder="Поиск 1">
  <input class="form-control" id="myInput2" type="text" placeholder="Поиск 2">
  <input class="form-control" id="myInput3" type="text" placeholder="Поиск 3">
  <input class="form-control" id="myInput4" type="text" placeholder="Поиск 4">
  <input class="form-control" id="myInput5" type="text" placeholder="Поиск 5"> {% endcomment %}
  <h2>Изменение содержимого КП №{{ invoice.invoice_number }} для {{ invoice.customer }} от {{ invoice.date_issued }}</h2>
  
  <form method="post" class="form-horizontal" enctype="multipart/form-data">
    {% csrf_token %}
    {{ formset.management_form }} 
    <table class="table">
      <thead>
          <tr>
              <th scope="col"></th>
              <th scope="col">Тип</th>
              <th scope="col">Тип цены</th>
              <th scope="col">Количество</th>
              <th scope="col">Удалить</th>
          </tr>
      </thead>
      <tbody>
          {% for form in formset %}
            {{ form.id }}
          <tr>
              <th scope="row">{{ forloop.counter }}</th>
              
              <td>{{ form.type_field }}</td>
              <td>{{ form.price_type }}</td>
              <td>
                  <div class="form-outline">
                      {{ form.quantity }}
                  </div>
              </td>
              <td>{{ form.DELETE }}</td>
          </tr>
          {% endfor %}
      </tbody>
  </table>
    <input type="submit" class="btn btn-primary" value="Сохранить">
  </form>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  {{ form.media.js }}

  {% else %}
<p>Вы не вошли в ваш аккаунт. Функционал доступен только для зарегистрированных пользователей.</p>
<a href="{% url "login" %}">Войти</a>
{% comment %} <a href="{% url "signup" %}">Регистрация</a> {% endcomment %}

{% endif %}
{% endblock %}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants