feat(contact-form): implement modal contact form with AJAX submission
Replace mailto link with modal popup containing Formidable job application form. Modal stays open after submission to show success message. Changes: - Add modal popup with contact form on job detail pages - Implement AJAX form submission to prevent page reload - Auto-populate job_id field when modal opens - Add field key compatibility for both job_id and job_id2 - Fix form ID comparison to use loose equality - Keep modal open after submission to display success message - Add modal styling and close functionality Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -174,6 +174,9 @@ class DDHH_JM_Formidable {
|
|||||||
|
|
||||||
// Hook to pre-populate edit form fields
|
// Hook to pre-populate edit form fields
|
||||||
add_filter( 'frm_get_default_value', array( __CLASS__, 'prepopulate_edit_form_fields' ), 10, 3 );
|
add_filter( 'frm_get_default_value', array( __CLASS__, 'prepopulate_edit_form_fields' ), 10, 3 );
|
||||||
|
|
||||||
|
// Hook to pre-populate job_id in application form
|
||||||
|
add_filter( 'frm_get_default_value', array( __CLASS__, 'prepopulate_application_job_id' ), 10, 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1425,4 +1428,46 @@ class DDHH_JM_Formidable {
|
|||||||
FrmField::create( $field );
|
FrmField::create( $field );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-populate job_id field in application form
|
||||||
|
*
|
||||||
|
* @param mixed $default_value The default value.
|
||||||
|
* @param object $field The field object.
|
||||||
|
* @param bool $dynamic_default Whether to use dynamic default.
|
||||||
|
* @return mixed The modified default value.
|
||||||
|
*/
|
||||||
|
public static function prepopulate_application_job_id( $default_value, $field, $dynamic_default ) {
|
||||||
|
// Only process for the job application form
|
||||||
|
if ( absint( $field->form_id ) !== self::get_job_application_form_id() ) {
|
||||||
|
return $default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only process the job_id field
|
||||||
|
if ( 'job_id' !== $field->field_key ) {
|
||||||
|
return $default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for job_id in shortcode attributes (passed from template)
|
||||||
|
// Formidable stores shortcode attributes in a global variable
|
||||||
|
global $frm_vars;
|
||||||
|
if ( isset( $frm_vars['job_id'] ) ) {
|
||||||
|
return absint( $frm_vars['job_id'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: Check URL parameter
|
||||||
|
if ( isset( $_GET['job_id'] ) ) {
|
||||||
|
return absint( $_GET['job_id'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: Try to get from current post if we're on a single job page
|
||||||
|
if ( is_singular( 'job_offer' ) ) {
|
||||||
|
global $post;
|
||||||
|
if ( $post && 'job_offer' === $post->post_type ) {
|
||||||
|
return absint( $post->ID );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $default_value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ class DDHH_JM_Notifications {
|
|||||||
public static function send_provider_application_notification( $entry_id, $form_id ) {
|
public static function send_provider_application_notification( $entry_id, $form_id ) {
|
||||||
// Only process job application form submissions
|
// Only process job application form submissions
|
||||||
$application_form_id = DDHH_JM_Formidable::get_job_application_form_id();
|
$application_form_id = DDHH_JM_Formidable::get_job_application_form_id();
|
||||||
if ( $form_id !== $application_form_id ) {
|
if ( $form_id != $application_form_id ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,6 +372,7 @@ class DDHH_JM_Notifications {
|
|||||||
$applicant_message = sanitize_textarea_field( $value );
|
$applicant_message = sanitize_textarea_field( $value );
|
||||||
break;
|
break;
|
||||||
case 'job_id':
|
case 'job_id':
|
||||||
|
case 'job_id2':
|
||||||
$job_id = absint( $value );
|
$job_id = absint( $value );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,8 +90,30 @@ class DDHH_JM_Template {
|
|||||||
|
|
||||||
<?php if ( $job_contact_email && is_user_logged_in() && current_user_can( 'read' ) ) : ?>
|
<?php if ( $job_contact_email && is_user_logged_in() && current_user_can( 'read' ) ) : ?>
|
||||||
<div class="job-application-section">
|
<div class="job-application-section">
|
||||||
<h3>Jetzt bewerben</h3>
|
<h3>Interesse?</h3>
|
||||||
<p>Interessiert? Kontaktieren Sie uns unter: <a href="mailto:<?php echo esc_attr( $job_contact_email ); ?>"><?php echo esc_html( $job_contact_email ); ?></a></p>
|
<button type="button" class="ddhh-contact-button" onclick="ddhhOpenContactModal(<?php echo absint( $post->ID ); ?>)">
|
||||||
|
Jetzt Kontakt aufnehmen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Contact Form Modal -->
|
||||||
|
<div id="ddhh-contact-modal-<?php echo absint( $post->ID ); ?>" class="ddhh-modal" style="display: none;">
|
||||||
|
<div class="ddhh-modal-content">
|
||||||
|
<span class="ddhh-modal-close" onclick="ddhhCloseContactModal(<?php echo absint( $post->ID ); ?>)">×</span>
|
||||||
|
<h3>Kontakt aufnehmen</h3>
|
||||||
|
<div class="ddhh-modal-body">
|
||||||
|
<?php
|
||||||
|
// Get the job application form ID
|
||||||
|
$form_id = DDHH_JM_Formidable::get_job_application_form_id();
|
||||||
|
if ( $form_id ) {
|
||||||
|
// Render the Formidable form with AJAX enabled to prevent page reload
|
||||||
|
echo do_shortcode( '[formidable id="' . absint( $form_id ) . '" job_id="' . absint( $post->ID ) . '" ajax="true"]' );
|
||||||
|
} else {
|
||||||
|
echo '<p>Formular konnte nicht geladen werden. Bitte kontaktieren Sie uns unter: <a href="mailto:' . esc_attr( $job_contact_email ) . '">' . esc_html( $job_contact_email ) . '</a></p>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
@@ -130,11 +152,171 @@ class DDHH_JM_Template {
|
|||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
border-left: 4px solid #0073aa;
|
border-left: 4px solid #0073aa;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.ddhh-job-offer-details .job-application-section h3 {
|
.ddhh-job-offer-details .job-application-section h3 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
.ddhh-job-offer-details .ddhh-contact-button {
|
||||||
|
background: #0073aa;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 30px;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.3s ease;
|
||||||
|
}
|
||||||
|
.ddhh-job-offer-details .ddhh-contact-button:hover {
|
||||||
|
background: #005a87;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modal Styles */
|
||||||
|
.ddhh-modal {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 9999;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(0,0,0,0.6);
|
||||||
|
}
|
||||||
|
.ddhh-modal-content {
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: 5% auto;
|
||||||
|
padding: 30px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 600px;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.ddhh-modal-close {
|
||||||
|
color: #aaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
}
|
||||||
|
.ddhh-modal-close:hover,
|
||||||
|
.ddhh-modal-close:focus {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.ddhh-modal-body {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.ddhh-modal h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function ddhhOpenContactModal(jobId) {
|
||||||
|
var modal = document.getElementById('ddhh-contact-modal-' + jobId);
|
||||||
|
if (modal) {
|
||||||
|
modal.style.display = 'block';
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
|
||||||
|
// Set the job_id in the hidden field
|
||||||
|
var jobIdField = modal.querySelector('input[id*="job_id"]');
|
||||||
|
if (jobIdField) {
|
||||||
|
jobIdField.value = jobId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent form from redirecting on submit
|
||||||
|
var form = modal.querySelector('form.frm-show-form');
|
||||||
|
if (form && !form.dataset.ddhhHandled) {
|
||||||
|
form.dataset.ddhhHandled = 'true';
|
||||||
|
|
||||||
|
jQuery(form).on('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log('Form submit intercepted - preventing page reload');
|
||||||
|
|
||||||
|
var $form = jQuery(this);
|
||||||
|
var formData = new FormData(this);
|
||||||
|
|
||||||
|
// Submit form via AJAX
|
||||||
|
jQuery.ajax({
|
||||||
|
url: $form.attr('action') || window.location.href,
|
||||||
|
type: 'POST',
|
||||||
|
data: formData,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(response) {
|
||||||
|
console.log('Form submitted successfully via AJAX');
|
||||||
|
// Replace form content with response
|
||||||
|
var formContainer = modal.querySelector('.ddhh-modal-body');
|
||||||
|
if (formContainer) {
|
||||||
|
var tempDiv = document.createElement('div');
|
||||||
|
tempDiv.innerHTML = response;
|
||||||
|
var newForm = tempDiv.querySelector('form.frm-show-form');
|
||||||
|
if (newForm) {
|
||||||
|
formContainer.innerHTML = newForm.outerHTML;
|
||||||
|
} else {
|
||||||
|
// Show success message if no form in response
|
||||||
|
var successMsg = tempDiv.querySelector('.frm_message');
|
||||||
|
if (successMsg) {
|
||||||
|
formContainer.innerHTML = successMsg.outerHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
console.error('Form submission failed');
|
||||||
|
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ddhhCloseContactModal(jobId) {
|
||||||
|
var modal = document.getElementById('ddhh-contact-modal-' + jobId);
|
||||||
|
if (modal) {
|
||||||
|
modal.style.display = 'none';
|
||||||
|
document.body.style.overflow = 'auto';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close modal when clicking outside of it
|
||||||
|
window.onclick = function(event) {
|
||||||
|
if (event.target.classList.contains('ddhh-modal')) {
|
||||||
|
event.target.style.display = 'none';
|
||||||
|
document.body.style.overflow = 'auto';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle successful form submission - keep modal open to show success message
|
||||||
|
jQuery(document).ready(function($) {
|
||||||
|
// Prevent redirect after form submission
|
||||||
|
$(document).on('frmBeforeFormRedirect', function(event, form, response) {
|
||||||
|
var formKey = $(form).find('input[name="form_key"]').val();
|
||||||
|
if (formKey === 'job_application') {
|
||||||
|
// Prevent the default redirect behavior
|
||||||
|
event.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('frmFormComplete', function(event, form, response) {
|
||||||
|
// Check if this is the job application form
|
||||||
|
var formKey = $(form).find('input[name="form_key"]').val();
|
||||||
|
if (formKey === 'job_application') {
|
||||||
|
// Modal stays open so user can see success message
|
||||||
|
// User can close it manually by clicking X or outside the modal
|
||||||
|
console.log('Form submitted successfully, modal staying open');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user