Mohssen A Mohssen نشر 20 يونيو 2022 أرسل تقرير نشر 20 يونيو 2022 لدي نموذج form ويحتوي على زر "add new field" وأريد عند الضغط على هذا الزر أن يتم إضافة حقل جديد إلى النموذج ليتمكن المستخدم من إضافة المزيد من المعلومات. هل يجب أن يتم إعادة تحديث الصفحة ليتم إضافة حقل جديد؟ وكيف أقوم بعمل مثل هذا الزر من الأساس؟ 1 اقتباس
1 محمد حجي2 نشر 20 يونيو 2022 أرسل تقرير نشر 20 يونيو 2022 حتى تستطيع إضافة حقل بشكل ألي و ديناميكي يجب إستخدام بعض من JS جافا سكربت سكون الشرح على 3 خطوات أولا ما سوف تفعله في ملف templates لماذا يجب إستخدام JS في المتصفح لتعديل على elements أو عناصر HTML بدون إعادة تحميل الصفحة يجب استخدام لغة برمجة تعمل على المتصفح نفسه. مثال على الفكرة المطلوبة أولاً views.py from django.contrib.auth.decorators import login_required from django.forms.models import modelformset_factory # model form for querysets from django.shortcuts import redirect, render, get_object_or_404 from .forms import RecipeForm, RecipeIngredientForm from .models import Recipe, RecipeIngredient @login_required def recipe_update_view(request, id=None): obj = get_object_or_404(Recipe, id=id, user=request.user) form = RecipeForm(request.POST or None, instance=obj) # Formset = modelformset_factory(Model, form=ModelForm, extra=0) RecipeIngredientFormset = modelformset_factory(RecipeIngredient, form=RecipeIngredientForm, extra=0) qs = obj.recipeingredient_set.all() # [] formset = RecipeIngredientFormset(request.POST or None, queryset=qs) context = { "form": form, "formset": formset, "object": obj } if all([form.is_valid(), formset.is_valid()]): parent = form.save(commit=False) parent.save() # formset.save() for form in formset: child = form.save(commit=False) child.recipe = parent child.save() context['message'] = 'Data saved.' return render(request, "recipes/create-update.html", context) ثانياً: recipes/create-update.html: templates أولاً جزء HTML {% if formset %} <h3>Ingredients</h3> {{ formset.management_form }} <div id='ingredient-form-list'> {% for form in formset %} <div class='ingredient-form'> {{ form.as_p }} </div> {% endfor %} </div> <div id='empty-form' class='hidden'>{{ formset.empty_form.as_p }}</div> <button id='add-more' type='button'>Add more</button> {% endif %} <button style='margin-top:10px;' type='submit' >Save</button> </form> </div> والأن مع جزء JS وسيكون في نفس ملف HTML في النهاية. <script> const addMoreBtn = document.getElementById('add-more') const totalNewForms = document.getElementById('id_form-TOTAL_FORMS') addMoreBtn.addEventListener('click', add_new_form) function add_new_form(event) { if (event) { event.preventDefault() } const currentIngredientForms = document.getElementsByClassName('ingredient-form') const currentFormCount = currentIngredientForms.length // + 1 const formCopyTarget = document.getElementById('ingredient-form-list') const copyEmptyFormEl = document.getElementById('empty-form').cloneNode(true) copyEmptyFormEl.setAttribute('class', 'ingredient-form') copyEmptyFormEl.setAttribute('id', `form-${currentFormCount}`) const regex = new RegExp('__prefix__', 'g') copyEmptyFormEl.innerHTML = copyEmptyFormEl.innerHTML.replace(regex, currentFormCount) totalNewForms.setAttribute('value', currentFormCount + 1) // now add new empty form element to our html form formCopyTarget.append(copyEmptyFormEl) } </script> {% endblock content %} قد يكون ليس من السهل فهم كل شئ في كود JS لكن ما يقوم به كود SCRIPT هو نسخ أحد العناصر من HTML عند حدوث حدث click على الزر Add more و في نفس الوقت يتم التعديل على بعض Attribute في عناصر Html الجديدة و بعد القيام بأي حفظ للبيانات سيقوم بعرض ما تم حفظه اقرأ الأكواد جيداً يستحسن أن يكون لديك فكرة عامة عن JS و أتوقع ان يكون الكود مفهوم بالنسبة لك وهذا المثال ليساعدك على حل مشكلة الخاصة بك اقتباس
1 Haroun Taha نشر 20 يونيو 2022 أرسل تقرير نشر 20 يونيو 2022 (معدل) إذا كنت تقصد ال Forms الخاصة بال Models في ال Admin الخاصة بالجانغو يمكننا عمل ذلك بواسطة إنشاء model في models.py سنسميه في حالتنا class ExtraField ونعرف بداخله الحقل الذي تريد إضافته عند الضغط على add new field ونربطه بعلاقة Foreign Key مع ال model المرتبط بال Form سنسميه في حالتنا Post هكذا سيكون الكود داخل ال models.py : class ExtraField(models.Model): extra_data = models.CharField(max_length=200) post = models.ForeignKey(Post, on_delete=models.CASCADE) def __str__(self): return self.extra_data ملاحظة : لا تنسى عمل makemigrations and migrate من ثم في ملف الadmin.py عند تسجيل ال model المرتبط بالForm نقوم بتعريف class ExtraFieldTabularInline : from .models import ExtraField, Post class ExtraFieldTabularInline(admin.TabularInline): model = ExtraField من ثم نقوم بتعريف class ال PostAdmin بإضافة انه سيقبل Inlines اذن سنضيف ايضاً class PostAdmin : class PostAdmin(admin.ModelAdmin): inlines = [ExtraFieldTabularInline] class Meta: model = Post من ثم تسجيل form الpost في لوحة التحكم : admin.site.register(Post, PostAdmin) هكذا أصبح لديك اضافة حقول كما تريد ولقد تم انشاء الزر دون تحديث الصفحة وهذا إجابة لسؤالك اذا كنت تقصد الforms داخل لوحة التحكم الخاصة بالدجانغو استخدمت في المثال الجدول الmodel المرتبط بال form اسميته Post لتوضيح الفكرة ولكن لك ان تطبق الفكرة على اي جدول او model حسب ما اسميته. كانت إجابتي بخصوص الforms داخل لوحة التحكم في دجانقو لم اتطرق الى الforms الخاص بالعرض في التمبلت تحياتي . مثال بصري الى النتيجة : تم التعديل في 20 يونيو 2022 بواسطة Haroun Taha اقتباس
السؤال
Mohssen A Mohssen
لدي نموذج form ويحتوي على زر "add new field" وأريد عند الضغط على هذا الزر أن يتم إضافة حقل جديد إلى النموذج ليتمكن المستخدم من إضافة المزيد من المعلومات.
هل يجب أن يتم إعادة تحديث الصفحة ليتم إضافة حقل جديد؟ وكيف أقوم بعمل مثل هذا الزر من الأساس؟
2 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.