HTML-Form + AJAX
/_tpl/adm/ap.htm
<!DOCTYPE html>
<html lang="uk">
<head>
{% include 'adm/_head.htm' %}
</head>
<body>
{% include 'adm/ap_form.htm' %}
</body>
</html>
/_tpl/adm/ap_form.htm
<div class="container my-4">
<h3><!--#echo encoding="none" var="PAGE_TITLE"--> <small> <!--#echo encoding="none" var="SMALL_TITLE"--></small></h3>
<p class="head mt-3">ADDR_ID: [<b>{{ ADDR_ID }}</b>]<br/>____________________</p>
<p class="my-3" >Обов'язкові поля позначені зірочкою <span class="text-danger">*</span></p>
<form id="addressForm" class="needs-validation" novalidate>
<!-- action="/cgi-bin/adm_ap.py" method="post" -->
<div class="form-row">
<div class="col-md-3 mb-3">
<label for="sAddrHouse">Корпус <span class="text-danger">*</span></label>
<select class="custom-select" id="sAddrHouse" name="s_addr_house" required>
<option selected disabled value="">корпус #...</option>
{%- for i in range(1,10) %}
{%- if i==SEL_HOUSE -%}
<option selected>{{ i }}</option>
{%- else -%}
<option>{{ i }}</option>
{%- endif -%}
{% endfor -%}
</select>
<div class="invalid-feedback">
Вкажіть номер корпусу.
</div>
</div>
<div class="col-md-5 mb-3">
<label for="tAddrFlat">Квартира <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="tAddrFlat" name="t_addr_flat" placeholder="123" minlength="1" maxlength="3" pattern="\d{1,3}" value="{{ FLAT }}" required>
<div class="invalid-feedback">
Від 1 до 3 цифр.
</div>
</div>
<div class="col-md-4 form-group">
<label for="cOffice">Якщо це офіс</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="cOffice" name="c_office" {{ 'checked' if OFFICE == 'Y'}}>
<label class="form-check-label" for="cOffice">
Офіс
</label>
</div>
</div>
</div>
<div class="my-4 text-center">
<input type="submit" value="Показати" class="btn btn-primary mt-5" id="bShow" />
</div>
</form>
</div>
<div class="container my-4" id="out">{{ TABLE_OF_RESIDENTS }}</div>
<script src="/js/jquery.min.js"></script>
<script src="/js/spin.min.js"></script>
<script>
var spinner = new Spinner({left:'15%'}).spin();
function lz(strn, size) // leading zeros
{
var strn = strn + '';
while (strn.length < size)
strn = '0' + strn;
return strn;
}
// $("#addUser").submit(function(e)
// {
// e.preventDefault();
// $('#out').html('add user');
// });
$("#addressForm").submit(function(e)
{
e.preventDefault();
$('#out').html('');
var inpHouse = $("#sAddrHouse").val();
var inpFlat = $("#tAddrFlat").val();
var err = 0;
var house_patt = /^\d$/;
if (inpHouse + 0 == 0 || !house_patt.test(inpHouse)) {
$('#sAddrHouse').removeClass('is-valid').addClass('is-invalid');
$("#sAddrHouse.invalid-feedback").show();
err = 1;
} else {
$('#sAddrHouse').removeClass('is-invalid').addClass('is-valid');
$("#sAddrHouse.invalid-feedback").hide();
}
var flat_patt = /^\d{1,3}$/;
if (inpFlat + 0 == 0 || !flat_patt.test(inpFlat)) {
$('#tAddrFlat').removeClass('is-valid').addClass('is-invalid');
$("#tAddrFlat.invalid-feedback").show();
err = 1;
} else {
$('#tAddrFlat').removeClass('is-invalid').addClass('is-valid');
$("#tAddrFlat.invalid-feedback").hide();
}
if (err == 1) return false;
var inp = inpHouse + lz(inpFlat,3);
var inp_patt = /^\d{4}$/;
if (inp_patt.test(inp))
{
$(".invalid-feedback").hide();
$('#sAddrHouse').removeClass('is-invalid');
$('#tAddrFlat').removeClass('is-invalid');
$('#out').append(spinner.el);
$.get('/cgi-bin/adm_ows_show.py', { aid:inp })
.done(function(result){
$('#out').html(result);
})
.fail(function(){
$('#out').html('Вибачте, виникла помилка!');
});
}
});
</script>
_tpl/adm/ows_show_table.htm
<table class="table table-striped">
<thead>
<tr>
<th scope="col">owid</th>
<th scope="col">name</th>
<th scope="col">home<br/>flat<br/>door</th>
<th scope="col">cars</th>
<th scope="col">tel1<br/>tel2<br/>tel3</th>
<th scope="col">email</th>
<th scope="col">st</th>
<!-- <th scope="col">cons</th> -->
<th scope="col">edit</th>
</tr>
</thead>
<tbody>
{{ TABLE_BODY }}
</tbody>
</table>
_tpl/adm/ows_show_table_row.htm
<tr>
<td>{{ OWID }}</td>
<td>{{ LNAME }}<br/>
{{ FNAME }}<br/>
{{ SNAME }}</td>
<td>{{ HOUSE }}<br/>{{ FLAT }}<br/>{{ DOOR }}</td>
{% if CAR and not NOCAR %}
<td class="alert-success text-center">{{ CAR }}</td>
{% elif CAR and NOCAR %}
<td class="alert-danger text-center">~~ NO CAR ~~<br>{{ CAR }}</td>
{% elif not CAR and NOCAR %}
<td class="alert-danger text-center">NO CAR</td>
{% else %}
<td class="text-center">NO</td>
{% endif %}
<td>{{ TEL1 }}<br/>{{ TEL2 }}<br/>{{ TEL3 }}</td>
<td>{{ EMAIL }}<br/><small>not confirmed!</small></td>
<td>{{ STATE }}</td>
<!-- <td class="{% if CONSENT=='N' %}alert-danger{% endif %} text-center">{{ CONSENT }}</td> -->
<td>
<form action="/adm/ow/{{ OWID }}/" method="POST">
<button type="submit" class="btn btn-outline-success btn-sm w-100">Edit Owner</button>
</form>
<form action="/adm/ow/add/{{ OWID }}/" method="POST" class="mt-2">
<button type="submit" class="btn btn-outline-info btn-sm w-100">Add Owner</button>
</form>
</td>
</tr>
#!/usr/local/bin/python3.7
import cgi
import re
from lib import aInit
from lib import aCom
from lib import aJ2 as j2
from lib.aDB import get_owners_by_flat, get_owner_cars_brands
SCRIPT_NAME = 'adm_ow_show.py'
form = cgi.FieldStorage()
aid = form.getfirst('aid','none')
s = re.search('^\d\d\d\d$', aid)
if not s:
j2.alert('danger', 'ERR_INCORRECT_ADDRESS_ID', f"id: {aid}")
else:
house, flat = aCom.addr_split(aid)
if house == 0 or flat == 0:
j2.alert('danger', 'ERR_INCORRECT_ADDRESS_ID', f"к.{house} / кв.{flat}")
else:
ows_list = get_owners_by_flat(house, flat)
if not len(ows_list):
j2.alert('warning', 'NOBODY_LIVES_HERE', f"к.{house} / кв.{flat} | <a href='/adm/ow/add/{aid}/'>Зареєструвати</a>")
else:
table_rows_rendered = ''
for item in ows_list: # item = Row(cid=129, num='AA0000KT', brand='VAZ', model='2109', color='BLU')
tpl_vars = dict(
OWID = item.owid,
LNAME = item.lname,
FNAME = item.fname,
SNAME = item.sname,
HOUSE = item.house,
DOOR = item.door,
FLAT = item.flat,
EMAIL = item.email,
NOCAR = 1 if item.nocar == 'NO CAR' else 0,
CAR = '<br>'.join(get_owner_cars_brands(item.owid)),
STATE = item.owstate,
TEL1 = aCom.tel_template(item.tel1),
TEL2 = aCom.tel_template(item.tel2),
TEL3 = aCom.tel_template(item.tel3),
APID = aCom.addr_join(item.house, item.flat),
)
table_rows_rendered += j2.render('adm/ows_show_table_row.htm', tpl_vars)
# for
tpl_vars = dict(
TABLE_BODY = table_rows_rendered,
)
print(j2.render('adm/ows_show_table.htm', tpl_vars))