Modal forms with Django+HTMX

Поделиться
HTML-код
  • Опубликовано: 3 июн 2024
  • This video shows how to use HTMX to show Django forms in modal dialog boxes.
    The solution presented here requires very few JavaScript lines, renders form errors nicely, and refreshes the main page on success.
    The following blog post contains a condensed version of this video:
    blog.benoitblanchon.fr/django...
    The following GitHub repository contains a complete project demonstrating the technique:
    github.com/bblanchon/django-h...
    See also the follow-up video that shows how to display a toast: • Toasts with Django+HTMX
    Contact me on Codementor for live 1:1 mentoring:
    www.codementor.io/@bblanchon
    Table of Contents:
    00:00 - Introduction
    01:26 - Presentation of the original project
    03:30 - Tour of the initial code
    08:18 - import HTMX's JavaScript
    08:53 - Lazy load movie list
    15:53 - Add a placeholder for the dialog
    17:40 - Change form's CSS
    19:11 - Move the form
    21:52 - Show the dialog
    28:06 - FIx dialog's Cancel button
    29:24 - Perform POST request with HTMX
    31:52 - Return an empty response on success
    34:29 - Hide the dialog
    42:01 - Update movie list on success
    45:25 - Reset the dialog's content
    50:28 - Support status 200
    52:58 - Recap
  • НаукаНаука

