feat: Implement AJAX Add/Edit for Manage Jobs page
This commit is contained in:
parent
a3f1bcb0ef
commit
243c1481be
3 changed files with 260 additions and 101 deletions
136
functions.php
136
functions.php
|
|
@ -71,15 +71,23 @@ function quiztech_theme_enqueue_scripts() {
|
|||
// Localize script with necessary data for AJAX calls
|
||||
wp_localize_script( 'quiztech-theme-script', 'quiztechThemeData', [
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'add_job_nonce' => wp_create_nonce( 'quiztech_add_new_job_action' ),
|
||||
'save_job_nonce' => wp_create_nonce( 'quiztech_save_job_action' ), // Renamed from add_job_nonce
|
||||
'get_job_nonce' => wp_create_nonce( 'quiztech_get_job_action' ), // Nonce for fetching job data
|
||||
'send_invite_nonce' => wp_create_nonce( 'quiztech_send_job_invite_action' ),
|
||||
'save_question_nonce' => wp_create_nonce( 'quiztech_save_question_action' ), // Nonce for saving
|
||||
'get_question_nonce' => wp_create_nonce( 'quiztech_get_question_action' ), // Nonce for fetching
|
||||
'save_question_nonce' => wp_create_nonce( 'quiztech_save_question_action' ), // Nonce for saving question
|
||||
'get_question_nonce' => wp_create_nonce( 'quiztech_get_question_action' ), // Nonce for fetching question
|
||||
'error_generic' => esc_html__( 'An error occurred. Please try again.', 'quiztech' ),
|
||||
'error_permissions' => esc_html__( 'You do not have permission to perform this action.', 'quiztech' ),
|
||||
'error_missing_assessment' => esc_html__( 'Error: No assessment is linked to this job.', 'quiztech' ),
|
||||
'invite_sent_success' => esc_html__( 'Invite sent successfully!', 'quiztech' ),
|
||||
'job_added_success' => esc_html__( 'Job added successfully!', 'quiztech' ),
|
||||
// Add translatable strings for JS
|
||||
'l10n' => [
|
||||
'addNewJobTitle' => esc_html__( 'Add New Job Details', 'quiztech' ),
|
||||
'editJobTitle' => esc_html__( 'Edit Job Details', 'quiztech' ),
|
||||
'saveJobButton' => esc_html__( 'Save Job', 'quiztech' ),
|
||||
'updateJobButton'=> esc_html__( 'Update Job', 'quiztech' ),
|
||||
'loading' => esc_html__( 'Loading...', 'quiztech' ),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -113,49 +121,131 @@ function quiztech_theme_enqueue_scripts() {
|
|||
add_action( 'wp_enqueue_scripts', 'quiztech_theme_enqueue_scripts' );
|
||||
|
||||
|
||||
/**
|
||||
* AJAX handler for adding a new job post from the frontend.
|
||||
*/
|
||||
function quiztech_ajax_add_new_job() {
|
||||
// 1. Verify Nonce
|
||||
check_ajax_referer( 'quiztech_add_new_job_action', 'nonce' );
|
||||
|
||||
// 2. Check Capabilities (adjust capability if needed)
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
/**
|
||||
* AJAX handler for fetching job data for editing.
|
||||
*/
|
||||
function quiztech_ajax_get_job() {
|
||||
// 1. Verify Nonce
|
||||
check_ajax_referer( 'quiztech_get_job_action', 'nonce' );
|
||||
|
||||
// 2. Check Capabilities
|
||||
$capability = 'manage_options'; // Or a more specific capability like 'edit_jobs'
|
||||
if ( ! current_user_can( $capability ) ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'Insufficient permissions.', 'quiztech' ) ], 403 );
|
||||
}
|
||||
|
||||
// 3. Sanitize Input
|
||||
$job_id = isset( $_POST['job_id'] ) ? absint( $_POST['job_id'] ) : 0;
|
||||
if ( ! $job_id ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'Invalid job ID provided.', 'quiztech' ) ], 400 );
|
||||
}
|
||||
|
||||
// 4. Fetch Post
|
||||
$post = get_post( $job_id );
|
||||
|
||||
// 5. Validate Post
|
||||
if ( ! $post || $post->post_type !== 'job' ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'Job not found.', 'quiztech' ) ], 404 );
|
||||
}
|
||||
|
||||
// Optional: Check if the current user is the author or has higher privileges
|
||||
if ( $post->post_author != get_current_user_id() && ! current_user_can( 'edit_others_posts' ) ) { // Adjust capability check if needed
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'You do not have permission to view this job\'s details.', 'quiztech' ) ], 403 );
|
||||
}
|
||||
|
||||
// 6. Send Response
|
||||
wp_send_json_success( [
|
||||
'id' => $post->ID,
|
||||
'title' => $post->post_title,
|
||||
'description' => $post->post_content,
|
||||
] );
|
||||
}
|
||||
add_action( 'wp_ajax_quiztech_get_job', 'quiztech_ajax_get_job' );
|
||||
|
||||
|
||||
/**
|
||||
* AJAX handler for saving (adding or updating) a job post from the frontend.
|
||||
*/
|
||||
function quiztech_ajax_save_job() {
|
||||
// 1. Verify Nonce
|
||||
check_ajax_referer( 'quiztech_save_job_action', 'nonce' ); // Use new nonce action
|
||||
|
||||
// 2. Check Capabilities (adjust capability if needed)
|
||||
$capability = 'manage_options'; // Or a more specific capability like 'edit_jobs'
|
||||
if ( ! current_user_can( $capability ) ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'Insufficient permissions.', 'quiztech' ) ], 403 );
|
||||
}
|
||||
|
||||
// 3. Sanitize Input
|
||||
$job_id = isset( $_POST['job_id'] ) ? absint( $_POST['job_id'] ) : 0;
|
||||
$job_title = isset( $_POST['job_title'] ) ? sanitize_text_field( wp_unslash( $_POST['job_title'] ) ) : '';
|
||||
$job_description = isset( $_POST['job_description'] ) ? sanitize_textarea_field( wp_unslash( $_POST['job_description'] ) ) : '';
|
||||
$current_user_id = get_current_user_id();
|
||||
|
||||
// Basic Validation
|
||||
if ( empty( $job_title ) ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'Job title cannot be empty.', 'quiztech' ) ], 400 );
|
||||
}
|
||||
|
||||
// 4. Create Post
|
||||
// 4. Prepare Post Data
|
||||
$post_data = [
|
||||
'post_title' => $job_title,
|
||||
'post_content' => $job_description,
|
||||
'post_status' => 'publish', // Or 'draft' if preferred
|
||||
'post_author' => get_current_user_id(),
|
||||
'post_type' => 'job',
|
||||
'post_status' => 'publish', // Default to publish, adjust if needed
|
||||
];
|
||||
|
||||
$post_id = wp_insert_post( $post_data, true ); // Pass true to return WP_Error on failure
|
||||
$result = 0;
|
||||
$is_update = false;
|
||||
|
||||
// 5. Determine if Update or Insert
|
||||
if ( $job_id > 0 ) {
|
||||
// --- Update Existing Job ---
|
||||
$is_update = true;
|
||||
$existing_post = get_post( $job_id );
|
||||
|
||||
// Validation for update
|
||||
if ( ! $existing_post || $existing_post->post_type !== 'job' ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'Job not found.', 'quiztech' ) ], 404 );
|
||||
}
|
||||
// Optional: Check if the current user is the author or has higher privileges
|
||||
if ( $existing_post->post_author != $current_user_id && ! current_user_can( 'edit_others_posts' ) ) { // Adjust capability check if needed
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'You do not have permission to edit this job.', 'quiztech' ) ], 403 );
|
||||
}
|
||||
|
||||
$post_data['ID'] = $job_id; // Set ID for update
|
||||
$result = wp_update_post( $post_data, true );
|
||||
|
||||
// 5. Send Response
|
||||
if ( is_wp_error( $post_id ) ) {
|
||||
wp_send_json_error( [ 'message' => $post_id->get_error_message() ], 500 );
|
||||
} else {
|
||||
// Optionally return HTML for the new row, or just success and let JS handle refresh/update
|
||||
// --- Insert New Job ---
|
||||
$post_data['post_author'] = $current_user_id; // Set author only for new posts
|
||||
$result = wp_insert_post( $post_data, true );
|
||||
}
|
||||
|
||||
// 6. Send Response
|
||||
if ( is_wp_error( $result ) ) {
|
||||
wp_send_json_error( [ 'message' => $result->get_error_message() ], 500 );
|
||||
} elseif ( $result === 0 ) {
|
||||
// wp_update_post returns 0 if nothing changed, which isn't an error here.
|
||||
// Treat it as success but maybe with a different message? For now, same success message.
|
||||
wp_send_json_success( [
|
||||
'message' => esc_html__( 'Job details saved (no changes detected).', 'quiztech' ),
|
||||
'job_id' => $job_id // Return the existing ID
|
||||
] );
|
||||
} else {
|
||||
// Success (Insert or Update)
|
||||
$success_message = $is_update
|
||||
? esc_html__( 'Job updated successfully.', 'quiztech' )
|
||||
: esc_html__( 'Job created successfully.', 'quiztech' );
|
||||
|
||||
wp_send_json_success( [
|
||||
'message' => esc_html__( 'Job created successfully.', 'quiztech' ),
|
||||
'post_id' => $post_id
|
||||
'message' => $success_message,
|
||||
'job_id' => $result // $result is the post ID on success
|
||||
] );
|
||||
}
|
||||
}
|
||||
add_action( 'wp_ajax_add_new_job', 'quiztech_ajax_add_new_job' );
|
||||
add_action( 'wp_ajax_quiztech_save_job', 'quiztech_ajax_save_job' ); // Use new action hook
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,26 +1,146 @@
|
|||
jQuery(document).ready(function($) {
|
||||
|
||||
// --- Add New Job Form ---
|
||||
// --- Job Add/Edit Form Elements ---
|
||||
const formWrapper = $('#add-new-job-form');
|
||||
const formElement = $('#new-job-form');
|
||||
const jobIdField = $('#quiztech-job-id');
|
||||
const jobTitleField = $('#job_title');
|
||||
const jobDescriptionField = $('#job_description');
|
||||
const formTitle = formWrapper.find('h2'); // Target the h2 inside the form div
|
||||
const submitButton = formElement.find('input[type="submit"]');
|
||||
const cancelButton = formElement.find('.cancel-add-job');
|
||||
const addButton = $('.add-new-job-button');
|
||||
const statusDiv = formWrapper.find('.add-job-status');
|
||||
const spinner = formWrapper.find('.spinner');
|
||||
const jobTableBody = $('.quiztech-manage-table tbody'); // For event delegation
|
||||
|
||||
// Show the "Add New Job" form when the button is clicked
|
||||
$('.add-new-job-button').on('click', function(e) {
|
||||
// --- Helper: Reset and Prepare Form ---
|
||||
function resetAndPrepareForm(mode = 'add') {
|
||||
formElement[0].reset(); // Reset native form fields
|
||||
jobIdField.val(''); // Clear hidden ID
|
||||
statusDiv.empty().removeClass('error success'); // Clear status messages
|
||||
spinner.css('visibility', 'hidden');
|
||||
|
||||
if (mode === 'add') {
|
||||
formTitle.text(quiztechThemeData.l10n.addNewJobTitle || 'Add New Job Details'); // Use localized string
|
||||
submitButton.val(quiztechThemeData.l10n.saveJobButton || 'Save Job');
|
||||
submitButton.prop('disabled', false);
|
||||
} else { // 'edit' mode
|
||||
formTitle.text(quiztechThemeData.l10n.editJobTitle || 'Edit Job Details'); // Use localized string
|
||||
submitButton.val(quiztechThemeData.l10n.updateJobButton || 'Update Job');
|
||||
submitButton.prop('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Add New Job Button ---
|
||||
addButton.on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$('#add-new-job-form').slideDown();
|
||||
resetAndPrepareForm('add'); // Prepare form for adding
|
||||
formWrapper.slideDown();
|
||||
$(this).hide(); // Hide the "Add New Job" button itself
|
||||
});
|
||||
|
||||
// Hide the "Add New Job" form when the cancel button is clicked
|
||||
$('#add-new-job-form .cancel-add-job').on('click', function(e) {
|
||||
// --- Cancel Button (in Add/Edit Form) ---
|
||||
cancelButton.on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$('#add-new-job-form').slideUp(function() {
|
||||
// Optional: Clear form fields on cancel
|
||||
// $('#new-job-form')[0].reset();
|
||||
// $('.add-job-status').empty();
|
||||
formWrapper.slideUp(function() {
|
||||
resetAndPrepareForm('add'); // Reset to add mode visuals when hiding
|
||||
});
|
||||
$('.add-new-job-button').show(); // Show the "Add New Job" button again
|
||||
addButton.show(); // Show the "Add New Job" button again
|
||||
});
|
||||
|
||||
// --- Send Invite Form ---
|
||||
// --- Edit Job Button Click (Event Delegation) ---
|
||||
jobTableBody.on('click', '.quiztech-edit-job-btn', function() {
|
||||
const $button = $(this);
|
||||
const jobId = $button.data('job-id');
|
||||
const originalButtonText = $button.text();
|
||||
|
||||
// Prevent double clicks and show loading state
|
||||
if ($button.prop('disabled')) {
|
||||
return;
|
||||
}
|
||||
$button.prop('disabled', true).text(quiztechThemeData.l10n.loading || 'Loading...');
|
||||
statusDiv.empty().removeClass('error success'); // Clear form status
|
||||
|
||||
$.ajax({
|
||||
url: quiztechThemeData.ajax_url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'quiztech_get_job',
|
||||
nonce: quiztechThemeData.get_job_nonce, // Use new nonce
|
||||
job_id: jobId
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
const data = response.data;
|
||||
resetAndPrepareForm('edit'); // Prepare form visuals for editing
|
||||
|
||||
// Populate form fields
|
||||
jobIdField.val(data.id);
|
||||
jobTitleField.val(data.title);
|
||||
jobDescriptionField.val(data.description);
|
||||
|
||||
formWrapper.slideDown(); // Show the form
|
||||
// Scroll to form for better UX
|
||||
$('html, body').animate({ scrollTop: formWrapper.offset().top - 50 }, 300);
|
||||
} else {
|
||||
// Display error near the button or globally? For now, alert.
|
||||
alert(response.data.message || quiztechThemeData.error_generic);
|
||||
}
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
console.error("AJAX Error fetching job:", textStatus, errorThrown, jqXHR.responseText);
|
||||
alert(quiztechThemeData.error_generic);
|
||||
},
|
||||
complete: function() {
|
||||
// Restore button state
|
||||
$button.prop('disabled', false).text(originalButtonText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// --- Add/Edit Job Form Submission AJAX ---
|
||||
formElement.on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
statusDiv.empty().removeClass('error success');
|
||||
spinner.css('visibility', 'visible');
|
||||
submitButton.prop('disabled', true);
|
||||
|
||||
var formData = {
|
||||
action: 'quiztech_save_job', // Use new action
|
||||
nonce: quiztechThemeData.save_job_nonce, // Use new nonce
|
||||
job_id: jobIdField.val(), // Include job_id (will be empty for new jobs)
|
||||
job_title: jobTitleField.val(),
|
||||
job_description: jobDescriptionField.val()
|
||||
};
|
||||
|
||||
$.post(quiztechThemeData.ajax_url, formData)
|
||||
.done(function(response) {
|
||||
if (response.success) {
|
||||
statusDiv.text(response.data.message || 'Job saved successfully.').addClass('success');
|
||||
// Reload page to see changes (simplest approach)
|
||||
// TODO: Implement dynamic row update/add for better UX later
|
||||
setTimeout(function() { location.reload(); }, 1500);
|
||||
} else {
|
||||
statusDiv.text(response.data.message || quiztechThemeData.error_generic).addClass('error');
|
||||
submitButton.prop('disabled', false); // Re-enable button on failure
|
||||
}
|
||||
})
|
||||
.fail(function(jqXHR, textStatus, errorThrown) {
|
||||
console.error("AJAX Error saving job:", textStatus, errorThrown, jqXHR.responseText);
|
||||
statusDiv.text(quiztechThemeData.error_generic).addClass('error');
|
||||
submitButton.prop('disabled', false); // Re-enable button on failure
|
||||
})
|
||||
.always(function() {
|
||||
spinner.css('visibility', 'hidden');
|
||||
// Keep button disabled on success until reload
|
||||
});
|
||||
});
|
||||
|
||||
// --- Send Invite Form (Existing Logic - Unchanged) ---
|
||||
|
||||
// Show the specific "Send Invite" form row when the link is clicked
|
||||
$('.send-job-invite').on('click', function(e) {
|
||||
|
|
@ -41,50 +161,6 @@ jQuery(document).ready(function($) {
|
|||
$(this).closest('.send-invite-form-row').slideUp();
|
||||
});
|
||||
|
||||
// --- AJAX Form Submissions ---
|
||||
|
||||
// Add New Job AJAX
|
||||
$('#new-job-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
var $form = $(this);
|
||||
var $submitButton = $form.find('input[type="submit"]');
|
||||
var $spinner = $form.find('.spinner');
|
||||
var $statusDiv = $form.find('.add-job-status');
|
||||
|
||||
$statusDiv.empty().removeClass('error success');
|
||||
$spinner.css('visibility', 'visible');
|
||||
$submitButton.prop('disabled', true);
|
||||
|
||||
var formData = {
|
||||
action: 'add_new_job',
|
||||
nonce: quiztechThemeData.add_job_nonce,
|
||||
job_title: $form.find('#job_title').val(),
|
||||
job_description: $form.find('#job_description').val()
|
||||
};
|
||||
|
||||
$.post(quiztechThemeData.ajax_url, formData)
|
||||
.done(function(response) {
|
||||
if (response.success) {
|
||||
$statusDiv.text(quiztechThemeData.job_added_success).addClass('success');
|
||||
// Optionally: Clear form, hide it, refresh job list via another AJAX call or page reload
|
||||
$form[0].reset();
|
||||
$('#add-new-job-form').slideUp();
|
||||
$('.add-new-job-button').show();
|
||||
// Consider adding the new job row dynamically instead of full reload
|
||||
location.reload(); // Simple reload for now
|
||||
} else {
|
||||
$statusDiv.text(response.data.message || quiztechThemeData.error_generic).addClass('error');
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
$statusDiv.text(quiztechThemeData.error_generic).addClass('error');
|
||||
})
|
||||
.always(function() {
|
||||
$spinner.css('visibility', 'hidden');
|
||||
$submitButton.prop('disabled', false);
|
||||
});
|
||||
});
|
||||
|
||||
// Send Invite AJAX
|
||||
$('.send-invite-submit').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
|
@ -92,33 +168,31 @@ jQuery(document).ready(function($) {
|
|||
var jobId = $button.data('job-id');
|
||||
var $wrapper = $button.closest('.send-invite-form-wrapper');
|
||||
var $emailInput = $wrapper.find('input[name="applicant_email"]');
|
||||
var $spinner = $wrapper.find('.spinner');
|
||||
var $statusDiv = $wrapper.find('.invite-status');
|
||||
var $inviteSpinner = $wrapper.find('.spinner'); // Use different spinner variable
|
||||
var $inviteStatusDiv = $wrapper.find('.invite-status'); // Use different status div variable
|
||||
var applicantEmail = $emailInput.val();
|
||||
|
||||
if (!applicantEmail) {
|
||||
$emailInput.focus();
|
||||
// Maybe add a small visual cue that email is required
|
||||
return;
|
||||
}
|
||||
|
||||
$statusDiv.empty().removeClass('error success');
|
||||
$spinner.css('visibility', 'visible');
|
||||
$inviteStatusDiv.empty().removeClass('error success');
|
||||
$inviteSpinner.css('visibility', 'visible');
|
||||
$button.prop('disabled', true).siblings('.cancel-invite').prop('disabled', true);
|
||||
|
||||
var formData = {
|
||||
var inviteFormData = { // Use different formData variable
|
||||
action: 'send_job_invite',
|
||||
nonce: quiztechThemeData.send_invite_nonce,
|
||||
job_id: jobId,
|
||||
applicant_email: applicantEmail
|
||||
};
|
||||
|
||||
$.post(quiztechThemeData.ajax_url, formData)
|
||||
$.post(quiztechThemeData.ajax_url, inviteFormData)
|
||||
.done(function(response) {
|
||||
if (response.success) {
|
||||
$statusDiv.text(quiztechThemeData.invite_sent_success).addClass('success');
|
||||
$inviteStatusDiv.text(quiztechThemeData.invite_sent_success || 'Invite sent successfully!').addClass('success');
|
||||
$emailInput.val(''); // Clear email field on success
|
||||
// Optionally hide the form row after a delay
|
||||
setTimeout(function() {
|
||||
$button.closest('.send-invite-form-row').slideUp();
|
||||
}, 2000);
|
||||
|
|
@ -126,18 +200,16 @@ jQuery(document).ready(function($) {
|
|||
var errorMessage = quiztechThemeData.error_generic;
|
||||
if (response.data && response.data.message) {
|
||||
errorMessage = response.data.message;
|
||||
} else if (response.data && response.data === 'error_missing_assessment') {
|
||||
// Example of handling specific error code if needed
|
||||
errorMessage = quiztechThemeData.error_missing_assessment;
|
||||
}
|
||||
$statusDiv.text(errorMessage).addClass('error');
|
||||
$inviteStatusDiv.text(errorMessage).addClass('error');
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
$statusDiv.text(quiztechThemeData.error_generic).addClass('error');
|
||||
.fail(function(jqXHR, textStatus, errorThrown) {
|
||||
console.error("AJAX Error sending invite:", textStatus, errorThrown, jqXHR.responseText);
|
||||
$inviteStatusDiv.text(quiztechThemeData.error_generic).addClass('error');
|
||||
})
|
||||
.always(function() {
|
||||
$spinner.css('visibility', 'hidden');
|
||||
$inviteSpinner.css('visibility', 'hidden');
|
||||
$button.prop('disabled', false).siblings('.cancel-invite').prop('disabled', false);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -63,12 +63,8 @@ get_header(); ?>
|
|||
</td>
|
||||
<td><?php echo esc_html( get_post_status( get_the_ID() ) ); ?></td>
|
||||
<td>
|
||||
<?php
|
||||
// Placeholder links - replace with actual frontend edit/view results page URLs when created
|
||||
$edit_url = '#edit-job-' . get_the_ID(); // Placeholder
|
||||
$results_url = '#view-results-' . get_the_ID(); // Placeholder
|
||||
?>
|
||||
<a href="<?php echo esc_url( $edit_url ); ?>"><?php esc_html_e( 'Edit', 'quiztech' ); ?></a> |
|
||||
<?php $results_url = '#view-results-' . get_the_ID(); // Placeholder ?>
|
||||
<button class="button button-small quiztech-edit-job-btn" data-job-id="<?php echo esc_attr( get_the_ID() ); ?>"><?php esc_html_e( 'Edit', 'quiztech' ); ?></button> |
|
||||
<a href="<?php echo esc_url( $results_url ); ?>"><?php esc_html_e( 'View Results', 'quiztech' ); ?></a> |
|
||||
<a href="#send-invite" class="send-job-invite" data-job-id="<?php echo esc_attr( get_the_ID() ); ?>"><?php esc_html_e( 'Send Invite', 'quiztech' ); ?></a>
|
||||
</td>
|
||||
|
|
@ -107,6 +103,7 @@ get_header(); ?>
|
|||
<p>
|
||||
<label for="job_title"><?php esc_html_e( 'Job Title:', 'quiztech' ); ?></label><br />
|
||||
<input type="text" id="job_title" name="job_title" value="" required style="width: 100%;" />
|
||||
<input type="hidden" id="quiztech-job-id" name="job_id" value="">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue