should i use HTMX's hx-target everywhere for my navbar ?

so i have this HTMX code in the navbar, that when you click a particular category, it fetches the data from the backend and displays it without refresh.

now the thing is if i go to some other page like “Contact-us” page, the hx-target wont be there and if i try the code from my navbar, it will throw a hx-target Error.

so that means inlcude the container everywhere ? that is not good practice yes ?

my views.py file

def home(request, category=None):
    if category:
        prods = retailer.objects.filter(category=category)
        prods = paginify_random(request, prods)
    else:
        prods = retailer.objects.all()
        prods = paginify_simple(request, prods)

    aff_id = get_affiliate_id(request)

    context = {
        "prods": prods,
        "aff_id": aff_id,
        "prods_obj": prods,
        "cat":category,
    }

    if request.htmx:
        return render(request, 'partials/all_prods.html', context)

    return render(request, 'testing/home.html', context)

my navbar HTMX code

        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Shop By Category
          </a>
          <div class="dropdown-menu" aria-labelledby="navbarDropdown">
            
            {% for cat in shop_cat_01 %}
  
            <a class="dropdown-item" href="/category/{{cat}}" 
            hx-push-url="/category/{{cat}}" 
            hx-get="/category/{{cat}}" 
            hx-trigger="click" 
            hx-target=".flexbox-container"> 
            {{cat}}</a>
  
            {% endfor %}
  
  
          </div>
        </li>

We don’t use classes for the target, we set up IDs for the target divs. Everything that gets rendered for the page goes into a named div.

The rendered template contains the div with the classes for the data being rendered.

This way, we create a separation between the structure of the page and the presentation aspects of that structure.

2 Likes

hi thanks i changed it into IDS, but still i get the same error as the ID is not in the page, so how to counter that ?

i tried using hx-boost=True, but that just kept on loading the infinite scroll in the console tab and didnt even go to the page.

and another thing about hx-boost is that i used it on a normal page for example, my contact-us page and it took me there without refresh, but the problem is that my custom CSS does not get
loaded on the page

Examine the html in the browser at each step of the way.

Start by looking at the first page received.

Look at the responses that you’re getting from the server to see what you’re getting back from your requests.

Then examine the html in the page again to understand what has been replaced.

If necessary, simplify things until you get a working prototype that is small enough for you to understand what htmx is doing.

so the CSS still does not load, when i use the htmx boost attribute,

only when i put the css with my base template then only it works.

but if i go regulary to the url without HTMX the css loads perfectly.

even in the response part of htmx i see the full page being loaded and also the css is being included, but it does not apply the styles to the page content

Everything that I’m familiar with for CSS files specifies that they must be placed in the <head> element of the page. (See <style>: The Style Information element - HTML: HyperText Markup Language | MDN)

That implies to me that you need to ensure that the new css gets injected into that section.

1 Like

Hi yes i did include them on top and then js files are followed after that.

Now one thing I noticed is that… i added hx-boost=true in the body tag of my base html itself

But now some pages like profile page load with the css but the search bar functionality does not work…

and as soon as I click the homepage, the navbar has disappeared and also footer disappeared… with only the content showing with no styles whatso ever. :frowning:

Please help, Thanks

Unfortunately, this type of situation is next-to-impossible to diagnose in the abstract. I’ve generally found that these situations are caused by one of three things:

  • Malformed HTML (~70%)
    • Duplicate ID attributes in the html
    • Closing tags not matching the opening tags
    • Elements not constructed properly
    • Elements in the wrong location
  • Elements being removed or overwritten when they shouldn’t be (~20%)
  • Everything else (~10%)

But this is why I suggest you use your browser’s developer tools to examine the html as it exists in the browser at times when things aren’t working.

1 Like

hi ok so i started from the beggining and started doing some testing, so once again

i have a contact-us page, and i want to load it without refresh, so this is waht i did and my code below

so now when i include the CSS in my base.html, the htmx works perfect, it loads the content with the styling

but as soon as i remove it from the base.html it loads without styling, so i tried different ways to load the CSS, but with no avail.

my views.py file

