Corp/backend/templates/feed/post_form.html
Игорь Надеин 2cc14bc208 refactor: Extract post form textarea autogrow styles
- Created: static/css/components/post-form.css (textarea.autogrow with min/max height, overflow control)
- Modified: templates/feed/post_form.html (replaced inline styles with CSS import)
- Description: Extracted 13-line style block for autogrow textarea behavior
- Result: Post form now uses reusable component CSS
2025-10-28 10:10:07 +03:00

156 lines
5.7 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends 'base.html' %}
{% load static django_bootstrap5 %}
{% block title %}
{% if is_update %}Редактировать{% else %}Создать{% endif %} публикацию
{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{% static 'css/components/post-form.css' %}">
{% endblock %}
{% block content %}
<!-- Header (без кнопки Отмена) -->
<div class="d-flex align-items-center justify-content-between mb-3">
<div class="d-flex align-items-center gap-2">
<i class="bi-megaphone fs-3 text-primary"></i>
<h2 class="mb-0">
{% if is_update %}Редактировать{% else %}Создать{% endif %} публикацию
</h2>
{% if context_type == 'department' and department %}
<span class="badge bg-secondary">Отдел: {{ department.name }}</span>
{% elif context_type == 'company' %}
<span class="badge bg-secondary">Компания</span>
{% elif context_type == 'employee' %}
<span class="badge bg-secondary">Личная публикация</span>
{% endif %}
</div>
</div>
<!-- Form -->
<form method="post" enctype="multipart/form-data" class="card shadow-sm border-0">
<div class="card-body">
{% csrf_token %}
<div class="row g-4">
<div class="col-lg-8">
{% if form.title %}{% bootstrap_field form.title %}{% endif %}
{% if form.body %}{% bootstrap_field form.body %}{% endif %}
{% if form.type %}{{ form.type }}{% endif %}
{% if form.department %}{% bootstrap_field form.department %}{% endif %}
</div>
<div class="col-lg-4">
<div class="border rounded-3 p-3">
<div class="mb-3">
<div class="fw-semibold mb-2">Изображение</div>
{% if form.instance.pk and form.instance.image %}
<div class="mb-2">
<img src="{{ form.instance.image.url }}" alt="Превью" class="img-fluid rounded" id="currentImagePreview">
</div>
{% endif %}
{% if form.image %}{% bootstrap_field form.image %}{% endif %}
<img id="newImagePreview" class="img-fluid rounded d-none" alt="Превью выбранного изображения">
</div>
<div>
<div class="fw-semibold mb-2">Вложение</div>
{% if form.instance.pk and form.instance.attachment %}
<p class="mb-2">
Текущее вложение:
<a href="{{ form.instance.attachment.url }}" target="_blank">
{{ form.instance.attachment.name|cut:"feed/attachments/" }}
</a>
</p>
{% endif %}
{% if form.attachment %}{% bootstrap_field form.attachment %}{% endif %}
</div>
</div>
</div>
</div>
<!-- Actions: одна Отмена -->
<div class="mt-4 d-flex align-items-center gap-2">
<button type="submit" class="btn btn-success">
<i class="bi-check2"></i> Сохранить
</button>
{% if cancel_url %}
<a href="{{ cancel_url }}" class="btn btn-outline-secondary">Отмена</a>
{% else %}
<a href="javascript:history.back()" class="btn btn-outline-secondary">Отмена</a>
{% endif %}
{% if form.instance.pk %}
<a href="{% url 'feed:post_delete' form.instance.pk %}?next={{ cancel_url|urlencode }}"
class="btn btn-outline-danger ms-auto">
<i class="bi-trash"></i> Удалить
</a>
{% endif %}
</div>
</div>
</form>
</div>
<script>
(function () {
const input = document.getElementById("id_image");
const preview = document.getElementById("newImagePreview");
if (!input || !preview) return;
input.addEventListener("change", function (e) {
const file = e.target.files && e.target.files[0];
if (!file) {
preview.classList.add("d-none");
preview.src = "";
return;
}
const url = URL.createObjectURL(file);
preview.src = url;
preview.classList.remove("d-none");
});
})();
</script>
<script>
(function(){
const form = document.querySelector('form.card'); // твоя форма публикации
if (!form) return;
// навешиваем класс и обработчики на все textarea внутри формы
const areas = Array.from(form.querySelectorAll('textarea'));
if (!areas.length) return;
areas.forEach(el => {
el.classList.add('autogrow');
autoSize(el);
el.addEventListener('input', () => autoSize(el));
});
// подгонка при смене размеров окна (перелом колонок и т.п.)
let raf;
window.addEventListener('resize', () => {
cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => areas.forEach(autoSize));
});
function autoSize(el){
// сброс высоты -> вычисление по контенту
el.classList.remove('is-max');
el.style.height = 'auto';
const borderBox = getComputedStyle(el).boxSizing === 'border-box';
const style = getComputedStyle(el);
const border = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
const desired = el.scrollHeight + (borderBox ? 0 : border);
el.style.height = desired + 'px';
// если упёрлись в max-height — включаем скролл
const maxH = parseFloat(style.maxHeight);
if (!Number.isNaN(maxH) && desired >= maxH) {
el.style.height = style.maxHeight;
el.classList.add('is-max');
}
}
})();
</script>
{% endblock %}