Небольшие доработки

Делитесь своими плагинами и темами оформления.
Ответить
Vidak
Сообщения: 6
Зарегистрирован: 12 окт 2021, 22:04
Имя: Виталий
Откуда: Москва

Небольшие доработки

Сообщение Vidak »

Добрый день, кому надо, есть такая штука, меняет стиль автостатуса
1.png
1.png (11.71 КБ) 2014 просмотров
2.png
Плюсы:
Выводит в древовидной структуре (есть этапы и подэтапы)
Возможность свернуть подэтапы
Разноцветная индикация (выполнен, текущий, будущий)
Возможность скрывать любые этапы
Возможность выводить этапы с зачеркиванием (для невалидных этапов)
Без внесения изменений в код
как пользоваться:
в созданном поле автоматический статус установить тип прямоугольник, можно поставить оба цвета #dddddd00
Настройка страницы записи -> JS код

Код: Выделить всё

autostatustransform("id поля", ["текст статуса для зачеркивания"], ["текст статуса для скрытия"]);
Пример использования:

Код: Выделить всё

const currentText = $('.stages-panel-849 .current').text().trim();
if (currentText !== 'Отменена' && currentText !== 'Нет запросов' && и тд.) {
  autostatustransform('849', [], ["Отменена", "Проект" и тд.]);
} else if (currentText === 'Отменена'){
  autostatustransform('849', ["Отменена"], ["Проект", "Не размещена" и тд.]);
  $('button:contains("Редактировать")').hide();
  $('a:contains("Удалить")').parent().hide();
} else if (currentText === 'Нет запросов'){
  autostatustransform('849', ["Нет запросов"], ["Проект", "Заявки" и тд.]);
  $('button:contains("Редактировать")').hide();
  $('a:contains("Удалить")').parent().hide();
} else if (currentText === 'Нет заявок'){
  autostatustransform('849', ["Нет заявок"], ["Нет запросов", "Проект" и тд.]);
  $('button:contains("Редактировать")').hide();
  $('a:contains("Удалить")').parent().hide();
} else if (currentText === 'ГК заключен'){
  autostatustransform('849', [], ["Проект", "Отменена" и тд.]);
  $('button:contains("Редактировать")').hide();
  $('a:contains("Удалить")').parent().hide();
}
Вложения
autostatustransform.js
(31.58 КБ) 43 скачивания
Vidak
Сообщения: 6
Зарегистрирован: 12 окт 2021, 22:04
Имя: Виталий
Откуда: Москва

Re: Небольшие доработки

Сообщение Vidak »

доработка меню
Использование:
само меню находится в файле
просто подключить
Плюсы:
выпадающее меню с любым числом подменю (можно настроить все что душе угодно)
реагирует на нажатие правой кнопкой мыши
базовый стиль
Минусы:
не понимает уровень доступа пользователей
1.png

Код: Выделить всё

function addCustomSubmenu(menulist) {
    const dropdownMenu = document.querySelector('.dropdown-menu');
    
    // Создаем HTML для подменю
    const submenuHTML = `
    <li class="dropdown-submenu">
        <a href="#" class="submenu-trigger">
            <i class="fa fa-table"></i> Таблицы
        </a>
        <ul class="dropdown-menu-left">
            <li><a href="index.php?module=items/items&path=46" class="submenu-link"><i class="fa fa-files-o"></i> Заявки</a></li>
            <li class="divider"></li>
            <li><a href="index.php?module=items/items&path=61" class="submenu-link"><i class="fa fa-object-group"></i> Планы-графики закупок</a></li>
            <li class="divider"></li>
            <li><a href="index.php?module=reports/view&reports_id=549" class="submenu-link"><i class="fa fa-object-ungroup"></i> Позиции планов-графиков закупок</a></li>
        </ul>
    </li>
    <li class="dropdown-submenu">
        <a href="#" class="submenu-trigger">
            <i class="la la-chart-pie"></i> Отчеты
        </a>
        <ul class="dropdown-menu-left">
            <li><a href="index.php?module=report_page/view&id=8" class="submenu-link"><i class="fa fa-table"></i> Заявленные товары (годовые заявки)</a></li>
            <li class="divider"></li>
            <li><a href="index.php?module=reports/view&reports_id=546" class="submenu-link"><i class="fa fa-calendar-check-o"></i> Сроки полученных ЭЦП</a></li>
            <li class="divider"></li>
            <li><a href="index.php?module=report_page/view&id=14" class="submenu-link"><i class="fa fa-list-alt"></i> Журнал учета полученных коммерческих предложений</a></li>
        </ul>
    </li>
    `;
    
    // Вставляем в начало меню
    dropdownMenu.insertAdjacentHTML('afterbegin', submenuHTML);
    
    // Добавляем обработчики событий
    initSubmenu();
    initContextMenu();
}

