Есть ли правильный способ открыть модальное окно в трясогузке-админке?

Я пытаюсь улучшить свою трясогузку-админку и теперь складываю, потому что нет возможности открыть модальное окно. Да, конечно, я мог бы создатьdivс кнопкой закрытия, но это было бы неправильно. Как у меня есть, есть специальная функция (или объект), которая отвечает за открытие такого окна.

Нет ссылки на такую ​​структуру js-объектов трясогузки-админа. Может кто знает, как это сделать? Или, может быть, мне стоит забыть об этом и создать модальное окно только на ванильном javascript?

1 ответ

Решение

Короткий ответ заключается в том, что не существует документированного способа использования существующих модальных окон администратора Wagtail.

Однако, немного взглянув на исходный код, можно использовать модальный рабочий процесс для реализации ваших собственных модальных окон. Подход в Wagtail состоит в том, чтобы ответ шаблона на стороне сервера предоставлялся render_modal_workflow.

На клиенте доступна функция ModalWorkflow. Это вызовет асинхронный URL-адрес и отобразит содержимое html внутри модального окна при ответе, он ожидает ответа, сформированного указанным вышеrender_modal_workflow помощник.

Исходя из этих основ, можно добавить поведение открытия с помощью триггера кнопки, обработки ошибок, отображать обратные вызовы и обратные вызовы на основе значения внутри модального окна.

Ниже приведен минимальный пример способа визуализации модального окна в админке с использованием этого подхода.

пример

1. Визуализируйте некоторый HTML-контент с кнопкой в ​​качестве триггера.

  • В качестве примера мы отрендерим модальное окно на главной странице (панели инструментов) Wagtail.
  • Используя construct_homepage_panels мы можем добавить HTML-код на панель частично вниз по странице.
wagtail_hooks.py
from django.utils.safestring import mark_safe
from wagtail.core import hooks

class WelcomePanel:
    order = 110

    def render(self):
        return mark_safe("""
        <section class="panel summary nice-padding">
          <h3>Dashboard Panel Section Title</h3>
          <button data-modal-trigger="some-param">Open Modal</button>
        </section>
        """)

@hooks.register('construct_homepage_panels')
def add_another_welcome_panel(request, panels):
    panels.append(WelcomePanel())

2. Убедитесь, что JS-скрипт модального рабочего процесса загружен.

  • По умолчанию только страницы, которые обрабатывают редактирование, имеют загруженный сценарий модального рабочего процесса.
  • Чтобы добавить его на эту конкретную страницу, нам нужно переопределить wagtailadmin/home.htmlшаблон шаблона.
  • Мы также добавим немного jquery, чтобы найти любые элементы, у которых есть data-modal-trigger атрибут и добавить onClick слушатель, который вызовет наш ModalWorkflowфункция. Эти данные можно передать обратно в модальное представление вместе с любыми другими конкретными данными.
templates/wagtailadmin/home.html
{% extends "wagtailadmin/home.html" %}
{% load wagtailadmin_tags %}

{% comment %}
    Javascript declaration added to bring in the modal loader, by default it is only available on edit pages
    example of usage - wagtail/search/templates/wagtailsearch/queries/chooser_field.js
{% endcomment %}

{% block extra_js %}
  {{ block.super }}
  <script src="{% versioned_static 'wagtailadmin/js/modal-workflow.js' %}"></script>
  <script type="text/javascript">
    $(function() {
      $('[data-modal-trigger]').on('click', function(element) {
        /* options passed in 'opts':
          'url' (required): initial
          'responses' (optional): dict of callbacks to be called when the modal content
              calls modal.respond(callbackName, params)
          'onload' (optional): dict of callbacks to be called when loading a step of the workflow.
              The 'step' field in the response identifies the callback to call, passing it the
              modal object and response data as arguments
        */
        ModalWorkflow({
          onError: function(error) { console.log('error', error); },
          url: '/admin/modal/?trigger=' + element.target.dataset.modalTrigger
        });
      });
    });
  </script>
{% endblock %}

3. Создайте представление и URL-адрес для обработки модальных запросов.

  • Убедитесь, что есть admin/... URL-адрес, с которого мы можем запросить модальное содержимое
  • Этот URL-адрес должен указывать на представление, которое возвращает ответ на основе render_modal_workflow
  • Можно инициировать данные на стороне клиента вместе с использованием обычного ответа шаблона Django для модального содержимого, отображаемого на стороне сервера.
views.py
from django.template.response import TemplateResponse

from wagtail.admin.modal_workflow import render_modal_workflow


def modal_view(request):

    return render_modal_workflow(
        request,
        'base/modal.html', # html template
        None, # js template
        {'trigger': request.GET.get('trigger')}, # html template vars
        json_data={'some': 'data'} # js template data
    )

urls.py
from django.conf.urls import url
from .views import modal_view

urlpatterns = [
    url(r'^admin/modal/', modal_view, name='modal'),
    url(r'^admin/', include(wagtailadmin_urls)),
    # ...
]

4. Настройте шаблон для отображения модального содержимого.

  • Все модальные окна используют один и тот же общий шаблон заголовка, что дает хороший способ сделать его согласованным.
templates/base/modal.html
{% include "wagtailadmin/shared/header.html" with title="Modal Title" icon="no-view" %}

<div class="nice-padding">
    <p>Modal Triggered by {{ trigger }}</p>
</div>

Другие вопросы по тегам