WordPressでプラグインなしでモーダルウィンドウを開くボタン

コメントはありません

 

WordPressでプラグインなしでモーダルウィンドウを開くボタン
モーダルウィンドウと、それをトリガーする黄色いボタンの下の例。バージョン1.0

今日のコードでは、WordPressの投稿やページにショートコード付きのボタンを追加して、クリックするとモーダルウィンドウが開き、そこに必要なコンテンツを追加できるようにします。

これは、購読フォーム、問い合わせフォーム、単発のお知らせ、画像、情報ボックス、あるいは私の場合のようにエラー通知フォームを表示するのに使うことができる。

どの投稿の下部でも、動作するショートコードをテストすることができます。

[error_report_form]

このブログでは何週間も正常に動作しているが、これはバージョン1.0であり、常に改良とデバッグの余地があることを忘れないでほしい。変更を簡単にするためにCSSを切り離すこともできるし、あえてプラグインにして、より多くの設定や構成を追加し、素早く簡単にアクセスできるようにすることもできる。

コードの下には、オプションの説明と、それを試す方法が書かれている。

コード

/*
 * Versión: 1.0
 * Última actualización: 13-03-2025 17:54:00
 */

// Shortcode para mostrar el botón y el formulario modal actualizado en jrmora.com
function error_report_form_shortcode() {
    // Generar números aleatorios para la operación matemática
    $num1 = rand(1, 9);
    $num2 = rand(1, 9);
    $sum = $num1 + $num2;

    // Iniciar sesión si no está iniciada
    if (!session_id()) {
        session_start();
    }

    // Guardar la suma en una variable de sesión para validar después
    $_SESSION['captcha_sum'] = $sum;

    // HTML del botón y el modal
    ob_start();
    ?>
    <button id="openErrorModal" style="padding: 10px 20px; background-color: #ffcc00; color: black; border: none; border-radius: 6px; cursor: pointer; font-weight: bold;">
        ⚠ Comunicar error
    </button>

    <div id="errorModalOverlay" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 999;">
        <div id="errorModal" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 20px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 1000; border-radius: 7px; width: 90%; max-width: 500px;">
            <span id="closeModalBtn" style="position: absolute; top: 10px; right: 10px; cursor: pointer; font-size: 20px; background-color: black; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; line-height: 30px;">&times;</span>
            <h3 style="font-size: 18px;">Comunicar error (Para errores ortográficos o de malfuncionamiento del sitio)</h3>
            <form id="errorForm" method="post">
                <input type="hidden" name="action" value="submit_error_report">
                <label for="name" style="font-size: 14px;">Nombre:</label>
                <input type="text" id="name" name="name" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;">
                <div id="nameError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">No se permiten enlaces o dominios en el campo "Nombre".</div>
                <label for="message" style="font-size: 14px;">Descripción del error:</label>
                <textarea id="message" name="message" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;"></textarea>
                <div id="messageError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">No se permiten enlaces o dominios en el campo "Mensaje".</div>
                <label for="captcha" style="font-size: 14px;">¿Eres humano? ¿Cuánto es <?php echo $num1; ?> + <?php echo $num2; ?>?</label>
                <input type="text" id="captcha" name="captcha" required style="background-color: #f5f5f5; padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 100%; margin-bottom: 12px;">
                <div id="captchaError" style="color: red; display: none; font-size: 12px; margin-bottom: 12px;">El resultado de la suma es incorrecto.</div>
                <!-- Opcional: Añadir reCaptcha si se proporcionan las claves -->
                <?php if (defined('RECAPTCHA_SITE_KEY') && defined('RECAPTCHA_SECRET_KEY')) : ?>
                    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
                    <div class="g-recaptcha" data-sitekey="<?php echo RECAPTCHA_SITE_KEY; ?>" style="margin-bottom: 12px;"></div>
                <?php endif; ?>
                <div style="text-align: center;">
                    <input type="submit" value="Enviar" style="background-color: #bc080e; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; font-weight: bold; display: inline-block;">
                </div>
            </form>
            <div id="successMessage" style="color: green; display: none; margin-top: 10px; font-size: 14px; text-align: center;">Gracias por comunicar el error.</div>
        </div>
    </div>

    <style>
        /* Estilos para dispositivos móviles */
        @media (max-width: 768px) {
            #errorModal {
                width: 90% !important; /* Ajusta el ancho del modal al 90% de la pantalla */
                max-width: 90% !important; /* Asegura que no exceda el 90% del ancho */
                padding: 15px !important; /* Reduce el padding para más espacio */
            }

            #errorForm input, #errorForm textarea {
                font-size: 16px !important; /* Aumenta el tamaño de la fuente para mejor legibilidad */
            }

            #errorForm label {
                font-size: 16px !important; /* Aumenta el tamaño de la fuente de las etiquetas */
            }
        }
    </style>

    <script>
        // Abrir modal
        document.getElementById('openErrorModal').addEventListener('click', function() {
            document.getElementById('errorModalOverlay').style.display = 'block';
        });

        // Cerrar modal al hacer clic en el aspa
        document.getElementById('closeModalBtn').addEventListener('click', function() {
            document.getElementById('errorModalOverlay').style.display = 'none';
        });

        // Cerrar modal al hacer clic fuera de él
        document.getElementById('errorModalOverlay').addEventListener('click', function(event) {
            if (event.target === document.getElementById('errorModalOverlay')) {
                document.getElementById('errorModalOverlay').style.display = 'none';
            }
        });

        // Función para validar si hay enlaces o dominios en el texto
        function containsUrlOrDomain(text) {
            // Expresión regular para detectar enlaces o dominios
            const urlPattern = /(http|https|www|\[url|\[link)|(\b\w+\.(com|org|net|io|co|edu|gov|mil|biz|info|xyz|me|tv|us|uk|ca|au|de|fr|es|it|nl|ru|jp|cn|in|br|mx|ar|cl|pe|ve|co\.uk|co\.jp|co\.in|ac\.uk|gov\.uk|edu\.au|com\.au|org\.uk|net\.au)\b)/i;
            return urlPattern.test(text);
        }

        // Manejar el envío del formulario con AJAX
        document.getElementById('errorForm').addEventListener('submit', function(e) {
            e.preventDefault(); // Evitar envío tradicional del formulario

            // Ocultar mensajes de error previos
            document.getElementById('nameError').style.display = 'none';
            document.getElementById('messageError').style.display = 'none';
            document.getElementById('captchaError').style.display = 'none';

            // Validar campos
            var name = document.getElementById('name').value;
            var message = document.getElementById('message').value;
            var captcha = document.getElementById('captcha').value;
            var hasError = false;

            // Validar enlaces o dominios en el nombre
            if (containsUrlOrDomain(name)) {
                document.getElementById('nameError').style.display = 'block';
                hasError = true;
            }

            // Validar enlaces o dominios en el mensaje
            if (containsUrlOrDomain(message)) {
                document.getElementById('messageError').style.display = 'block';
                hasError = true;
            }

            // Validar el captcha
            if (captcha !== '<?php echo $sum; ?>') {
                document.getElementById('captchaError').style.display = 'block';
                hasError = true;
            }

            // Si hay errores, detener el envío
            if (hasError) {
                return;
            }

            // Enviar el formulario si no hay errores
            var formData = new FormData(this);
            fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
                method: 'POST',
                body: formData
            })
            .then(response => response.text())
            .then(data => {
                // Mostrar mensaje de éxito
                document.getElementById('successMessage').style.display = 'block';

                // Ocultar el formulario
                document.getElementById('errorForm').style.display = 'none';

                // Esperar 3 segundos y cerrar el modal
                setTimeout(function() {
                    document.getElementById('errorModalOverlay').style.display = 'none';
                    document.getElementById('successMessage').style.display = 'none';
                    document.getElementById('errorForm').style.display = 'block'; // Restaurar el formulario
                }, 3000);
            })
            .catch(error => console.error('Error:', error));
        });
    </script>
    <?php
    return ob_get_clean();
}
add_shortcode('error_report_form', 'error_report_form_shortcode');

