Drupal 8.4网站PDF链接点击后Web Form失效问题求助
1. Diagnose the Core Problem
The root issue here is that your PDF links are executing their default behavior (opening the PDF in a new tab) instead of triggering the hidden form overlay. This almost always means the JavaScript responsible for intercepting the link click, blocking the default navigation, and showing the form is either missing, broken, or not properly attached to your links.
2. Step-by-Step Solutions
a. Add/Repair JavaScript to Intercept Link Clicks
First, you need to implement JavaScript that targets your PDF links and stops them from navigating directly. Let's assume your PDF links have a class like pdf-download-link (adjust this selector to match your actual link classes). Add this code to your theme's .js file (e.g., yourtheme/js/pdf-overlay.js):
(function ($, Drupal) { Drupal.behaviors.pdfDownloadOverlay = { attach: function (context, settings) { // Target all PDF links (adjust selector to match your site's links) $('.pdf-download-link, [href$=".pdf"]', context) .once('pdfOverlay') .on('click', function(e) { e.preventDefault(); // Stop the default link action const pdfUrl = $(this).attr('href'); // Store the PDF URL for post-submission redirect // Show the overlay and form $('.overlay').show(); $('.contactForm').show(); // Store PDF URL in a hidden input to use after form submission $('#pdf-target-url').val(pdfUrl); }); // Handle close button click to hide overlay $('.close', context) .once('pdfOverlayClose') .on('click', function() { $('.overlay').hide(); $('.contactForm').hide(); }); // Handle form submission (AJAX-based) $('#ajaxpdf_submit', context) .once('pdfFormSubmit') .on('click', function(e) { e.preventDefault(); const form = $(this).closest('form'); // Validate form (browser handles HTML5 required attributes, but add custom checks if needed) if (form[0].checkValidity()) { $.ajax({ url: form.attr('action'), // Update to your actual submission endpoint method: 'POST', data: form.serialize(), success: function() { // On success, hide form and open PDF $('.overlay').hide(); $('.contactForm').hide(); window.open($('#pdf-target-url').val(), '_blank'); }, error: function() { alert('Oops, there was an error submitting your form. Please try again.'); } }); } }); } }; })(jQuery, Drupal);
b. Update Your Form HTML
Add a hidden input to your form to store the PDF URL, and fix the garbled close button text:
<div class="overlay" style="display:none"> <div class="contactForm" style="display:none"> <b><span class="close">×</span></b> <!-- Fixed encoding issue with close button --> <div> <p><b>Please submit form to download Pdf</b></p> </div> <form action="/submit-pdf-request" method="post"> <!-- Update action to your submission path --> <input type="hidden" id="pdf-target-url" name="pdf_url" value=""> <!-- Hidden input for PDF URL --> <input class="inputc" name="name" placeholder="Name" required="" type="text" value="" /> <input class="inputc" name="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$" placeholder="Email" required="" type="text" value="" /> <input class="inputc" name="phone" pattern="[789][0-9]{9}" placeholder="Phone" required="" type="text" value="" /> <textarea class="textarea" name="comment" placeholder="Comments.." required=""></textarea> <input class="contbtn" id="ajaxpdf_submit" name="submit" type="submit" value="Submit" /> </form> </div> </div>
c. Set Up a Drupal Controller for Form Submission
To handle the form data, create a custom module with a controller:
- Create a module (e.g.,
pdf_request_form) - Add a route in
pdf_request_form.routing.yml:
pdf_request_form.submit: path: '/submit-pdf-request' defaults: _controller: '\Drupal\pdf_request_form\Controller\PdfRequestController::submit' _title: 'Submit PDF Request' requirements: _access: 'TRUE'
- Create the controller file
src/Controller/PdfRequestController.php:
<?php namespace Drupal\pdf_request_form\Controller; use Drupal\Core\Controller\ControllerBase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\JsonResponse; class PdfRequestController extends ControllerBase { public function submit(Request $request) { // Retrieve form data $submissionData = [ 'name' => $request->request->get('name'), 'email' => $request->request->get('email'), 'phone' => $request->request->get('phone'), 'comment' => $request->request->get('comment'), 'pdf_url' => $request->request->get('pdf_url'), ]; // Example: Save to database or send notification email $mailManager = \Drupal::service('plugin.manager.mail'); $mailManager->mail( 'pdf_request_form', 'new_request', 'your-admin-email@example.com', // Replace with your email \Drupal::currentUser()->getPreferredLangcode(), ['data' => $submissionData], NULL, TRUE ); return new JsonResponse(['status' => 'success']); } }
d. Load Your JavaScript in Drupal
Add this to your theme's yourtheme.libraries.yml:
pdf_overlay: js: js/pdf-overlay.js: {} dependencies: - core/jquery - core/drupal - core/drupal.behaviors
Then attach the library to your pages in yourtheme.theme:
function yourtheme_preprocess_page(&$variables) { $variables['#attached']['library'][] = 'yourtheme/pdf_overlay'; }
3. Common Pitfalls to Check
- Link Selector: Ensure your JavaScript selector matches your actual PDF links. Use
[href$=".pdf"]if your links don't have a specific class. - Form Action: Replace
action="#"with your controller's path (e.g.,/submit-pdf-request). - Drupal Behaviors: Wrapping JS in Drupal behaviors ensures it works with dynamic content loads.
- Encoding: The close button had garbled text ("鉁�") which I fixed to "×" – verify this displays correctly.
4. Alternative: Use a Drupal 8-Compatible Module
Note that the official Webform module fully supports Drupal 8.4. It offers built-in conditional logic and can be configured to require a form submission before allowing PDF downloads. This might be a more maintainable solution than custom code if you're open to using it.
内容的提问来源于stack exchange,提问作者userInz

