Any limitation on HTML <li>? - python

I have the following code with Python:
<div id="sidebar-wrapper" class="container-fluid" style="background-color: lightgray">
<nav id="spy" class="nav nav-pills navbar-stacked">
<ul class="sidebar-nav nav">
<li class="">
<a href="{% url 'PHIproduct' %}" data-scroll="" class="">
<span class="fa fa-anchor solo"><h3>Product List</h3></span>
</a>
<li class="">
{% for i in loop_times_product %}
<a href="{% url 'PHI' %}?id={{ i }}" data-scroll="" class="">
<span class="fa fa-anchor solo" id="{{ i }}">{{ i|safe }}</span>
</a>
{% endfor %}
<li class="">
{% for i in loop_times %}
<a href="{% url 'PHIc' %}?id={{ i }}" data-scroll="" class="">
<span class="fa fa-anchor solo" id="{{ i }}">{{i|safe}}</span>
</a> {% endfor %}
<li class="">
{% for i in loop_timesc %}
<a href="{% url 'button' %}?id={{ i }}" data-scroll="" class="">
<span class="fa fa-anchor solo" id="{{ i }}">{i|safe}}</span>
</a> {% endfor %}
</li>
</li>
</li>
</li>
</ul>
</nav>
</div>
The main purpose is to add following feature:
After I apply this code, when product A is clicked, the car and motor will not show, which means this part of code is not running:
<li class="">
{% for i in loop_timesc %}<span class="fa fa-anchor solo" id="{{ i }}">{{i|safe}}</span>
{% endfor %}
</li>
Is there any limitation on li code or am I writing the wrong code here? Can anyone help me look at this because I already spent 2 days trying to find the mistake here but have failed.

I didn't inspect your code in great detail, but one thing jumped out at me: you're nesting <li> elements directly inside each other. You can't do that; an <li> needs to be a direct child of an <ol> or <ul>.
Forget about Python for the moment and just look at a simple HTML example.
Invalid:
<ul>
<li>
One
<li>
One A
</li>
</li>
</ul>
Valid:
<ul>
<li>
One
<ul>
<li>
One A
</li>
</ul>
</li>
</ul>
There may be other problems in your code, but this is certainly one to fix.
Another tip: if you're working a suspected HTML issue like this where one of the problems may be that the generated HTML simply isn't valid, don't try to figure out everything from your Python template source code. Instead, do a View Source in the browser where you can see exactly what the browser sees.
In fact, you can do a Select All and Copy from the View Source window, and then paste into the W3C HTML Validator to see if the HTML is valid. If you're generating invalid HTML, all bets are off, so that is the first thing to check.
If you treat your server code (including templates) separately from the actual downloaded HTML that the browser sees, you'll have a much easier time debugging. The server generates HTML code; the browser parses and renders the HTML code that the server generated.

Related

django query: stuck trying to display only one instance of the model per id