def contact_us(request):

    if request.htmx:
        css_url = static('testing/contact_us.css')
        print(css_url)
        html = render_block_to_string("testing/contact_us.html", "contact-us-content", {'css_url': css_url})
        return HttpResponse(html)
    return render(request, 'testing/contact_us.html')

my HTMX code in the navbar

  <a class="navbar-brand burn" href="{% url 'contact-us-page' %}" 
  hx-include="{{ css_url }}"
  hx-get="{% url 'contact-us-page' %}" 
  hx-trigger ="click"
  hx-target="#main-base-content">Contact-Us</a>

And what is the html that is returned to the browser by this request?

  html = render_block_to_string("testing/contact_us.html", "contact-us-content", {'css_url': css_url})
        return HttpResponse(html)

it returns the block content

If you’re looking for me to help diagnose this, I would need to see the actual html being returned to the browser.

hi, ok i have made a video below, please let me know if more info is needed thanks

the video shows me clicking on the EARN MONEY link on the navbar which loads the content with the css styles, as everything is centered

and then after that i go to my testing page and there i again click the link but this time it fetches the data though HTMX but with no styles

I understand what you’re describing. However, none of the information that you are providing is of any help to me trying to help you solve this problem.

I need to see the actual html that is being returned to the browser by the view.
There is no other information that is going to allow me to diagnose this.

1 Like

Oh i am really sorry… once I get back home will give you the proper info.

hi sorry i am back, so i finally found out on how to load css styles using htmx with combination of render_block_to_string

so my views.py file below succesfully returns the html with css style loaded, now i hope this is the correct of way of doing it

def earn_money(request):

    if request.htmx:
        
        **# the below load_static_code gets the {% load static %} from the html**

        load_static_code = render_block_to_string("partials/load_static.html", "static_code")

        scripts_html = render_block_to_string("testing/earn_money.html", "scripts") 

        content_html= render_block_to_string("testing/earn_money.html", "earn-money-content")

        html = f"{load_static_code}{scripts_html}{content_html}"

        return HttpResponse(html)

    return render(request, 'testing/earn_money.html')

And finally i made a function for it in my utils.py file for easy acces for other views
:slight_smile:

def earn_money(request):

    return return_my_htmx(request,"testing/earn_money.html", "earn-money-content")

    return render(request, 'testing/earn_money.html')

the return_my_htmx function below

def return_my_htmx(request,template_file_name,block_name):
    
    if request.htmx:
        
        load_static_code = render_block_to_string("partials/load_static.html", "static_code")

        scripts_html = render_block_to_string(template_file_name, "scripts") 

        content_html= render_block_to_string(template_file_name, block_name)

        html = f"{load_static_code}{scripts_html}{content_html}"

        return HttpResponse(html)

oh so now i got the CSS part settled, can you help me in the websockets part,

i can connect it succesfully via htmx, but dont know how to send messages via htmx

the docs i didnt find anything, it was only with a form tag

<div hx-ext="ws" ws-connect="/ws/justtesting/" id="websocket">
    
  
  </div>

sorry if i am taking too much of your time

That establishes the connection.

The ws-send attribute sends data through the socket. See websockets extension - </> htmx - high power tools for html to get started.

You’ll also want to become familiar with the hx-vals and hx-swap attributes along with being aware that all data coming from the server is treated as an OOB request. (Since there’s no direct relationship between a websocket frame being sent to the server and the html being returned, the browser and HTMX have no direct mechanism to associate a frame with a previous request. Therefore, all responses coming back need to identify the ID of the element being updated - or else you need to perform that logic yourself, perhaps as a custom extension.)

If you want to see an example, I did a PoC project that replaces the JavaScript in the standard Channels chat tutorial with an HTMX implementation. The code is at GitHub - KenWhitesell/htmx_channels.

1 Like

hey thanks a lot, i checked out your project and have also applied into my project, mostly the js part

is there a way to do less JS like by htmx ? for example in my code above the websocket gets established with very minimal code.

now i can send and receive message by regular JS, as i have usually done, was thinking how can HTMX do the same, with minimum JS ofcourse

thanks for your time

Please take a look at the sample project I referenced. I don’t write any JavaScript for sending or receiving websocket frames. (The custom extension is the exception to that, but not strictly speaking necessary.)