Это очень выполнимо, вам нужно будет решить, как вы хотите, чтобы ваши модальные окна выглядели и работали, найдя подходящую модальную библиотеку.
Как только у вас это будет, вам нужно будет определить, как ваш интерфейс администратора предоставит настройку, которая FormPage
будет использоваться в базовом шаблоне для рендеринга модального окна. Хороший вариант - настройки сайта Wagtail .
Отсюда вам нужно получить связанную форму и использовать ее метод get_form()
(все страницы, расширяющие AbstractForm
или AbstractEmailForm
есть это). Если вы хотите понять, как обрабатывается форма, вы можете увидеть здесь код .
Самый простой способ обработать отправку формы - отправить POST в исходную форму, в этом случае нет необходимости быть какой-либо дополнительной обработкой в другом месте. Вы также получаете страницу «Успех», как обычно, без необходимости визуализировать ее внутри модального окна.
Ниже приведен базовый пример кода c, который должен вас начать.
Пример кода. через
1. установить настройки трясогузки
# settings.py
INSTALLED_APPS += [
'wagtail.contrib.settings',
]
2. Настройте модель настроек
- Это будет содержать отношение к любому
FormPage
, вам нужно будет создать страницу формы отдельно. - Примечание: вы может захотеть снять флажок «показывать в меню» на странице формы, если вы не хотите, чтобы пользователи могли go переходить к этой форме по ее собственному URL-адресу, а также
- Документы - https://docs.wagtail.io/en/stable/reference/contrib/settings.html#defining -настройки
- Не забудьте запустить
makemigrations
& migrate
from django.db import models
from wagtail.contrib.settings.models import BaseSetting, register_setting
from wagtail.admin.edit_handlers PageChooserPanel
# ... other models & imports
@register_setting
class MyAppSettings(BaseSetting):
# relationship to a single form page (one per site)
modal_form_page = models.ForeignKey(
'wagtailcore.Page',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
verbose_name='Modal Form'
)
panels = [
# note the kwarg - this will only allow form pages to be selected (replace base with your app)
PageChooserPanel('modal_form_page', page_type='base.FormPage')
]
3. Установите базовую c модальную библиотеку
- Это зависит от вас, например, если вы используете bootrap, она поставляется с модальной библиотекой
- В этом примере я использовал https://micromodal.now.sh/#installation
- Есть много способов сделать это, это самый простой и не требует никаких асинхронных c фоновых вызовов сервера
3a . Добавьте css в папку stati c (например, my-app / static / css / micromodal. css), а затем импортируйте его в центральный заголовок или шаблон макета.
<head>
<!-- ALL OTHER ITEMS -->
<!-- Modal CSS -->
<link href="{% static 'css/micromodal.css' %}" rel="stylesheet" type="text/css">
</head>
3b . Добавьте вызов JS & init в ваш базовый шаблон, лучше всего сделать это как последний элемент перед закрывающим тегом body
<!-- Modal JS -->
<script src="https://unpkg.com/micromodal/dist/micromodal.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
MicroModal.init();
});
</script>
4. Настройте тег шаблона
- Есть несколько способов сделать это, но в основном мы хотим, чтобы в нашем шаблоне
base.html
был удобный способ размещения модального и модального триггера. template tags
Django - отличный способ сделать это. - Docs - https://docs.djangoproject.com/en/3.0/howto/custom-template-tags/#inclusion -tags
- Использование инструкций на странице настроек сайта Wagtail мы можем импортировать нашу модель настроек и получить доступ к соответствующей странице формы, отсюда мы можем сгенерировать объект формы.
- Приведенный ниже код шаблона является минимальным, вы, вероятно, захотите сделать больше стилей, он предполагает триггер будет просто отображаться вместе с модальным содержимым.
- Шаблон содержит некоторые базовые c logi c, позволяющие отслеживать страницу, на которой форма была отправлена
source-page-id
, чтобы мы могли перенаправить пользователя на их исходную страницу и чтение request.session, чтобы показать сообщение об успешном завершении.
# my-app/templatetags/modal_tags.py
from django import template
from models import MyAppSettings
register = template.Library()
# reminder - you will need to restart Django when adding a template tag
@register.inclusion_tag('tags/form_modal.html', takes_context=True)
def form_modal(context):
request = context['request'] # important - you must have the request in context
settings = MyAppSettings.for_request(request)
form_page = settings.modal_form_page
if not form_page:
return context
form_page = form_page.specific
# this will provide the parts needed to render the form
# this does NOT handle the submission of the form - that still goes to the form page
# this does NOT handle anything to do with rendering the 'thank you' message
context['form_page'] = form_page
context['form'] = form_page.get_form(page=form_page, user=request.user)
return context
{% comment %} e.g. my-app/templates/tags/form_modal.html {% endcomment %}
{% load wagtailcore_tags %}
{% if request.session.form_page_success %}
Thanks for submitting the form!
{% endif %}
{% if form %}
<button data-micromodal-trigger="modal-1">Open {{ form_page.title }} Modal</button>
<div class="modal micromodal-slide" id="modal-1" aria-hidden="true">
<div class="modal__overlay" tabindex="-1" data-micromodal-close>
<div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-1-title">
<header class="modal__header">
<h2 class="modal__title" id="modal-1-title">
{{ form_page.title }}
</h2>
<button class="modal__close" aria-label="Close modal" data-micromodal-close></button>
</header>
<form action="{% pageurl form_page %}" method="POST" role="form">
<main class="modal__content" id="modal-1-content">
{% csrf_token %}
{{ form.as_p }}
{% if page.pk != form_page.pk %}
{% comment %} only provide the source page if not on the actual form page {% endcomment %}
<input name="source-page-id" type="hidden" value="{{ page.pk }}">
{% endif %}
</main>
<footer class="modal__footer">
<input class="modal__btn modal__btn-primary" type="submit">
<button class="modal__btn" data-micromodal-close aria-label="Close this dialog window">Close</button>
</footer>
</form>
</div>
</div>
</div>
{% endif %}
5. Используйте тег шаблона там, где вы хотите, чтобы модальный триггер
- Теперь вы можете добавить модальный (вместе с его триггером)
- Важно: чтобы тег шаблона выше имел доступ к запросу через контекст вам может потребоваться добавить это (в зависимости от вашей настройки).
<!-- Footer -->
<footer>
{% form_modal %}
{% include "includes/footer.html" %}
</footer>
6. Перенаправление обратно на исходную страницу
# models.py
class FormPage(AbstractEmailForm):
# .. fields etc
def render_landing_page(self, request, form_submission=None, *args, **kwargs):
source_page_id = request.POST.get('source-page-id')
source_page = Page.objects.get(pk=source_page_id)
if source_page:
request.session['form_page_success'] = True
return redirect(source_page.url, permanent=False)
# if no source_page is set, render default landing page
return super().render_landing_page(request, form_submission, *args, **kwargs)