// Manejar el envío del formulario
function handle_error_report_form() {
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'submit_error_report') {
        // Iniciar sesión si no está iniciada
        if (!session_id()) {
            session_start();
        }

        // Validar el captcha
        if (!isset($_SESSION['captcha_sum']) || !isset($_POST['captcha']) || $_POST['captcha'] != $_SESSION['captcha_sum']) {
            wp_die('Captcha incorrecto. Por favor, intenta de nuevo.');
        }

        // Validar que no haya enlaces o dominios en los campos
        $name = isset($_POST['name']) ? sanitize_text_field($_POST['name']) : '';
        $message = isset($_POST['message']) ? sanitize_text_field($_POST['message']) : '';
        if (preg_match('/(http|https|www|\[url|\[link)|(\b\w+\.(com|org|net|io|co|edu|gov|mil|biz|info|xyz|me|tv|us|uk|ca|au|de|fr|es|it|nl|ru|jp|cn|in|br|mx|ar|cl|pe|ve|co\.uk|co\.jp|co\.in|ac\.uk|gov\.uk|edu\.au|com\.au|org\.uk|net\.au)\b)/i', $name . $message)) {
            wp_die('No se permiten enlaces o dominios en los campos.');
        }

        // Validar reCaptcha (opcional)
        if (defined('RECAPTCHA_SITE_KEY') && defined('RECAPTCHA_SECRET_KEY')) {
            if (!isset($_POST['g-recaptcha-response'])) {
                wp_die('Por favor, completa el reCaptcha.');
            }

            $recaptcha_response = $_POST['g-recaptcha-response'];
            $recaptcha_secret = RECAPTCHA_SECRET_KEY;
            $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
            $recaptcha_data = [
                'secret' => $recaptcha_secret,
                'response' => $recaptcha_response,
                'remoteip' => $_SERVER['REMOTE_ADDR']
            ];

            $recaptcha_options = [
                'http' => [
                    'header' => "Content-type: application/x-www-form-urlencoded\r\n",
                    'method' => 'POST',
                    'content' => http_build_query($recaptcha_data)
                ]
            ];

            $recaptcha_context = stream_context_create($recaptcha_options);
            $recaptcha_result = file_get_contents($recaptcha_url, false, $recaptcha_context);
            $recaptcha_json = json_decode($recaptcha_result);

            if (!$recaptcha_json->success) {
                wp_die('Por favor, completa el reCaptcha correctamente.');
            }
        }

        // Obtener la URL de origen
        $url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'URL desconocida';

        // Enviar correo electrónico
        $to = get_option('admin_email'); // Correo del administrador
        $subject = 'Comunicación de Error desde ' . $url;
        $body = "Nombre: $name\n\nMensaje: $message\n\nURL: $url";
        $headers = array('Content-Type: text/plain; charset=UTF-8');

        if (wp_mail($to, $subject, $body, $headers)) {
            echo 'success';
        } else {
            echo 'Hubo un error al enviar el mensaje.';
        }

        exit;
    }
}
add_action('wp_ajax_submit_error_report', 'handle_error_report_form');
add_action('wp_ajax_nopriv_submit_error_report', 'handle_error_report_form');

