Search code examples
pythondjangodjango-modelsdjango-formsdjango-templates

How to show/hide a django form field based on the stored value while editing?


models.py:

cv_choices = (
    ('One Time', 'One Time'),
    ('Renewal', 'Renewal'),
)

class Certification(models.Model):
    user = models.ForeignKey(Account, on_delete=models.CASCADE, null=True)
    certName = models.CharField(_('Certification Name'), max_length=100, null=True)
    certId = models.CharField(_('Certification ID'), max_length=100, null=True)
    certUrl = models.URLField(_('Certification URL'), max_length=500, null=True)
    certStartDate = models.DateField(_('Certification Start Date'), null=True)
    certEndDate = models.DateField(_('Certification End Date'), null=True, blank=True)
    certValidity = models.CharField(_('Certification Validity'), max_length=10, choices=cv_choices, default='Renewal', null=True)
    createdDate = models.DateTimeField(_('Created Date'), auto_now_add=True, editable=False)
    modifiedDate = models.DateTimeField(_('Modified Date'), auto_now=True, editable=False)

    def __str__(self):
        return self.certName

forms.py:

class CertificationForm(forms.ModelForm):
    certValidity = forms.ChoiceField(choices=[('One Time', 'One Time'),('Renewal', 'Renewal')])

    class Meta:
        model = empCertification
        fields = ('user', 'certName', 'certId', 'certUrl', 'certStartDate', 'certEndDate', 'certValidity')

    def __init__(self, *args, **kwargs):
        super(empCertificationForm, self).__init__(*args, **kwargs)
        self.fields['user'].widget.attrs['class'] = 'form-select'
        self.fields['certName'].widget.attrs['class'] = 'form-control'
        self.fields['certId'].widget.attrs['class'] = 'form-control'
        self.fields['certUrl'].widget.attrs['class'] = 'form-control'
        self.fields['certStartDate'].widget.attrs['class'] = 'form-control'
        self.fields['certEndDate'].widget.attrs['class'] = 'form-control'
        self.fields['certValidity'].widget.attrs['class'] = 'form-select'
        for field in self.fields:
            self.fields[field].widget.attrs['placeholder'] = 'Provide Details'

Edit Template File:

<form action="{% url 'certificationEdit' certification.pk %}" method="post" class="form"
                                  enctype="multipart/form-data" novalidate>
                                {% csrf_token %}
                                <div class="card-body border-top p-9">
                                    {% if certificaitonForm.errors %}
                                        {% for field in certificaitonForm %}
                                            {% for error in field.errors %}
                                            <div class="alert alert-danger">
                                                <strong>{{field.name|title}} - {{error|escape}}</strong>
                                            </div>
                                            {% endfor %}
                                        {% endfor %}
                                        {% for error in certificaitonForm.non_field_errors %}
                                        <div class="alert alert-danger">
                                            <strong>{{error|escape}}</strong>
                                        </div>
                                        {% endfor %}
                                    {% endif %}
                                    <div class="row">
                                        <div class="col-lg-6">
                                            <div class="form-floating mb-7">
                                                {{certificaitonForm.user}}
                                                <label class="required">User</label>
                                            </div>
                                        </div>
                                        <div class="col-lg-6">
                                            <div class="form-floating mb-7">
                                                {{certificaitonForm.certValidity}}
                                                <label>Certification Validity</label>
                                            </div>
                                        </div>
                                        <div class="col-lg-6">
                                            <div class="form-floating mb-7">
                                                {{certificaitonForm.certName}}
                                                <label class="required">Certification Name</label>
                                            </div>
                                        </div>
                                        <div class="col-lg-6">
                                            <div class="form-floating mb-7">
                                                {{certificaitonForm.certId}}
                                                <label class="required">Certification ID</label>
                                            </div>
                                        </div>
                                        <div class="col-lg-6">
                                            <div class="form-floating mb-7">
                                                {{certificaitonForm.certUrl}}
                                                <label class="required">Certification URL</label>
                                            </div>
                                        </div>
                                        <div class="col-lg-6">
                                            <div class="form-floating mb-7">
                                                {{certificaitonForm.certStartDate}}
                                                <label class="required">Certification Start Date</label>
                                            </div>
                                        </div>
                                        <div class="col-lg-6 certEndDate">
                                            <div class="form-floating mb-7">
                                                {{certificaitonForm.certEndDate}}
                                                <label>Certification End Date</label>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="card-footer d-flex justify-content-end py-6 px-9">
                                    <a href="{% url 'certificationList' %}" class="btn btn-light-info me-3">Discard</a>
                                    <button type="submit" class="btn btn-primary">Save Changes</button>
                                </div>
                            </form>

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('certificationEdit/<int:pk>', views.certificationEdit, name='certificationEdit'),
]

views.py

@login_required(login_url='login')
def certificationEdit(request, pk):
    certification = get_object_or_404(empCertification, id=pk)
    certificaitonForm = empCertificationForm(instance=certification)
    if request.method == 'POST':
        certificaitonForm = empCertificationForm(request.POST, instance=certification)
        if certificaitonForm.is_valid():
            certificaitonForm.save()
            messages.success(request, 'Certification has been updated.')
            return redirect('certificationList')
        else:
            messages.error(request, 'Please correct form errors.')

    context = {
        'certification': certification,
        'certificaitonForm': certificaitonForm,
    }
    return render(request, 'back/pages/certification/update.html', context)

Show/Hide Form Fields I am using the following JavaScript function to show and hide the field while adding data.

$('select[name="certValidity"]').on('change', function(){
        if ($(this).val() == 'One Time') {
            $('.certEndDate').hide();
        } else {
            $('.certEndDate').show();
        }
    });

But while retrieving the same row using Django template, it is showing all the fields.

For Example: If i saved certification validity as "One Time" which do not include "CertEndDate" and when i try to retrieve the same data its showing "certEndDate" field.

So my question is how to hide the certEndDate while retrieving the "One Time" certificate data.


Solution

  • I found a solution to the above.

    Sharing here will help others if they have similar issues.

    You need to add the following in the template file.

    {% if certificaitonForm.certValidity.value != 'One Time' %}
    <div class="col-lg-6 certEndDate">
       <div class="form-floating mb-7">
          {{certificaitonForm.certEndDate}}
          <label>Certification End Date</label>
       </div>
    </div>
    {% endif %}