I am writing a conversation module for a django app and I am failing desperately at buildin g a side menu that shows for each conversation:
the name of the recipient
the last message in the conversation
the timestamp of that last message
I am struggling to write an accurate query.
conversations = ChatRoom.objects.filter(building=building.building_id, participants__in=[user]).prefetch_related(
'participants','chat_set').order_by('-chat__timestamp')
the issue with this query is that it returns one chatroom object per message, and therefore in template the following code:
<ul class="flex flex-col space-y-1 mt-4 -mx-2 overflow-y-auto" style="height:300px">
<h2 class="my-2 mb-2 ml-2 text-lg text-gray-600">Chats</h2>
{% for convo in conversations %}
<li>
{% if convo.chat_set.last.content %}
{% for participant in convo.participants.all %}
{% if participant.id != request.user.id %}
<a href="{% url 'room' room_id=convo.id %}"
class="flex items-center px-3 py-2 text-sm transition duration-150 ease-in-out border-b border-gray-300 cursor-pointer hover:bg-gray-100 focus:outline-none">
<div class="w-10 h-10 rounded-full border-2 border-black flex justify-center items-center m-2">
<span> {{ participant.username|first|upper }}</span>
</div>
<div class="w-full pb-2">
<div class="flex justify-between">
<span class="block ml-2 font-semibold text-gray-600"> {{ participant.username }}</span>
<span class="block ml-2 text-sm text-gray-600">{{ convo.chat_set.last.timestamp}}</span>
</div>
<span class="block ml-2 text-sm text-gray-600">{{ convo.chat_set.last.content }}</span>
</div>
</a>
{% endif %}
{% endfor %}
</li>
{% for %}
{% endfor %}
</ul>
shows one line per message sent, instead of showing one line per conversation with the latest message in it.
I honestly have no clue how to modify the query on the backend (trying the dinstinct() method does not work and I dont find a way either to twick what I have in the front to only show one item per conversation.
Any help is welcome and I am available to share more info if needed.

Hide Elements within Jinja2 template? Any possible way to hide a button?

I am working on my web application using Python and Flask. I have got a navbar and some buttons on it and I would like to hide one of buttons when I am not on the index page. Is that possible? I would like the button "select brand" to be visible only on index.html page.
{% block navbar %}
<nav class="navbar navbar-expand-lg navbar-default fixed-top ">
<div class="container">
<div class="navbar-header">
<button button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" rel="home" href="{{ url_for('main.index') }}" title="Mobile phones and accessories">
<img style="max-width:40px; margin-top: -9px;"
src="http://www.logospng.com/images/38/devfest-2016-38885.png" >
</a>
</div>
<div id="navbar" class="collapse navbar-collapse navbar-responsive-collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
{% if current_user.is_authenticated and current_user.admin %}
<li>Add phone</li>
<li>Add brand</li>
{% endif %}
<li class="dropdown">
Select brand <span class="caret"></span>
<ul class="dropdown-menu">
{% for brand in brands %}
<li class="list-group-item">
{{ brand }}
{% endfor %}
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated %}
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<span class="glyphicon glyphicon-user"> </span> {{ current_user.username }}
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('auth.logout') }}" >Logout</a></li>
</ul>
</li>
{% else %}
<li><a class="nav-link" href="{{ url_for('auth.login') }}" >Login</a></li>
<li><a class="nav-link" href="{{ url_for('auth.register') }}" >Register</a></li>
{% endif %}
</ul>
<form class="navbar-form navbar-right" method='POST' action="{{ url_for('phones.search') }}">
<div class="form-group">
<input class="search-query form-control" placeholder="Search..." aria-label="Search" type="text" name="search">
</div>
</form>
</div>
</div>
</nav>
{% endblock %}
Create a new variable within your index route and pass that variable into the render_template method of said route. The presence of this variable will determine if the <button> or link within your <nav> should be rendered or not. Since the <nav> will be shared across all other layouts, its HTML code should be put within your base layout, or the layout which all other views are inheriting from.
Something along the lines of:
index route:
#app.route("/")
def index():
# isIndex is the variable we will use to determine
# whether or not to render your navigation link or button
return render_template('index.html', isIndex=True)
base layout file:
<div class="navbar-nav">
{% if isIndex %}
<a class="nav-item nav-link" href="">linkOnlyForIndexPage</a>
{% else %}
<a class="nav-item nav-link" href="">link1</a>
<a class="nav-item nav-link" href="">link2</a>
{% endif %}
</div>
This is exactly what you're already doing with {% if current_user.is_authenticated %} for your navigation links. The reason this works is because the index route is the only route which sets this variable, within your jinja2 templates, so all other routes which render corresponding views will default to false on this conditional check: {% if isIndex %}
Hopefully that helps!
I think this will work.
Set the following on your child pages:
{% set active_page = "index" %}
Then in your base template:
{% if active_page == "index" %}
... button html here
{% endif %}

