Пропустить контент
Купить

Примеры использования модальных окон

Эта страница содержит практические примеры использования модальных окон в различных сценариях.

E-commerce сценарии

1. Быстрый просмотр товара

Создание модального окна для быстрого просмотра товара без перехода на страницу:

php
<?php
/**
 * Добавление кнопки "Быстрый просмотр" к товарам в цикле
 */
add_action('woocommerce_after_shop_loop_item', 'add_quick_view_button');

function add_quick_view_button() {
    global $product;
    
    if (!$product) return;
    
    $quick_view_link = \iiko\Modal::create_link('Быстрый просмотр', [
        'id' => 'quick_view_' . $product->get_id(),
        'title' => $product->get_name(),
        'content' => get_quick_view_content($product),
        'class' => 'medium',
        'link_class' => 'button quick-view-btn'
    ]);
    
    echo '<div class="quick-view-wrapper">' . $quick_view_link . '</div>';
}

function get_quick_view_content($product) {
    ob_start();
    ?>
    <div class="product-quick-view">
        <div class="product-image">
            <?php echo $product->get_image('medium'); ?>
        </div>
        <div class="product-details">
            <h3><?php echo esc_html($product->get_name()); ?></h3>
            <p class="price"><?php echo $product->get_price_html(); ?></p>
            <div class="description">
                <?php echo wp_kses_post($product->get_short_description()); ?>
            </div>
            <div class="product-actions">
                <?php echo do_shortcode('[add_to_cart id="' . $product->get_id() . '"]'); ?>
                <a href="<?php echo esc_url($product->get_permalink()); ?>" class="button view-details">
                    Подробнее
                </a>
            </div>
        </div>
    </div>
    <?php
    return ob_get_clean();
}

2. Модальное окно корзины

Кастомное модальное окно корзины с дополнительной функциональностью:

php
<?php
/**
 * Кастомное модальное окно корзины
 */
add_action('woocommerce_after_mini_cart', 'add_custom_cart_modal');

function add_custom_cart_modal() {
    $cart_modal = \iiko\Modal::create([
        'id' => 'custom_cart_modal',
        'title' => 'Ваша корзина',
        'content' => get_custom_cart_content(),
        'class' => 'medium',
        'display' => false,
        'close' => true
    ]);
}

function get_custom_cart_content() {
    ob_start();
    ?>
    <div class="custom-cart-content">
        <?php echo do_shortcode('[woocommerce_cart]'); ?>
        
        <div class="cart-extras">
            <div class="delivery-info">
                <h4>Информация о доставке</h4>
                <p>Бесплатная доставка при заказе от 1000</p>
            </div>
            
            <div class="payment-methods">
                <h4>Способы оплаты</h4>
                <ul>
                    <li>Наличными при получении</li>
                    <li>Банковской картой онлайн</li>
                    <li>СПБ (СБП)</li>
                </ul>
            </div>
        </div>
    </div>
    <?php
    return ob_get_clean();
}

3. Модальное окно с вариантами товара

Модальное окно для выбора вариантов товара:

php
<?php
/**
 * Модальное окно выбора вариантов товара
 */
function create_variation_modal($product_id) {
    $product = wc_get_product($product_id);
    
    if (!$product || !$product->is_type('variable')) {
        return '';
    }
    
    $modal = \iiko\Modal::create([
        'id' => 'variations_' . $product_id,
        'title' => 'Выберите вариант товара',
        'content' => get_variations_content($product),
        'class' => 'medium',
        'display' => false,
        'close' => true
    ]);
    
    return $modal;
}

