简体   繁体   中英

How to create a dynamic formset from form in Django/AJAX

I'm working on a page which contains two forms. One of this forms is regular one - name, description, notes etc. The second one is two dropdown menus - Language and Level where the Level is chained with Language using AJAX .

I want to make this form appears on the page as many times as user wants. So ifthey fill Language and Level , there appears new Language and Level form below the old one.

The problem is that if the form is chained, I have to identify each Language and Level separately so I can't just copy the form this in repeat. (Maybe I can but I can't figure it out since I'm new in AJAX).

This is a create job django/html:

{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% load static %}
{% block head %}
    <script src="{% static  "js/main.js" %}"></script>
{% endblock %}
{% block content %}
    {% if user.is_authenticated %}
        <form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
            {{ language_form }}
            <button value="Update" type="submit">Submit</button>
        </form>
    {% endif %}
{% endblock %}

This is the JQuery:

 $(document).on('change','#id_language',function(){
     language_id = $(this).val();
     request_url = '/get-highest-level/'+language_id+'/';
     $.ajax({
         url:request_url,
         success: function(data){
             var select = $('#id_level');
             select.empty();
             $.each(data, function (key,value) {
                 $('select[name="level"]').append('<option value="'+ key + '">'+value + '</option>');
             });
             return false;
         }
     })
});

And a simple view:

@login_required
def create_order(request):
    language_form = LanguageLevelForm(request.POST or None)
    return render(request,'auth/jobs/create-job-test.html',context={'language_form':language_form})

I know that it should be possible to use FormSet but I can't figure out how to make it work with the JQuery . 这就是HTML中的表单集的样子

To refresh select options, you don't have to identify them. If the language form is wrapped with div or something, there's only one closest level select for a language select.

$(document).on('change','select.language',function(){ // use class, not id
     language_id = $(this).val();
     request_url = '/get-highest-level/'+language_id+'/';
     var language = $(this);
     $.ajax({
         url:request_url,
         success: function(data){
             //find closest select with class "level"
             var select = language.closest('select.level'); 
             select.empty();
             $.each(data, function (key,value) {
                 // use select found above.
                 select.append('<option value="'+ key + '">'+value + '</option>');
             });
             return false;
         }
     })
});

Similarly, you can change attributes of them without identifying.

$('select.language').each(function(index){
    $(this).attr('name', 'language' + index);
});

EDIT : With your sample HTML, try this..

$(document).on('change','select[id$="language"]',function(){ // id ends with 'language'
     language_id = $(this).val();
     request_url = '/get-highest-level/'+language_id+'/';
     var level_select_id = $(this).attr('id').replace('language', 'level'); // tricky..
     $.ajax({
         url:request_url,
         success: function(data){
             var select = $('#' + level_select_id); // use id string found above
             select.empty();
             $.each(data, function (key,value) {
                 select.append('<option value="'+ key + '">'+value + '</option>');
             });
             return false;
         }
     })
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM