Commit 5cb7a92c authored by YSelf Tool's avatar YSelf Tool

Implemented events and front page

parent c76c322c
...@@ -34,44 +34,68 @@ class User(db.Model, UserMixin): ...@@ -34,44 +34,68 @@ class User(db.Model, UserMixin):
) )
class Event(db.Model):
__tablename__ = "events"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, unique=True)
date = db.Column(db.Date)
def __init__(self, name, date):
self.name = name
self.date = date
def __repr__(self):
return "<Event(id={}, name='{}', date={})>".format(
self.id,
self.name,
self.date
)
class Speaker(db.Model): class Speaker(db.Model):
__tablename__ = "speakers" __tablename__ = "speakers"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, unique=True) name = db.Column(db.String)
event = db.Column(db.Integer, db.ForeignKey("events.id"), nullable=False)
def __init__(self, name): def __init__(self, name, event):
self.name = name self.name = name
self.event = event
def __repr__(self): def __repr__(self):
return "<Speaker(id={}, name={})>".format(self.id, self.name) return "<Speaker(id={}, name={}, event={})>".format(
self.id,
self.name,
self.event
)
class Statement(db.Model): class Statement(db.Model):
__tablename__ = "statements" __tablename__ = "statements"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
speaker = db.Column(db.Integer, db.ForeignKey("speakers.id"), nullable=False) speaker = db.Column(db.Integer, db.ForeignKey("speakers.id"), nullable=False)
event = db.Column(db.Integer, db.ForeignKey("events.id"), nullable=False)
insertion_time = db.Column(db.DateTime) insertion_time = db.Column(db.DateTime)
executed = db.Column(db.Boolean) executed = db.Column(db.Boolean)
execution_time = db.Column(db.DateTime) execution_time = db.Column(db.DateTime)
def __init__(self, speaker, insertion_time=None, executed=False, execution_time=None): def __init__(self, speaker, event, insertion_time=None, executed=False, execution_time=None):
self.speaker = speaker self.speaker = speaker
self.event = event
self.insertion_time = insertion_time or datetime.now() self.insertion_time = insertion_time or datetime.now()
self.executed = executed self.executed = executed
self.execution_time = execution_time or datetime.now() self.execution_time = execution_time or datetime.now()
def __repr__(self): def __repr__(self):
return "<Statement(id={}, speaker={}, insertion_time={}, executed={}, execution_time={})>".format( return "<Statement(id={}, speaker={}, event={}, insertion_time={}, executed={}, execution_time={})>".format(
self.id, self.id,
self.speaker, self.speaker,
self.event,
self.insertion_time, self.insertion_time,
self.executed, self.executed,
self.execution_time self.execution_time
) )
def dump(self):
return { "speaker": self.speaker, "insertion_time": self.insertion_time.timestamp(), "executed": self.executed, "execution_time": self.execution_time.timestamp() }
def done(self): def done(self):
if self.executed: if self.executed:
return False return False
......
from flask.ext.wtf import Form from flask.ext.wtf import Form
from wtforms import StringField, PasswordField, BooleanField, SelectMultipleField, SelectField, DateField, IntegerField, TextAreaField from wtforms import StringField, PasswordField, BooleanField, SelectMultipleField, SelectField, DateField, IntegerField, TextAreaField, HiddenField
from wtforms.validators import InputRequired, Length, EqualTo, Email, Optional, Length, NumberRange, AnyOf from wtforms.validators import InputRequired, Length, EqualTo, Email, Optional, Length, NumberRange, AnyOf
from models.database import User from models.database import User
...@@ -24,3 +24,8 @@ class AdminUserForm(Form): ...@@ -24,3 +24,8 @@ class AdminUserForm(Form):
class AddStatementForm(Form): class AddStatementForm(Form):
speaker_name = StringField("Speaker", validators=[InputRequired("Entering the speaker is required.")]) speaker_name = StringField("Speaker", validators=[InputRequired("Entering the speaker is required.")])
event = HiddenField("Event")
class NewEventForm(Form):
name = StringField("Name", validators=[InputRequired("Entering the name is required.")])
date = DateField("Date (DD.MM.YYYY)", validators=[InputRequired("Entering the date is required.")], format="%d.%m.%Y")
...@@ -2,8 +2,8 @@ from flask import Blueprint, render_template, redirect, url_for, request, flash, ...@@ -2,8 +2,8 @@ from flask import Blueprint, render_template, redirect, url_for, request, flash,
from flask.ext.login import login_required from flask.ext.login import login_required
from passlib.hash import pbkdf2_sha256 from passlib.hash import pbkdf2_sha256
from models.database import User from models.database import User, Event
from models.forms import AdminUserForm, NewUserForm from models.forms import AdminUserForm, NewUserForm, NewEventForm
from shared import db, admin_permission from shared import db, admin_permission
...@@ -15,7 +15,8 @@ admin = Blueprint("admin", __name__) ...@@ -15,7 +15,8 @@ admin = Blueprint("admin", __name__)
@admin_permission.require() @admin_permission.require()
def index(): def index():
users = User.query.limit(10).all() users = User.query.limit(10).all()
return render_template("admin_index.html", users=users) events = Event.query.limit(10).all()
return render_template("admin_index.html", users=users, events=events)
@admin.route("/user/") @admin.route("/user/")
@login_required @login_required
...@@ -66,3 +67,56 @@ def user_new(): ...@@ -66,3 +67,56 @@ def user_new():
db.session.commit() db.session.commit()
return redirect(url_for(".user")) return redirect(url_for(".user"))
return render_template("admin_user_new.html", form=form) return render_template("admin_user_new.html", form=form)
@admin.route("/event/new", methods=["GET", "POST"])
@login_required
@admin_permission.require()
def event_new():
form = NewEventForm()
if form.validate_on_submit():
if Event.query.filter_by(name=form.name.data).count() > 0:
flash("There already is an event with that name.", "alert-error")
return render_template("admin_event_new.html", form=form)
event = Event(form.name.data, form.date.data)
db.session.add(event)
db.session.commit()
return redirect(url_for(".event"))
return render_template("admin_event_new.html", form=form)
@admin.route("/event/delete")
@login_required
@admin_permission.require()
def event_delete():
event_id = request.args.get("id", None)
if event_id is not None:
event = Event.query.filter_by(id=event_id).first()
db.session.delete(event)
db.session.commit()
flash("Event deleted.", "alert-success")
return redirect(url_for(".event"))
@admin.route("/event/edit", methods=["GET", "POST"])
@login_required
@admin_permission.require()
def event_edit():
event_id = request.args.get("id", None)
if event_id is not None:
event = db.session.query(Event).filter_by(id=event_id).first()
form = NewEventForm(obj=event)
if form.validate_on_submit():
form.populate_obj(event)
db.session.commit()
return redirect(url_for(".index"))
else:
return render_template("admin_event_edit.html", form=form, id=event_id)
else:
return redirect(url_for(".index"))
@admin.route("/event/")
@login_required
@admin_permission.require()
def event():
events = Event.query.all()
print(events)
return render_template("admin_event_index.html", events=events)
from flask import Blueprint, render_template, redirect, url_for, request, flash, abort, send_file, Response from flask import Blueprint, render_template, redirect, url_for, request, flash, abort, send_file, Response
from flask.ext.login import login_required from flask.ext.login import login_required
from models.database import User, Statement, Speaker from models.database import User, Statement, Speaker, Event
from models.forms import AddStatementForm from models.forms import AddStatementForm
from shared import db, admin_permission, user_permission from shared import db, admin_permission, user_permission
...@@ -15,36 +15,59 @@ def transpose(arr): ...@@ -15,36 +15,59 @@ def transpose(arr):
print(list) print(list)
return list(map(list, zip(*arr))) return list(map(list, zip(*arr)))
def query_statements(mode): def query_statements(mode, event_id):
statements = [] statements = []
if mode == "pending": if mode == "pending":
statements = db.session.query(Statement, Speaker, db.func.count(Statement.speaker).label("total")).group_by(Speaker.id).join(Speaker).order_by("total ASC", Statement.insertion_time).all() statements = db.session.query(Statement, Speaker, db.func.count(Statement.speaker).label("total")).group_by(Speaker.id).join(Speaker).filter(Statement.event == event_id).order_by("total ASC", Statement.insertion_time).all()
elif mode == "all": elif mode == "all":
statements = db.session.query(Statement, Speaker).join(Speaker).order_by(Statement.insertion_time).all() statements = db.session.query(Statement, Speaker).join(Speaker).filter(Statement.event == event_id).order_by(Statement.insertion_time).all()
elif mode == "past": elif mode == "past":
statements = db.session.query(Statement, Speaker).join(Speaker).filter(Statement.executed == True).order_by(Statement.execution_time).all() statements = db.session.query(Statement, Speaker).join(Speaker).filter(Statement.executed == True).filter(Statement.event == event_id).order_by(Statement.execution_time).all()
return statements return statements
@speech.route("/index") @speech.route("/index")
def index(): def index():
mode = request.args.get("mode", "pending") mode = request.args.get("mode", "pending")
statements = query_statements(mode) event_id = request.args.get("event", None)
add_form = AddStatementForm() meta = []
current = ".index" if event_id is not None and event_id != "-1":
return render_template("speech_index.html", statements=statements, add_form=add_form, current=current) event = Event.query.filter_by(id=event_id).first()
form = AddStatementForm()
form.event.data = event.id
meta.append((query_statements(mode, event_id), form, event))
else:
for event in Event.query.all():
form = AddStatementForm()
form.event.data = event.id
meta.append((query_statements(mode, event.id), form, event))
event_id = -1
return render_template("speech_index.html", meta=meta, event_id=event_id)
@speech.route("/show") @speech.route("/show")
def show(): def show():
mode = request.args.get("mode", "pending") mode = request.args.get("mode", "pending")
statements = query_statements(mode) event_id = request.args.get("event", None)
current = ".show" meta = []
return render_template("speech_show.html", statements=statements, current=current, mode=mode) if event_id is not None and event_id is not "-1":
event = Event.query.filter_by(id=event_id).first()
meta.append((query_statements(mode, event_id), event))
else:
for event in Event.query.all():
meta.append((query_statements(mode, event.id), event))
return render_template("speech_show.html", mode=mode, meta=meta, event_id=event_id)
@speech.route("/update") @speech.route("/update")
def update(): def update():
mode = request.args.get("mode", "pending") mode = request.args.get("mode", "pending")
statements = query_statements(mode) event_id = request.args.get("event", None)
return render_template("speech_update_show.html", statements=statements, mode=mode) meta = []
if event_id is not None and event_id != "-1":
event = Event.query.filter_by(id=event_id).first()
meta.append((query_statements(mode, event_id), event))
else:
for event in Event.query.all():
meta.append((query_statements(mode, event.id), event))
return render_template("speech_update_show.html", mode=mode, meta=meta)
@speech.route("/add", methods=["GET", "POST"]) @speech.route("/add", methods=["GET", "POST"])
...@@ -54,28 +77,31 @@ def add(): ...@@ -54,28 +77,31 @@ def add():
add_form = AddStatementForm() add_form = AddStatementForm()
if add_form.validate_on_submit(): if add_form.validate_on_submit():
speaker_name = add_form["speaker_name"].data speaker_name = add_form["speaker_name"].data
if speaker_name is None: event_id = add_form["event"].data
flash("Missing speaker name", "alert-error") if speaker_name is None or event_id is None:
return redirect(url_for(".show")) flash("Missing data", "alert-error")
speaker = Speaker.query.filter_by(name=speaker_name).first() return redirect(url_for(".index"))
speaker = Speaker.query.filter_by(name=speaker_name).filter_by(event=event_id).first()
if not speaker: if not speaker:
speaker = Speaker(speaker_name) speaker = Speaker(speaker_name, event_id)
db.session.add(speaker) db.session.add(speaker)
db.session.commit() db.session.commit()
if Statement.query.filter_by(speaker=speaker.id).filter_by(executed=False).count() > 0: if Statement.query.filter_by(speaker=speaker.id).filter_by(event=event_id).filter_by(executed=False).count() > 0:
flash("Speaker already listet", "alert-error") flash("Speaker already listet", "alert-error")
return redirect(url_for(request.args.get("next") or ".show")) return redirect(url_for(request.args.get("next") or ".show"))
statement = Statement(speaker.id) statement = Statement(speaker.id, event_id)
db.session.add(statement) db.session.add(statement)
db.session.commit() db.session.commit()
mode = request.args.get("mode", "pending") mode = request.args.get("mode", "pending")
return redirect(url_for(request.args.get("next") or ".index", mode=mode)) event_id = request.args.get("event", None)
return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id))
@speech.route("/cancel") @speech.route("/cancel")
@user_permission.require() @user_permission.require()
def cancel(): def cancel():
statement_id = request.args.get("statement", None) statement_id = request.args.get("statement", None)
event_id = request.args.get("event", -1)
if not statement_id: if not statement_id:
flash("Missing statement id", "alert-error") flash("Missing statement id", "alert-error")
return redirect(url_for(request.args.get("next") or ".index")) return redirect(url_for(request.args.get("next") or ".index"))
...@@ -84,12 +110,13 @@ def cancel(): ...@@ -84,12 +110,13 @@ def cancel():
db.session.commit() db.session.commit()
flash("Statement canceled", "alert-success") flash("Statement canceled", "alert-success")
mode = request.args.get("mode", "pending") mode = request.args.get("mode", "pending")
return redirect(url_for(request.args.get("next") or ".index", mode=mode)) return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id))
@speech.route("/done") @speech.route("/done")
@user_permission.require() @user_permission.require()
def done(): def done():
statement_id = request.args.get("statement", None) statement_id = request.args.get("statement", None)
event_id = request.args.get("event", -1)
if not statement_id: if not statement_id:
flash("Missing statement id", "alert-error") flash("Missing statement id", "alert-error")
return redirect(url_for(request.args.get("next") or ".index")) return redirect(url_for(request.args.get("next") or ".index"))
...@@ -99,10 +126,11 @@ def done(): ...@@ -99,10 +126,11 @@ def done():
else: else:
flash("Statement already done", "alert-error") flash("Statement already done", "alert-error")
mode = request.args.get("mode", "pending") mode = request.args.get("mode", "pending")
return redirect(url_for(request.args.get("next") or ".index", mode=mode)) return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id))
@speech.route("/update_show.js") @speech.route("/update_show.js")
def update_show_js(): def update_show_js():
mode = request.args.get("mode", "pending") mode = request.args.get("mode", "pending")
return render_template("update_show.js", mode=mode) event_id = request.args.get("event", -1)
return render_template("update_show.js", mode=mode, event_id=event_id)
...@@ -8,7 +8,7 @@ from passlib.hash import pbkdf2_sha256 ...@@ -8,7 +8,7 @@ from passlib.hash import pbkdf2_sha256
import config import config
from shared import db, login_manager from shared import db, login_manager
from models.forms import LoginForm, NewUserForm from models.forms import LoginForm, NewUserForm
from models.database import User, Statement, Speaker from models.database import User, Statement, Speaker, Event
app = Flask(__name__) app = Flask(__name__)
app.config.from_object(config) app.config.from_object(config)
...@@ -34,8 +34,23 @@ def index(): ...@@ -34,8 +34,23 @@ def index():
user = User(fullname, username, password, ["admin", "user"]) user = User(fullname, username, password, ["admin", "user"])
db.session.add(user) db.session.add(user)
db.session.commit() db.session.commit()
#return render_template("index.html") events = Event.query.all()
return redirect(url_for("speech.show", mode="pending")) meta = []
for event in events:
meta.append(([ (statement, speaker, count) for (statement, speaker, count) in speech.query_statements("pending", event.id) if not statement.executed ][0], event))
return render_template("index.html", meta=meta)
@app.route("/update")
def update():
events = Event.query.all()
meta = []
for event in events:
meta.append(([ (statement, speaker, count) for (statement, speaker, count) in speech.query_statements("pending", event.id) if not statement.executed ][0], event))
return render_template("update_index.html", meta=meta)
@app.route("/update.js")
def update_js():
return render_template("update_index.js")
@app.route("/login", methods=["GET", "POST"]) @app.route("/login", methods=["GET", "POST"])
def login(): def login():
......
{% extends "layout.html" %}
{% from "macros.html" import render_form %}
{% block title %}Edit Event - Administration{% endblock %}
{% block content %}
{{ render_form(form, action_url=url_for(".event_edit", id=id), action_text="Apply", title="Edit Event") }}
{% endblock %}
{% extends "admin_index.html" %}
{% block admin_title %}Events{% endblock %}
{% block content %}
<div class="mdl-cell mdl-cell--3-col mdl-grid mdl-grid--no-spacing">
<table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--3-col">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Name</th>
<th class="mdl-data-table__cell--non-numeric">Date</th>
<th class="mdl-data-table__cell--non-numeric">Delete</th>
</tr>
</thead>
<tbody>
{% for event in events %}
<tr>
<td class="mdl-data-table__cell--non-numeric"><a href="{{ url_for(".event_edit", id=event.id) }}">{{ event.name }}</a></td>
<td class="mdl-data-table__cell--non-numeric">{{ event.date.strftime("%d.%m.%Y") }}</td>
<td class="mdl-data-table__cell--non-numeric">
<a href="{{ url_for('.event_delete', id=event.id) }}">
<i class="material-icons">delete</i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="rede-separator">
<div class="mdl-cell mdl-cell--1-col">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-button--fab mdl-js-ripple-effect" href="{{ url_for('.event_new') }}">
<i class="material-icons">add</i>
</a>
</div>
</div>
</div>
{% endblock %}
{% extends "layout.html" %}
{% from "macros.html" import render_form %}
{% block title %}Add Event - Administration{% endblock %}
{% block content %}
{{ render_form(form, action_url=url_for(".event_new", id=id), action_text="Add", title="Create Event") }}
{% endblock %}
...@@ -27,4 +27,28 @@ ...@@ -27,4 +27,28 @@
</a> </a>
</div> </div>
</div> </div>
<div class="mdl-cell mdl-cell--6-col mdl-cell--8-col-tablet mdl-cell--4-col-phone mdl-grid mdl-grid--no-spacing">
<table class="mdl-data-table mdl-js-table mdl-shadow--2dp sortable mdl-cell mdl-cell--12-col mdl-cell--8-col-tablet mdl-cell--4-col-phone">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Name</th>
<th class="mdl-data-table__cell--non-numeric">Date</th>
</tr>
</thead>
<tbody>
{% for event in events %}
<tr>
<td class="mdl-data-table__cell--non-numeric"><a href="{{ url_for(".event_edit", id=event.id) }}">{{ event.name }}</a></td>
<td class="mdl-data-table__cell--non-numeric">{{ event.date.strftime("%d.%m.%Y") }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="mdl-cell mdl-cell--3-col mdl-cell--3-col-tablet mdl-cell--2-col-phone">
<a class="mdl-button mdl-button--colored mdl-js-button" href="{{ url_for(".event") }}">
All events
</a>
</div>
</div>
{% endblock %} {% endblock %}
{% extends "layout.html" %} {% extends "layout.html" %}
{% block title %}Index{% endblock %} {% block title %}Index{% endblock %}
{% block additional_js %}
<script src="{{ url_for(".update_js") }}" async></script>
{% endblock %}
{% block content %} {% block content %}
<div class="rede-nocontent mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell-12-col mdl-grid"> {% for (statement, speaker, count), event in meta %}
No content here <div class="mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--4-col-phone mdl-card">
<div class="mdl-card__title">
<h3 class="mdl-card__title-text">{{ event.name }}: {{ speaker.name }}</h3>
</div>
<div class="mdl-card__actions">
{% if current_user.is_authenticated() and "user" in current_user.roles %}
<a href="{{ url_for("speech.index", event=event.id, mode="pending") }}">
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
<i class="material-icons" role="presentation">build</i>
</button>
</a>
{% endif %}
<a href="{{ url_for("speech.show", event=event.id, mode="pending") }}">
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
<i class="material-icons" role="presentation">announcement</i>
</button>
</a>
<a href="{{ url_for("speech.show", event=event.id, mode="all") }}">
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
<i class="material-icons" role="presentation">list</i>
</button>
</a>
<a href="{{ url_for("speech.show", event=event.id, mode="past") }}">
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
<i class="material-icons" role="presentation">schedule</i>
</button>
</a>
</div>
</div> </div>
{% endfor %}
{% endblock %} {% endblock %}
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
{% macro render_stringfield(field) -%} {% macro render_stringfield(field) -%}
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input id="{{ field.id }}" name="{{ field.id }}" class="mdl-textfield__input" type="text"{% if field.data is not none %}value="{{ field.data }}"{% endif %} /> <input id="{{ field.id }}" name="{{ field.id }}" class="mdl-textfield__input" type="text" {% if field.data is not none %}value="{{ field.data }}"{% endif %} />
<label class="mdl-textfield__label" for="{{ field.id }}">{{ field.label.text }}</label> <label class="mdl-textfield__label" for="{{ field.id }}">{{ field.label.text }}</label>
{% if field.errors %} {% if field.errors %}
{% for e in field.errors %} {% for e in field.errors %}
...@@ -55,14 +55,33 @@ ...@@ -55,14 +55,33 @@
{%- endmacro %} {%- endmacro %}
{% macro render_selectmultiplefield(field) -%} {% macro render_selectmultiplefield(field) -%}
<button id="{{ field.id }}-button" class="mdl-button mdl-js-button" type="button"> <button id="{{ field.id }}-button" class="mdl-button mdl-js-button mdl-button--colored mdl-shadow--2dp mdl-color--grey-100 " type="button">
{{ field.label.text }} {{ field.label.text }}
</button> </button>
<select id="{{ field.id }}" name="{{ field.id }}" multiple class="mdl-menu mdl-js-menu mdl-menu--top-left" for="{{ field.id }}-button"> <select id="{{ field.id }}" name="{{ field.id }}" multiple class="mdl-menu mdl-js-menu mdl-menu--top-left" for="{{ field.id }}-button">
{% for name, text in field.choices %} {% for name, text in field.choices %}
<option value="{{ name }}" {% if field.data is not none and name in field.data %}selected{% endif %} class="mdl-menu__item" >{{ text }}</option> <option value="{{ name }}"
{% endfor %} {% if field.data is not none and name in field.data %}
</select> selected
{% endif %}
class="mdl-menu__item">
{{ text }}
</option>
{% endfor %}
</select>
{% if field.errors %}
{% for e in field.errors %}
<div class="mdl-card__supporting-text">
{{ e }}
</div>
{% endfor %}
{% endif %}
{%- endmacro %}
{% macro render_datefield(field) -%}
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input id="{{ field.id }}" name="{{ field.id }}" class="mdl-textfield__input" type="text"{% if field.data is not none %} value="{{ field.data.strftime("%d.%m.%Y") }}"{% endif %} />
<label class="mdl-textfield__label" for="{{ field.id }}">{{ field.label.text }}</label>
{% if field.errors %} {% if field.errors %}
{% for e in field.errors %} {% for e in field.errors %}
<div class="mdl-card__supporting-text"> <div class="mdl-card__supporting-text">
...@@ -70,12 +89,22 @@ ...@@ -70,12 +89,22 @@
</div> </div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</label> </div>
{%- endmacro %} {%- endmacro %}
{% macro render_hiddenfield(field) -%}
<input id="{{ field.id }}" name="{{ field.id }}" type="hidden"{% if field.data is not none %} value="{{ field.data }}"{% endif %} />
{% if field.errors %}
{% for e in field.errors %}
<div class="mdl-card__supporting-text">
{{ e }}
</div>
{% endfor %}
{% endif %}
{%- endmacro %}
{% macro render_form(form, action_url="", title=None, action_text="Submit", class_="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--4-col-phone", title_class="mdl-card__title", title_next_class="mdl-card__title-text", content_class="mdl-card__supporting-text", action_class="mdl-card__actions", btn_class="mdl-button mdl-js-button mdl-button--raised mdl-button-colored") -%} {% macro render_form(form, action_url="", title=None, action_text="Submit", class_="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--4-col-phone", title_class="mdl-card__title", title_text_class="mdl-card__title-text", content_class="mdl-card__supporting-text", action_class="mdl-card__actions", btn_class="mdl-button mdl-js-button mdl-button--raised mdl-button-colored") -%}
<div class="{{ class_ }}"> <div class="{{ class_ }}">
<form method="POST" action="{{ action_url }}"> <form method="POST" action="{{ action_url }}">
<div class="{{ title_class }}"> <div class="{{ title_class }}">
...@@ -93,6 +122,10 @@ ...@@ -93,6 +122,10 @@
{{ render_csrftokenfield(f, kwargs) }} {{ render_csrftokenfield(f, kwargs) }}
{% elif f.type == "SelectMultipleField" %} {% elif f.type == "SelectMultipleField" %}
{{ render_selectmultiplefield(f) }} {{ render_selectmultiplefield(f) }}
{% elif f.type == "DateField" %}
{{ render_datefield(f) }}
{% elif f.type == "HiddenField" %}
{{ render_hiddenfield(f) }}
{% else %} {% else %}
{{ f.type }} {{ f.type }}
{{ render_field(f) }} {{ render_field(f) }}
......
...@@ -3,49 +3,51 @@ ...@@ -3,49 +3,51 @@
{% block title %}Statements{% endblock %} {% block title %}Statements{% endblock %}
{% block content %} {% block content %}
<table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-cell--4-col-phone sortable">