I have a base form which contains fields to be filled in by the user and a button which allows the user to add up to ten instances of a different form that is relevant to the base form (this is just dynamically adding forms through django formset). When the html is loaded the base form and all content looks great, but when I go to add a form from the formset, the CSS gets messed up because the form from the formset will neither conform to the base form CSS or any CSS I've added to it.
I've made a div to contain all forms added via the formset add button so that I can format all added forms with one CSS id. However, it seems no formatting works - the added forms' elements expand the base form's margins and seem to be floated.
HTML:
<div class="center-text jumbotron">
<h2>Incident Report Form</h2>
<form method="post" class="form-horizontal">
{% crispy incident_form %}
<div id="form_set_class">
{{ incident_formset.management_form }}
<table>
{% for form in incident_formset %}
{{form.non_filed_errors}}
{{form.errors}}
{% crispy form %}
{% endfor %}
</table>
</div>
<input type="button" id="add_def_report" value="Add Report">
<div id="empty_form" style="display:none">
{{incident_formset.empty_form}}
</div>
<input type="submit" class="btn btn-primary" value="Submit">
</form>
</div>
CSS:
.center-text{
display: block;
text-align: center;
}
form{
display: inline-block;
margin-right: auto;
margin-left: auto;
text-align: left;
}
legend {
float: left; /*allows for top margin */
border-bottom: 1px solid black;
margin-bottom: 20px;
margin-top: 20px;
}
#form_set_class{
clear: both;
display: block;
text-align: center;
}
Good Styling (image shows top part of form):
Messed Up Styling (image shows bottom part of form; the added formset starts at the "Supplier" dropdown):
I presume you have a parent and child model scenario. If that is so, then you may layout your child forms like this (laid out in tabular fashion):
<!-- ABOVE THIS WOULD BE YOUR PARENT FORMS -->
<!-- HERE WE CAN HAVE TABLE HEADER FOR THE FORMS ADDED DYNAMICALLY -->
<table class="table table-bordered table-striped table-sm">
{{ incident_formset.management_form }}
{% for form in incident_formset.forms %}
{% if forloop.first %}
<thead id="hdrID">
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<!-- HERE WILL BE THE FORMS ADDED BY THE USER -->
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
{% endfor %}
</table>
<!-- BELOW THIS WOULD BE THE FORM SUBMISSION AND THE REST -->
You may then think of applying css as per your requirements using tags (eg. hdrID shown in the code).
Related
I am working on CS50 Project 2 and have a webpage that displays active listings. I want to add some changes to the css, but it nothing happens when I add changes to the style in the head, but inline styles work. How do I make it work in the head style?
{% extends "auctions/layout.html" %}
<head>
{% block style %}
<style>
.text {
font-size: 10%;
}
</style>
{% endblock %}
</head>
{% block body %}
<h2>Active Listings</h2>
{% for listing in listings %}
<img src ="{{ listing.image }}" style = "height: 10%; width: 10%;">
<h4 class = "text" style = "color: aqua;">{{ listing.title }}</h4>
<h6>Description: {{ listing.description }}</h6>
<h6>Category: {{ listing.category }}</h6>
<h6>Price: ${{ listing.bid }}</h6>
{% endfor %}
{% endblock %}
This is the code. The font size doesn't change, but it will change colors because of the inline style.
If I add the color style to the head style, not in the inline, nothing happens. This is that code.
<head>
{% block style %}
<style>
.text {
font-size: 50%;
font-family: fantasy;
color: aqua;
}
</style>
{% endblock %}
</head>
{% block body %}
<h2>Active Listings</h2>
{% for listing in listings %}
<img src ="{{ listing.image }}" style = "height: 10%; width: 10%;">
<h4 class = "text">{{ listing.title }}</h4>
<h6>Description: {{ listing.description }}</h6>
<h6>Category: {{ listing.category }}</h6>
<h6>Price: ${{ listing.bid }}</h6>
{% endfor %}
{% endblock %}
In this code the style does not change at all.
This is the html code that is rendered.
{% block body %}
<h2>Active Listings</h2>
{% for listing in listings %}
<img src ="{{ listing.image }}" style = "height: 10%; width: 10%;">
<h4 class = "text">{{ listing.title }}</h4>
<h6>Description: {{ listing.description }}</h6>
<h6>Category: {{ listing.category }}</h6>
<h6>Price: ${{ listing.bid }}</h6>
{% endfor %}
{% endblock %}
Because this is a Django template, you can link a stylesheet stored in a static file folder. This link is a video that explains how to do it.
I would like to change the content of the row divs inside the indices_container when the screen becomes small. Currently, on all screen sizes, each row shows the index name, price, 1-day change, and ytd change. I would only like to show the index name and ytd change on small screens.
I am only using Flask and bootstrap to serve my application so I am not even sure if this is even possible without something like react and vue. Can this be done with #media or browser JS?
index.html file:
{% extends 'base.html' %}
{% block body %}
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
{{message}}
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div class="indices-container">
<div class="row">
{% for index in total_payload.get('indexes').get('meta_data') %}
<div class="col-sm-2 text-center">
{% set d = total_payload.get('indexes').get(index) %}
{{ "{} ${:.2f}".format(index, d['current_price']) }}
{{ "{:0.2f}% 1-Day".format(d['percent_change']) }}
{{ "{:0.2f}% YTD".format(d['ytd_percent_change']) }}
</div>
{% endfor %}
</div>
</div>
<div class="sp500-table-container">
<div class="table-responsive" id="sp500Table">
<table class="table table-light table-striped table-sm" id="sp500Table">
<thead class="thead-light">
<tr> {% for col in total_payload.get('companies').get('meta_data') %}
<th>{{ col }}</th>
{% endfor %}
</tr>
</thead>
<tbody> {% for num, r in enumerate(total_payload.get('companies').get('sp500companies')) %}
<tr>
<td>{{ num+1 }}</td>
<td>{{ r.get('Symbol') }}</td>
<td>{{ r.get('Security') }}</td>
<td>link</td>
<td>{{ r.get('Sector') }}</td>
<td>{{ r.get('SubSector') }}</td>
<td>{{ r.get('Headquarters') }}</td>
<td>{{ r.get('DateFirstAdded') }}</td>
</tr> {% endfor %}
</tbody>
</table>
</div>
</div>
<script>
$(document).ready(function(){
$("button").click(function(){
$("p.name-price").css("color", "red");
});
});
</script>
{% endblock %}
style.css file:
html {
font-family: Arial, Helvetica, sans-serif;
}
body {
/* padding-bottom: 80px; */
/* height: 100% */
}
main {
/* display: flex; */
/* flex-direction: column; */
/* flex-grow: 1; */
padding-bottom: 80px;
overflow: hidden;
}
footer {
padding-top: 80px;
}
.indices-container {
margin: auto;
}
.sp500-table-container {
height: 70vh;
width: 100vw;
overflow: auto;
position: relative;
padding-bottom: 16px;
margin: auto;
/* flex: 1; */
/* margin-bottom: 16px; */
}
This is done with css native Media Queries, no additional libraries needed.
It would look something like this:
#media (max-width: 400px){
.indicie-payment { display: none; }
...
}
BUT
Since you said you are already using Bootstrap, you can use some utility classes for display that are already provided by Bootstrap
In your case you would need to wrap some of your items in an element like div or span and use a utility class like d-sm-none
So it might look something like this:
<div class="indices-container">
<div class="row">
{% for index in total_payload.get('indexes').get('meta_data') %}
<div class="col-sm-2 text-center">
{% set d = total_payload.get('indexes').get(index) %}
<span class="d-sm-none">{{ "{} ${:.2f}".format(index, d['current_price']) }}</span>
<span class="d-sm-none">{{ "{:0.2f}% 1-Day".format(d['percent_change']) }}</span>
{{ "{:0.2f}% YTD".format(d['ytd_percent_change']) }}
</div>
{% endfor %}
</div>
</div>
I use this Twig code to display checkboxes (or radio) of my Symfony form:
{% for o in my_form.magic_choices %}
{{ form_row(o) }}
{% endfor %}
This generates following output for each choice:
<div>
<label for="myform_magic_choices_0">Secret option</label>
<input type="checkbox" value="secret_option" ...>
</div>
This forces checkbox input element to be after its label visually, how do i fix this to make my choice lists better? I need to make checks to be in a left side.
You could simply float the input left.
Rather than render using form_row render the item individually like..
<div class="checkbox{% if o.vars.errors|length > 0 %} has-error{% endif %}">
{{ form_widget(o) }} {{ form_label(o) }}
{% if o.vars.errors|length > 0 %}
<span class="help_block">{{ form_errors(o) }}</span>
{% endif %}
</div>
The actual Bootstrap layout using the "checkbox" class has the input element inside the label and uses a margin-left for the input so that renders correctly so you might want to override the CSS for that.
.checkbox input[type=checkbox],
.checkbox-inline input[type=checkbox],
.radio input[type=radio],
.radio-inline input[type=radio] {
// margin-left: -20px;
margin-left: 0;
}
Alternatively
You could render the label as text so that it conforms to the Bootstrap thinking like..
<div class="checkbox{% if o.vars.errors|length > 0 %} has-error{% endif %}">
<label>
{{ form_widget(o) }} {{ o.vars.label }}
</label>
{% if o.vars.errors|length > 0 %}
<span class="help_block">{{ form_errors(o) }}</span>
{% endif %}
</div>
twig
{{ form_row(o, {'attr': {'class': 'checkboxy'}}) }}
css
checkboxy {
float:left;
}
Well, this was not mentioned in Symfony Docs and this is the epic fail.
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 %}
I have this div element in the body of the html page:
<div id="alerts">
{% block alerts %}
{% try %}
{% if alerts is not None %}
{% for alert in alerts %}
<div class="{{alert.get('level', 'alert') }}">
{{ alert.get('content') }}
</div>
{% end %}
{% end %}
{% except NameError %}
{% end %}
{% end %}
</div>
that shows an alert or error in some situations.
But when I scroll down the page, this is not visible. How can show this element in the top of the page in relation with the scrolling of the page itself?
The css is this:
#alerts {
display:none;
top: 0;
left: 0;
width: 100%;
position: absolute;
z-index: 0;
}
Try position:fixed instead of absolute here's more info on positioning just in case: https://developer.mozilla.org/en-US/docs/CSS/position