• Resolved Windurin

    (@windurin)


    I have a rather unique situation and I don’t know if the solution is necessarily related to ACFE but I am using an ACFE form.

    I’m using ACFE to call a custom function on form submit. This function is run after updating a Card Pack post type – it awards collectible Cards to users, and updates a hidden True/False field called ‘is_card_pack_opened’ to True. This then shows a different template for the Card Pack post, showing the Cards that were in the pack. This is all working fine. My issue is… I realised there’s nothing stopping users having the unopened Card Pack page open in another tab and clicking the button to basically be awarded the Cards twice, or even more if they have more than 2 tabs open.

    I suppose I somehow need to stop the post being updated on the second tab if it’s already been updated – so if the ‘is_card_pack_opened’ is now true, but obviously without the page being refreshed in the other tab, it will still think the Card Pack is unopened. Is it actually possible to update the true/false field ‘live’ – through ajax presumably – and stop the form being submitted again? Or any kind of validation, perhaps even a limit on how many times a form/post can be updated and just set that to once only?

    Appreciate any suggestions you might have. Thanks.

Viewing 9 replies - 1 through 9 (of 9 total)
  • Plugin Author Konrad Chmielewski

    (@hwk-fr)

    Hello,

    Thanks for the feedback!

    You can use the acfe/form/validation hook in order to validate your form globally. See documentation.

    There are also similar hooks to target specific Post Action, User Action etc… if you prefer.

    In those validation hooks you can check the value of a field within the form, or a value in the database. The validation is run in ajax right before the form submission, so you can stop the submission if a specific value is already set in the database.

    Hope it helps!

    Have a nice day!

    Regards.

    Thread Starter Windurin

    (@windurin)

    Hi, Thanks for the response. I just tried this code and it didn’t seem to work:

    add_action('acfe/form/validation/form=open-bronze-card-pack-form', 'my_form_validation', 10, 2);
    function my_form_validation($form, $post_id){
        
        // Get field input value
        $opened = get_field('is_card_pack_opened');
        
        if($opened === '1'){
            
            // Add validation error
            acfe_add_validation_error('is_card_pack_opened', 'You Have Already Opened This Pack!');
            
        }
        
    }

    The ‘is_card_pack_opened’ field is a True/False field so when it’s checked the value should be 1 right? Where would the error message actually appear? Next to the field? The field is actually hidden, although only with CSS so the value does still get updated with update_field

    Even so, I tried the above code even with the field not hidden and the form is still allowed to be submitted in the other tab.

    Plugin Author Konrad Chmielewski

    (@hwk-fr)

    Hello,

    As explained in the documentation, using get_field('my_field') without any post_id in the ACFE Forms hooks will retrieve the field input value in the current form (what the user actually typed in the fields before clicking “Submit”).

    So if there is no is_card_pack_opened field in your current form, there will be no value.

    If you want to retrieve a value from the database, you have to set the post_id argument. Example: get_field('my_field', 122). See get_field() documentation.

    I would recommend to use acf_log() combined with WP_DEBUG_LOG in order to log the values you have in those hooks in wp-content/debug.log, so you can understand what is going on. Usage example:

    acf_log(get_field('is_card_pack_opened', 122));
    

    Regards.

    Thread Starter Windurin

    (@windurin)

    Hi. There might be some misunderstanding. This form is UPDATING the post, and the form is actually on the post itself so the is_card_pack_opened’ field is in the form.

    But the user doesn’t actually enter any values in the form – all the fields like the Cards and points rewarded are hidden and were prefilled from when the Card Pack post was created. By ‘opening’ the pack (actually updating the post), the function to award the Cards is called and the ‘is_card_pack_opened’ field is set to true. I’ve recorded a quick video (just 42 seconds) to show you the problem, with 2 windows side by side:

    The ‘is_card_pack_opened’ True/False field is normally hidden too but I’ve got it showing here just for the video. So all the user actually does is click the submit button to open the pack (update the post).

    I tried the following code, including the post ID, though it is actually already the current post the form is on:

    add_action('acfe/form/validation/post/form=open-bronze-card-pack-form', 'my_form_validation', 10, 3);
    function my_form_validation($form, $post_id, $action){
        
        // Get field input value
    	$post_id = get_the_ID();
    	
        $opened = get_field('is_card_pack_opened', $post_id);
        
        if($opened === 1){
            
            // Add validation error
            acfe_add_validation_error('is_card_pack_opened', 'You Have Already Opened This Pack!');
            
        }
        
    }

    What am I doing wrong? Really appreciate the help and sorry if I didn’t explain it very well. I understand it’s quite a unique case.

    Plugin Author Konrad Chmielewski

    (@hwk-fr)

    Hello,

    I want to help, but I would like to ask you to read the answers I write and the documentation link I provide. You should use acf_log() in order to log the variables, so you don’t write code blindly without knowing what is behind those variables.

    For example, you’re using get_the_ID() which will not work here because you’re in an ajax request (the ajax validation). If you do acf_log(get_the_ID()) you will see that it is empty.

    You already have the $post_id in this hook, as an argument. It will return post id of page where the form is being displayed, as explained in the documentation, so you don’t need to use get_the_ID().

    Try to do an acf_log($post_id) and check if that’s the ID you’re looking for from the database. Write a post id in plain text, and check the field value from the database. Example:

    add_action('acfe/form/validation/post/form=open-bronze-card-pack-form', 'my_form_validation', 10, 3);
    function my_form_validation($form, $post_id, $action){
        
        // Get field from database on the post id = 122
        $opened = get_field('is_card_pack_opened', 122);
    
        // log
        acf_log($opened);
        
        if($opened){
            acfe_add_validation_error('', 'You Have Already Opened This Pack!');
        }
        
    }
    

    Regarding your general development question, I don’t know you project specification document, what the form update, what is the data structure etc… I try to answer precise questions, but please understand that I cannot make custom development for users as it would take too much time.

    Forms are complex web applications, and it looks like you’re working on a complicated project. My advice is: you need to find a way to debug and log variables before using them.

    Hope it helps!

    Regards.

    Thread Starter Windurin

    (@windurin)

    UPDATE: Using acf_log() I saw that the output was true, not 1. I thought the database value was 1 for true and 0 for false? Either way, I changed 1 to true and it now works!

    My only issue: it’s just a blank page with the validation error at the top. Is there a way to format the error or have it appear on the same page? Thanks.

    Plugin Author Konrad Chmielewski

    (@hwk-fr)

    Hello,

    The error should be displayed on the same page as the form, at the top of the form.

    If you see a blank page with the error it means the Ajax request didn’t work correctly, so you probably have a JS error on your form page. I would recommend to check your browser console.

    Also note, again, that get_the_ID() will not work during the ajax request, but will work during the second validation (after the submission). You should not use get_the_ID() in the validation hook, otherwise your ajax validation will not display an error, and the 2nd validation will display an error on an empty page.

    The True/False ACF field will return true or false when using the format value argument. See get_field() documentation.

    Regards.

    Thread Starter Windurin

    (@windurin)

    Hi again. Yes, I got excited but I realise now that was a WordPress error ha. After removing get_the_ID(), I do now get the validation error in the form area. At first I had the error appearing by the true/false field but because the field is hidden the validation error message was too. After changing field name to just ” as in your later snippet, the error message appears in the general form area and is visible. Here’s an image to confirm it’s working as I wanted:

    View post on imgur.com

    Thank you so much for your help and for the tips on debugging!

    Plugin Author Konrad Chmielewski

    (@hwk-fr)

    I’m glad to hear it now works as expected.

    If you enjoy this plugin and its support, feel free to submit a review. It always helps and it’s much appreciated!

    Have a nice day!

    Regards.

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘Stopping Same Form Being Updated Twice In Another Tab’ is closed to new replies.