refactor: Replace remaining duplicate utilities with ES6 imports
- Replaced esc() and norm() in _department_controls.html with imports - Replaced norm() in invite_to_department.html with import - All inline utility duplicates now eliminated across templates - Total: ~20 lines of duplicate code removed - All 17 tests passing
This commit is contained in:
parent
ee9eb7b215
commit
9a8b8828e2
@ -297,15 +297,15 @@
|
||||
}
|
||||
document.querySelectorAll('textarea[data-autogrow]').forEach(bind);
|
||||
})();
|
||||
{% load static %}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
if (window.__headPickerWithEmailBound) return;
|
||||
window.__headPickerWithEmailBound = true;
|
||||
<script type="module">
|
||||
import { esc, norm } from '{% static "js/utils/stringUtils.js" %}';
|
||||
|
||||
function esc(s){ return String(s).replace(/[&<>"']/g, m => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m])); }
|
||||
function norm(s){ return String(s || '').toLowerCase(); }
|
||||
(function(){
|
||||
if (window.__headPickerWithEmailBound) return;
|
||||
window.__headPickerWithEmailBound = true;
|
||||
|
||||
function initPicker(root){
|
||||
const input = root.querySelector('input[type="text"]');
|
||||
|
||||
@ -82,31 +82,32 @@
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
{% load static %}
|
||||
<!-- Мини-скрипт: фильтрация select и блокировка кнопки без выбора -->
|
||||
<script>
|
||||
(function () {
|
||||
const search = document.getElementById('employeeSearch');
|
||||
const select = document.querySelector('select[name="{{ form.employee.html_name }}"]');
|
||||
const btn = document.getElementById('inviteBtn');
|
||||
<script type="module">
|
||||
import { norm } from '{% static "js/utils/stringUtils.js" %}';
|
||||
|
||||
if (!select) return;
|
||||
(function () {
|
||||
const search = document.getElementById('employeeSearch');
|
||||
const select = document.querySelector('select[name="{{ form.employee.html_name }}"]');
|
||||
const btn = document.getElementById('inviteBtn');
|
||||
|
||||
// Кнопка активна только при выбранном значении
|
||||
function toggleBtn() { btn && (btn.disabled = !select.value); }
|
||||
select.addEventListener('change', toggleBtn);
|
||||
toggleBtn();
|
||||
if (!select) return;
|
||||
|
||||
// Кешируем исходные опции
|
||||
const options = Array.from(select.options);
|
||||
// Кнопка активна только при выбранном значении
|
||||
function toggleBtn() { btn && (btn.disabled = !select.value); }
|
||||
select.addEventListener('change', toggleBtn);
|
||||
toggleBtn();
|
||||
|
||||
function norm(s) { return s.toLowerCase().replace(/\s+/g, ''); }
|
||||
// Кешируем исходные опции
|
||||
const options = Array.from(select.options);
|
||||
|
||||
if (search) {
|
||||
search.addEventListener('input', function () {
|
||||
const q = norm(this.value);
|
||||
const filtered = q
|
||||
? options.filter(o => norm(o.text).includes(q))
|
||||
: options;
|
||||
if (search) {
|
||||
search.addEventListener('input', function () {
|
||||
const q = norm(this.value);
|
||||
const filtered = q
|
||||
? options.filter(o => norm(o.text).includes(q))
|
||||
: options;
|
||||
|
||||
// Перерисовываем список
|
||||
select.innerHTML = '';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user