// Глобальные переменные для управления состоянием
let currentSubmenu = null;
let contextMenuVisible = false;

// Инициализация контекстного меню
function initContextMenu() {
    const submenuLinks = document.querySelectorAll('.submenu-link');
    
    // Создаем контекстное меню
    const contextMenuHTML = `
        <div id="submenu-context-menu" class="context-menu">
            <ul>
                <li><a href="#" class="context-menu-item" data-action="open-current">Открыть в текущем окне</a></li>
                <li><a href="#" class="context-menu-item" data-action="open-new">Открыть в новом окне</a></li>
            </ul>
        </div>
    `;
    
    document.body.insertAdjacentHTML('beforeend', contextMenuHTML);
    
    let currentTargetLink = null;
    const contextMenu = document.getElementById('submenu-context-menu');
    
    // Функция для скрытия контекстного меню
    function hideContextMenu() {
        contextMenu.style.display = 'none';
        contextMenuVisible = false;
        currentTargetLink = null;
        
        // Если есть активное подменю, убедимся что оно остается видимым
        if (currentSubmenu) {
            currentSubmenu.style.display = 'block';
        }
    }
    
    // Обработчик клика правой кнопкой мыши
    submenuLinks.forEach(link => {
        link.addEventListener('contextmenu', function(e) {
            e.preventDefault();
            e.stopPropagation();
            
            currentTargetLink = this;
            const href = this.getAttribute('href');
            
            // Находим родительское подменю
            const parentSubmenu = this.closest('.dropdown-menu-left');
            if (parentSubmenu) {
                currentSubmenu = parentSubmenu;
                // Блокируем скрытие подменю
                parentSubmenu.classList.add('context-menu-active');
            }
            
            // Сохраняем URL в контекстном меню
            contextMenu.dataset.url = href;
            
            // Позиционируем меню
            const x = e.clientX;
            const y = e.clientY;
            
            contextMenu.style.left = `${x}px`;
            contextMenu.style.top = `${y}px`;
            contextMenu.style.display = 'block';
            contextMenuVisible = true;
            
            // Добавляем обработчик для всего документа
            setTimeout(() => {
                document.addEventListener('click', handleDocumentClick);
                document.addEventListener('contextmenu', handleDocumentContextMenu);
            }, 10);
        });
        
        // Обычный клик левой кнопкой работает как обычно
        link.addEventListener('click', function(e) {
            if (e.button === 0 && !contextMenuVisible) { // Левая кнопка мыши и контекстное меню не активно
                window.location.href = this.getAttribute('href');
            }
        });
    });
    
    // Обработчик клика по документу
    function handleDocumentClick(e) {
        // Если клик не внутри контекстного меню и не по ссылке подменю
        if (!contextMenu.contains(e.target) && !e.target.closest('.submenu-link')) {
            hideContextMenu();
            
            // Убираем блокировку скрытия подменю
            if (currentSubmenu) {
                currentSubmenu.classList.remove('context-menu-active');
                currentSubmenu = null;
            }
            
            // Убираем обработчики
            document.removeEventListener('click', handleDocumentClick);
            document.removeEventListener('contextmenu', handleDocumentContextMenu);
        }
    }
    
    // Обработчик контекстного меню на документе
    function handleDocumentContextMenu(e) {
        // Если правый клик не внутри контекстного меню и не по ссылке подменю
        if (!contextMenu.contains(e.target) && !e.target.closest('.submenu-link')) {
            hideContextMenu();
            
            // Убираем блокировку скрытия подменю
            if (currentSubmenu) {
                currentSubmenu.classList.remove('context-menu-active');
                currentSubmenu = null;
            }
            
            // Убираем обработчики
            document.removeEventListener('click', handleDocumentClick);
            document.removeEventListener('contextmenu', handleDocumentContextMenu);
        }
    }
    
    // Обработчики для пунктов контекстного меню
    contextMenu.addEventListener('click', function(e) {
        const menuItem = e.target.closest('.context-menu-item');
        if (!menuItem || !currentTargetLink) return;
        
        e.preventDefault();
        e.stopPropagation();
        
        const action = menuItem.getAttribute('data-action');
        const url = currentTargetLink.getAttribute('href');
        
        switch(action) {
            case 'open-current':
                window.location.href = url;
                break;
            case 'open-new':
                window.open(url, '_blank');
                break;
        }
        
        hideContextMenu();
        
        // Убираем блокировку скрытия подменю
        if (currentSubmenu) {
            currentSubmenu.classList.remove('context-menu-active');
            currentSubmenu = null;
        }
        
        // Убираем обработчики
        document.removeEventListener('click', handleDocumentClick);
        document.removeEventListener('contextmenu', handleDocumentContextMenu);
    });
    
    // Скрыть контекстное меню при нажатии ESC
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape' && contextMenuVisible) {
            hideContextMenu();
            
            // Убираем блокировку скрытия подменю
            if (currentSubmenu) {
                currentSubmenu.classList.remove('context-menu-active');
                currentSubmenu = null;
            }
            
            // Убираем обработчики
            document.removeEventListener('click', handleDocumentClick);
            document.removeEventListener('contextmenu', handleDocumentContextMenu);
        }
    });
}

