1

ページに新しいフォームを追加するために ajax を使用する Web アプリケーションを作成しています。既存のフォームは inlineformset_factory を使用して作成されます。クライアント側がフォームを取得すると、それを正しい位置に挿入し、#id_form_type-TOTAL_FORMS" の値を更新します (この例では、form_type はフォームの名前です)。

既存のフォームには、name="form_type-1-source" のような各フィールドの名前があり、1 は一意のフォーム ID です。

問題は、すべてのフォームが異なるように、新しいフォームの次の ID を生成することです。私は1つの解決策を作りましたが、それは好きではありません。

ajax 呼び出しの URL は次のようになります。

(r'^ajax/get_form/(?P<form_type>\w+)$', views.get_form),

フォーム ビューを取得します。

def get_form(request, form_type):
    """
    Returns form for requested model if invoken with ajax.
    If invoken directly returns empty string.

    The form is rendered into HTML using as_p method. 
    """
    if request.method == "GET" and request.is_ajax():
        current_forms_no = int(request.GET["current_forms_no"])
        form_class = all_forms[form_type]
        Formset = inlineformset_factory(Component, form_class.Meta.model, extra=current_forms_no + 1, form = form_class, can_delete = False)
        form = Formset()
        return HttpResponse(form.forms[current_forms_no].as_p())
    else:
        return HttpResponse()

そして、それを呼び出す JavaScript 関数:

function add_new_form(event) {
    event.preventDefault();
    form_type = $(this).attr("href");

    // for id generation
    formset = $("#id_" + form_type + "-TOTAL_FORMS");
    current_forms_no = formset.val()

    container = $(this).parent().parent();
    $.get("/ajax/get_form/" + form_type, {"current_forms_no" : current_forms_no}, function(data) {
        container.append(data);
        container.append("<hr>");

        // increment form count so they can be saved on server
        formset.val(parseInt(formset.val()) + 1);
    })
}

私は複数のフォームを持っているので、関数は汎用的です。アンカーの href 属性に form_type を保持しています。

つまり、ここで行っているのは、必要以上のフォームを作成していて、最後のフォームだけを使用していることです。

では、最初に生成したい ID を inlineformset_factory に伝える方法はありますか?

PS: 下手な英語でごめんなさい...

4

2 に答える 2

2

私がしたことは、非表示の追加フォームを作成し、Javascript でコピーするだけでした。つまり、最後のフォームをコピーし、非表示のフォームを表示して、フォームの新しいコピーを非表示にします。

このようにして、ページ上のフォームの数をカウントし、それをメタ Total-Forms 変数に使用できます。

ページ上のフォームを削除できるようにしたい場合は、DELETED 属性を使用して大騒ぎする必要があります。編集: これは、プロトタイプ js を使用した私の主な機能の 1 つです。

function add_form_to_formset(formset, callbacks etc...){
   // Management form
   total_forms_element = $('id_' + formset.prefix + '-TOTAL_FORMS');

   var curr_last_id = biggest_id(formset.form_class);
   var last_form = $('id_' + formset.prefix + '-' + curr_last_id + '-id').up();

   // Copy it
   var new_form = last_form.cloneNode(true);

   ...register some buttons like add/remove etc..

   set_form_id(new_form, curr_last_id+1);

   last_form.show();
   last_form.insert({after:new_form});


   // Increment the management form count
   total_forms_element.value = parseInt(total_forms_element.value) + 1;
于 2009-03-18T18:38:02.843 に答える
0

フォームセット ファクトリを生成する代わりに、auto_id パラメータを使用して一意の ID を持つフォームを生成できます。

def get_form(request, form_type):
    current_forms_no = int(request.GET["current_forms_no"])
    form_class = all_forms[form_type]
    form = form_class(auto_id='id_%%s_%s' % current_forms_no)
    return HttpResponse(form.as_p())
于 2011-05-19T10:01:00.127 に答える