How use django Form with complex CSS

Hi everyone,

Here is my current case. For development, I used a UL/LI pattern for rendering a dropdown menu within a search bar.

now, the backend start to getting life and the prepopulated data become database data.

I made a very basic form for the moment, working incrementally as much as possible.

the CSS in not just plain dropdown menu.

You can check the image how it’s look like.

Here is the code of the

    and
  • <ul id="searchbar-in-dropdown-menu" role="listbox"
                                                        aria-labelledby="searchbar-in-cat-label"
                                                        class="searchbar-in-dropdown-menu">
                                                        
                                                        
                                                        {% for choice in form.categoryList %}
                                                        <!-- {{ cat.get_absolute_url }} -->
                                                        <li class="categorie-dropdown-list-item" role="option" aria-selected="false" onclick="dropdownItemSelected({{forloop.counter0}})">
                                                            <div class="categorie-dropdown-item-div" aria-expanded="false" aria-haspopup="true">
                                                                <svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" height="32" width="32"><g fill="#3e4153"><path d="M20.45 4h-5.67a.51.51 0 00-.5.5.5.5 0 00.5.5H20v5.17a3.351 3.351 0 01-.84 2.48l-8 7.9a1.76 1.76 0 01-1.25.51 1.78 1.78 0 01-1.25-.51l-4-4A2.26 2.26 0 014 14.91a2.23 2.23 0 01.66-1.59c0-.05 5.37-5.14 6.56-6.34a.481.481 0 000-.7.5.5 0 00-.71 0C9.28 7.46 4 12.54 3.91 12.6a3.26 3.26 0 000 4.62l4 4a2.7 2.7 0 002 .81 2.771 2.771 0 002-.8l8-7.94A4.32 4.32 0 0021 10.17V4.5a.5.5 0 00-.55-.5z"></path><path d="M17 10a2 2 0 10-1.41-.58A1.94 1.94 0 0017 10zm-1-2a1 1 0 112 0 1 1 0 01-2 0zM10.86 11.84l.63-.63a1.48 1.48 0 00-2-.19L9 10.5l-.49.5.51.51a1.49 1.49 0 00.13 2.06c.63.64 1.32.53 2.23.09.71-.35 1.09-.42 1.39-.12a.76.76 0 01-.06 1.16.88.88 0 01-1.37 0l-.63.62a1.61 1.61 0 002.28.15l.52.51.49-.48-.56-.5a1.53 1.53 0 00-.09-2.15c-.57-.58-1.18-.58-2.26-.06-.68.3-1 .42-1.37.08a.67.67 0 010-1 .74.74 0 011.14-.03z"></path></g></svg>
                                                                <span id="categoryId">{{ choice }}</span>
                                                            </div>
                                                        </li>
                                                        {% endfor %}
                                                    </ul>
    

    I need to turn it into Select or anything else. So when the client press the search button (rightmost button), the server will receive the selected option.

    I tried many way but Select/Option cant have extra div. The icon can’t be removed.

    the form is very simple and anything can be changed to fit the client requirement.

    The forms

    class AdsSearchForm(forms.Form):
        searchBarInput = forms.CharField(required=False, label="Que recherchez-vous ?", max_length=255, widget=forms.TextInput(attrs={"id":"main-searchbar-input-text", "class":"main-searchbar-input-text" }))
        categoryList = forms.ModelChoiceField(queryset= Categorie.objects.all(), required=False)
    

    I dont think the model pattern is relevant here. If needed I’ll post it.

    The user select any dropdown choice and then the server parse the choice.

    As you can see, actually I use an for-loop to show the choice. I can change everything on backend side and I can change everything on frontend side as long as the look remain the same.

    Thank you.

This isn’t really anything to do with Django, because it’s entirely about the front-end - you might have better luck asking elsewhere. But maybe someone can help!

My first thought is to use a <select> field by default, but use JavaScript to hide it and replace it with the HTML you have now. Then, when a user chooses an option from your list, have the JavaScript make the same <option> in the <select> be selected. So when the form is submitted that info is submitted.

It’s possible that a custom web component would help with this too, but I’m a bit out of touch, so can’t be sure.

Finally, I think a out-of-the-box solution that is very cool.

I did a Template with all the preformatted html I will want get back from the async request.
Because template support django tags it’s very convenient.

Here is an example :

{% load static %}
{% for ad in annonce %}
            <li>
                <section class="ad-card">
                    <div class="ad-card-container">
                        <div class="ad-card-image-container">
                            <span class="ad-card-img-setup">
                                <img class="ad-card-img" src="{% static 'Asset/img/iphone-se-2022-2.webp' %}"
                                    alt="test">
                            </span>
                        </div>
                        <div class="ad-side-container">
                            <div class="ad-side-ad">
                                <div class="ad-price">
                                    <p>100$</p>
                                </div>
                                <h3 class="ad-titre">
                                    <a class="ad-titre-link" href="">{{ad.titre}}</a>
                                </h3>
                                <div class="ad-detail-short">
                                    <p class="ad-detail-location">Longueuil, Rive-sud</p>
                                    <div class="ad-detail-spacer-container">
                                        <div role="separator" class="ad-detail-spacer">
                                        </div>
                                        <p class="ad-detail-elapsed">Il y a moins de 12 heures</p>
                                    </div>
                                </div>
                                <p class="ad-description-container">
                                    {{ad.description}}
                                </p>
                                <div class="showed">
                                    <div class="ad-end-filler">
                                    </div>
                                </div>
                            </div>
                            <div class="ad-extra">

                            </div>
                        </div>
                    </div>
                </section>
            </li>
            {% endfor%}

This is a template for creating card for ads web site.

Then in the view that will receive the async request:

annonce = Annonce.objects.all().order_by('-id')[:1]
            html = "async/asyncAds.html"
            context = {
                "annonce": annonce
            }

            return HttpResponse(render(request, html, context))

now your javascript receive fully html code.

Here is a basic javascript async request :

async function Fetche() {
  }
  const csrftoken = getCookie("csrftoken");
  const request = new Request("getLocalisation/", {
    method: "POST",
    headers: { "X-CSRFToken": csrftoken },
    mode: "same-origin", // Do not send CSRF token to another domain.
  });
  const response = await fetch(request);
 
  const serverInfo = await response.text();
  console.log(serverInfo);   //Here is HTML code.
  return serverInfo;
}

From there, you have fully html, parsed the exact way you want. Because your website structure will probably not change. You queryselector the parent and change the inner html with the new one.

I hope it will help many people and endind all the complains about template and Async.

You can Async template that way.