// Инициализация функциональности подменю
function initSubmenu() {
    const submenuTriggers = document.querySelectorAll('.dropdown-submenu');
    
    submenuTriggers.forEach(trigger => {
        const submenu = trigger.querySelector('.dropdown-menu-left');
        
        // Показ при наведении
        trigger.addEventListener('mouseenter', function() {
            // Показываем только если контекстное меню не активно
            if (!contextMenuVisible) {
                submenu.style.display = 'block';
            }
        });
        
        // Скрытие при уходе мыши
        trigger.addEventListener('mouseleave', function(e) {
            // Проверяем, не перешла ли мышь на подменю или контекстное меню
            const relatedTarget = e.relatedTarget;
            const contextMenu = document.getElementById('submenu-context-menu');
            
            // Не скрываем если:
            // 1. Мышь перешла на подменю
            // 2. Мышь перешла на контекстное меню
            // 3. Контекстное меню активно
            // 4. Подменю заблокировано для скрытия
            if (submenu.contains(relatedTarget) || 
                (contextMenu && contextMenu.contains(relatedTarget)) ||
                contextMenuVisible ||
                submenu.classList.contains('context-menu-active')) {
                return;
            }
            
            submenu.style.display = 'none';
        });
        
        // Для подменю тоже добавляем обработчик скрытия
        submenu.addEventListener('mouseleave', function(e) {
            const relatedTarget = e.relatedTarget;
            const contextMenu = document.getElementById('submenu-context-menu');
            const parentTrigger = this.closest('.dropdown-submenu');
            
            // Не скрываем если:
            // 1. Мышь перешла на триггер
            // 2. Мышь перешла на контекстное меню
            // 3. Контекстное меню активно
            // 4. Подменю заблокировано для скрытия
            if (parentTrigger.contains(relatedTarget) || 
                (contextMenu && contextMenu.contains(relatedTarget)) ||
                contextMenuVisible ||
                this.classList.contains('context-menu-active')) {
                return;
            }
            
            this.style.display = 'none';
        });
    });
}