Комментарии • 98

  • @Flechashe
    @Flechashe 3 дня назад

    This is exactly what I was looking for, thank you so much. It gets a bit complex so thank you for explaining it in a simple and detailed manner. Great content.

  • @russf
    @russf 2 месяца назад +1

    Excellent! Thanks Benoit. I love your style. You are very confident and you go right to the issue. I love the way you left your little mysteries in the video, and took time to solve them. Thanks again!

  • @ColinVarney
    @ColinVarney 2 года назад +3

    You're awesome! Literally have been looking this up for the past week on getting it implemented in a project! Thank you so much Benoit! 🙏🙏

    • @BenoitBlanchon
      @BenoitBlanchon  2 года назад +1

      Thanks, Colin. It took me a while to find this pattern :-)
      Let me know if you have any difficulty implementing it.

  • @etiennecoppel9013
    @etiennecoppel9013 Год назад +1

    J'ai galéré à mettre en place mon formulaire dans un modal et que tout fonctionne parfaitement, jusqu'à que je tombe sur ta vidéo! Une perle! Merci beaucoup pour l'aide!

  • @GavinElie
    @GavinElie Год назад +3

    Very nice tutorial. Highly appreciated. Keep up the good work!! 👍

  • @thomasdb6126
    @thomasdb6126 Год назад +1

    Merci Benoit pour ce tuto parfait!

  • @yeboahdominic1896
    @yeboahdominic1896 2 года назад +1

    That's great, do more of this django+htmx in the coming future.

  • @pau1phi11ips
    @pau1phi11ips 4 месяца назад

    Thanks a lot. I actually needed it for PHP but it's close enough to understand how it works
    😁👍

  • @isaacjpg
    @isaacjpg 2 года назад

    Thank you very much for your video! I will try with my Django projects

  • @ADPenrose
    @ADPenrose 3 месяца назад

    What a great video! I actually implemented modals using django + htmx + tailwindcss this week and I'm surprised that my approach was really close to this one haha! Also, thanks for the heads up on how to listen for events. I kid you not I was just thinking about it this afternoon haha. Merci beacoup!

  • @StonedApe420
    @StonedApe420 Год назад

    I realy like video edit at the beggining of video, explanation is great. I wonder why so few videos on your channel. I would like to see more of Python, Django and particulary HTMX Tutorials from you. Keep up the god work.

  • @AdamMalesevic
    @AdamMalesevic 6 месяцев назад

    This tutorial is awesome! I've been looking for something like this so I could catch up with HTMX in Django. This is the perfect approach as many of us Django developers are looking for a way to integrate HTMX in our existing Django code. This could be easily renamed as a Django + HTMX tutorial as it would help people find appropriate content for starting with HTMX (in combination with Django)
    Thanks!

  • @rogeriodacosta5805
    @rogeriodacosta5805 Год назад +1

    Great job. I'm making a project with django+htmx+bulma based in your tutorial. I found only one problem: My modal dialogs don't keep open if found form validation errors (like unique=True field). The modal closes and the error is displayed in a partial form page with no css. Do you know how to keep the dialog open?

  • @AlexeyDzuba
    @AlexeyDzuba 5 месяцев назад

    Hi bro! Want to say thank you for your article based on this video. Artice is preffered for me and that awesome!

  • @s_houdini_
    @s_houdini_ 9 дней назад

    Thank you, the tutorial is very nice.

  • @islamimankhodzhaev543
    @islamimankhodzhaev543 9 месяцев назад

    Thank you, Master!

  • @angeatgr
    @angeatgr 3 месяца назад

    Merci Benoit !

  • @vivaldi-qo7xj
    @vivaldi-qo7xj Год назад

    htmx in very useful for django. thnx for all

  • @Youdude2
    @Youdude2 2 года назад

    Thanks for this! Been struggling with htmx modal forms for a week

    • @BenoitBlanchon
      @BenoitBlanchon  2 года назад

      You're welcome! Let me know if you have any remarks.

    • @Youdude2
      @Youdude2 2 года назад

      @@BenoitBlanchon Can you also show how to display success messages when movie added without page refresh? My success messages are now only showing when I click refresh

    • @BenoitBlanchon
      @BenoitBlanchon  2 года назад

      @@Youdude2, I'll try to make a follow-up for this video.

    • @skumpuntele8941
      @skumpuntele8941 2 года назад

      @@BenoitBlanchon Came here to ask the same question. I already have a custom middleware that will add messages to the context when using HTMX requests but only when request object is added to the returned response. It works fine when returning TemplateResponse or render() but it doesn't with HttpResponse so some kind of workaround is needed.

    • @BenoitBlanchon
      @BenoitBlanchon  2 года назад

      Here is the follow-up: ruclips.net/video/pAtrj8A-Kl4/видео.html

  • @forregisters2230
    @forregisters2230 Год назад

    Hello, the course is very good. The problem was that after applying the changes, the pagination no longer works. How can this be fixed?
    Very grateful, best regards.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    I have reached 3:00 in this video so far. I will watch more soon.
    *Goal:* Show a Modal Form when a button was tapped, and the modal form has 3 buttons.
    When one of the buttons are tapped, then send the data to a queryset [ update an existing queryset ]. At last redirect to a url that are different.

  • @innerthreatcircus5651
    @innerthreatcircus5651 29 дней назад

    It would be amazing to see examples of multiple modals stacked. Natively bootstrap doesn't support it but I've seen people doing very small tweaks to make it happen. This way we could add intermediary fields and populate the previous modal with the just added record creating the only (IMO) usable experience for forms. But struggling to make this. Thanks a lot for this video anyway.

  • @motowhiz1
    @motowhiz1 2 года назад +1

    Can you please give an example using datatables?

  • @peterholzer98
    @peterholzer98 4 месяца назад

    Awesome. I have used this method in several projects now. Benoit, could you do the same with the HTML tag as well? I need bigger dialog form than bootstraps Modal. Or is theere any other way?

    • @BenoitBlanchon
      @BenoitBlanchon  4 месяца назад

      You can use the same technique with a , you just need to call dialog.showModal() and dialog.close() in the event handlers.

  • @kapitankidlattv9613
    @kapitankidlattv9613 Год назад

    I followed to the T but the modal is not popping up, if I inspect it it's there and everything loads up :(

  • @ayubkara1092
    @ayubkara1092 2 года назад

    you're the best

  • @master4755
    @master4755 5 месяцев назад

    can something like this be done without javascript

  • @zongomathieu8252
    @zongomathieu8252 Год назад

    Awesome!!! But I have this error : TypeError: __init__() got an unexpected keyword argument 'headers'

  • @Wonganm
    @Wonganm Год назад

    Very Nice tutorial. Highly appreciated. Can the same be done using crispy forms

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад

      I don't see any reason why this would not work with Crispy Forms.

  • @garidodo272
    @garidodo272 Год назад

    I have an image field included in the modal form. In the template, I added the attribute hx-encoding="multipart/data-form" in the element. And in the view, I added request.FILES when declaring the form such that form = ProductForm(request.POST, request.FILES). However, when I tried to upload an image for the product using the modal form, and click on save, the image field has an empty value, and the image was not uploaded to the MEDIA_ROOT as defined in the settings. I got "204 No content" in the terminal/console.
    It works fine using the admin page. Any thoughts?

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад

      Is it possible that you forgot to add the file field in the ModelForm?
      Here is a fully functional example: github.com/bblanchon/django-htmx-modal-form/tree/bootstrap4-file-upload
      The 204 is expected since that's the way we tell the front end to hide the modal.

    • @garidodo272
      @garidodo272 Год назад

      @@BenoitBlanchon thanks, i forgot to include request.FILES in the product_edit view.. thanks much

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    I saw at 53:00 it says *Modal from,* same thing I keep doing is using *form* when it should be *from,* and *from* when it should be *form.*

  • @garidodo272
    @garidodo272 Год назад +1

    Very nice reusable modal + htmx combo.. However, if you could make refinements such that when the user edited a movie, only the table row containing that movie will be updated, not necessarily refreshing all rows, e.g. instead of movieListChanged event in , it should be something like movieRowChanged event for . Is this possible?

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад

      You could change this event to be "movieChanged" and include some information about the movie in the event's payload.
      For example, you could include the movie id or its URL so that HTMX can fetch the row from the backend; however, this requires adding a new view in Django.
      Alternatively, you could include all the movie information in the payload and add some JS code to update the row. However, it means that you now have two pieces of code that know how to render a movie row: one in the Django template and another in JavaScript.
      Honestly, this optimization isn't worth the effort: the performance improvement is marginal, but the damage to the code is significant.
      If your table is too big, use pagination. If pagination is not applicable for some reason, I recommend that you forget about this Django + HTMX pattern and fall back to a more classic JS Frontend + REST backend approach.

    • @garidodo272
      @garidodo272 Год назад

      @@BenoitBlanchon "Honestly, this optimization isn't worth the effort: the performance improvement is marginal, but the damage to the code is significant." - thank you for this.. I have actually tried to refine your code but was stuck.. so i think will have to rebirth..

    • @garidodo272
      @garidodo272 Год назад

      I tried using your technique with datatables but it seems unstable - sometimes the datatable will work, sometimes not.. If i build the datatable in a single page, it will work as expected.. but when i inject the partial list via the , the datatable becomes unstable. I also tried to build the complete datatable in the list.html, replaced the targeted with a in the index.html but still doesn't work.

  • @serkangulten
    @serkangulten 2 года назад

    perfect

  • @trash2treasure786
    @trash2treasure786 2 года назад

    Thanks for this informative video,
    is it possible to create an Excel-Like data entry table with htmx in Django?
    if possible create a video for us on that

    • @BenoitBlanchon
      @BenoitBlanchon  2 года назад +1

      No, I don't think it's possible to do that with HTMX.
      To create a data grid, you need to use a JavaScript library, like grid.js.

  • @fullofmysteries
    @fullofmysteries Год назад

    Every time a new modal is opened the background goes darker and darker. Is there a way to have the same background, even after opening and closing multiple modals?

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад

      The sample code doesn't have this problem: github.com/bblanchon/django-htmx-modal-form
      Ensure you're swapping the "modal" and not the "dialog".

  • @officialkhusus48
    @officialkhusus48 3 месяца назад

    Hello sir,
    Please your add post description htmx ckeditor

  • @yousefpahang
    @yousefpahang 2 года назад

    Thanks its perfect !! I added pagenation and each time that I click the next page, it will reload the same page. Any idea how to solve it ?

    • @BenoitBlanchon
      @BenoitBlanchon  2 года назад

      You can probably fix this issue with "hx-vals": htmx.org/attributes/hx-vals/

    • @yousefpahang
      @yousefpahang 2 года назад

      @@BenoitBlanchon not so familiar with it. maybe in your future video you can make whole package of datatables.net + pagenation 😎

  • @z3r0krypt
    @z3r0krypt Год назад

    In the select input the first option is something like "------------", that's quite annoying for me, do you know how could i change this first option to a personal message and make it hidden, selected and so?

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад +1

      docs.djangoproject.com/en/4.0/ref/forms/fields/#django.forms.ModelChoiceField.empty_label

    • @z3r0krypt
      @z3r0krypt Год назад

      ​@@BenoitBlanchon Thanks man, now i can edit the select option text but i'm getting mad about to set some attributes like hidden, the empty_label is visible and can't figure it out how to make it hidden.
      Anyways, my modal form renders the entire object list inside the same modal when i click ok to create a new entry, any idea about it too? i'm going mad about that.
      Sorry to bother you but i'm quite new on django, i'm trying to understand this process for one of my class exercises.

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад

      I'm sorry, @@z3r0krypt, but RUclips is not the right place for this type of assistance. If you want, I provide live mentoring at a very affordable price here: www.codementor.io/@bblanchon

  • @heathergray4880
    @heathergray4880 Год назад

    Can't figure out how to keep the modal from closing when clicking outside of it. data-backdrop="static" in the modal div does not work :(

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад +1

      On Bootstrap 5, it's data-bs-backdrop="static"

    • @heathergray4880
      @heathergray4880 Год назад

      @@BenoitBlanchon thank you so much!! You saved my day :)

  • @reelsergealain
    @reelsergealain Год назад

    You make really great tutorials so I don't understand why you stopped making videos but I want you to do a blogging theme with HTMX if possible

  • @serychristianrenaud
    @serychristianrenaud 10 месяцев назад

    Thank

  • @jorgeramiroalarconvargas2580
    @jorgeramiroalarconvargas2580 2 года назад

    Awesome info about modals Thanks for the time and effort invested. I have to ask you. could you pls teach how to make two or three related dropdowns using HTMX using Django.

    • @BenoitBlanchon
      @BenoitBlanchon  2 года назад +1

      I'm using dependent/cascaded dropdowns/selects in my applications, but I still haven't found a satisfying solution. Be sure that I'll make a video once I find a clean and reusable technique.

    • @jorgeramiroalarconvargas2580
      @jorgeramiroalarconvargas2580 2 года назад

      @@BenoitBlanchon thanks man any hel is really appreciated, the best tutorial about modal forms in django and htmx.

    • @jorgeramiroalarconvargas2580
      @jorgeramiroalarconvargas2580 2 года назад

      @@BenoitBlanchon ers un genio carajo!!! You are a genius fuckk!!!

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day: 2.*
    So I ended at 4:01 today. Since I paused the video, and made my own *model.*

  • @djuliano4912
    @djuliano4912 2 года назад

    thx

  • @isaacsamuel1689
    @isaacsamuel1689 Год назад

    Benoit!, thank you very much for this great video. I have been watching it carefully for some days now. But I have a challenge.
    If there is an error on a popup page, where user_form.is_valid() is not valid and you return HttpResponse(status=204), how do you show the error message back to the user.
    If I return redirect() to a template the error messages show.
    Kindly help redirect me to a video that shows how to do this.
    Thanks.

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад

      If the form is invalid, you must render the page as usual:
      github.com/bblanchon/django-htmx-modal-form/blob/0c5246dc24c719dbdc07e511b807ef583eb33f68/movie_collection/views.py#L25

  • @z3r0krypt
    @z3r0krypt Год назад

    Don't know why but my views and urls are ok, i did the hx-get on tbody like you but can't get my info, i'm quite lost, checked everything, no error anyways and i can't take my data. Checked the network tab and nothing comes.

    • @z3r0krypt
      @z3r0krypt Год назад

      Oh man forget about that, sorry mate i'm super dumb in this hours of day, it's quite late here and my brain broken up, it was my fault, copy paste mistake when tried to get the script. You're making my day anyways with this video, thanks! :)

    • @SamSam-rq5fw
      @SamSam-rq5fw Год назад

      @@z3r0krypt I am having thesame issue but i have look at the code again no errors. Please how did you resolve yours. I ahve also change the version of htmx to hmtx@1.6.1 but it dont return the list

  • @basilhaffar3129
    @basilhaffar3129 8 месяцев назад

    when using htmx to load "movie list" instead of "{% include ...etc%}" the size is increase too much, you can see the difference if the database have 1000 records for example.

  • @wiki-infodevelopment3369
    @wiki-infodevelopment3369 10 месяцев назад

    very good and useful method, but if you have a file to load it will not be a works.
    normal form use "multipart/form-data" to load files and the HTMX don't support it?

    • @BenoitBlanchon
      @BenoitBlanchon  10 месяцев назад

      You can upload files with this technique. See: github.com/bblanchon/django-htmx-modal-form/commit/f7b86fec9e47937d71d73ac28ea2b13953b9f8db

  • @delsananthony.official
    @delsananthony.official Год назад

    Django and htmx is match made in heaven. Since I find django being too dependent to the anchor tag for triggering transactions.

  • @user-ug1su3kf8t
    @user-ug1su3kf8t 11 месяцев назад

    I'm Ngoc, from Vietnam.
    I thank you sir. You are really great tutorials Great, very helpful. How to upload files, image file on modal- HTMX. ???? Thank you

    • @BenoitBlanchon
      @BenoitBlanchon  11 месяцев назад

      I didn't try but it should work as a regular Django view. As usual, don't forget to add enctype="multipart/form-data" to the form. Please refer to the official documentation for more information: docs.djangoproject.com/en/4.2/topics/http/file-uploads/

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 3.
    So I ended at 5:20 today.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 1.
    So I ended at 4:00 today.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 5.
    So I ended at 20:10 today.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 6.
    So I ended at 21:40 today.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 10.
    So I ended at 48:00 today.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 9.
    So I ended at 37:00 today.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 8.
    So I ended at 31:40 today.

  • @garidodo272
    @garidodo272 Год назад

    If using CVB, how can we add to the header the movieListChanged event? like this one in your FBV..
    headers={
    'HX-Trigger': json.dumps({
    "movieListChanged": None,
    "showMessage": f"{movie.title} edited."
    })
    })

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад

      I stopped using CBV years ago, so please forgive me if my answer isn't accurate. If you're deriving from FormView, you can simply override the form_valid() method and return the HttpResponse object shown in the video. If you're not using FormView, you'll have to override post() and do something similar.

  • @sumiyaaltangerel8280
    @sumiyaaltangerel8280 Год назад

    Dear im triying to fix this issue in whole week. Can you solve this on bootstrap v5.2
    bootstrap.bundle.min.js:6 Uncaught TypeError: Cannot read properties of undefined (reading 'backdrop')
    at Ni._initializeBackDrop (bootstrap.bundle.min.js:6:52003)
    at new Ni (bootstrap.bundle.min.js:6:50880)
    at dialog.js:2:17
    at dialog.js:16:3

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    The form doesn't load for me when I submit the form, I need to refresh the page to see the change:
    views . py
    *return HttpResponse(*
    *status=204,*
    *headers={*
    *'HX-Trigger': json.dumps({*
    *"profileListChanged": None,*
    *})'*
    *},*
    *)*
    home . html
    **

    • @derekkroeker4582
      @derekkroeker4582 Год назад

      *Solution Time:* It should be *from:body,* not *form:body.* I just read it now on the videos subtitles, and I was thinking; " I wrote *form:body,* maybe if I change it to *from:body* it will work ", and it did.
      43:00, subtitles at the end

    • @BenoitBlanchon
      @BenoitBlanchon  Год назад +1

      Check the network tab to make sure the 204 is actually returned.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 4.
    So I ended at 14:30 today.

  • @derekkroeker4582
    @derekkroeker4582 Год назад

    *Day:* 7.
    So I ended at 28:50 today.