// Definir claves de reCaptcha (opcional)
// define('RECAPTCHA_SITE_KEY', 'TU_SITE_KEY');
// define('RECAPTCHA_SECRET_KEY', 'TU_SECRET_KEY');

フォームの機能性


  • ショートコード
[error_report_form]
  • エラー報告用のモーダルフォームを開くボタンを表示します。
  • フォームには、名前、メッセージ、簡単な数学的キャプチャのフィールドがあります。
  • フィールドにリンクやドメインが入力されていないことを確認する。
  • ブログ管理者にエラーの詳細を記載したメールを送信してください。

  • フォーム・フィールド
    :ポリラン・プレースホルダは変更しない

  • バリデーション
    :ポリラング・プレースホルダは変更しない

  • ポリラン・プレースホルダーは変更しないでください。

  • スパム防止
    :ポリラン・プレースホルダは変更しないでください

フォームスタイル


  • エラー報告」ボタン
    :ポリランプレースホルダは変更しないでください。

  • モーダル(ポップアップウィンドウ)
    :ポリランプレースホルダは変更しない
  • 閉じるハンドル(モーダルを閉じるボタン、クラスは id="closeModalBtn")
    :ポリラン・プレースホルダは変更しないでください。
  • フォーム・フィールド
    :ポリラン・プレースホルダは変更しない

  • 送信 "ボタン
    :ポリランプレースホルダは変更しないでください。

  • エラーメッセージ
    :Polylangプレースホルダは変更されません。
  • 成功メッセージ
    :ポリラン・プレースホルダーは変更しないでください

スタイルの修正方法


  • colors
    :Polylangプレースホルダを
    修正する。

  • フォントサイズの変更
    :ポリラン・プレースホルダは変更しない

  • ボーダーと角丸の修正
    :ポリラング・プレースホルダーは修正しない

  • スペーシングの変更
    :ポリラン・プレースホルダーは変更しない

  • フィールドの幅を変更する
    :ポリラング・プレースホルダーは変更しない

追加オプション


  • reCaptcha
    :Polylangプレースホルダは変更しないでください。

  • Eメールのパーソナライズ
    :Polylangプレースホルダは変更しないでください。

使用方法


  • コードをコピーして、テーマのfunctions.phpファイルに貼り付けます。
  • ショートコードはどのページや投稿にも使えます。
  • 必要に応じてスタイルをカスタマイズする。
  • reCaptchaを使用する場合は、「追加オプション」セクションの指示に従ってください。

Suscripción por email

関連記事

コメントする

Este blog se aloja en LucusHost

LucusHost, el mejor hosting