• Hello,

    I managed to add a field for Tags in Submit form on Frontend. However the tags are not saved. Could you please help me achieve this?

    Thanks

Viewing 15 replies - 1 through 15 (of 19 total)
  • Thread Starter amineriad

    (@amineriad)

    Note that Tags were enebled in Events Settings and that I added the code below in event-editor.php:

    <?php if ( get_option('dbem_tags_enabled') ) : ?>
    <div class="event-extra-details <?php echo $template; ?>">
    <div class="input" style="width:80%">
    <label for="event_tags"><?php _e('Tags', 'events-manager'); ?></label>

    <?php
    // Get existing tags for this event
    $event_tags = array();
    if( !empty($EM_Event->post_id) ){
    $event_tags = wp_get_post_terms($EM_Event->post_id, EM_TAXONOMY_TAG, ['fields' => 'names']);
    }

    // Get all tags
    $tags = get_terms([
    'taxonomy' => EM_TAXONOMY_TAG,
    'hide_empty' => false
    ]);
    ?>

    <select name="event_tags[]" multiple="multiple" class="em-selectize" style="width:100%;">
    <?php foreach($tags as $tag): ?>
    <option value="<?php echo esc_attr($tag->name); ?>"
    <?php selected(in_array($tag->name, $event_tags)); ?>>
    <?php echo esc_html($tag->name); ?>
    </option>
    <?php endforeach; ?>
    </select>

    <p class="description"><?php _e('Select one or more tags for this event.', 'events-manager'); ?></p>
    </div>
    </div>
    <?php endif; ?>

    We’re also very curious about this, it would save us much time.

    I found this old post with some snippets too https://wordpress.org/support/topic/adding-tags-to-event-submission-form/

    Thread Starter amineriad

    (@amineriad)

    I tried the snippets above but unfortunately they do not work.

    To avoid the event-editor.php from getting overwritten when you update the plugin create the directory wp-content/plugin-templates/events-manager/forms then copy event-editor.php to that directory then edit the copied file and add the following after line 105:

                        <?php if(em_get_option('dbem_tags_enabled')) { em_locate_template('forms/event/tags-public.php',true); }  ?>

    Then create the file wp-content/plugin-templates/events-manager/forms/event/tags-public.php with the following content:

    <?php
    /**
    * Event Tags Form
    * @version 1.0
    */
    global $EM_Event;
    ?>
    <div class="event-tags">
    <label for="event_tags"><?php esc_html_e( 'Event Tags', 'events-manager'); ?></label>
    <input type="text" name="event_tags" id="event-tags" class="em-tags-input"
    value="<?php
    if( !empty($EM_Event->post_id) ) {
    $tags = wp_get_object_terms($EM_Event->post_id, EM_TAXONOMY_TAG, array('fields' => 'names'));
    // Escape each tag individually
    $escaped_tags = array_map('esc_attr', $tags);
    echo esc_attr(implode(', ', $escaped_tags));
    }
    ?>"
    maxlength="1000"
    pattern="[^<>\/\'\"]*"
    title="<?php esc_attr_e('Tags cannot contain <, >, /, \', or " characters', 'events-manager'); ?>"
    placeholder="<?php esc_attr_e('Separate tags with commas', 'events-manager'); ?>">
    <p class="description"><?php esc_html_e('Add tags to help categorize your event. Separate multiple tags with commas.', 'events-manager'); ?></p>
    </div>

    Then add the following code snippet to save the tags:

    function save_event_tags_from_frontend($result, $EM_Event) {
    // Verify nonce if it's a frontend submission
    if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'wpnonce_event_save')) {
    return $result; // Don't process tags if nonce is invalid
    }
    if ($result && isset($_POST['event_tags']) && is_string($POST['event_tags']) && $EM_Event->can_manage('edit_events')) {
    if (strlen($_POST['event_tags']) > 1000) {
    return $result;
    }
    // Use WordPress core function to sanitize terms
    $tags = sanitize_text_field($_POST['event_tags']);

    // Split and process each tag
    $tags = str_getcsv($tags, ','); // Better than explode for handling quotes

    $clean_tags = array();

    foreach ($tags as $tag) {
    $tag = trim($tag);

    // Skip if empty
    if (empty($tag)) {
    continue;
    }

    // Additional sanitization
    $tag = sanitize_term_field('name', $tag, 0, EM_TAXONOMY_TAG, 'db');

    // Validate the tag name
    if (term_exists($tag, EM_TAXONOMY_TAG) !== 0 || is_wp_error($tag)) {
    // Tag is valid, add it
    $clean_tags[] = $tag;
    } else {
    // Check if it's a valid string for a term name
    $valid = true;

    // Check length
    if (strlen($tag) > 200 || strlen($tag) < 1) {
    $valid = false;
    }

    // Check for invalid characters
    if (preg_match('/[<>\/\'\"]/', $tag)) {
    $valid = false;
    }

    if ($valid) {
    $clean_tags[] = $tag;
    }
    }
    }

    // Apply limits
    $clean_tags = array_slice(array_unique($clean_tags), 0, 50);

    // Save tags
    if (!empty($clean_tags)) {
    wp_set_object_terms($EM_Event->post_id, $clean_tags, EM_TAXONOMY_TAG, false);
    } else {
    wp_set_object_terms($EM_Event->post_id, array(), EM_TAXONOMY_TAG, false);
    }
    }
    return $result;
    }
    add_filter('em_event_save', 'save_event_tags_from_frontend', 10, 2);

    You can use the Code Snippets plugin to add this code snippet.
    This version of the code does all the necessary escaping the sanitizing of inputs as well as adding a nonce check.

    There was a typo on line 6 of the code snippet (in the save_event_tags_from_frontend function). It should have been

    is_string($_POST['event_tags'])

    Instead of :

    is_string($POST['event_tags'])

    Here’s the corrected version of the code snippet:

    function save_event_tags_from_frontend($result, $EM_Event) {
    / Verify nonce if it's a frontend submission
    if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'wpnonce_event_save')) {
    return $result; // Don't process tags if nonce is invalid
    }
    if ($result && isset($_POST['event_tags']) && is_string($_POST['event_tags']) && $EM_Event->can_manage('edit_events')) {
    if (strlen($_POST['event_tags']) > 1000) {
    return $result;
    }
    // Use WordPress core function to sanitize terms
    $tags = sanitize_text_field($_POST['event_tags']);

    // Split and process each tag
    $tags = str_getcsv($tags, ','); // Better than explode for handling quotes

    $clean_tags = array();

    foreach ($tags as $tag) {
    $tag = trim($tag);

    // Skip if empty
    if (empty($tag)) {
    continue;
    }

    // Additional sanitization
    $tag = sanitize_term_field('name', $tag, 0, EM_TAXONOMY_TAG, 'db');

    // Validate the tag name
    if (term_exists($tag, EM_TAXONOMY_TAG) !== 0 || is_wp_error($tag)) {
    // Tag is valid, add it
    $clean_tags[] = $tag;
    } else {
    // Check if it's a valid string for a term name
    $valid = true;

    // Check length
    if (strlen($tag) > 200 || strlen($tag) < 1) {
    $valid = false;
    }

    // Check for invalid characters
    if (preg_match('/[<>\/\'\"]/', $tag)) {
    $valid = false;
    }

    if ($valid) {
    $clean_tags[] = $tag;
    }
    }
    }

    // Apply limits
    $clean_tags = array_slice(array_unique($clean_tags), 0, 50);

    // Save tags
    if (!empty($clean_tags)) {
    wp_set_object_terms($EM_Event->post_id, $clean_tags, EM_TAXONOMY_TAG, false);
    } else {
    wp_set_object_terms($EM_Event->post_id, array(), EM_TAXONOMY_TAG, false);
    }
    }
    return $result;
    }
    add_filter('em_event_save', 'save_event_tags_from_frontend', 10, 2);

    You can use the Code Snippets plugin to add the code snippet.

    Here’s some updates so that it will “autocomplete” the tags. Add the following code snippet:

    /*
    * AJAX Handler for Events Manager Tag Autocomplete
    */
    add_action('wp_ajax_em_frontend_tag_search', 'em_frontend_tag_search_callback');
    add_action('wp_ajax_nopriv_em_frontend_tag_search', 'em_frontend_tag_search_callback');

    function em_frontend_tag_search_callback() {
    // 1. Get the search term
    $term = isset($_GET['term']) ? sanitize_text_field($_GET['term']) : '';

    // 2. Search for tags in the Events Manager taxonomy (EM_TAXONOMY_TAG constant)
    // If the constant isn't defined for some reason, fallback to 'event-tag'
    $taxonomy = defined('EM_TAXONOMY_TAG') ? EM_TAXONOMY_TAG : 'event-tag';

    $tags = get_terms(array(
    'taxonomy' => $taxonomy,
    'hide_empty' => false,
    'search' => $term, // matches partial names
    'number' => 10 // limit results for performance
    ));

    // 3. Format for jQuery UI Autocomplete
    $results = array();
    if ( ! empty($tags) && ! is_wp_error($tags) ) {
    foreach ( $tags as $tag ) {
    $results[] = array(
    'id' => $tag->term_id,
    'label' => $tag->name,
    'value' => $tag->name
    );
    }
    }

    // 4. Return JSON
    wp_send_json($results);
    }

    Then change tags-public.php to this:

    <?php
    /**
    * Custom Template for displaying Event Tags with Autocomplete
    * Save to: /wp-content/themes/YOUR-THEME/plugins/events-manager/forms/event/tags-public.php
    */

    global $EM_Event;

    // 1. Safety Check
    if( !em_get_option('dbem_tags_enabled') ) return;

    // 2. Enqueue jQuery UI Autocomplete (Standard WP Library)
    wp_enqueue_script('jquery-ui-autocomplete');
    // Ensure basic styles for the dropdown are loaded (optional, but recommended)
    wp_enqueue_style('jquery-ui-css', 'https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css');

    // 3. Prepare value
    $event_tags_value = '';
    if ( !empty($EM_Event->post_id) ) {
    $tags = wp_get_object_terms( $EM_Event->post_id, EM_TAXONOMY_TAG, array('fields'=>'names') );
    if ( !is_wp_error($tags) && !empty($tags) ) {
    $event_tags_value = implode(', ', $tags);
    }
    } elseif ( !empty($_REQUEST['event_tags']) ) {
    $event_tags_value = sanitize_text_field($_REQUEST['event_tags']);
    }
    ?>

    <div class="event-tags-div">
    <label for="event_tags"><?php esc_html_e('Event Tags', 'events-manager'); ?></label>

    <input type="text" name="event_tags" id="event_tags" value="<?php echo esc_attr($event_tags_value); ?>" class="input" style="width:100%;" />

    <p class="description">
    <?php esc_html_e('Separate tags with commas. Start typing to see existing tags.', 'events-manager'); ?>
    </p>

    <script type="text/javascript">
    jQuery(document).ready(function($) {

    // Helper to split terms by comma
    function split( val ) {
    return val.split( /,\s*/ );
    }

    // Helper to get the term currently being typed (the last one)
    function extractLast( term ) {
    return split( term ).pop();
    }

    $( "#event_tags" )
    // don't navigate away from the field on tab when selecting an item
    .on( "keydown", function( event ) {
    if ( event.keyCode === $.ui.keyCode.TAB &&
    $( this ).autocomplete( "instance" ).menu.active ) {
    event.preventDefault();
    }
    })
    .autocomplete({
    source: function( request, response ) {
    $.getJSON(
    "<?php echo admin_url('admin-ajax.php'); ?>",
    {
    action: "em_frontend_tag_search",
    term: extractLast( request.term )
    },
    response
    );
    },
    search: function() {
    // custom minLength implementation for the last term
    var term = extractLast( this.value );
    if ( term.length < 2 ) {
    return false;
    }
    },
    focus: function() {
    // prevent value inserted on focus
    return false;
    },
    select: function( event, ui ) {
    var terms = split( this.value );
    // remove the current input
    terms.pop();
    // add the selected item
    terms.push( ui.item.value );
    // add placeholder to get the comma-and-space at the end
    terms.push( "" );
    this.value = terms.join( ", " );
    return false;
    }
    });
    });
    </script>

    <style>
    /* Optional: Fix z-index issues if the dropdown hides behind other elements */
    .ui-autocomplete { z-index: 99999 !important; }
    .ui-helper-hidden-accessible { display: none; }
    </style>
    </div>
    Thread Starter amineriad

    (@amineriad)

    Thanks joneiseman,

    I will test and get back to you.

    Thread Starter amineriad

    (@amineriad)

    I test the codes proposed by joneiseman, but they do not work.

    It does work and I know that because I tested it. You didn’t provide any details so I don’t know what you did wrong. Perhaps you didn’t put put the files tags-public.php and event-editor.php in the correct directory?

    Works perfectly. Thank you!

    There is one bug.

    The Tags are not passed on to repeating events.

    The tag is visible when editing the repeated event. Only if you edit and save the repeating event in the WP Dashboard, are the tags passed on to the repeated events.

    joneiseman

    (@joneiseman)

    Here’s the corrected version of the save_event_tags_from_frontend function to handle recurring/repeating events.

    function save_event_tags_from_frontend($result, $EM_Event) {
    // Verify nonce if it's a frontend submission
    if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'wpnonce_event_save')) {
    return $result; // Don't process tags if nonce is invalid
    }
    if ($result && isset($_POST['event_tags']) && is_string($_POST['event_tags']) && $EM_Event->can_manage('edit_events')) {
    if (strlen($_POST['event_tags']) > 1000) {
    return $result;
    }
    // Use WordPress core function to sanitize terms
    $tags = sanitize_text_field($_POST['event_tags']);

    // Split and process each tag
    $tags = str_getcsv($tags, ','); // Better than explode for handling quotes

    $clean_tags = array();

    foreach ($tags as $tag) {
    $tag = trim($tag);
    // Skip if empty
    if (empty($tag)) {
    continue;
    }

    // Additional sanitization
    $tag = sanitize_term_field('name', $tag, 0, EM_TAXONOMY_TAG, 'db');

    // Validate the tag name
    if (term_exists($tag, EM_TAXONOMY_TAG) !== 0 || is_wp_error($tag)) {
    // Tag is valid, add it
    $clean_tags[] = $tag;
    } else {
    // Check if it's a valid string for a term name
    $valid = true;

    // Check length
    if (strlen($tag) > 200 || strlen($tag) < 1) {
    $valid = false;
    }

    // Check for invalid characters
    if (preg_match('/[<>\/\'\"]/', $tag)) {
    $valid = false;
    }

    if ($valid) {
    $clean_tags[] = $tag;
    }
    }
    }

    // Apply limits
    $clean_tags = array_slice(array_unique($clean_tags), 0, 50);

    // Save tags
    if (!empty($clean_tags)) {
    wp_set_object_terms($EM_Event->post_id, $clean_tags, EM_TAXONOMY_TAG, false);
    } else {
    wp_set_object_terms($EM_Event->post_id, array(), EM_TAXONOMY_TAG, false);
    }
    // RECURRING EVENT FIX: If this is a recurring (or repeating event),
    // update all child events.
    if ( $EM_Event->is_recurring( true ) ) {
    // Get all child events spawned by this recurring (or repeating) template
    $child_events = EM_Events::get(array(
    'recurring_id' => $EM_Event->event_id,
    'scope' => 'all',
    'status' => 'all'
    ));

    if ( !empty($child_events) ) {
    foreach ( $child_events as $child_event ) {
    if ( empty($clean_tags) ) {
    wp_set_object_terms( $child_event->post_id, array(), EM_TAXONOMY_TAG );
    } else {
    wp_set_object_terms( $child_event->post_id, $clean_tags, EM_TAXONOMY_TAG );
    }
    }
    }
    }
    }
    return $result;
    }
    • This reply was modified 3 months ago by joneiseman. Reason: corrected a comment

    Thank you for the updated code.

    There is still a bug. I am not getting tags saved at all now when adding recurring events from the frontend

    joneiseman

    (@joneiseman)

    I was not able to reproduce this problem. For me it works well for both recurring events and repeating events. Try turning on WP_DEBUG in wp-config.php and then check your debug.log to see if there are any warnings or errors. Add the following to your wp-config.php:

    define( 'WP_DEBUG', true );
    define( 'WP_DEBUG_DISPLAY', false );
    define( 'WP_DEBUG_LOG', true );

    Do you see the tags and categories when you view the individual recurring events?

    • This reply was modified 3 months ago by joneiseman.
    joneiseman

    (@joneiseman)

    Looks like the categories and tags don’t display for recurring events in the event list but they do show up in the single event page. This is true with or without my change. This is also the case when the tag was entered in the frontend or the backend. The tags do show up for repeating events or single events in the event list.

Viewing 15 replies - 1 through 15 (of 19 total)

You must be logged in to reply to this topic.