How to know which ad was clicked and send that data to a singles page

I'm practicing with a flask website that is sort of a mock classifieds website. On a browse page, I am displaying all results for whatever a user searches for. How can I track which ad was clicked by the user so I can redirect them to a 'singles' page where it will show in greater detail the item they clicked on...?
My first instinct was to use sessions, but I just couldn't quite figure out the logic. I am rendering the data dynamically, where in the HTML template, data contains all the query results:
<ul class="list">
{% for row in data %}
<a href="/iLike/">
<li>
<img src="{{ url_for('static', filename='images/logo.png') }}"
title="" alt=""/>
<section class="list-left">
<h5 class="title">{{ row[1] }}</h5>
<p class="catpath">
<Strong>Condition</strong>: {{ row[3] }}</p>
<p class="catpath"><Strong>details</strong>: {{ row[2] }}</p>
<p class="catpath"><strong>Looking for</strong>: {{ row[5] }}</p>
</section>
<section class="list-right">
<span class="date">{{ transType }}</span>
</section>
<div class="clearfix"></div>
</li>
</a>
Add some argument to link - ie href="/iLike/?ad_number=1" or href="/iLike/1" (second version needs argument in route/function)

how to change batch argument dynamically in jinja template depending on device size

I have the below bootstrap panels, three col-xs-4 per row rendered in a jinja template, and it looks super nice on a desktop.
but when trying smaller devices it get ugly. so I want to know if there is a way to change the batch argument to 1 per row under a certain device size ?
or maybe there is a better approach, I'm very open as I'm very new to this :)
<div class="container-fluid">
{% for raceorganizers in res.keys() | batch(3, ' ') %}
<div class="row">
{% for raceorganizer in raceorganizers %}
<div class="col-xs-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ raceorganizer.name }}<span
class="text-right pull-right flag-icon flag-icon-{{ raceorganizer.country_code }}"></span>
</h3>
</div>
<div class="panel-body panel-image">
<img class="panel-image-preview"
src="{{ url_for('static', filename='img/full/' + im ) }}" alt='{{ im }}'>
</div>
<div class="panel-footer">
{% for race in res[raceorganizer] %}
<ul class="list-unstyled">
<li>
<span class="glyphicon glyphicon-road"></span>
<span class="badge">{{ '{:.1f}'.format(race.distance_number) }}</span>
<span class="flaticon-mountain40"></span>
<span class="badge">{{ '{:.0f}'.format(race.elevation_number) if race.elevation_number is not none else '-' }}</span>
</li>
</ul>
{% endfor %}
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
If you look more closely at bootstrap's grid system, you could completely get rid of the batch call. If you play with different tiers of classes (col-xs for phones+, col-md for desktops+) on the same element, you will be able to get bootstrap to split the content into 3 columns on desktops and 1 on smaller screens.

How to debug strange artefacts in django template?

I'm using django template to render my hierarchical tree in a web page. In the process of rendering of a tree I see these strange whitespaces between nodes:
Here is my recursive template:
index.html:
<ul class="Container">
<li class="IsRoot">
<div class="Expand">
</div>
<div class="Content">
Содержание
</div>
</li>
{% include 'list.html' with data=list %}
</ul>
and list.html (as a recursive part):
<ul class="Container">
<li class="Node ExpandClosed">
<div class="Expand"></div>
<div class="Content">
<a href="/help/{{data.name}}">
{{data.content}}
</a>
</div>
{% for item in data.decendent %}
{% include 'list.html' with data=item %}
{% endfor %}
</li>
</ul>
How to debug what's the matter with this template and in what period of time it happens? As you can see, I don't generate any whitespaces in this template.
The white space is not the problem, and it is not causing the spaces in your rendered tree. The reason for that appears to be that you are nesting ul elements directly inside uls, which isn't strictly speaking valid: they should be inside lis.

Categories

Resources