Files
fzjg_local/fzjgact/huodong/templates/contact_list.html

310 lines
14 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" %}
{% block content %}
<div class="container mx-auto p-4">
<h2 class="text-xl font-bold mb-4">联系人信息</h2>
<!-- 新增筛选表单 -->
<form method="GET" class="mb-4 p-4 bg-gray-100 rounded-lg" id="filterForm">
<div class="flex flex-wrap gap-4">
<!-- 分支机构筛选(带搜索的下拉框) -->
<div class="flex flex-col w-full md:w-1/3">
<label class="text-sm font-medium">分支机构</label>
<div class="relative" id="branchSelectContainer">
<!-- 选择框主体 -->
<div class="relative">
<input
type="text"
id="branchSearchInput"
class="w-full pl-4 pr-10 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-300 focus:border-blue-500 outline-none text-sm"
placeholder="输入分支机构名称搜索..."
readonly
onclick="toggleBranchDropdown()"
>
<span class="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 transition-transform duration-200" id="branchArrowIcon">
<i class="fa fa-chevron-down"></i>
</span>
<!-- 隐藏的分支机构ID输入框用于表单提交 -->
<input type="hidden" name="branch" id="selectedBranchId">
</div>
<!-- 下拉内容 -->
<div id="branchDropdownContent" class="absolute z-10 mt-1 w-full bg-white rounded-lg shadow-md overflow-hidden hidden">
<!-- 搜索输入框 -->
<div class="p-2 border-b border-gray-100">
<input
type="text"
id="branchFilterInput"
class="w-full px-3 py-2 border border-gray-200 rounded-lg focus:ring-1 focus:ring-blue-300 focus:border-blue-500 outline-none text-sm"
placeholder="搜索分支机构..."
oninput="filterBranchOptions()"
autofocus
>
</div>
<!-- 选项列表 -->
<div id="branchOptionsList" class="max-h-60 overflow-y-auto">
<ul>
{% for branch in branches %}
<li class="branch-option px-4 py-2.5 hover:bg-gray-100 cursor-pointer text-sm transition-colors"
data-id="{{ branch.id }}"
data-name="{{ branch.name }}">
{{ branch.name }}
</li>
{% endfor %}
</ul>
</div>
<!-- 无结果提示 -->
<div id="branchNoResult" class="px-4 py-4 text-center text-gray-500 text-sm hidden">
没有找到匹配的分支机构
</div>
</div>
</div>
</div>
<!-- 联系人类别筛选(改为带搜索的下拉框) -->
<div class="flex flex-col w-full md:w-1/3">
<label class="text-sm font-medium">联系人类别</label>
<div class="relative" id="categorySelectContainer">
<div class="relative">
<input
type="text"
id="categorySearchInput"
class="w-full pl-4 pr-10 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-300 focus:border-blue-500 outline-none text-sm"
placeholder="输入类别名称搜索..."
readonly
onclick="toggleCategoryDropdown()"
value="{{ selected_category|default:'' }}"
>
<span class="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 transition-transform duration-200" id="categoryArrowIcon">
<i class="fa fa-chevron-down"></i>
</span>
<input type="hidden" name="category" id="selectedCategory">
</div>
<div id="categoryDropdownContent" class="absolute z-10 mt-1 w-full bg-white rounded-lg shadow-md overflow-hidden hidden">
<div class="p-2 border-b border-gray-100">
<input
type="text"
id="categoryFilterInput"
class="w-full px-3 py-2 border border-gray-200 rounded-lg focus:ring-1 focus:ring-blue-300 focus:border-blue-500 outline-none text-sm"
placeholder="搜索联系人类别..."
oninput="filterCategoryOptions()"
autofocus
>
</div>
<div id="categoryOptionsList" class="max-h-60 overflow-y-auto">
<ul>
{% for cat in categories %}
<li class="category-option px-4 py-2.5 hover:bg-gray-100 cursor-pointer text-sm transition-colors"
data-value="{{ cat }}">
{{ cat }}
</li>
{% endfor %}
</ul>
</div>
<div id="categoryNoResult" class="px-4 py-4 text-center text-gray-500 text-sm hidden">
没有找到匹配的类别
</div>
</div>
</div>
</div>
<!-- 联系人姓名筛选(保持原结构) -->
<div class="flex flex-col w-full md:w-1/3">
<label class="text-sm font-medium">联系人姓名</label>
<input type="text" name="contact_name" class="mt-1 p-2 border rounded" placeholder="输入联系人姓名筛选" value="{{ selected_contact_name|default:'' }}">
</div>
<div class="flex items-end">
<button type="submit" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">筛选</button>
</div>
</div>
</form>
<table class="min-w-full border-collapse border border-gray-300">
<thead>
<tr>
<th class="p-2 border border-gray-300 bg-gray-100">分支机构</th>
<th class="p-2 border border-gray-300 bg-gray-100">分类</th>
<th class="p-2 border border-gray-300 bg-gray-100">姓名</th>
<th class="p-2 border border-gray-300 bg-gray-100">电话</th>
<th class="p-2 border border-gray-300 bg-gray-100">邮箱</th>
</tr>
</thead>
<tbody>
{% for contact in contacts %}
<tr class="{% cycle 'bg-white' 'bg-gray-50' %}">
<td class="p-2 border border-gray-300">{{ contact.branch.name }}</td>
<td class="p-2 border border-gray-300">{{ contact.category|default:"" }}</td>
<td class="p-2 border border-gray-300">{{ contact.name|default:"" }}</td>
<td class="p-2 border border-gray-300">{{ contact.phone|default:"" }}</td>
<td class="p-2 border border-gray-300">{{ contact.email|default:"" }}</td>
</tr>
{% empty %}
<tr>
<td colspan="5" class="p-4 text-center text-gray-500">没有找到匹配的联系人</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script>
// 控制分支机构下拉框显示/隐藏
function toggleBranchDropdown() {
const dropdown = document.getElementById('branchDropdownContent');
const arrow = document.getElementById('branchArrowIcon');
if (dropdown.classList.contains('hidden')) {
dropdown.classList.remove('hidden');
arrow.classList.add('rotate-180');
document.getElementById('branchFilterInput').focus();
document.addEventListener('click', handleBranchOutsideClick);
} else {
closeBranchDropdown();
}
}
// 关闭分支机构下拉框
function closeBranchDropdown() {
const dropdown = document.getElementById('branchDropdownContent');
const arrow = document.getElementById('branchArrowIcon');
dropdown.classList.add('hidden');
arrow.classList.remove('rotate-180');
document.removeEventListener('click', handleBranchOutsideClick);
}
// 点击外部关闭下拉框
function handleBranchOutsideClick(event) {
const container = document.getElementById('branchSelectContainer');
if (!container.contains(event.target)) {
closeBranchDropdown();
}
}
// 筛选分支机构选项
function filterBranchOptions() {
const searchText = document.getElementById('branchFilterInput').value.toLowerCase();
const options = document.querySelectorAll('.branch-option');
const noResult = document.getElementById('branchNoResult');
let hasMatch = false;
let firstMatch = null;
options.forEach(option => {
const name = option.dataset.name.toLowerCase();
if (name.includes(searchText)) {
option.style.display = 'block';
hasMatch = true;
if (!firstMatch) firstMatch = option;
} else {
option.style.display = 'none';
}
});
noResult.classList.toggle('hidden', hasMatch);
// 自动滚动到第一个匹配项
if (firstMatch) {
firstMatch.scrollIntoView({block: 'nearest'});
firstMatch.classList.add('bg-blue-50');
setTimeout(() => firstMatch.classList.remove('bg-blue-50'), 1000);
}
}
// 选择分支机构选项
document.querySelectorAll('.branch-option').forEach(option => {
option.addEventListener('click', function() {
const name = this.dataset.name;
const id = this.dataset.id;
document.getElementById('branchSearchInput').value = name;
document.getElementById('selectedBranchId').value = id;
closeBranchDropdown();
});
});
// 键盘导航(可选)
document.getElementById('branchFilterInput').addEventListener('keydown', function(e) {
const options = document.querySelectorAll('.branch-option:not([style*="display: "])');
const active = document.querySelector('.branch-option.bg-gray-100');
let index = -1;
if (active) index = Array.from(options).indexOf(active);
if (e.key === 'ArrowDown') {
e.preventDefault();
if (active) active.classList.remove('bg-gray-100');
const next = (index + 1) % options.length;
options[next]?.classList.add('bg-gray-100');
options[next]?.scrollIntoView({ block: 'nearest' });
} else if (e.key === 'ArrowUp') {
e.preventDefault();
if (active) active.classList.remove('bg-gray-100');
const prev = index > 0 ? index - 1 : options.length - 1;
options[prev]?.classList.add('bg-gray-100');
options[prev]?.scrollIntoView({ block: 'nearest' });
} else if (e.key === 'Enter') {
e.preventDefault();
active?.click();
}
});
// 新增联系人类别下拉框控制函数
function toggleCategoryDropdown() {
const dropdown = document.getElementById('categoryDropdownContent');
const arrow = document.getElementById('categoryArrowIcon');
if (dropdown.classList.contains('hidden')) {
dropdown.classList.remove('hidden');
arrow.classList.add('rotate-180');
document.getElementById('categoryFilterInput').focus();
document.addEventListener('click', handleCategoryOutsideClick);
} else {
closeCategoryDropdown();
}
}
function closeCategoryDropdown() {
const dropdown = document.getElementById('categoryDropdownContent');
const arrow = document.getElementById('categoryArrowIcon');
dropdown.classList.add('hidden');
arrow.classList.remove('rotate-180');
document.removeEventListener('click', handleCategoryOutsideClick);
}
function handleCategoryOutsideClick(event) {
const container = document.getElementById('categorySelectContainer');
if (!container.contains(event.target)) {
closeCategoryDropdown();
}
}
function filterCategoryOptions() {
const searchText = document.getElementById('categoryFilterInput').value.toLowerCase();
const options = document.querySelectorAll('.category-option');
const noResult = document.getElementById('categoryNoResult');
let hasMatch = false;
options.forEach(option => {
const value = option.dataset.value.toLowerCase();
if (value.includes(searchText)) {
option.style.display = 'block';
hasMatch = true;
} else {
option.style.display = '';
}
});
noResult.classList.toggle('hidden', hasMatch || !searchText);
}
document.querySelectorAll('.category-option').forEach(option => {
option.addEventListener('click', function() {
const value = this.dataset.value;
document.getElementById('categorySearchInput').value = value;
document.getElementById('selectedCategory').value = value;
closeCategoryDropdown();
});
});
</script>
{% endblock %}