function get_variations_content($product) {
    $variations = $product->get_available_variations();
    
    ob_start();
    ?>
    <div class="variations-modal">
        <div class="product-info">
            <h3><?php echo esc_html($product->get_name()); ?></h3>
            <p class="base-price">Базовая цена: <?php echo $product->get_price_html(); ?></p>
        </div>
        
        <div class="variations-list">
            <?php foreach ($variations as $variation): ?>
                <div class="variation-item" data-variation-id="<?php echo $variation['variation_id']; ?>">
                    <div class="variation-details">
                        <h4><?php echo esc_html($variation['attributes']['attribute_pa_size'] ?? 'Стандарт'); ?></h4>
                        <p class="price"><?php echo wc_price($variation['display_price']); ?></p>
                    </div>
                    <button class="select-variation" data-variation="<?php echo $variation['variation_id']; ?>">
                        Выбрать
                    </button>
                </div>
            <?php endforeach; ?>
        </div>
        
        <div class="selected-variation-info" style="display: none;">
            <h4>Выбранный вариант:</h4>
            <div class="selected-details"></div>
            <button class="add-to-cart-variation">Добавить в корзину</button>
        </div>
    </div>
    <?php
    return ob_get_clean();
}

Формы и взаимодействие

4. Форма обратной связи

Модальное окно с формой обратной связи:

php
<?php
/**
 * Модальное окно формы обратной связи
 */
class FeedbackModal {
    public static function create_feedback_form() {
        $modal = \iiko\Modal::create([
            'id' => 'feedback_form',
            'title' => 'Обратная связь',
            'content' => self::get_feedback_form_html(),
            'class' => 'medium',
            'display' => false,
            'close' => true
        ]);
        
        return $modal;
    }
    
    private static function get_feedback_form_html() {
        ob_start();
        ?>
        <form class="feedback-form" id="feedback_form">
            <div class="form-group">
                <label for="feedback_name">Имя *</label>
                <input type="text" id="feedback_name" name="name" required>
            </div>
            
            <div class="form-group">
                <label for="feedback_email">Email *</label>
                <input type="email" id="feedback_email" name="email" required>
            </div>
            
            <div class="form-group">
                <label for="feedback_phone">Телефон</label>
                <input type="tel" id="feedback_phone" name="phone">
            </div>
            
            <div class="form-group">
                <label for="feedback_subject">Тема</label>
                <select id="feedback_subject" name="subject">
                    <option value="">Выберите тему</option>
                    <option value="general">Общий вопрос</option>
                    <option value="order">Вопрос по заказу</option>
                    <option value="delivery">Доставка</option>
                    <option value="payment">Оплата</option>
                    <option value="complaint">Жалоба</option>
                    <option value="suggestion">Предложение</option>
                </select>
            </div>
            
            <div class="form-group">
                <label for="feedback_message">Сообщение *</label>
                <textarea id="feedback_message" name="message" rows="4" required 
                          placeholder="Опишите ваш вопрос или предложение"></textarea>
            </div>
            
            <div class="form-group">
                <label class="checkbox-label">
                    <input type="checkbox" name="agree" required>
                    <span class="checkmark"></span>
                    Я согласен с <a href="/privacy-policy" target="_blank">политикой конфиденциальности</a>
                </label>
            </div>
            
            <button type="submit" class="btn btn-primary">Отправить сообщение</button>
        </form>
        
        <div class="feedback-success" style="display: none;">
            <div class="success-icon"></div>
            <h3>Сообщение отправлено!</h3>
            <p>Мы свяжемся с вами в ближайшее время.</p>
        </div>
        <?php
        return ob_get_clean();
    }
}

// Использование
add_action('wp_footer', function() {
    if (is_page('contact') || is_front_page()) {
        echo FeedbackModal::create_feedback_form();
    }
});

5. Модальное окно авторизации

Кастомное модальное окно авторизации:

php
<?php
/**
 * Кастомное модальное окно авторизации
 */
function create_custom_auth_modal() {
    if (is_user_logged_in()) {
        return '';
    }
    
    $modal = \iiko\Modal::create([
        'id' => 'custom_auth_modal',
        'title' => 'Вход в личный кабинет',
        'content' => get_custom_auth_content(),
        'class' => 'medium',
        'display' => false,
        'close' => true
    ]);
    
    return $modal;
}

