I am building a garage controller using Raspberry Pi with a Flask Server on it. Everything is working as expected except the fact that I still need to figure out how to automatically update the GPIO pin status and refresh the html page to open/close automatically.
I have attached my code below, any help would be appreciated.
The refresh status button you see right now is a workaround I created to refresh the page. But I am looking for something to refresh the page automatically per PIN status change.
Flask Code
import time
from datetime import datetime
from flask import Flask, render_template, request
import RPi.GPIO as GPIO
import logging
app = Flask(__name__)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.IN, GPIO.PUD_UP)
GPIO.setup(7, GPIO.OUT)
#app.route("/", methods=['GET', 'POST'])
def Status():
if GPIO.input(16) == GPIO.LOW:
app.logger.info('Gate is Closed')
return render_template('Closed.html')
elif GPIO.input(16) == GPIO.HIGH:
app.logger.info('Gate is Open')
return render_template('Open.html')
#app.route("/Open", methods=['GET', 'POST'])
def Open():
GPIO.output(7, True)
app.logger.info('Gate is Opening')
return render_template('Open.html')
#app.route("/Closed", methods=['GET', 'POST'])
def Closed():
GPIO.output(7, False)
app.logger.info('Gate is Closing')
return render_template('Closed.html')
if __name__ == "__main__":
app.run()
HTML Code for Closed
<html>
<head>
<meta name="viewport" content="width=device-width">
<!--<meta http-equiv="refresh"
content="1; url = /" />-->
<!--<link rel="stylesheet" type="text/css" href="stylesheet.css">-->
<style>
.switch {
vertical-align: middle;
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.button {
color: #fff !important;
text-transform: uppercase;
text-decoration: none;
background: #000;
padding: 10px;
border-radius: 5px;
display: inline-block;
border: none;
transition: all 0.4s ease 0s;
}
.sliderWrapper{display: inline-block;margin:24px 24px 24px 24px;position:relative;}
.sliderWrapper div{display: inline-block;line-height:60px;}
</style>
<script type="text/javascript">
setTimeout (
function() { window.location.reload(); },
500
)
</script>
</head>
<body bgcolor="#ff5c33">
<center>
<br>
<h1>Gate Control</h1>
<br><br> <br> <br>
<h3>Use the toggle to Open/Close the Relay!</h3>
<form action="/Open">
<div class="sliderWrapper">
<div>Close </div>
<label class="switch">
<input type="checkbox" onclick="submit();">
<span class="slider round"></span>
</label>
<div> Open </div>
</div>
</form>
<div class="refresh">
<br><br>
<h3>Use the button to Refresh the Page/Status!</h3>
Refresh
</div>
</center>
</body>
</html>
HTML Code for Open
<html>
<head>
<meta name="viewport" content="width=device-width">
<!--<meta http-equiv="refresh"
content="1; url = /" />-->
<!--<link rel="stylesheet" type="text/css" href="stylesheet.css">-->
<style>
.switch {
vertical-align: middle;
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.button {
color: #fff !important;
text-transform: uppercase;
text-decoration: none;
background: #000;
padding: 10px;
border-radius: 5px;
display: inline-block;
border: none;
transition: all 0.4s ease 0s;
}
.sliderWrapper{display: inline-block;margin:24px 24px 24px 24px;position:relative;}
.sliderWrapper div{display: inline-block;line-height:60px;}
</style>
<script type="text/javascript">
setTimeout (
function() { window.location.reload(); },
500
)
</script>
</head>
<body bgcolor="lightgreen">
<center>
<br>
<h1>Gate Control</h1>
<br><br> <br> <br>
<h3>Use the toggle to Open/Close the Relay!</h3>
<form action="/Closed">
<div class="sliderWrapper">
<div>Close </div>
<label class="switch">
<input type="checkbox" checked onclick="submit();">
<span class="slider round"></span>
</label>
<div> Open </div>
</div>
</form>
<div class="refresh">
<br><br>
<h3>Use the button to Refresh the Page/Status!</h3>
Refresh
</div>
</center>
</body>
</html>
You are running into how HTTP works in the classic client server way.
Your client in the front end request something from your server
if the requested resource/page is available the server responds. and sends it back to client.
Done
The above request/response cycle explains why your refresh button is needed.
In the past one way to work around this was to run some javascript/JQuery in the front end and periodically refresh the page (AJAX/long polling) And that will still work.
By now there are other ways too, for example use a (web)sockets to create a bi directional channel in which the server can push data to the client. Working around the problem you have with classic request/response. (Flask Socket IO for example)
Both ways are worth researching, but javascript to periodically poll will probably be the quickest if not the prettiest fix.
Related
This question already has answers here:
Link to Flask static files with url_for
(2 answers)
Closed 2 years ago.
I am making a 404 error page, I have made an HTML file and An CSS file but it's not working. The file is in same directory, Can anyone Help Me? Please. Thanks
I am trying this for days, no fixes. Thanks ! Any help is appreciated.
Below You can see code.
My Html Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./style.css">
<title>Awesome 404 Error Page Design - Vikas Kukreti</title>
<meta name="keywords" content="404, error, 404 error, 404 error page design, design, html, css, Vikas, Vikas kukreti" />
<meta name="description" content="Awesome 404 error page design for 404 errors including cool looks and animations with HTML and CSS only. Developed with love ❤ by Vikas Kukreti" />
</head>
<body>
<div id="particles" class="particles">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<main>
<section>
<h1>Page Not Found!</h1>
<div>
<span>4</span>
<span class="circle">0</span>
<span>4</span>
</div>
<p>We are unable to find the page.<br>you're looking for.</p>
<div>
<button>Back to mHome Page</button>
</div>
</section>
</main>
</body>
</html>
My CSS Code:
* {
padding: 0;
margin: 0;
}
body {
background: radial-gradient( circle, rgb(28, 27, 90) 0%, rgb(15, 18, 44) 30%, rgb(15, 13, 31) 100%);
height: 100vh;
color: #efefef;
}
.particles {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.particles span {
position: absolute;
top: 10%;
left: 10%;
display: block;
content: '';
width: 6px;
height: 6px;
background: rgba(255, 255, 255, 0.6);
border-radius: 0.5rem;
filter: blur(5px);
}
.particles span:nth-child(2) {
top: 15%;
left: 70%;
filter: blur(3px);
}
.particles span:nth-child(3) {
top: 70%;
left: 40%;
filter: blur(5px);
}
.particles span:nth-child(4) {
top: 52%;
left: 20%;
filter: blur(4px);
}
.particles span:nth-child(5) {
top: 74%;
left: 90%;
filter: blur(5px);
}
.particles span:nth-child(6) {
top: 85%;
left: 10%;
filter: blur(7px);
}
.particles span:nth-child(7) {
top: 67%;
left: 79%;
filter: blur(3px);
}
.particles span:nth-child(8) {
top: 48%;
left: 40%;
filter: blur(4px);
}
.particles span:nth-child(9) {
top: 45%;
left: 30%;
filter: blur(5px);
}
.particles span:nth-child(10) {
top: 96%;
left: 29%;
filter: blur(4px);
}
.particles span:nth-child(11) {
top: 55%;
left: 89%;
filter: blur(6px);
}
.particles span:nth-child(12) {
top: 55%;
left: 60%;
filter: blur(7px);
}
main {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-family: cursive;
}
main h1{
font-weight: normal;
}
main h1 {
text-align: center;
text-shadow: 0 0 5px #c3d168a2;
}
main div {
margin-top: 2rem;
text-align: center;
}
main div span{
font-size: 5rem;
line-height: 6rem;
text-shadow: 0 0 7px #c3d168a2;
}
.circle {
user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
display: inline-block;
position: relative;
width: 6rem;
height: 6rem;
text-shadow: none;
background: #e6f1a3 radial-gradient(#f9ffd2, #ecff70);
color: rgba(0, 0, 0, 0);
border-radius: 50%;
box-shadow: 0 0 7px #e7f1a3a2;
}
.circle:after {
display: block;
position: absolute;
content: '';
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
width: 10rem;
height: 4rem;
border-radius: 50%;
border: 2px solid #fafafa;
border-top: 0px solid #fafafa;
border-bottom: 4px solid #fafafa;
z-index: 2
}
.circle:before {
display: block;
position: absolute;
content: '';
top: 50%;
left: 50%;
background: #124;
border-radius: 50%;
width: 4px;
height: 4px;
transform-origin: 2.5rem 0;
transform: translate(-2.5rem, 0) rotate(0deg);
animation: circle-around 5s infinite linear;
}
#keyframes circle-around {
0% { transform: translate(-2.5rem, 0) rotate(0deg); }
100% { transform: translate(-2.5rem, 0) rotate(360deg); }
}
main p {
margin-top: 3rem;
text-align: center;
text-shadow: 0 0 5px #c3d168a2;
}
main button {
padding: 0.55rem 1.2rem;
border: none;
outline: none;
appearance: none;
border-radius: 1rem;
background: rgb(17, 141, 44);
color: #fafafa;
box-shadow: 0 0 4px #e1f17859;
}
main button:hover {
cursor: pointer;
}
Please Help Why This Doesn't works?
I tested your code, It is working well. I recommend you trying a different browser or trying Ctrl + F5 in your browser to force an update.
try doing it like this ... try removing the "." in your href
Can you please also post any messages from your console. If you are using Chrome, then go to View -> Developer -> Developer Tools, the click on Console. If you are using a different browser, then see here how to open it: https://balsamiq.com/support/faqs/browserconsole/
Also, try loading your website in a different browser or in Incognito mode. Usually if CSS isn't being applied, it may have been cached so it is not updating for you.
I would make this a comment if I had enough reputation.
So I am at the last couple details of my portfolio website, and everything has gone relatively smoothly. I have not had an issue with images before, but this time I am using a {% for loop %} to iterate over the code for the card and I just have the variable template tags that create a new object every time I add something new in the django admin interface.
I feel like there is some small detail I am just completely missing, because I had it working at one point, but then decided to do the iteration instead of hard-coding it in, and it just won't show up. Another pair of eyes would be nice.
This is the section of my index.html:
{% block content %}
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Jordan Miracle</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/static/portfolio/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<body>
<div class="jumbotron text-center ui-datepicker-next-hover" style="margin-bottom:0">
<div class="align-center">
<img src="{% static 'portfolio/mylogo.png' %}" id="img-bastet" class="img-fluid"
alt="Jordan and Bastet">
</div>
<h1><p style="font-family: 'Ubuntu Mono', Monospaced, monospace; font-size: medium;">Developer and Aspirant Data
Scientist</p>
</div>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<a class="navbar-brand" href="{% url 'home' %}">Home</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="https://github.com/jordanmiracle">Github</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://twitter.com/jordanmiracle1">Twitter</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://www.linkedin.com/in/jordan-m-605b4b1a9/">LinkedIn</a>
</div>
<div class="topnav-right">
Blog
</nav>
<div class="container" style="margin-top:30px">
<div class="row">
<h2>About Me</h2>
<div class="row justify-content-center my-3">
<div class="col-5" style="border: #303030" aria-setsize="10px">
<img src="{% static 'portfolio/me-bastet-and-babys-turtle.jpg' %}" class="img-fluid"
alt="Jordan and Bastet">
</div>
</div>
<div class="intro-text">
<p style="font-family: 'Ubuntu Mono', Monospaced, monospace; font-size: small; ">
<p>I enjoy web development, and have a true love for analyzing data. Whether creating visualizations and
interpreting what I find,<br>
or creating a machine learning model to try and make predictions. <br>
Things that interest me the most are the climate and our ecosystem, consciousness, and the cosmos that we live
in.
</p>
</div>
<ul class="nav nav-pills flex-column">
<div class="button-row-main">
<button class="nav-button highlight-green">
<a href="mailto:jordanmiracle#protonmail.com" target="_blank">Contact
Me</a>
</button>
</div>
<div class="portfolio">
{% for project in projects %}
<div class="project">
<h2>{{ project.title }}</h2>
<p class="technologies">
</p>
<!-- Depending on availability, display either the image as a link,
only image, or a string explaining that the img is missing-->
{% if project.image %}
<a href="{{ project.url }}" target="_blank">
<div class="img-container" style="background-image: url('{{ project.image }}')"></div>
</a>
<p>{{ project.description }}
</p><br>
<div class="project-links">
Live Site
Code
</div>
{% endif %}
</div>
{% endfor %}
</body>
{% endblock %}
</html>
My style.css:
font-family: 'Oswald', sans-serif;
text-align: center;
background-color: #00FF00;
color: #303030;
}
/* ---------- HOME ---------- */
/* create color-hover-effect for M logo and buttons */
.highlight-orange:hover {
color: #417FD5;
border-color: #ffa000;
}
.highlight-green:hover {
color: darkred;
border-color: indianred;
}
button a {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
text-decoration: darkslateblue;
color: inherit;
/* increase the clickable area */
display: inline-block;
position: relative;
z-index: 1;
padding: 1.3em;
margin: -1.3em;
}
.nav-button {
font-size: 1.1em;
margin: 20px;
padding: 10px;
border: 2px solid #303030;
border-radius: 25px;
color: #303030;
background-color: #fdfdfd;
box-shadow: #417FD5;
}
.button-row-mobile,
.button-row-portfolio-mobile {
display: none;
}
/* ---------- PORTFOLIO ---------- */
.portfolio {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
.project {
margin: 20px;
padding: 20px;
border: 3px solid #303030;
border-radius: 20px;
color: transparent;
background-color: transparent;
max-width: 300px;
}
.project-links {
display: flex;
justify-content: space-around;
}
.project-links a {
color: #4DAAE3;
}
.project-links a:visited {
color: #ffffff;
}
.project-links a:hover {
color: #4DAAE3;
}
.button-row-portfolio {
position: fixed;
width: 100%;
justify-content: space-between;
bottom: 5px;
}
.button-row-portfolio .nav-button {
opacity: 0.8;
}
/*
restrict img to uniform size automatically,
while showing the center portion of the screenshot. adapted from:
https://stackoverflow.com/questions/15866223/how-to-make-images-get-cut-off
*/
.img-container {
height: 200px;
width: 250px;
color: transparent;
background-position: center;
border: 1px solid #303030;
border-radius: 20px;
background-repeat: no-repeat;
}
/* ---------- FOOTER ---------- */
.separator {
display: none;
}
#footer {
position : absolute;
bottom : 0;
height : 40px;
margin-top : 40px;
}
footer {
font-size: 16px;
color: #303030;
}
.site-footer {
padding-left: 40px;
padding-right: 40px;
padding-top: 15px;
padding-bottom: 5px;
background-color: #aa2222;
color: white;
font-style: italic;
text-align: center;
}
.icon {
height: 36px;
width: auto;
padding: 8px;
}
.overflow {
color: #fdfdfd;
font-size: 2.5em;
}
/* ---------- RESPONSIVE ELEMENTS ---------- */
/* TODO: remove blue highlighting when buttons are clicked */
#media only screen and (max-width: 768px) {
.logo {
font-size: 14em;
}
.button-row-main,
.button-row-portfolio {
display: none;
}
.button-row-mobile {
margin-top: 50px;
margin-bottom: 50px;
display: flex;
justify-content: space-around;
}
.button-row-portfolio-mobile {
display: flex;
position: fixed;
width: 100%;
justify-content: space-around;
bottom: 5px;
}
.button-row-portfolio-mobile .nav-mobile {
opacity: 0.8;
}
.nav-mobile {
font-family: 'Oswald', sans-serif;
font-size: 1em;
border: none;
border-radius: 100px;
background-color: #fdfdfd;
}
.highlight-orange {
color: #4DAAE3;
border-color: #4DAAE3;
fill: #4DAAE3;
}
.highlight-green {
color: lightgreen;
border-color: lightgreen;
fill: lightgreen;
}
.highlight-blue {
color: lightblue;
border-color: lightblue;
fill: lightblue;
}
.separator {
display: block;
}
footer {
margin-top: 24px;
}
.icon {
height: 45px;
width: auto;
padding: 20px;
}
}
* {
box-sizing: border-box;
}
body {
background-color: #f1f1f1;
padding: 20px;
font-family: "Ubuntu Mono", serif;
}
/* Center website */
.main {
max-width: 1000px;
margin: auto;
}
h1 {
font-size: 50px;
word-break: break-all;
}
.row {
margin: 8px -16px;
}
/* Add padding BETWEEN each column (if you want) */
.row,
.row > .column {
padding: 8px;
}
/* Create four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
}
/* Clear floats after rows */
.row:after {
content: "";
display: table;
clear: both;
}
/* Content */
.content {
background-color: white;
padding: 10px;
}
/* Responsive layout - makes a two column-layout instead of four columns */
#media screen and (max-width: 900px) {
.column {
width: 75%;
}
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 600px) {
.column {
width: 100%;
}
}
My models.py:
class Project(models.Model):
title = models.CharField(max_length=100)
description = models.CharField(max_length=120)
image = models.FilePathField(path='portfolio/images')
url = models.URLField(blank=True)
code_url = models.URLField(blank=True)
def __str__(self):
return self.title
Here is my file structure.
If anybody needs more information, or if I need to provide more details, just let me know. This is the last thing really standing in my way of deploying and it's been a pain.
Before changing it to img class
After changing it from a div class to img class
The images needed to be registered properly in the Django admin shell.
Once in the shell, I had to import the models.
from portfolio.models import Project
Then, p2 = Project.objects.get(id=2)
p2.image = <path_to_file>
And so on. Once they were registered in the DB, they popped up right away.
Looks like you might need to set a background image size on .img-container. If that doesn't work, also try setting display: block;
.img-container {
height: 200px;
width: 250px;
color: transparent;
background-position: center;
border: 1px solid #303030;
border-radius: 20px;
background-repeat: no-repeat;
background-size: cover;
display: block;
}
I have just started making a "Student Database Project" with Flask. I have set up a MySQL Database using the flask_mysqldb module. I have also inserted some student data into it. But I want to fetch the data (name, grade, phone number, address, email , etc) of a specific student. How should I do it? Please help me because I'm new to Flask and MySQL. Here's my code:
from flask import Flask,render_template, redirect, url_for, request, jsonify
from flask_mysqldb import MySQL
app = Flask(__name__)
app.config['SECRET_KEY'] = 'ILUVTOFART'
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = ''
app.config['MYSQL_DB'] = 'student_db'
mysql = MySQL(app)
#app.route("/add_s_data", methods=["GET","POST"]) #This is the page for adding student information to DB
def handle_s_data():
if request.method == "POST":
cur = mysql.connection.cursor()
sid = request.form.get('id', False) # Student ID
name = request.form.get('name', False) # Full Name
f_name = request.form.get('fname', False) # Father's Name
m_name = request.form.get('mname', False) # Mother's Name
clas = request.form.get('class', False) # His grade/class
roll = request.form.get('roll', False) # His roll number
section = request.form.get('section', False) # His class section
dob = request.form.get('dob', False) # Date of Birth
join = request.form.get('join', False) # Admission date
phone = request.form.get('phone', False) # Phone number
address = request.form.get('address', False) # Address
sequence = (sid, name, f_name, m_name, clas, roll, section, dob, join, phone, address)
formula = "INSERT INTO student_data (id, name, f_name, m_name, class, roll, section, dob, joindate, phone, address) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s )"
cur.execute(formula,sequence)
mysql.connection.commit()
return str(sequence) + " Done!"
return render_template('add_s_data.html')
#I want to fetch these data from the database and show them on the page. I know how to use Jinja2 Variables, but how do I fetch the data?
#import url('https://fonts.googleapis.com/css?family=Josefin+Sans&display=swap');
#import url('https://fonts.googleapis.com/css?family=Noto+Sans+TC&display=swap');
#import url('https://fonts.googleapis.com/css?family=Lato&display=swap');
#import url('https://fonts.googleapis.com/css?family=Raleway&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
list-style: none;
text-decoration: none;
font-family: 'Josefin Sans', sans-serif;
}
body{
background-color: #f3f5f9;
}
.wrapper{
display: flex;
position: relative;
}
.wrapper .sidebar{
width: 240px;
height: 100%;
background: #0080ff;
padding: 30px 0px;
position: fixed;
}
.wrapper .sidebar h2{
margin-left: 15px;
padding-top: 05px;
padding-bottom: 05px;
color: white;
font-family: 'Noto Sans TC', sans-serif;
-webkit-text-stroke: 0.5px black;
}
.wrapper .sidebar ul li{
padding: 15px;
border-bottom: 1px solid #bdb8d7;
border-bottom: 1px solid rgba(0,0,0,0.05);
border-top: 1px solid rgba(255,255,255,0.05);
}
.wrapper .sidebar ul li a{
color: white;
display: block;
}
.wrapper .sidebar ul li a .fas{
width: 25px;
}
.wrapper .sidebar ul li:hover{
background-color: #0f52ba;
}
.wrapper .sidebar ul li:hover a{
color: #fff;
}
.wrapper .sidebar .social_media{
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
display: flex;
}
.wrapper .sidebar .social_media a{
display: block;
width: 40px;
background: #594f8d;
height: 40px;
line-height: 45px;
text-align: center;
margin: 0 5px;
color: #bdb8d7;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.home {
background: #0080ff;
}
.add{
background: #0f52ba;
}
.wrapper .main_content{
width: 100%;
margin-left: 200px;
}
.wrapper .main_content .header{
padding: 20px;
background: #fff;
color: #717171;
border-bottom: 1px solid #e0e4e8;
}
.wrapper .main_content .info{
margin: 20px;
color: #717171;
line-height: 25px;
}
.wrapper .main_content .info div{
margin-bottom: 20px;
}
#media (max-height: 500px){
.social_media{
display: none !important;
}
}
.id{
font-size: 30px;
margin-top: 5%;
margin-left:20%;
}
.id input{
margin-left: 16.5%;
width: 30%;
height: 5;
font-size: 30px;
}
.name{
font-size: 30px;
margin-top: 3%;
margin-left:20%;
}
.name input{
width: 30%;
height: 5;
font-size: 30px;
margin-left: 11.5%;
}
.fname{
font-size: 30px;
margin-top: 3%;
margin-left:20%;
}
.fname input{
width: 30%;
height: 5;
margin-left: 1%;
font-size: 30px;
}
.mname{
font-size: 30px;
margin-top: 3%;
margin-left:20%;
}
.mname input{
width: 30%;
height: 5;
font-size: 30px;
}
.class{
font-size: 30px;
margin-top: 3%;
margin-left:20%;
}
.class input{
width: 30%;
height: 5;
font-size: 30px;
margin-left: 12.5%;
}
.roll{
font-size: 30px;
margin-top: 3%;
margin-left:20%;
}
.roll input{
width: 30%;
height: 5;
font-size: 30px;
margin-left: 14%;
}
.section{
font-size: 30px;
margin-top: 3%;
margin-left:20%;
}
.section input{
width: 30%;
height: 5;
font-size: 30px;
margin-left: 9.5%;
}
.dob{
position: absolute;
margin-left: 65%;
top: 18.5%;
font-size: 30px;
}
.dob input{
width: 50%;
font-size: 30px;
height: 1;
}
.joining{
position: absolute;
margin-left: 65%;
top: 29.5%;
font-size: 30px;
}
.joining input{
margin-left: 2%;
width: 50%;
font-size: 30px;
height: 1;
}
.phone{
position: absolute;
margin-left: 65%;
top: 42.5%;
font-size: 30px;
}
.phone input{
margin-left: 10%;
width: 50%;
font-size: 30px;
height: 1;
}
.address{
position: absolute;
margin-left: 65%;
top: 54.5%;
font-size: 30px;
}
.address input{
margin-left: 16%;
width: 51%;
font-size: 30px;
height: 1;
}
button{
font-size: 20px;
border: 1px solid black;
background: lightblue;
color: white;
margin-left: 77%;
position: absolute;
top: 70%;
width: 100px;
height: 50px;
border-radius: 8px;
}
<!DOCTYPE html>
<html lang="eng">
<head>
<meta charset="utf-8">
<title>I am Ahnaf</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename = 'css/bootstrap.min.css')}}">
<link rel="stylesheet" type="text/css" href="../static/css/add_s_data.css">
<link rel="stylesheet" type="text/css" href="../static/fontawsome/css/all.css">
</head>
<body>
<!-- Sidebar Section -->
<div class="wrapper">
<div class="sidebar">
<h2>Ahnaf's SDMS</h2>
<ul>
<li class="home"><i class="fas fa-home"></i>Home</li>
<li class="search"><i class="fas fa-search"></i>Search Data</li>
<li class="add"><i class="fas fa-users"></i>Add Data</li>
<li class="modify"><i class="fas fa-edit"></i>Modify Data</li>
<li class="delete"><i class="fas fa-user-minus"></i>Delete Data</li>
<li class="report"><i class="fas fa-flag"></i>Add Student Report</li>
<li class="present"><i class="fas fa-address-card"></i>ID Card Maker</li>
<li class="exam"><i class="fas fa-pen"></i>Exams</li>
<li class="events"><i class="fas fa-calendar-week"></i>Events</li>
<li class="contact"><i class="fas fa-address-book"></i>Contact</li>
</ul>
</div>
</div>
<div class="choice">
<p style="color:blue;position: absolute; top:2%;margin-left: 35%;font-size: 30px;">Student</p>
<hr style="position: relative; margin-top: 4%; margin-left: 29%; width: 20%">
<div style="position:absolute;top:0;border-left:1px solid #000;height:50px; margin-left: 57%;"></div>
<a style="color: black;position: absolute; top:2%;margin-left: 70%;font-size: 30px;"href="/add_t_data">Teacher</a>
</div>
<div class="form">
<form action="/add_s_data" method='POST'>
<div class="id">
<label>ID:</label>
<input type="text" name="id" ><br>
</div>
<div class="name">
<label>Name:</label>
<input type="text" name="name" ><br>
</div>
<div class="fname">
<label>Father's Name:</label>
<input type="text" name="fname" ><br>
</div>
<div class="mname">
<label>Mother's Name:</label>
<input type="text" name="mname" ><br>
</div>
<div class="class">
<label>Class:</label>
<input type="text" name="class" ><br>
</div>
<div class="roll">
<label>Roll:</label>
<input type="text" name="roll" ><br>
</div>
<div class="section">
<label>Section:</label>
<input type="text" name="section" ><br>
</div>
<div class="dob">
<label>Date of Birth:</label>
<input type="date" name="dob" ><br>
</div>
<div class="joining">
<label>Joining Date:</label>
<input type="date" name="join" ><br>
</div>
<div class="phone">
<label>Phone No:</label>
<input type="text" name="phone" ><br>
</div>
<div class="address">
<label>Address:</label>
<input type="text" name="address" ><br>
</div>
<button type="submit" value="Submit" >Submit</button>
</form>
</div>
<script type="text/javascript">
</script>
</body>
</html>
Thank you for your convenience.
Here is how you possibly can do it.
#app.route("/user/<int:id>")
def user(id):
cur = mysql.connection.cursor()
cur.execute("""SELECT * FROM student_data WHERE id = %s""", (id,))
user = cur.fetchone()
return render_template('user.html', user = user)
Inside user.html
<!DOCTYPE html>
<html lang="eng">
<head>
<meta charset="utf-8">
<title>User : {{ user.name }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename = 'css/bootstrap.min.css')}}">
<link rel="stylesheet" type="text/css" href="../static/css/add_s_data.css">
<link rel="stylesheet" type="text/css" href="../static/fontawsome/css/all.css">
</head>
<body>
<div class="user">
<p>ID: {{ user.id }}</p>
<p>ID: {{ user.name }}</p>
<p>...</p>
</div>
</body>
</html>
I advise you to go and check Flask-SQLAlchemy, Flask-WTForms they will help you manager database and forms better.
I have a google map with a HTML form. The user searches for his location and places a marker. After clicking on the marker the form pops up and after filling the form and clicking submit the data gets stored into the MySQL database table.
However I also want the location of the user, that is where the user has placed the marker, its latitude and longitude to be stored into the MySQL database table.
I am using Python 2.7 for the processing part, i.e. for inserting data into the MySQL database from the form.
I am using Mac OS Sierra.
I am using Python,MySQL and Apache that is already pre-installed on mac.
Since I am new to coding, can please someone tell me what I need to add to my code for it to run smoothly.
I am attaching my HTML as well as Python code below :
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta charset="utf-8" />
<title>MAPS</title>
<style>
#map {
width: 100%;
height: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#description {
font-family: Calibri;
font-size: 15px;
font-weight: 300;
}
#infowindow-content .title {
display: none;
}
#map #infowindow-content {
display: none;
}
.pac-card {
margin: 10px 10px 0 0;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
background-color: #fff;
font-family: Calibri;
}
#pac-container {
padding-bottom: 12px;
margin-right: 12px;
}
.pac-controls {
display: inline-block;
padding: 5px 11px;
}
.pac-controls label {
font-family: Calibri;
font-size: 16px;
font-weight: 400;
}
#pac-input {
background-color: #fff;
font-family: Calibri;
font-size: 15px;
font-weight: 400;
margin-left: 12px;
padding: 8px 12px;
text-overflow: ellipsis;
width: 400px;
border: 1px solid #ccc;
}
#pac-input:focus {
border-color: #4d90fe;
}
#title {
color: #fff;
background-color: #4d90fe;
font-size: 25px;
font-weight: 400;
padding: 6px 12px;
}
#target {
width: 345px;
}
#form
{
display: none;
}
#heading {
text-align: center;
color: #003366;
font-size: 30px;
font-family: Calibri;
padding: 8px 12px;
}
label.field {
text-align: left;
font-weight: bolder;
font-size: 16px;
font-family: Calibri;
}
input[type=text], input[type=email], input[type=number], select {
font-family: Calibri;
font-size: 16px;
font-weight: bolder;
padding: 8px 12px;
width: 100%;
margin: 8px 0;
display: inline-block;
border: 1px solid black;
border-radius: 4px;
box-sizing: border-box;
}
input[type=submit] {
font-family: Calibri;
font-size: 16px;
font-weight: bolder;
background-color: white;
color: #00b300;
padding: 8px 12px;
margin: 8px 0;
border: 2px solid #00b300;
border-radius: 4px;
cursor: pointer;
box-sizing: border-box;
}
input[type=submit]:hover {
background-color: #00b300;
color: white;
}
input[type=reset] {
font-family: Calibri;
font-size: 16px;
font-weight: bolder;
background-color: white;
color: #cc0000;
padding: 8px 12px;
margin: 8px 0;
border: 2px solid #cc0000;
border-radius: 4px;
cursor: pointer;
box-sizing: border-box;
}
input[type=reset]:hover {
background-color: #cc0000;
color: white;
}
input[type=text]:focus {
background-color: #f2f2f2;
border-color: #4d90fe;
}
input[type=email]:focus {
background-color: #f2f2f2;
border-color: #4d90fe;
}
input[type=number]:focus {
background-color: #f2f2f2;
border-color: #4d90fe;
}
select:focus {
background-color: #f2f2f2;
border-color: #4d90fe;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC8EAfEQrYVs4c_kMBUQw3tVY8uhEViDCU&libraries=places&callback=initAutocomplete"
async defer>
</script>
</head>
<body>
<div id="map"></div>
<input id="pac-input" class="controls" type="text" placeholder="Search your location..." />
<div id="form">
<form action="/cgi-bin/processing.py" method="post">
<p id="heading">PERSONAL INFORMATION</p>
<label class="field" for="fullname"><b>Full Name:</b></label>
<input type="text" name="fullname" placeholder="Eg. Suraj Makhija" size="30" required />
<br />
<br />
<label class="field" for="emailid"><b>E-mail:</b></label>
<input type="email" name="emailid" placeholder="Eg. contact#domain.com" size="30" required />
<br />
<br />
<label class="field" for="mobile"><b>Mobile:</b></label>
<input type="text" name="mobile" placeholder="Eg. 9999999999" maxlength="10" minlength="10" size="30" required />
<br />
<br />
<label class="field" for="gender"><b>Gender:</b></label>
<select name="gender" required>
<option value="male">Male</option>
<option value="female">Female</option>
<option value="other">Other</option>
</select>
<br />
<br />
<label class="field" for="areaofexpertise"><b>Area of Expertise:</b></label>
<input type="text" name="areaofexpertise" placeholder="Eg. Android/iOS Developer" size="30" required />
<br />
<br />
<label class="field" for="yearsofexperience"><b>Years of Experience:</b></label>
<input type="number" name="yearsofexperience" placeholder="Eg. 10" min="0" max="100" required />
<br />
<br />
<p style="text-align: center;">
<input type="submit" value="Submit" />
<input type="reset" value="Clear All" />
</p>
</form>
</div>
<script>
var map;
var iconBase;
var input;
var searchBox;
var markers=[];
var markerArray =[];
var infowindow;
function initAutocomplete() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 20.5937, lng: 78.9629},
zoom: 5,
mapTypeId: 'roadmap',
gestureHandling: 'cooperative'
});
//Declaring infowindow.
infowindow = new google.maps.InfoWindow({
content: document.getElementById('form')
});
// Create the search box and link it to the UI element.
input = document.getElementById('pac-input');
searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
//Creates a marker when the user clicks on a location on the map.
google.maps.event.addListener(map, 'click', function(event) {
addMarker(event.latLng, map);
});
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
//Marker function declaration.
function addMarker(location, map) {
// Add the marker at the clicked location.
var iconBase = 'https://maps.google.com/mapfiles/kml/paddle/';
marker = new google.maps.Marker({
draggable: true,
animation: google.maps.Animation.DROP,
position: location,
map: map,
icon: iconBase + 'ylw-blank.png'
});
//Infowindow pops up on clicking the marker.
google.maps.event.addListener(marker, 'click', function() {
document.getElementById('form').style.display='inline-block';
infowindow.open(map, marker);
});
var lat = marker.getPosition().lat();
var lng = marker.getPosition().lng();
}
</script>
</body>
Python code:
#!/usr/local/bin/python
import cgi
import MySQLdb
import cgitb
cgitb.enable()
form = cgi.FieldStorage()
fullname = form.getvalue('fullname', '')
emailid = form.getvalue('emailid', '')
mobile = form.getvalue('mobile', '')
gender = form.getvalue('gender', '')
areaofexpertise = form.getvalue('areaofexpertise', '')
yearsofexperience = form.getvalue('yearsofexperience', '')
db = MySQLdb.connect(host="localhost", user="root", passwd="suraj", db="client_database")
cursor = db.cursor()
query = """INSERT INTO client_info (FULL_NAME, EMAIL_ID, MOBILE, GENDER, AREA_OF_EXPERTISE, YEARS_OF_EXPERIENCE)
VALUES (%s, %s, %s, %s, %s, %s)"""
cursor.execute(query, (fullname, emailid, mobile, gender, areaofexpertise, yearsofexperience))
result = cursor.fetchall()
db.commit()
db.close()
Ok so I have the web.py file called app.py.
app.py references index.html and foo.html.
Both of these html files call just fine, what I mean is when I run app.py and go to http://localhost:8080/ and http://localhost:8080/Foo both of them display a webpage just fine, the issue is with the foo.html file tho. I have a large section in there that is supposed to use the rotate.css file and make the text in the section spin. The problem is the text doesn't even show up.
Files are below:
app.py
import web
urls = (
'/', 'Index',
'/Foo', 'Foo'
)
app = web.application(urls, globals())
render = web.template.render('templates/')
class Index(object):
def GET(self):
greeting_Index = "Hello World"
return render.index(greeting = greeting_Index)
class Foo(object):
def GET(self):
greeting_Foo = 'FooBAR'
return render.foo(greeting = greeting_Foo)
if __name__ == "__main__":
app.run()
foo.html
$def with (greeting)
$var cssfiles: static/rotate.css
<html>
<head>
<meta charset="UTF-8">
<title>Foobar</title>
</head>
<body>
$if greeting:
<em style="color: red; font-size: 5em;">Welcome to the Foo bar. $greeting.</em>
$else:
Herro world!
<section class="rw-wrapper">
<h2 class="rw-sentence">
<span>Real poetry is like</span>
<span>creating</span>
<div class="rw-words rw-words-1">
<span>breathtaking moments</span>
<span>lovely sounds</span>
<span>incredible magic</span>
<span>unseen experiences</span>
<span>happy feelings</span>
<span>beautiful butterflies</span>
</div>
<br />
<span>with a silent touch of</span>
<div class="rw-words rw-words-2">
<span>sugar</span>
<span>spice</span>
<span>colors</span>
<span>happiness</span>
<span>wonder</span>
<span>happiness</span>
</div>
</h2>
</section>
</body>
</html>
rotate.css
.rw-wrapper{
width: 80%;
position: relative;
margin: 110px auto 0 auto;
font-family: 'Bree Serif';
padding: 10px;
}
.rw-sentence{
margin: 0;
text-align: left;
text-shadow: 1px 1px 1px rgba(255,255,255,0.8);
}
.rw-sentence span{
color: #444;
white-space: nowrap;
font-size: 200%;
font-weight: normal;
}
.rw-words{
display: inline;
text-indent: 10px;
}
.rw-words span{
position: absolute;
opacity: 0;
overflow: hidden;
width: 100%;
color: #6b969d;
}
.rw-words-1 span{
animation: rotateWordsFirst 18s linear infinite 0s;
}
.rw-words-2 span{
animation: rotateWordsSecond 18s linear infinite 0s;
}
.rw-words span:nth-child(2){
animation-delay: 3s;
color: #6b889d;
}
.rw-words span:nth-child(3){
animation-delay: 6s;
color: #6b739d;
}
.rw-words span:nth-child(4){
animation-delay: 9s;
color: #7a6b9d;
}
.rw-words span:nth-child(5){
animation-delay: 12s;
color: #8d6b9d;
}
.rw-words span:nth-child(6){
animation-delay: 15s;
color: #9b6b9d;
}
#keyframes rotateWordsFirst {
0% { opacity: 1; animation-timing-function: ease-in; height: 0px; }
8% { opacity: 1; height: 60px; }
19% { opacity: 1; height: 60px; }
25% { opacity: 0; height: 60px; }
100% { opacity: 0; }
}
#keyframes rotateWordsSecond {
0% { opacity: 1; animation-timing-function: ease-in; width: 0px; }
10% { opacity: 0.3; width: 0px; }
20% { opacity: 1; width: 100%; }
27% { opacity: 0; width: 100%; }
100% { opacity: 0; }
}
According to http://webpy.org/cookbook/staticfiles you may have to alter your apache.conf file to allow apache to serve up those files.
And I did notice that nowhere in your html file do you actually link to the css file
<link rel="stylesheet" href="static/rotate.css" type="text/css">
somewhere in the head is missing or since your using it as a variable it should be
<link rel="stylesheet" href="$cssfiles" type="text/css">