Display max number of td elements in table row - html

I am using the http://www.highcharts.com/demo/gauge-speedometer on a page that dynamically renders multiple gauges. The gauges are grouped by their current level. I only want a maximum of 6 gauges in a row with any additional gauges to display on a new row.
The gauges are all working properly. However, if there are 7 gauges with a level of "red", they are flowing off the page.
My view returns a "gauge_list" which is a list of dictionaries for each gauge like this:
{'cnt': 48, 'yellow_to': 66, 'level': 'yellow', 'gauge_min': 0, 'gauge_link': 'gauges:contracts', 'green_to': 33, 'gauge_max': 100, 'gauge_title': 'contracts', 'gauge_name': 'Contracts'}
Any suggestions on the best way to handle this?
<div class="row">
<div class="span12">
<table>
{% for gauge in gauge_list %}
{% if gauge.level == "red" %}
<td><div id="{{gauge.gauge_title}}" style="width: 280px; height: 210px; margin: 0 auto"></div></td>
{% endif %}
{% endfor %}
</table>
</div>
</div>
<div class="row">
<div class="span12">
<table>
{% for gauge in gauge_list %}
{% if gauge.level == 'yellow' %}
<td><div id="{{gauge.gauge_title}}" style="width: 280px; height: 210px; margin: 0 auto"></div></td>
{% endif %}
{% endfor %}
</table>
</div>
</div>
<div class="row">
<div class="span12">
<table>
{% for gauge in gauge_list %}
{% if gauge.level == 'green' %}
<td><div id="{{gauge.gauge_title}}" style="width: 280px; height: 210px; margin: 0 auto"></div></td>
{% endif %}
{% endfor %}
</table>
</div>
</div>

I think the simplest way to do this is to either a) determine the grouped lists in the view or b) use the built-in groupby template tag. groupby requires that the list of dictionaries be arranged by the grouping key, which would be level here. That's best done in the view, since you probably don't want the naive alphabetic sorting that the dictsort filter would give you.
{% regroup gauge_list by level as level_list %}
{% for level in level_list %}
<div class="row">
<div class="span12">
<table>
{% for gauge in level.list %}
{% if forloop.counter0|divisibleby:"6" %}
{% if not forloop.first %}</tr>{% endif %}
<tr>
{% endif %}
<td><div id="{{gauge.gauge_title}}" style="width: 280px; height: 210px; margin: 0 auto"></div></td>
{% endfor %}
</tr>
</table>
</div>
</div>
{% endfor %}
By doing it in the view, I mean something like providing a nested data structure instead of a simple list. Something like:
levels_and_gauges = [['red', [...red guage dicts]],
['yellow', [...yellow guage dicts]],
['green'], [...green guage dicts]]]
The template code would then be something like this:
{% for level, guages in levels_and_guages %}
<div class="row">
<div class="span12">
<table>
{% for guage in guages %}
{% if forloop.counter0|divisibleby:"6" %}
{% if not forloop.first %}</tr>{% endif %}
<tr>
{% endif %}
<td><div id="{{gauge.gauge_title}}" style="width: 280px; height: 210px; margin: 0 auto"></div></td>
{% endfor %}
</tr>
</table>
</div>
</div>
{% endfor %}
Or you could group into 6-length rows in the view rather than the template.

{% for level in ["red", "yellow", "green"] %}
<div class="row">
<div class="span12">
<table>
{% for gauge in gauge_list %}
{% if gauge.level == level %}
<td><div id="{{gauge.gauge_title}}" style="width: 280px; height: 210px; margin: 0 auto"></div></td>
{% endif %}
{% endfor %}
</table>
</div>
</div>
{% endfor %}

Related

why is flask jinja giving me error when I use this {{bg_color}} as a background Color