function get_custom_auth_content() {
    ob_start();
    ?>
    <div class="custom-auth-modal">
        <div class="auth-tabs">
            <button class="auth-tab active" data-tab="login">Вход</button>
            <button class="auth-tab" data-tab="register">Регистрация</button>
        </div>
        
        <div class="auth-content">
            <!-- Форма входа -->
            <div class="auth-form active" id="login-form">
                <form class="login-form">
                    <div class="form-group">
                        <label for="login_email">Email</label>
                        <input type="email" id="login_email" name="email" required>
                    </div>
                    
                    <div class="form-group">
                        <label for="login_password">Пароль</label>
                        <input type="password" id="login_password" name="password" required>
                    </div>
                    
                    <div class="form-group">
                        <label class="checkbox-label">
                            <input type="checkbox" name="remember">
                            <span class="checkmark"></span>
                            Запомнить меня
                        </label>
                    </div>
                    
                    <button type="submit" class="btn btn-primary">Войти</button>
                </form>
                
                <div class="auth-links">
                    <a href="#" class="forgot-password">Забыли пароль?</a>
                </div>
            </div>
            
            <!-- Форма регистрации -->
            <div class="auth-form" id="register-form">
                <form class="register-form">
                    <div class="form-group">
                        <label for="register_name">Имя</label>
                        <input type="text" id="register_name" name="name" required>
                    </div>
                    
                    <div class="form-group">
                        <label for="register_email">Email</label>
                        <input type="email" id="register_email" name="email" required>
                    </div>
                    
                    <div class="form-group">
                        <label for="register_password">Пароль</label>
                        <input type="password" id="register_password" name="password" required>
                    </div>
                    
                    <div class="form-group">
                        <label for="register_password_confirm">Подтвердите пароль</label>
                        <input type="password" id="register_password_confirm" name="password_confirm" required>
                    </div>
                    
                    <div class="form-group">
                        <label class="checkbox-label">
                            <input type="checkbox" name="agree_terms" required>
                            <span class="checkmark"></span>
                            Я согласен с <a href="/terms" target="_blank">условиями использования</a>
                        </label>
                    </div>
                    
                    <button type="submit" class="btn btn-primary">Зарегистрироваться</button>
                </form>
            </div>
        </div>
    </div>
    <?php
    return ob_get_clean();
}

Медиа контент

6. Модальное окно с видео

Модальное окно для отображения видео:

php
<?php
/**
 * Модальное окно с видео
 */
class VideoModal {
    public static function create_video_modal($video_id, $title = '', $provider = 'youtube') {
        $modal = \iiko\Modal::create([
            'id' => 'video_' . $video_id,
            'title' => $title ?: 'Видео',
            'content' => self::get_video_embed($video_id, $provider),
            'class' => 'medium',
            'display' => false,
            'close' => true
        ]);
        
        return $modal;
    }
    
    private static function get_video_embed($video_id, $provider) {
        switch ($provider) {
            case 'youtube':
                return '<div class="video-container"><iframe src="https://www.youtube.com/embed/' . 
                       esc_attr($video_id) . '?rel=0" frameborder="0" allowfullscreen></iframe></div>';
            
            case 'vimeo':
                return '<div class="video-container"><iframe src="https://player.vimeo.com/video/' . 
                       esc_attr($video_id) . '" frameborder="0" allowfullscreen></iframe></div>';
            
            case 'custom':
                return '<div class="video-container">' . wp_kses_post($video_id) . '</div>';
            
            default:
                return '<div class="video-container">Неподдерживаемый провайдер видео</div>';
        }
    }
}

// Использование
function add_product_video_button() {
    global $product;
    
    if (!$product) return;
    
    $video_id = get_post_meta($product->get_id(), '_product_video_id', true);
    $video_provider = get_post_meta($product->get_id(), '_product_video_provider', true);
    
    if ($video_id) {
        $video_link = VideoModal::create_link('Смотреть видео', [
            'id' => 'product_video_' . $product->get_id(),
            'title' => 'Видео: ' . $product->get_name(),
            'content' => VideoModal::get_video_embed($video_id, $video_provider),
            'link_class' => 'button video-btn'
        ]);
        
        echo '<div class="product-video">' . $video_link . '</div>';
    }
}