// CSS стили для подменю
function addSubmenuStyles() {
    const style = document.createElement('style');
    style.textContent = `
        .dropdown-submenu {
            position: relative;
        }
        
        .dropdown-menu-left {
            display: none;
            position: absolute;
            top: 0;
            right: 100%;
            left: auto;
            background: white;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            min-width: 200px;
            margin-right: 5px;
            list-style: none;
            padding: 0;
            margin: 0;
            z-index: 1000;
        }
        
        .dropdown-menu-left li a {
            padding: 4px 17px 4px 10px;
            color: #333;
            text-decoration: none;
            display: block;
            white-space: nowrap;
            cursor: pointer;
        }
        
        .dropdown-menu-left li a:hover {
            background-color: #f5f5f5;
        }
        
        .dropdown-menu-left .divider {
            height: 1px;
            margin: 5px 0;
            background-color: #e5e5e5;
            overflow: hidden;
        }
        
        .dropdown-submenu:hover .dropdown-menu-left {
            display: block;
        }
        
        .submenu-trigger::after {
            content: ">";
            float: left;
            margin-left: 10px;
        }
        
        .dropdown-menu-left {
            margin-right: -0.5px; /* Перекрываем возможный зазор */
        }
        
        /* Стили для контекстного меню */
        #submenu-context-menu {
            display: none;
            position: fixed;
            background: white;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            min-width: 200px;
            z-index: 10001; /* Выше чем подменю */
            padding: 5px 0;
        }
        
        #submenu-context-menu ul {
            list-style: none;
            margin: 0;
            padding: 0;
        }
        
        #submenu-context-menu li {
            margin: 0;
        }
        
        #submenu-context-menu a {
            display: block;
            padding: 8px 15px;
            color: #333;
            text-decoration: none;
            font-size: 14px;
        }
        
        #submenu-context-menu a:hover {
            background-color: #f0f0f0;
        }
        
        .context-menu-item {
            cursor: pointer;
        }
        
        /* Когда контекстное меню активно, предотвращаем скрытие подменю */
        .dropdown-menu-left.context-menu-active {
            display: block !important;
        }
    `;
    document.head.appendChild(style);
}

// Запуск при загрузке страницы
document.addEventListener('DOMContentLoaded', function() {
    addSubmenuStyles();
    addCustomSubmenu();
});
Последний раз редактировалось Vidak 06 фев 2026, 15:16, всего редактировалось 1 раз.
Vidak
Сообщения: 6
Зарегистрирован: 12 окт 2021, 22:04
Имя: Виталий
Откуда: Москва

Re: Небольшие доработки

Сообщение Vidak »

в зависимости от значения в полях .fieldtype_dropdown, .fieldtype_autostatus, .fieldtype_php_code
скрывает те или иные кнопки (удалить, редактировать, информация)
выглядит так
1.png
1.png (3.17 КБ) 1990 просмотров
использование:
убрать права у пользователей с выбранными
Добавьте код перед тегом </body>

Код: Выделить всё

monitorTable('.fa-trash-o', ['Активный', 'Учтено']);
monitorTable('.fa-edit', ['В проекте', 'Учтено']);
monitorTable('.fa-info', ['Согласован', 'Не согласован']);
Вложения
monitor_table.js
(1.72 КБ) 47 скачиваний
Vidak
Сообщения: 6
Зарегистрирован: 12 окт 2021, 22:04
Имя: Виталий
Откуда: Москва

Re: Небольшие доработки

Сообщение Vidak »

кому нужен предпросмотр файлов в отчетах в конструкторе отчетов -> SQL таблица

Код: Выделить всё

concat('<a href="index.php?module=items/attachment_preview_pdf&amp;path=[entity]&amp;file=', REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (REPLACE (TO_BASE64 ([fieldtype_input_file]),'\n', ''),'+', '%2B'),'/', '%2F'),'=', '%3D'),'_', '%5F'),'-', '%2D'),'" target="_blank" class="fancybox-ajax btn btn-default btn-xs purple"><i class="la la-book-open"></i></a>')
где:
[fieldtype_input_file] = field_123 (поле для загрузки файла)
[entity] = entity_id
Vidak
Сообщения: 6
Зарегистрирован: 12 окт 2021, 22:04
Имя: Виталий
Откуда: Москва

Re: Небольшие доработки

Сообщение Vidak »

есть прикрученный tesseract прямо в форму, в лс
Безымянный.png
Ответить