this is my code i want to give different colors to comments
like grey(#eee) to odd and blue (#e6f9ff) to even
here this line is giving me error
background-color: {{ bg_color }}
{% extends 'base.html' %}
{% block content %}
<h1>{% block title %} Comments {% endblock %}</h1>
<div style="width: 50%; margin: auto">
{% for comment in comments %}
{% if loop.index % 2 == 0 %}
{% set bg_color = '#e6f9ff' %}
{% else %}
{% set bg_color = '#eee' %}
{% endif %}
<div style="padding: 10px; background-color: {{ bg_color }}; margin: 20px">
<p>#{{ loop.index }}</p>
<p style="font-size: 24px">{{ comment }}</p>
</div>
{% endfor %}
</div>
{% endblock %}
I think jinja version is updated and my course which Im following is old
so anyone who knows to answer me
You should note the scope for the variables. If you define a variable within an if-else block, it is only valid there.
<div style="width: 50%; margin: auto">
{% for comment in comments -%}
{% set bg_color = '#e6f9ff' if loop.index % 2 == 0 else '#eee' %}
<div style="padding: 10px; background-color: {{ bg_color }}; margin: 20px">
<p>#{{ loop.index }}</p>
<p style="font-size: 24px">{{ comment }}</p>
</div>
{% endfor -%}
</div>
Instead of using jinja you can also use css to assign a different background color to every other line.
<div class="comments">
{% for comment in comments -%}
<div>
<p>#{{ loop.index }}</p>
<p class="text">{{ comment }}</p>
</div>
{% endfor -%}
</div>
<style type="text/css">
.comments {
width: 50%;
margin: auto;
}
.comments div {
padding: 10px;
background-color: #e6f9ff;
margin: 20px
}
.comments div:nth-child(odd) {
background-color: #eee;
}
.comments .text {
font-size: 24px
}
</style>

bootstrap listgroup scrollspy not working, using jinja

I am working on a simple web-application with flask and am currently trying to dynamically create a scrollspy list group with jinja. In the code snippet the variable "choices" represents a list of lists of dictionaries. So the variable dict will be a list of dictionaries that populates the ids needed for the list group to work. For simplicity, I am testing it with choices containing only one list of dictionaries and loop.index to create the ids, but I was going to change that to uniquly generated ids later as choices will have more elements.
Unfortunately, the list group does not work properly. Any ideas as to what I'm doing wrong? The browser console throws me an error, "uncaught TypeError: i is null", relating to the bootstrap scrollspy.js. I was not able to trace it back and figure out what causes the error.
{% extends "layout.html" %}
{% block title %}
Results
{% endblock %}
{% block main %}
<!--course display-->
{% for i in choices %}
<div class= "container-fluid">
<div class="row justify-content-center">
<div class="col-9 heading">
<div>
<h1>Coursera Courses</h1>
</div>
</div>
</div>
<div class="row justify-content-center result-background">
<div id="list-example" class="col-2 list-group">
{% for dict in i%}
<a class="list-group-item list-group-item-dark list-group-item-action" href="#list-item-{{ loop.index }}">{{ dict["Course Name"] }}</a>
{% endfor %}
</div>
<div class="col-7">
<div class="scrollspy-example" data-bs-spy="scroll" data-bs-target="#list-example" data-bs-offset="40" tabindex="0">
{% for dict in i %}
<div class="boxlayout" id="#list-item-{{ loop.index }}">
<img src="{{ dict["Image URL"] }}" alt="responsive webite" class="img-thumbnail" align="left" width="15%" height="15%">
<h2>{{ dict["Course Name"] }}</h2>
<details close>
<summary>Lorem ipsum</summary>
Lorem ipsum
</details>
</br>
<table>
<tr>
<td>Manufacturer</td><td> </td>
<tr>
<td>Certificate</td><td>{{ dict["Certificate"] }}</td>
</tr>
<tr>
<td>Costs</td><td>${{ dict["Current Price"] }}</td>
</tr>
<tr>
<td>Landing Page</td>
</tr>
</table>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
The CSS I use as per the Bootstrap requirements:
.scrollspy-example{
position: relative;
overflow-y: scroll;
height: 300px;
}

Hide the Iframe scrollbars but still can scroll

Actually, I know that this question has been a lot even just in stackoverflow, but still, the answers I found does not work for me - lots of them are asked long ago. But however, I'm trying to put an iframe inside a web page, and it's from the same origin. The problem is, every time I scroll, these annoying scrollbars came out. I've tried to make changes like adding overflow: hidden (which makes it worse - it disables scrolling!), scrolling="no" (same as overflow, disables scrolling), and more. Is there a simple way that I can remove the scrollbar on the iframe but still can scroll it? CSS are better, but if it can be done in JavaScript at someways, it's also OK. Thanks a lot!!
Update: My code:
the parent page: (things in {%%} and {{}} are jinja templates, I use them to render the template)
<!--
#Author: Sam Zhang
#Date: 2020-04-10 20:05:53
#Last Modified by: Sam Zhang
#Last Modified time: 2020-05-06 17:01:45
-->
{% extends 'base.html' %}
{% block title %}{{ keyword }}{% endblock %}
{% block top %}{% endblock %}
{% block content %}
<nav class="navbar navbar-dark bg-primary fixed-top">
<a class="navbar-brand" href="/">Guangdu <small class="text-light">Baidu</small></a>
<form method="post" class="container-fluid" style="max-width: 60%; margin-left: 0"
action="{{ url_for('baidu.index') }}">
<div class="input-group">
<input class="form-control" name="query" value="{{ keyword }}" id="search" autocomplete="off" type="search">
<button class="btn btn-success" type="submit">Guangdu</button>
</div>
</form>
<a onclick="changeTheme()" href="" class="text-white" title="Change theme"><i class="fa fa-adjust"></i></a>
</nav>
<br><br><br><br>
<div class="iframe-wrap">
<iframe id="iframe iframe-real" onload="$(this).fadeIn(500); show()" seamless="seamless" src="{{ url_for('baidu.search_s', q=keyword, page=cur) }}" class="iframe"></iframe>
</div>
<div class="d-flex justify-content-center" id="load-container">
<div class="spinner-grow text-primary" role="status" id="load">
<span class="sr-only" id="load-sr">Loading</span>
</div>
</div>
</div>
<script>
function hide() {
$("#iframe").hide();
$("#load-container").fadeIn(500);
$("#load").fadeIn(500);
$("#load-sr").fadeIn(500);
}
function show() {
$("#load-container").fadeOut(500);
$("#load").fadeOut(500);
$("#load-sr").fadeOut(500);
}
window.onload = hide();
</script>
{% endblock %}
And my web page in the iframe:
<!--
#Author: Sam Zhang
#Date: 2020-04-10 20:05:53
#Last Modified by: Sam Zhang
#Last Modified time: 2020-05-06 17:26:20
-->
{% extends 'base.html' %}
{% block title %}{{ keyword }}{% endblock %}
{% block top %}{% endblock %}
{% block body %}id="body" style="overflow:auto;height:100%" onload="document.getElementById('body').style.width=document.body.offsetWidth+20+'px'"{% endblock %}
{% block content %}
<style>
</style>
<script>
function change(pn) {
this.parent.location.href = "{{ url_for('baidu.search') }}?q={{ keyword }}&page=" + pn;
}
</script>
{% if results %}
{% for result in results %}
{% if result.title and result.link %}
<div class="container">
{% if result.domain %}
<p class="text-success">
{{ result.domain }}
{% if result.path %}
›
{% for loc in result.path %}
{% if loop.index != result.path | length %}
{{ loc }}
›
{% else %}
{{ loc }}
{% endif %}
{% endfor %}
{% endif %}
</p>
{% endif %}
<h5 id="{{ loop.index }}h5">{{ result.title }}</h5>
{% if result.time %}<p class="d-inline text-muted">{{ result.time }} · </p>{% endif %}<p class="d-inline text-secondary text-wrap" id="{{ loop.index }}">{% if result.des %}{{ result.des }}{% else %}No description{% endif %}</p>
<hr>
</div>
{% endif %}
{% endfor %}
{% else %}
<div class="container">
<p>Keyword {{ keyword }} has np search results</p>
</div>
{% endif %}
<div class="container">
<nav>
<ul class="pagination justify-content-center">
{% if cur != 0 and cur != 10 %}
{% set url = "javascript:change(pn='" + (cur - 1) | string + "')" %}
{% else %}
{% set url = '#' %}
{% endif %}
<li class="page-item{% if cur == 0 %} disabled{% endif %}">
<a class="page-link" href="{{ url }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% if pages | length <= 10 %}
{% for i in pages %}
<li class="page-item{% if i == cur %} active{% endif %}"><a class="page-link" href="javascript:change(pn='{{ i }}')">{{ i + 1 }}</a></li>
{% endfor %}
{% endif %}
{% if cur < pages | length %}
{% set url = "javascript:change(pn='" + (cur + 1) | string + "')" %}
{% else %}
{% set url = '#' %}
{% endif %}
<li class="page-item{% if cur == pages | length - 1 or cur == 9 %} disabled{% endif %}"{% if cur == 9 %} data-toggle="tooltip" data-placement="top"{% endif %}>
<a class="page-link" href="{{ url }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</div>
{% endblock %}
Kind of a hacky solution, but this will hide the scrollbars by making the frame bigger than the container.
.outer {
width: 500px;
height: 150px;
overflow: hidden;
}
.outer iframe {
width: 520px;
height: 170px;
overflow: auto;
}
<div class="outer">
<iframe src="/"></iframe>
</div>

remove empty div and parent

Hello I have a HTML that shows all the artworks based on their collections as bellow:now, the collection "No_COLLECTION" is empty but it shows it's collection name and an empty space. I tried to remove it but i couldn't. Please help me to remove all the collections that doesn't have artworks in them.
{% extends "base.html" %}
{% load static %}
{% block content %}
<div id="main" style='min-height:800px;'>
{% with 'No_COLLECTION woodtest Test-2 Culture KASHAN HUMAN mine' as list %}
{% for i in list.split %}
<script>
var level = 0;
</script>
<div class="row" style="position: relative;margin-bottom: 30px;">
<div>{{i}}</div>
<div class="workSeriesThumbnailStrip">
{% for obj in object_list %}
{% if obj.collection == i %}
<script>
var level = level+1;
</script>
<a href="{{ obj.get_absolute_url }}"><img src="{{ obj.image.url }}"
style="float:left;width:67px;height:87px;margin:10px;" ></a>
{% endif %}
{% endfor %}
</div>
<script>
document.write(level);
</script>
</div>
{% endfor %}
<script>
if ($('.workSeriesThumbnailStrip').is(':empty')) {
$('.row').remove();
}
</script>
{% endwith %}
</div>
<div class="clear"></div>
{% endblock content %}
Add if statement. If the list is not empty, put your div inside that if statement body. else just div an empty div.

Stick the pencil on the right

I'd like to center 'Status' with the pencil on the picture :
Here is the html code :
{{ headers }}
{% load i18n admin_static material_admin %}
{% if results %}
<div class="results">
<table id="result_list" class="table bordered highlight">
<thead>
<tr>
{% for header in result_headers %}
{% if 'action_checkbox' in cl.list_display and forloop.counter == 1 %}
<th class="action-checkbox">
{{ header.text }}<label for="action-toggle"> </label>
</th>
{% else %}
<th scope="col" {{ header.class_attrib }}>
{% if header.sortable %}
{% if header.sort_priority == 0 %}
{{ header.text|capfirst }}
{% elif header.ascending %}
<i class="material-icons">arrow_upward</i>{{ header.text|capfirst }}
{% else %}
<i class="material-icons">arrow_downward</i>{{ header.text|capfirst }}
{% endif %}
{% else %}
<span>{{ header.text|capfirst }}</span>
{% endif %}
</th>{% endif %}{% endfor %}
<th style="text-align:right;" style='postion: relative; right: 500px'>{% trans "Status" %}</th>
{% if row_actions_template %}
<th style="text-align:right;">{% trans "Actions" %}</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for row in results %}
<tr class="{% cycle 'row1' 'row2' %}">
{% for item in row.cols %}
{{ item }}
{% endfor %}
<td class="material-icons">create</td>
{% if row_actions_template %}
<td class="row-actions">{% include row_actions_template with object=row.object %}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% include "loanwolf/pagination.inc.html" %}
The two important lines here are <th style="text-align:right;">{% trans "Actions" %}</th> and <td class="material-icons">create</td>. How could I modify the pencil so that it could be a little bit on the right?
I thought I could do <td class="material-icons" style='position: relative;
right: 200px'>create</td>, but it didn't work.
Thanks in advance!
P.S. Please tell me if the question is unclear.
Don't put your icons in a sub-table. Tables are not meant for layout, they're for displaying tabular data only.
Instead, apply the following to the table cell containing your action buttons:
.actions {
text-align: right;
}
Then just make your icons a list of anchor tags. I'm having to make assumptions about how your icons are structured and their classes because you didn't include the icon html:
<td class="actions">
Action1
Action2
Action3
</td>
Anchor tags are "inline" elements and will respond to text-align styles. Tables, divs, etc. are "block" elements and can't be aligned with text styles.