add_action('woocommerce_single_product_summary', 'add_product_video_button', 25);

7. Галерея изображений

Модальное окно для галереи изображений:

php
<?php
/**
 * Модальное окно галереи изображений
 */
function create_gallery_modal($gallery_images, $title = 'Галерея') {
    $modal = \iiko\Modal::create([
        'id' => 'gallery_modal',
        'title' => $title,
        'content' => get_gallery_content($gallery_images),
        'class' => 'medium',
        'display' => false,
        'close' => true
    ]);
    
    return $modal;
}

function get_gallery_content($gallery_images) {
    if (empty($gallery_images)) {
        return '<p>Изображения не найдены</p>';
    }
    
    ob_start();
    ?>
    <div class="gallery-modal">
        <div class="gallery-main">
            <img src="<?php echo esc_url($gallery_images[0]['url']); ?>" 
                 alt="<?php echo esc_attr($gallery_images[0]['alt']); ?>" 
                 class="gallery-main-image">
        </div>
        
        <div class="gallery-thumbnails">
            <?php foreach ($gallery_images as $index => $image): ?>
                <div class="gallery-thumb <?php echo $index === 0 ? 'active' : ''; ?>" 
                     data-index="<?php echo $index; ?>">
                    <img src="<?php echo esc_url($image['sizes']['thumbnail']); ?>" 
                         alt="<?php echo esc_attr($image['alt']); ?>">
                </div>
            <?php endforeach; ?>
        </div>
        
        <div class="gallery-nav">
            <button class="gallery-prev" disabled></button>
            <span class="gallery-counter">1 из <?php echo count($gallery_images); ?></span>
            <button class="gallery-next"></button>
        </div>
    </div>
    <?php
    return ob_get_clean();
}

// Использование для товаров WooCommerce
function add_product_gallery_modal() {
    global $product;
    
    if (!$product) return;
    
    $gallery_images = $product->get_gallery_image_ids();
    
    if (!empty($gallery_images)) {
        $gallery_data = [];
        foreach ($gallery_images as $image_id) {
            $gallery_data[] = [
                'url' => wp_get_attachment_url($image_id),
                'sizes' => [
                    'thumbnail' => wp_get_attachment_image_url($image_id, 'thumbnail'),
                    'medium' => wp_get_attachment_image_url($image_id, 'medium'),
                    'large' => wp_get_attachment_image_url($image_id, 'large')
                ],
                'alt' => get_post_meta($image_id, '_wp_attachment_image_alt', true)
            ];
        }
        
        $gallery_link = \iiko\Modal::create_link('Показать все фото', [
            'id' => 'product_gallery_' . $product->get_id(),
            'title' => 'Галерея: ' . $product->get_name(),
            'content' => get_gallery_content($gallery_data),
            'link_class' => 'gallery-link'
        ]);
        
        echo '<div class="product-gallery-link">' . $gallery_link . '</div>';
    }
}

add_action('woocommerce_single_product_summary', 'add_product_gallery_modal', 20);

JavaScript для интерактивности

8. AJAX загрузка содержимого

javascript
/**
 * AJAX загрузка содержимого в модальное окно
 */
class ModalContentLoader {
    constructor() {
        this.init();
    }
    
    init() {
        this.bindEvents();
    }
    
    bindEvents() {
        // Загрузка содержимого по клику
        jQuery(document).on('click', '.load-modal-content', this.loadContent.bind(this));
        
        // Обработка форм в модальных окнах
        jQuery(document).on('submit', '.modal-form', this.handleFormSubmit.bind(this));
        
        // Закрытие модального окна
        jQuery(document).on('click', '.md-close, .md-overlay', this.closeModal.bind(this));
    }
    
