Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing information on how to customize the modal #49

Open
jeffreyfabrique opened this issue Oct 5, 2023 · 3 comments
Open

Missing information on how to customize the modal #49

jeffreyfabrique opened this issue Oct 5, 2023 · 3 comments

Comments

@jeffreyfabrique
Copy link

Is it possible to provide examples on how to use the modelchooser in version 4.0.1 (with Wagtail 4.1)? In the past I could easily extend the templates for showing more properties in the modal and also add a search form to it. Basically the last two steps in version 3: https://pypi.org/project/wagtail-modelchooser/3.0.0/

Thank you so much in advance!

@jeffreyfabrique jeffreyfabrique changed the title Provide more examples Missing information on how to customize the modal Oct 5, 2023
@seb-b
Copy link
Member

seb-b commented Oct 6, 2023

No worries, most of that functionality is still there, some of the templates and paths have changes so it was easier to remove that section that it was to update it. If you're considering a heavily customised chooser, I'd recommend looking further into the ChooserViewSet docs, they are very brief but once you dive into the class there's lots of customisation options.

If you wanted do the example from the old readme you could do something like this -

@register_model_chooser
class CityChooser(Chooser):
    model = City
    modal_template = 'wagtailmodelchooser/city_modal.html'
    modal_results_template = \
        'wagtailmodelchooser/city_modal_results.html'

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.GET.get('capital'):
            qs = qs.filter(capital=request.GET.get('capital') == '0')

        return qs
{% extends "wagtailmodelchooser/modal.html" %}

{% block search_fields %}
<ul class="fields">
	<li>
		<div class="w-field__wrapper">
			<label class="w-field__label" for="id_q" id="id_q-label">
				Search term
			</label>
			<div class="w-field w-field--char_field w-field--text_input">
				<div class="w-field__input">
					<input type="text" name="q" placeholder="Search" id="id_q">					
				</div>
				<div class="w-field__input">
					<input type="checkbox" name="capital">				
				</div>
			</div>
		</div>
	</li>
</ul>
{% endblock %}
{% extends "wagtailmodelchooser/results.html" %}
{% block results_listing %}
<table>
   <thead>
       <tr>
           <th>Name</th>
           <th>Is Capital</th>
       </tr>
   </thead>
   <tbody>
        {% for result in results %}
        <tr>
            <td>{{ result }}</td>
            <td>{{ result.capital }}</td>
        </tr>
  </tbody>
 </table>
{% endblock %}

Bit messy and I have no idea if this would work properly, the equivalent using the ChooserViewSet would looks something like this

# This is the 'search' view
class CityChooseView(ChooseView):
  filter_form_class = CityFilter # A filterset class that inherits from BaseFilterForm and SearchFilterMixin
  
  @property
  def columns(self):
     columns = super().columns
     return columns + [
          TitleColumn("capital", label="Is Capital?")
     ]

class CityChooserViewSet(ChooserViewSet):
  model = City  
  chooser_view_class = CityChooserView

@jeffreyfabrique
Copy link
Author

jeffreyfabrique commented Oct 6, 2023

Hey @seb-b,

Thank you for the quick response and providing an example. When I try to use the above I don't see the form though.

{% extends "wagtailmodelchooser/modal.html" %}

{% block search_fields %}
<ul class="fields">
	<li>
		<div class="w-field__wrapper">
			<label class="w-field__label" for="id_q" id="id_q-label">
				Search term
			</label>
			<div class="w-field w-field--char_field w-field--text_input">
				<div class="w-field__input">
					<input type="text" name="author" placeholder="Author" id="id_author">
				</div>
			</div>
		</div>
	</li>
</ul>
{% endblock %}
@register_model_chooser
class BlogAuthorSnippetChooser(Chooser):
    model = BlogAuthorSnippet
    modal_template = 'snippet/blog_author_modal.html'
    # modal_results_template = 'snippet/blog_author_modal_results.html'

    def get_queryset(self, request):
        qs = super().get_queryset(request)

        if request.GET.get('author'):
            qs = qs.filter(name__icontains=request.GET.get('author'))

        return qs
Screenshot 2023-10-06 at 09 12 26

These are my dependencies:
wagtail==4.1.6
wagtail-modelchooser==4.0.1

I have tried overriding the template or even use is_searchable. But I can't seem to add a custom field to it (or a new property in the list).

@jeffreyfabrique
Copy link
Author

jeffreyfabrique commented Oct 6, 2023

I managed to do it with a ChooseViewSet!

Screenshot 2023-10-06 at 11 06 02
class BlogAuthorSnippet(index.Indexed, models.Model):
    name = models.CharField(max_length=255)
    locale = models.ForeignKey('wagtailcore.Locale', on_delete=models.CASCADE, related_name='+')

    search_fields = [
        index.SearchField('name', partial_match=True)
    ]

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Blog author')
        verbose_name_plural = _('Blog authors')


class BlogAuthorChooseView(ChooseView):
    @property
    def columns(self):
        columns = super().columns

        return columns + [
            Column("locale", label="Locale")
        ]


class BlogAuthorChooserViewSet(ChooserViewSet):
    model = BlogAuthorSnippet
    choose_view_class = BlogAuthorChooseView
    choose_one_text = "Choose an author"
    edit_item_text = "Edit this author"
    form_fields = ["name", "locale"]


blog_author_chooser_viewset = BlogAuthorChooserViewSet("blog_author_chooser")


@hooks.register("register_admin_viewset")
def register_viewset():
    return blog_author_chooser_viewset

My biggest issue was that I was using filter.IndexField instead of index.SearchField(partial=True). But of course @register_model_chooser is a lot shorter and would prefer to use it like that. The only problem is that I can't seem to add a new column (in my case locale), because the listing template loops through a table instance. Which is why the example given above doesn't work anymore. If you can fix this that would be amazing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants