Ajax를 사용하여 Django 폼셋에 새 폼을 자동으로 추가하고 싶습니다. 따라서 사용자가 “add”버튼을 클릭하면 새로운 폼 (폼셋의 일부)을 페이지에 추가하는 JavaScript가 실행됩니다.
답변
이것이 jQuery를 사용하여 수행하는 방법입니다 .
내 템플릿 :
<h3>My Services</h3>
{{ serviceFormset.management_form }}
{% for form in serviceFormset.forms %}
<div class='table'>
<table class='no_error'>
{{ form.as_table }}
</table>
</div>
{% endfor %}
<input type="button" value="Add More" id="add_more">
<script>
$('#add_more').click(function() {
cloneMore('div.table:last', 'service');
});
</script>
자바 스크립트 파일에서 :
function cloneMore(selector, type) {
var newElement = $(selector).clone(true);
var total = $('#id_' + type + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function() {
var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
$(this).attr('for', newFor);
});
total++;
$('#id_' + type + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
}
그것이하는 일 :
cloneMore
받아들이는 selector
첫 번째 인수로하고, type
제 2 하나의 formset의. 무엇을 selector
해야하는 것은 중복해야하는지 전달할 수 있습니다. 이 경우 div.table:last
jQuery가 클래스가있는 마지막 테이블을 찾도록 전달합니다 table
. :last
이 있기 때문에 그 부분은 중요하다 selector
또한 새로운 형태 다음에 삽입 할 것을 결정하는 데 사용됩니다. 나머지 양식의 끝에 그것을 원할 것입니다. type
우리는 업데이트 할 수 있도록 인수는 management_form
특히 필드 TOTAL_FORMS
뿐만 아니라 실제 양식 필드를. 당신은, 말하자면, 가득 해당 formset있는 경우 Client
모델을 관리 필드의 ID를해야합니다 id_clients-TOTAL_FORMS
및 id_clients-INITIAL_FORMS
양식 필드의 형식이됩니다 반면, id_clients-N-fieldname
과N
로 시작하는 양식 번호입니다 0
. 그래서 함께 type
인수로 사용 cloneMore
하는 방법을 여러 가지 형태의 기능 모습이 현재와 같은에서 모든 필드 이름 / ID를 대체하는 새로운 형태의 내부의 모든 입력 및 레이블을 통과 id_clients-(N)-name
하는 id_clients-(N+1)-name
등등. 완료된 후에는 TOTAL_FORMS
필드를 업데이트하여 새 양식을 반영하고 세트 끝에 추가합니다.
이 기능은 설정 방식에 따라 양식 세트에서 더 많은 양식을 제공하려고 할 때 앱 전체에서 사용할 수 있으며 복제하기 위해 숨겨진 “템플릿”양식을 가질 필요가 없기 때문에 특히 유용합니다. 내가 그것을 전달하는 한 양식 이름과 양식이 배치되는 형식. 도움이 되길 바랍니다.
답변
empty_form
템플릿으로 사용하는 Paolo의 답변 단순화 버전 .
<h3>My Services</h3>
{{ serviceFormset.management_form }}
<div id="form_set">
{% for form in serviceFormset.forms %}
<table class='no_error'>
{{ form.as_table }}
</table>
{% endfor %}
</div>
<input type="button" value="Add More" id="add_more">
<div id="empty_form" style="display:none">
<table class='no_error'>
{{ serviceFormset.empty_form.as_table }}
</table>
</div>
<script>
$('#add_more').click(function() {
var form_idx = $('#id_form-TOTAL_FORMS').val();
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
});
</script>
답변
나는 한 코드 조각 게시 한 동안의 뒷면에 근무 응용 프로그램에서합니다. Paolo와 유사하지만 양식을 삭제할 수도 있습니다.
답변
Paolo의 제안은 브라우저의 뒤로 / 앞으로 버튼이라는 하나의 경고와 함께 아름답게 작동합니다.
사용자가 뒤로 / 앞으로 단추를 사용하여 양식 세트로 돌아 오면 Paolo의 스크립트로 작성된 동적 요소가 렌더링되지 않습니다. 일부에게는 문제가 될 수있는 문제입니다.
예:
1) 사용자는 “추가 항목”버튼을 사용하여 두 개의 새 양식을 양식 세트에 추가합니다.
2) 사용자가 양식을 채우고 양식을 제출합니다.
3) 사용자가 브라우저에서 뒤로 버튼을 클릭
4) 이제 양식 세트가 원래 양식으로 축소되고 동적으로 추가 된 모든 양식이 없습니다
이것은 Paolo의 스크립트에 전혀 결함이 아닙니다. 그러나 DOM 조작과 브라우저 캐시의 삶의 사실.
양식에 값을 세션에 저장할 수 있고 양식 세트가 요소를 다시 작성하고 세션에서 값을 다시로드하기 위해로드 할 때 약간의 마법을 가질 수 있다고 가정합니다. 그러나 동일한 사용자와 양식의 여러 인스턴스에 대해 항문이 얼마나 필요한지에 따라 이것은 매우 복잡해질 수 있습니다.
누구든지 이것을 다루는 데 좋은 제안이 있습니까?
감사!
답변
동적 장고 양식에 대한 다음 솔루션을 확인하십시오.
http://code.google.com/p/django-dynamic-formset/
https://github.com/javisantana/django-dinamyc-form/tree/master/frm
둘 다 jQuery를 사용하고 장고에 따라 다릅니다. 첫 번째는 좀 더 세련되어 보이고 우수한 데모가 포함 된 다운로드를 제공합니다.
답변
시뮬레이션 및 모방 :
- “추가”단추를 클릭 하기 전에 상황에 해당하는 양식 세트를 작성하십시오 .
- 페이지를로드하고 소스를보고 모든
<input>
필드를 기록하십시오. - “추가”단추를 클릭 한 후 상황에 맞게 양식 세트를 수정하십시오 (추가 필드 수 변경).
- 페이지를로드하고 소스를보고
<input>
필드 변경 . - DOM을 이전 상태에서 이후 상태 로 이동하기에 적합한 방식으로 DOM을 수정하는 JavaScript를 작성하십시오 .
- 해당 JavaScript를 “추가”버튼에 첨부하십시오.
폼 세트가 특수 숨겨진 <input>
필드를 사용 하고 대본이 무엇을 해야하는지 아는 동안 머리 꼭대기에서 세부 사항을 기억하지는 않습니다. 위에서 설명한 것은 귀하의 상황에서 내가 할 일입니다.
답변
이것에 대한 jquery 플러그인이 있으며, 장고 1.3에서 inline_form 세트와 함께 사용했으며 사전 채우기, 클라이언트 측 양식 추가, 제거 및 여러 inline_formsets를 포함하여 완벽하게 작동합니다.