    loadContent(e) {
        e.preventDefault();
        
        const button = jQuery(e.currentTarget);
        const modalId = button.data('modal');
        const contentUrl = button.data('url');
        const loadingText = button.data('loading') || 'Загрузка...';
        
        if (!modalId || !contentUrl) {
            console.error('Missing modal ID or content URL');
            return;
        }
        
        // Показываем модальное окно
        jQuery('#' + modalId).addClass('md-show');
        
        // Показываем индикатор загрузки
        this.showLoading(modalId, loadingText);
        
        // Загружаем содержимое
        jQuery.get(contentUrl, (data) => {
            jQuery('#' + modalId + ' .md-content').html(data);
            this.hideLoading(modalId);
            
            // Инициализируем загруженный контент
            this.initLoadedContent(modalId);
        }).fail((xhr, status, error) => {
            this.hideLoading(modalId);
            this.showError(modalId, 'Ошибка загрузки: ' + error);
        });
    }
    
    showLoading(modalId, text) {
        const modal = jQuery('#' + modalId);
        modal.find('.md-content').html(`
            <div class="modal-loading">
                <div class="spinner"></div>
                <p>${text}</p>
            </div>
        `);
    }
    
    hideLoading(modalId) {
        jQuery('#' + modalId + ' .modal-loading').remove();
    }
    
    showError(modalId, message) {
        const modal = jQuery('#' + modalId);
        modal.find('.md-content').html(`
            <div class="modal-error">
                <div class="error-icon">⚠</div>
                <h3>Ошибка</h3>
                <p>${message}</p>
                <button class="button retry-btn">Повторить</button>
            </div>
        `);
    }
    
    initLoadedContent(modalId) {
        const modal = jQuery('#' + modalId);
        
        // Инициализируем формы
        modal.find('form').each((index, form) => {
            this.initForm(jQuery(form));
        });
        
        // Инициализируем слайдеры
        modal.find('.slider').each((index, slider) => {
            this.initSlider(jQuery(slider));
        });
        
        // Инициализируем табы
        modal.find('.tabs').each((index, tabs) => {
            this.initTabs(jQuery(tabs));
        });
    }
    
    initForm(form) {
        form.on('submit', this.handleFormSubmit.bind(this));
        
        // Валидация полей
        form.find('input[required], textarea[required]').on('blur', function() {
            const field = jQuery(this);
            if (!field.val()) {
                field.addClass('error');
            } else {
                field.removeClass('error');
            }
        });
    }
    
    handleFormSubmit(e) {
        e.preventDefault();
        
        const form = jQuery(e.currentTarget);
        const submitBtn = form.find('button[type="submit"]');
        const originalText = submitBtn.text();
        
        // Показываем индикатор отправки
        submitBtn.prop('disabled', true).text('Отправка...');
        
        // Собираем данные формы
        const formData = new FormData(form[0]);
        
        // Отправляем AJAX запрос
        jQuery.ajax({
            url: form.attr('action') || window.location.href,
            method: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: (response) => {
                this.handleFormSuccess(form, response);
            },
            error: (xhr, status, error) => {
                this.handleFormError(form, error);
            },
            complete: () => {
                submitBtn.prop('disabled', false).text(originalText);
            }
        });
    }
    
    handleFormSuccess(form, response) {
        const modal = form.closest('.md-modal');
        
        // Показываем сообщение об успехе
        modal.find('.md-content').html(`
            <div class="form-success">
                <div class="success-icon">✓</div>
                <h3>Успешно!</h3>
                <p>${response.message || 'Форма отправлена успешно'}</p>
                <button class="button close-modal">Закрыть</button>
            </div>
        `);
        
        // Автоматически закрываем через 3 секунды
        setTimeout(() => {
            this.closeModal();
        }, 3000);
    }
    
    handleFormError(form, error) {
        // Показываем ошибку
        form.find('.form-error').remove();
        form.prepend(`
            <div class="form-error">
                <p>Ошибка: ${error}</p>
            </div>
        `);
    }
    
    closeModal() {
        jQuery('.md-modal.md-show').removeClass('md-show');
    }
}

