Files
Voting/templates/dyn_dt/model.html
Victor Alexandrovich Tsyrenschikov 42ed1b04cb Django
2025-11-21 00:02:57 +05:00

585 lines
36 KiB
HTML

{% extends "layouts/base.html" %}
{% load static get_attribute %}
{% block title %} {% if page_title %} {{page_title}} {% else %} Dynamic DataTables {% endif %} {% endblock title %}
{% block extrastyle %}
<style>
.hide-show-dropdown {
max-height: 350px;
overflow-y: scroll;
}
.page-size .export-csv-img {
width: 35px;
cursor: pointer;
}
.export-img {
width: 30px;
}
.modal-header {
display: block !important;
}
.height{
height: 40px !important;
}
.table-row {
position: relative;
}
.action-td {
position: absolute;
left: 50%;
right: 50%;
bottom: -5px;
}
.table-row:hover .data-td {
opacity: 0.1;
}
.table-row:hover .action-td {
display: flex !important;
gap:3px !important;
}
</style>
{% endblock extrastyle %}
{% block content %}
<div class="container-fluid py-2">
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="d-flex justify-content-between my-4">
<form class="search">
<div class="d-flex gap-2 align-items-center">
<div class="mr-3">
<input type="text" placeholder="Search for items" name="search" id="" class="form-control border ps-2">
</div>
<button type="submit" class="btn mb-0 btn-primary">
<i class="material-symbols-rounded opacity-5">search</i>
</button>
</div>
</form>
<div class="">
<form method="post">
<div class="dropdown">
<button class="btn mb-0 btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Hide / Show Column
</button>
<div id="dropdownDefaultCheckbox">
<ul class="dropdown-menu hide-show-dropdown px-3">
{% for field_name in field_names %}
<div class="form-check mb-2 ps-0">
<input class="form-check-input" {% if field_name.value %} checked {% endif %} type="checkbox" data-bs-target="{{ field_name.key }}" value="" id="checkbox-item-{{ field_name.id }}">
<label class="form-check-label" for="checkbox-item-{{ field_name.id }}">
{{ field_name.key }}
</label>
</div>
{% endfor %}
</ul>
</div>
</div>
</form>
</div>
<div class="page-size form-group mb-2">
<div class="d-flex gap-2">
<form method="post" class="">
{% csrf_token %}
<select onchange="getPageItems(this)" name="" id="" class="form-select border ps-2">
<option {% if page_items == 5 %} selected {% endif %} value="5">5 Items</option>
<option {% if page_items == 10 %} selected {% endif %} value="10">10 Items</option>
<option {% if page_items == 15 %} selected {% endif %} value="15">15 Items</option>
<option {% if page_items == 25 %} selected {% endif %} value="25">25 Items</option>
<option {% if page_items == 50 %} selected {% endif %} value="50">50 Items</option>
<option {% if page_items == 100 %} selected {% endif %} value="100">100 Items</option>
</select>
</form>
<div class="d-flex ">
<a data-bs-toggle="modal" data-bs-target="#exportCSV">
<img class="export-csv-img" style="width: 40px" src="{% static "img/csv.png" %}" alt="img">
</a>
</div>
{% if request.user.is_authenticated %}
<div>
<button data-bs-toggle="modal" data-bs-target="#addSales" type="button" class="btn mb-0 btn-primary p-0 px-3 py-2 ">
Add
</button>
</div>
{% endif %}
</div>
</div>
</div>
<div>
<form action="{% url "create_filter" link %}" method="post">
{% csrf_token %}
<div class="d-flex align-items-center gap-3 mb-3">
<h3 class="">Filters</h3>
<button id="addButton" type="button" class="btn mb-0 btn-primary">Add</button>
</div>
<div class="mb-3" id="inputContainer">
{% if filter_instance %}
{% for filter_data in filter_instance %}
<div class="d-flex gap-3 mb-3">
<div class="d-flex gap-2">
<select name="key" id="" class="form-select border ps-2 w-50">
{% for field in db_field_names %}
<option {% if filter_data.key == field %}selected{% endif %} value="{{ field }}">{{ field }}</option>
{% endfor %}
</select>
<input type="text" value="{{ filter_data.value }}" placeholder="Enter value" name="value" id="" class="form-control border ps-2">
</div>
<a href="{% url "delete_filter" link filter_data.id %}" class="remove-button btn mb-0 btn-danger">X</a>
</div>
{% endfor %}
{% endif %}
</div>
<button id="submitButton" type="submit" {% if not filter_instance %} style="display: none;" {% endif %} class="btn mb-0 btn-success">Submit</button>
</form>
<div class="card-body">
<div class="dt-responsive table-responsive">
<table class="table">
<thead>
<tr>
{% for field in db_field_names %}
<th class="px-2" id="th_{{ field }}" scope="col">{{ field }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for item in items %}
<tr class="align-middle table-row">
{% for field_name in db_field_names %}
<td class="td_{{ field_name }} data-td">{{ item|getattribute:field_name }}</td>
{% endfor %}
{% if request.user.is_authenticated %}
<td class="d-none action-td" >
<a data-bs-toggle="modal" data-bs-target="#editSales-{{item.id}}" class="btn mb-0 btn-primary btn-sm p-0 px-3 pe-4 ps-2 py-2" href="#">
<i style="font-size: 14px;" class="material-symbols-rounded opacity-5">edit</i>
</a>
<a data-bs-toggle="modal" data-bs-target="#deleteSales-{{item.id}}" class="btn mb-0 btn-primary btn-sm p-0 px-3 pe-4 ps-2 py-2" href="#">
<i style="font-size: 14px;" class="material-symbols-rounded opacity-5">delete</i>
</a>
</td>
{% else %}
<td class="d-none action-td">
<a data-bs-toggle="modal" data-bs-target="#viewSales-{{item.id}}" class="btn mb-0 btn-primary btn-sm p-0 px-3 pe-4 ps-2 py-2" href="#">
<i style="font-size: 14px;" class="material-symbols-rounded opacity-5">visibility</i>
</a>
</td>
{% endif %}
</tr>
<!-- Edit Sales -->
<div class="modal fade" id="editSales-{{item.id}}" tabindex="-1" aria-labelledby="editSalesLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header">
<div class="d-flex justify-content-between">
<div>
<h1 class="modal-title fs-5" id="editSalesLabel">Edit {{ link|capfirst }}</h1>
</div>
<div>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
<div class="modal-body">
<form action="{% url "update" link item.id %}" method="post">
{% csrf_token %}
<div class="row">
<!-- FKs -->
{% for key, values in fk_fields.items %}
<div class="col-md-6">
<div class="form-group mb-2">
<label for="id_{{ key }}" class="form-label ml-0">{{ key|title }}</label>
<select class="form-control border ps-2" name="{{ key }}" id="id_{{ key }}">
{% for i in values %}
<option value="{{ i.id }}">{{ i }}</option>
{% endfor %}
</select>
</div>
</div>
{% endfor %}
{% for field_name in db_field_names %}
{% if field_name not in read_only_fields and field_name not in fk_fields_keys %}
<div class="col-md-6">
<div class="form-group mb-2">
<label for="id_{{ field_name }}" class="form-label ml-0">{{ field_name|title }}</label>
{% if field_name in choices_dict %}
<select name="{{ field_name }}" id="id_{{ field_name }}" class="form-select border ps-2">
<option value="">Select {{ field_name }}</option>
{% for key, value in choices_dict|get:field_name %}
<option {% if item|getattribute:field_name == key %} selected {% endif %} value="{{ key }}">{{ value }}</option>
{% endfor %}
</select>
{% else %}
{% if field_name in integer_fields %}
<input type="number" name="{{ field_name }}" value="{{ item|getattribute:field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% elif field_name in date_time_fields %}
<input type="datetime-local" name="{{ field_name }}" value="{{ item|getattribute:field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% elif field_name in email_fields %}
<input type="email" name="{{ field_name }}" value="{{ item|getattribute:field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% elif field_name in text_fields %}
<input type="text" name="{{ field_name }}" value="{{ item|getattribute:field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% else %}
<input type="text" name="{{ field_name }}" value="{{ item|getattribute:field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% endif %}
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
</div>
<div class="mt-3">
<button type="submit" class="btn mb-0 btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Delete Sales -->
<div class="modal fade" id="deleteSales-{{item.id}}" tabindex="-1" aria-labelledby="deleteSalesLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<div class="d-flex justify-content-between">
<div>
<h1 class="modal-title fs-5" id="deleteSalesLabel">Delete Item</h1>
</div>
<div>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
<div class="modal-body">
<h5>Are you sure you want to delete this item?</h5>
</div>
<div class="modal-footer">
<button type="button" class="btn mb-0 btn-secondary" data-bs-dismiss="modal">Close</button>
<a href="{% url "delete" link item.id %}" class="btn mb-0 btn-danger">Delete</a>
</div>
</div>
</div>
</div>
<!-- View Sales -->
<div class="modal fade" id="viewSales-{{item.id}}" tabindex="-1" aria-labelledby="viweSalesLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header">
<div class="d-flex justify-content-between">
<div>
<h1 class="modal-title fs-5" id="viewSalesLabel">View {{ link|capfirst }}</h1>
</div>
<div>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
<div class="modal-body">
<form action="{% url "update" link item.id %}" method="post">
{% csrf_token %}
<div class="row">
{% for field_name in db_field_names %}
<div class="col-md-6">
<div class="form-group mb-2">
<label for="{{ field_name }}" class="form-label ml-0">{{ field_name|title }}</label>
<input readonly type="text" value="{{ item|getattribute:field_name }}" name="{{ field_name }}" id="{{ field_name }}" class="form-control border ps-2">
</div>
</div>
{% endfor %}
</div>
</form>
</div>
</div>
</div>
</div>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% if items.has_other_pages %}
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
{% if items.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ items.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Previous</span>
</a>
</li>
{% endif %}
{% for n in items.paginator.page_range %}
{% if items.number == n %}
<li class="page-item active"><a class="page-link">{{ n }}</a></li>
{% elif n > items.number|add:'-3' and n < items.number|add:'3' %}
<li class="page-item"><a class="page-link" href="?page={{n}}">{{ n }}</a></li>
{% endif %}
{% endfor %}
{% if items.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ items.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
</div>
<!-- Export as CSV -->
<div class="modal fade" id="exportCSV" tabindex="-1" aria-labelledby="exportCSVLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header">
<div class="d-flex justify-content-between">
<div>
<h1 class="modal-title fs-5" id="exportCSVLabel">Export as CSV</h1>
</div>
<div>
{% if request.GET.order_by or request.GET.search %}
{% with order_by=request.GET.order_by search=request.GET.search %}
<a href="{% url 'export_csv' link %}?{% if order_by %}order_by={{ order_by }}{% endif %}{% if order_by and search %}&{% endif %}{% if search %}search={{ search }}{% endif %}">
<img style="width: 30px" class="export-img" src="{% static 'img/export.png' %}" alt="">
</a>
{% endwith %}
{% else %}
<a href="{% url 'export_csv' link %}">
<img style="width: 30px" class="export-img" src="{% static 'img/export.png' %}" alt="">
</a>
{% endif %}
</div>
<div>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
<div class="modal-body">
{% include "dyn_dt/items-table.html" with items=items %}
</div>
</div>
</div>
</div>
<!-- Add Sales -->
<div class="modal fade" id="addSales" tabindex="-1" aria-labelledby="addSalesLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header">
<div class="d-flex justify-content-between">
<div>
<h1 class="modal-title fs-5" id="addSalesLabel">Add {{ link|capfirst }}</h1>
</div>
<div>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
<div class="modal-body">
<form method="post" action="{% url "create" link %}" class="row">
{% csrf_token %}
<!-- FKs -->
{% for key, values in fk_fields.items %}
<div class="col-md-6">
<div class="form-group mb-2">
<label for="id_{{ key }}" class="form-label ml-0">{{ key|title }}</label>
<select class="form-control border ps-2" name="{{ key }}" id="id_{{ key }}">
{% for i in values %}
<option value="{{ i.id }}">{{ i }}</option>
{% endfor %}
</select>
</div>
</div>
{% endfor %}
{% for field_name in db_field_names %}
{% if field_name not in read_only_fields and field_name not in fk_fields_keys %}
<div class="col-md-6">
<div class="form-group mb-2">
<label for="id_{{ field_name }}" class="form-label ml-0">{{ field_name|title }}</label>
{% if field_name in choices_dict %}
<select name="{{ field_name }}" id="id_{{ field_name }}" class="form-select border ps-2">
<option value="">Select {{ field_name }}</option>
{% for key, value in choices_dict|get:field_name %}
<option value="{{ key }}">{{ value }}</option>
{% endfor %}
</select>
{% else %}
{% if field_name in integer_fields %}
<input type="number" name="{{ field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% elif field_name in date_time_fields %}
<input type="datetime-local" name="{{ field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% elif field_name in email_fields %}
<input type="email" name="{{ field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% else %}
<input type="text" name="{{ field_name }}" class="form-control border ps-2" placeholder="{{ field_name }}" id="id_{{ field_name }}">
{% endif %}
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
<div class="mt-3">
<button type="submit" class="btn mb-0 btn-primary">Add</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block extra_js %}
<script>
const link = '{{ link }}';
document.addEventListener('DOMContentLoaded', function () {
var checkboxes = document.querySelectorAll('#dropdownDefaultCheckbox input[type="checkbox"]');
checkboxes.forEach(function (checkbox) {
var targetColumnId = checkbox.getAttribute('data-bs-target');
var targetColumn = document.getElementById('th_' + targetColumnId);
var exportTargetColumn = document.getElementById('th_' + targetColumnId + '_export');
var targetDataCells = document.querySelectorAll('.td_' + targetColumnId);
if (checkbox.checked) {
targetColumn.style.display = 'none';
exportTargetColumn.style.display = 'none';
targetDataCells.forEach(function (dataCell) {
dataCell.style.display = 'none';
});
}
checkbox.addEventListener('change', function () {
var targetColumnId = this.getAttribute('data-bs-target');
var targetColumn = document.getElementById('th_' + targetColumnId);
var exportTargetColumn = document.getElementById('th_' + targetColumnId + '_export');
var targetDataCells = document.querySelectorAll('.td_' + targetColumnId);
if (this.checked) {
targetColumn.style.display = 'none';
exportTargetColumn.style.display = 'none';
targetDataCells.forEach(function (dataCell) {
dataCell.style.display = 'none';
});
} else {
targetColumn.style.display = '';
exportTargetColumn.style.display = '';
targetDataCells.forEach(function (dataCell) {
dataCell.style.display = '';
});
}
fetch(`/create-hide-show-items/${link}/`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': '{{ csrf_token }}',
},
body: JSON.stringify({
key: targetColumnId,
value: this.checked
})
})
});
});
});
</script>
<script>
function getPageItems(selectObject) {
var value = selectObject.value;
fetch(`/create-page-items/${link}/`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': '{{ csrf_token }}',
},
body: `items=${value}`
})
.then(response => {
location.reload()
})
}
</script>
<script>
document.getElementById('addButton').addEventListener('click', function() {
var fieldNames = {{ db_filters|safe }};
var template = `
<div class="input-container d-flex align-items-center gap-3 mb-3">
<div class="d-flex gap-2">
<select name="key" class="form-select border ps-2 w-50">
${fieldNames.map(option => `<option value="${option}">${option}</option>`).join('')}
</select>
<input name="value" class="form-control border ps-2" type="text" placeholder="Enter value">
</div>
<button class="remove-button btn mb-0 btn-danger" onclick="removeInputContainer(this)">X</button>
</div>
`;
var tempDiv = document.createElement('div');
tempDiv.innerHTML = template;
document.getElementById('inputContainer').appendChild(tempDiv);
document.getElementById('submitButton').style.display = 'inline-block';
});
function removeInputContainer(element) {
var inputContainer = element.closest('.input-container');
inputContainer.remove();
var inputContainers = document.getElementsByClassName('input-container');
if (inputContainers.length === 0) {
document.getElementById('submitButton').style.display = 'none';
}
}
</script>
{% endblock extra_js %}