// Инициализация
jQuery(document).ready(function() {
    new ModalContentLoader();
});

CSS стили для примеров

9. Дополнительные стили

css
/* Стили для модальных окон */

/* Быстрый просмотр товара */
.product-quick-view {
    display: flex;
    gap: 20px;
}

.product-quick-view .product-image {
    flex: 0 0 200px;
}

.product-quick-view .product-image img {
    width: 100%;
    height: auto;
    border-radius: 8px;
}

.product-quick-view .product-details {
    flex: 1;
}

.product-quick-view .price {
    font-size: 1.2em;
    font-weight: bold;
    color: #007cba;
    margin: 10px 0;
}

.product-quick-view .product-actions {
    margin-top: 20px;
    display: flex;
    gap: 10px;
}

/* Форма обратной связи */
.feedback-form .form-group {
    margin-bottom: 20px;
}

.feedback-form label {
    display: block;
    margin-bottom: 5px;
    font-weight: 500;
}

.feedback-form input,
.feedback-form textarea,
.feedback-form select {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 14px;
}

.feedback-form input:focus,
.feedback-form textarea:focus,
.feedback-form select:focus {
    outline: none;
    border-color: #007cba;
    box-shadow: 0 0 0 2px rgba(0, 124, 186, 0.2);
}

.feedback-form .checkbox-label {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}

.feedback-form button[type="submit"] {
    width: 100%;
    padding: 12px;
    background: #007cba;
    color: white;
    border: none;
    border-radius: 4px;
    font-size: 16px;
    cursor: pointer;
    transition: background 0.3s;
}

.feedback-form button[type="submit"]:hover {
    background: #005a87;
}

/* Галерея изображений */
.gallery-modal {
    text-align: center;
}

.gallery-main {
    margin-bottom: 20px;
}

.gallery-main-image {
    max-width: 100%;
    height: auto;
    border-radius: 8px;
}

.gallery-thumbnails {
    display: flex;
    gap: 10px;
    justify-content: center;
    margin-bottom: 20px;
}

.gallery-thumb {
    width: 60px;
    height: 60px;
    cursor: pointer;
    border: 2px solid transparent;
    border-radius: 4px;
    overflow: hidden;
    transition: border-color 0.3s;
}

.gallery-thumb.active {
    border-color: #007cba;
}

.gallery-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.gallery-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
}

.gallery-nav button {
    background: #007cba;
    color: white;
    border: none;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    cursor: pointer;
    font-size: 18px;
}

.gallery-nav button:disabled {
    background: #ccc;
    cursor: not-allowed;
}

/* Индикаторы загрузки и ошибок */
.modal-loading,
.modal-error,
.form-success {
    text-align: center;
    padding: 40px 20px;
}

.modal-loading .spinner {
    width: 40px;
    height: 40px;
    border: 4px solid #f3f3f3;
    border-top: 4px solid #007cba;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin: 0 auto 20px;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.modal-error .error-icon {
    font-size: 48px;
    color: #dc3545;
    margin-bottom: 20px;
}

.form-success .success-icon {
    font-size: 48px;
    color: #28a745;
    margin-bottom: 20px;
}

/* Адаптивность */
@media (max-width: 768px) {
    .product-quick-view {
        flex-direction: column;
    }
    
    .product-quick-view .product-image {
        flex: none;
        text-align: center;
    }
    
    .gallery-thumbnails {
        flex-wrap: wrap;
    }
    
    .gallery-nav {
        flex-direction: column;
        gap: 10px;
    }
}

Заключение

Эти примеры демонстрируют различные способы использования модальных окон в woo2iiko. Они показывают, как создавать интерактивные элементы интерфейса, улучшать пользовательский опыт и интегрировать модальные окна с существующей функциональностью WordPress и WooCommerce.

Для получения дополнительной информации обратитесь к:

  • Основной документации по модальным окнам
  • API документации
  • Руководству по расширению
WOO2IIKO © 2019 - 2026 Алексей Тихомиров.