Skip Navigation

[Resolved] Generic Checkbox Behaviour with Cred Edit Forms

This support ticket is created 2 years, 2 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 9:00 – 12:00 9:00 – 12:00 9:00 – 12:00 9:00 – 12:00 9:00 – 12:00 -
- 13:00 – 18:00 13:00 – 18:00 13:00 – 18:00 14:00 – 18:00 13:00 – 18:00 -

Supporter timezone: America/Jamaica (GMT-05:00)

This topic contains 12 replies, has 2 voices.

Last updated by Dave 2 years, 2 months ago.

Assisted by: Shane.

Author
Posts
#2283741

Tell us what you are trying to do?
Use a checkbox generic field to allow the user an option when submitting an edit form.

What is the link to your site?
Provided securely if needed.

I'm trying to use a checkbox to give the user an option to enable an extra piece of functionality when submitting a simple CRED edit form. The idea being that the form, which updates a post relationship and cascades that update to all other posts created along with it (the details aren't relevant there), and if the generic field checkbox is checked it will update other data along with it.

However, I cannot get the checkbox to behave in a way that makes any sense to me so I'm convinced I'm missing something, yet I can find no one else talking about this on the forums.

Firstly, I cannot force the checkbox to be ticked by default. I've tried setting it a "default" parameter, providing a "value" parameter, and tried this jQuery:

jQuery('input[name="migrate-dates"]').attr( "checked", "checked")

Nothing works to force the checked state on load. Now this may have something to do with the face this is loaded within a View and something is causing AJAX issues potentially. But this is a guess and I can't see any way of finding out as there's no error data anywhere.

Secondly, I cannot seem to access the checkbox via standard means in PHP. Usually I'd pull generic field data from the $_POST array, but the name of the checkbox isn't present, not properly at least. Also, the only place in the $_POST array that does reference it always claims it's set to 1. This seems to happen with all checkboxes regardless of any values I do or don't give them. Is this because it's an edit form?

Here's the checkbox, you can see at the moment it's set to absolute basics:

  [cred_generic_field type='checkbox' field='migrate-dates']
  {
  "required":0,
  <!--"value":, Not needed but nothing seems to set the box to checked automatically-->
  "default":"",
  "label":"Automatically Migrate Dates to New Term?"
  }
  [/cred_generic_field]

and $_POST array:

array(8) { 
["@term-class_parent"]=> string(3) "555" 
["_wptoolset_checkbox"]=> array(1) 
{ ["cred_form_1240_1_1_migrate-dates"]=> string(1) "1" } 
["form_submit_8"]=> string(7) "Confirm" 
["_cred_cred_wpnonce_cred_form_1240_1"]=> string(10) "4b565640b3" 
["_cred_cred_prefix_post_id"]=> string(4) "1196" 
["_cred_cred_prefix_cred_container_id"]=> string(4) "1196"
 ["_cred_cred_prefix_form_id"]=> string(4) "1240" 
["_cred_cred_prefix_form_count"]=> string(1) "1" 
}

As you can see, the only reference of "migrate-dates" is within a cred_form tag for some reason.

This $_POST array is being captured via the cred_submit_complete hook, but cred_save_data has the same effect:

/*** Function to process class group term edits ***/
function edit_class_group_term( $post_id, $form_data ) {
  //If Edit Class Date form
  if( $form_data['id'] == 1240 ) {
    //Get classes in group and remove current post being edited from array
    $classes = get_class_group( $post_id );
    unset( $classes[array_search( $post_id, $classes )] );
    $classes = array_values( $classes );

    //Loop through classes in group
    foreach( $classes as $class ) {
      //Ensure the post has a term set to avoid PHP error
      if( toolset_get_related_post( $class, 'term-class' ) <> 0 ) {
        //Delete current Class Term relationship
        toolset_disconnect_posts( 'term-class', toolset_get_related_post( $class, 'term-class' ), $class );
      }
      //Set new Class Term relationship based on edited class
      toolset_connect_posts( 'term-class', toolset_get_related_post( $post_id, 'term-class' ), $class );
      
      var_dump($_POST);
      print_r("<br /><br />");
      print_r($_POST['migrate-dates']);
      die();

    }
  }
}

add_action('cred_save_data', 'edit_class_group_term', 10, 2);

So to summarise, this generic checkbox is giving me these three issues:

1. I can't set the state of this generic field to checked by default.
2. I can't access it properly via $_POST or PHP.
3. The only reference to it in $_POST seems to suggest it's reading as checked all the time.

Am I really missing something here or is this a weird issue with edit forms?

Regardless, I'd really appreciate some help sorting this out so we can get on as I've wasted a few hours messing with what should be something very simple.

Many thanks in advance.

#2283861

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Dave,

1. I can't set the state of this generic field to checked by default.
Are you trying to set the value on the frontend meaning the user is allowed to check the box or is it something that you're doing programmatically.

From your post above I see that you're using some javascript to check the box. Based on the field it implies that the user has the choice to check or uncheck the box.

2. I can't access it properly via $_POST or PHP.
3. The only reference to it in $_POST seems to suggest it's reading as checked all the time.

The checkboxes are generally serialized, however in your case you should be able to get the checkbox value by doing using the _wptoolset_checkbox key since this contains the array for the checkbox.

["_wptoolset_checkbox"]=> array(1) 
{ ["cred_form_1240_1_1_migrate-dates"]=> string(1) "1" } 

So if you were to do this

$_POST["_wptoolset_checkbox"][0]

You should get the string 1 given that its stored at index 0.

Please let me know if this allows you to progress.

Thanks,
Shane

#2285627

Hi Shane,

Apologies for the slow response but I did not get a notification email informing me of your reply.

1. I want the checkbox to be checked by default on the front end but the user is allowed to uncheck it. So this would mean that by default it would be checked and return 1 unless the user unchecks it, leading to it returning a 0, which is normal behaviour, right? I don't care how this is achieved, but what I detailed in my initial post was that I have tried every method that should work, including JS, and none of them are, which makes no sense.

2. What do you mean "generally serialised" exactly? I thought a single checkbox was a binary return, it certainly is if I use a checkbox created through Types as I have used them in other places quite successfully and you just refer to the checkbox's name in PHP and it will return a 0 or a 1 without any trouble. The issue here is that it is not being referred to in this standard way in the $_POST data.

Why would it's name not be being used? Referring to it in the way you suggest sounds incredibly hacky and as though something is not right. This is the whole point in naming them, so they can be referred to easily, not like this. Why is this the case here?

3. I don't believe you addressed this, but the $_POST entry that you have highlighted, which is what I was discussing in my initial post, always returns 1 as the checkbox value regardless of it's state and this is with and without and extra code trying to effect it.

Something is clearly not right here as none of this behaviour appears "normal" to me and isn't how Toolset has operated in any other aspect of the site.

#2285815

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Dave,

I want the checkbox to be checked by default on the front end but the user is allowed to uncheck it. So this would mean that by default it would be checked and return 1 unless the user unchecks it, leading to it returning a 0, which is normal behaviour, right? I don't care how this is achieved, but what I detailed in my initial post was that I have tried every method that should work, including JS, and none of them are, which makes no sense.

Can you provide a link to the frontend page so that I can have a look at this for you ?

2. What do you mean "generally serialised" exactly? I thought a single checkbox was a binary return, it certainly is if I use a checkbox created through Types as I have used them in other places quite successfully and you just refer to the checkbox's name in PHP and it will return a 0 or a 1 without any trouble. The issue here is that it is not being referred to in this standard way in the $_POST data.

Checking the post data we can see exactly how it is being sent using the POST request i know for radio buttons and select fields they would usually send a single value but given that checkboxes can have multiple values then they are stored in a type of associative array with key value pairs.

3. I don't believe you addressed this, but the $_POST entry that you have highlighted, which is what I was discussing in my initial post, always returns 1 as the checkbox value regardless of it's state and this is with and without and extra code trying to effect it.

Given the case it is possible to define your own checkbox field using HTML inside the form like my example below.

<input type="checkbox" id="test" name="test"
         checked>
  <label for="scales">Test Field</label>

This will allow you to set the default state of the checkbox field. Based on my checks on the generic field it doesn't appear that the checked/unchecked states for the generic checkbox fields are being set through HTML given.

However with the HTML above you are able to set the checked state by default.

Also does this issue only presents itself on this particular site ?

Please let me know if this workaround helps.
Thanks,
Shane

#2285831

Hi Shane,

1. Hopefully links will not render for people not involved in this thread, so you can find an example here:

hidden link

Click on the Class Group tab and then under the Structure tab that appears click the edit button next to the Term option.

But what this is going to show that my code hasn't I don't know.

2. Regardless of how many states a checkbox can have, the point stands that what is appearing in the $_POST array is not labelled in any way that is remotely useful unlike every other generic field that Toolset provides. This does not seem right and you seem to keep avoiding answering this point.

3. Just to check, your advice is not to use Toolset for generic checkboxes? I know you're right, I could use a standard HTML checkbox, but I seriously have to question why that should be the solution here because the only purpose of a generic checkbox on a Cred form would be to check it's status on submit so you can handle some post-submission options. Using a HTML checkbox instead seems like you're telling me that the generic ones don't work properly, why else would this issue have arisen?

I've never encountered this issue before so I couldn't say I've it's isolated or not, however this website is in a development state and only has basic WordPress and Toolset installed, no other plugins, no other themes.

This all seems really bizarre and counter-intuitive to Toolset, which is otherwise excellent. Please can we get to the bottom of this behaviour for generic checkboxes.

#2285881

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Screenshot 2022-02-07 at 10.50.49 AM.png
Screenshot 2022-02-07 at 10.47.36 AM.png

Hi Dave,

2. Regardless of how many states a checkbox can have, the point stands that what is appearing in the $_POST array is not labelled in any way that is remotely useful unlike every other generic field that Toolset provides. This does not seem right and you seem to keep avoiding answering this point.

Not avoiding your point but i'm trying to replicate the issue and provide workarounds for your case. In my testing to see what appears in the POST Request Payload i'm able to get the field's value using the name of the generic field that was created. See Screenshot.

This screenshot illustrate the generic_checkbox field as apart of the POST request Payload. Now as you can see the checkbox returns 1 when it is checked.

In my next screenshot you will notice that the generic_checkbox field isn't there. This is what happens when the checkbox state is NOT checked.

Based on my testing I would be able to check if empty($_POST['generic_checkbox'])

Which to me indicates that the generic checkbox field is functioning as intended on a fresh install.

3. Just to check, your advice is not to use Toolset for generic checkboxes? I know you're right, I could use a standard HTML checkbox, but I seriously have to question why that should be the solution here because the only purpose of a generic checkbox on a Cred form would be to check it's status on submit so you can handle some post-submission options. Using a HTML checkbox instead seems like you're telling me that the generic ones don't work properly, why else would this issue have arisen?

Given that i'm not able to replicate the issue then this would mean that the production environment is different and could be the source of the issue.

Click on the Class Group tab and then under the Structure tab that appears click the edit button next to the Term option.

When I click here a modal appears with no form. Unfortunately without this i'm not able to check your post request payload. Perhaps the form is hidden behind an access setting ?

Thanks,
Shane

#2287703

Hi Shane,

Sorry if I misunderstood where you were going with your explanation before, I didn't follow it in the way you meant. Also, the cred forms haven't been set up for proper user visibility yet, so it seems they're only appearing to logged-in users at present, so please accept my apologies for that as well.

I have figured out what the issue is and there was definitely something weird going on as now when the box is ticked (manually) it appears in the $_POST as expected. HOWEVER, this functionality only works if the checkbox has a default property set.

The way this works is that the checkbox returns nothing unless you set the generic field default property, so this will not work:

[cred_generic_field type='checkbox' field='migrate-dates']
  {
  "required":0,
  "default":"",
  "label":"Automatically Migrate Dates to New Term?"
  }
  [/cred_generic_field]

But this will:

[cred_generic_field type='checkbox' field='migrate-dates']
  {
  "required":0,
  "default":"1",
  "label":"Automatically Migrate Dates to New Term?"
  }
  [/cred_generic_field]

The default value does not have to be "1", it appears to accept any alphanumeric value as I've tried it with numbers and letters. Whatever is here is what will be returned in the $_POST data if the box is checked. For example, setting the default property to "p" results in this:

["migrate-dates"]=> string(1) "p"

Knowing this now, yes you're quite right using "empty($_POST['migrate-dates'])" will handle the logic correctly, which was what I was trying to do from the start!

I think some confusion has arisen from the fact that the field will create with no default property set as a standard and there is nothing to tell you it needs to be set in the user interface or the documentation, add to this that it only shows up in the $_POST if it is checked rather than returning a 0 or NULL if it's unchecked and this array within the data:

["_wptoolset_checkbox"]=> array(1) { ["cred_form_1240_1_1_migrate-dates"]=> string(1) "1" }

This initially reads as if it's identifying the checkbox state as "1", but after looking at this behavior I think this is simply listing its presence on the form, is this correct? Either way, this is not a usable piece of information, but seeing it was the only place the checkbox was being named really confused matters.

I hope that all makes sense, as it really should be added to the documentation for clarity if nothing else.

However, the checkbox is now working and being read, but it still won't allow me to force its state to be checked by default. This is the last little issue and then this is all sorted.

Can you please offer any suggestions on how I can force it to be checked by default (something that really should be a built-in setting) without resorting to a standard HTML checkbox field?

Many thanks.

#2287873

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Screenshot 2022-02-09 at 10.23.15 AM.png

Hi Dave,

There is definitely something odd on your end. The reason being is that I have this field below.

	<label for="%%FORM_ID%%_generic">[cred_i18n name='generic-label']Checkboxes [/cred_i18n]</label>
	[cred_generic_field type='checkbox' field='generic_checkbox']
{
"required":0,
"default":""
}
[/cred_generic_field]
	</div>

Notice there is no value set for the default. However when I submit the form on the frontend with it being checked. This is the result see Screenshot

Is there a way that I can have access to the form that you're testing this on ? Perhaps being able to experience the issue first hand will allow me to understand better.

From my screenshot you can see that even though the default option isn't set to any value it is still reading it as an empty string which will still be sent over the Post request.

I've enabled the private fields for your next response so that you can provide me with credentials and how to replicate the issue on your site.

Thanks,
Shane

#2287903

Hi Shane,

I've sent login credentials for you.

In regards to your screenshot, it's not clear to me how exactly you're getting this output, which is only important because "generic_checkbox" could just be a label written in to show where the output would be if it exists. I only bring this up as it does not show the normal array structure of $_POST and that it also just shows blank rather than a 0 as the value so it's left me wondering how it was generated.

Honestly, now I have access to it I'm not as worried about it, but please take a look and see what you can find. It's bothering me far more that I can't set it to checked by default, so if you can see any reason for that whilst you're in there then that would be good to solve.

#2288029

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Screenshot 2022-02-09 at 1.38.33 PM.png

Hi Dave,

I can confirm in testing your site that your POST request Payload displays as normal when checked and unchecked. See Screenshot

As you can see in the screenshot I submitted the form with the field manually checked and this was the output on the Post Request so there shouldn't be any issue checking if the field was selected or not.

This brings me to the second issue of having the field checked/unchecked automatically on the frontend. I wasn't able to find a solution until i did some searching in the forums.

I was able to find that using "checked":1, causes the default state of the field to be checked.

Unfortunately this is undocumented as i've checked our documents to see if there was anything that could clue me to a solution.

Please let me know if this helps.
Thanks
Shane

#2288061

Hi Shane,

It looks like adding a "checked: 1" property to the generic checkbox field does indeed work perfectly. It's amazing that this is not documented you're right, especially seeing as numerous support threads have been answered by telling users to add JS to their forms. I hope you can report this to the documentation team and get it updated.

In regards to the other issue, whilst I understand how this works and what's going on now, I'm still seeing an anomaly compared to what you're saying.

I'm guessing you are using some kind of debug viewer to check PHP variables? Is this correct?

If so, this is probably to reason why there's a difference, I'm just using an error monitor and print_r to examine variables, including $_POST.

I've just run the test again with the checked and unchecked checkbox and here are the direct results from this code on a "cred_submit_complete" hook:

    print_r($_POST);
    print_r("<br /><br />");
    print_r("Migrate Dates Checkbox = ");
    print_r($_POST['migrate-dates']);
    die;

Here is the output with an unchecked box:

Array ( [@term-class_parent] => 427 [_wptoolset_checkbox] => Array ( [cred_form_1240_1_1_migrate-dates] => 1 ) [form_submit_8] => Confirm [_cred_cred_wpnonce_cred_form_1240_1] => d47b429d86 [_cred_cred_prefix_post_id] => 1201 [_cred_cred_prefix_cred_container_id] => 1201 [_cred_cred_prefix_form_id] => 1240 [_cred_cred_prefix_form_count] => 1 )

Migrate Dates Checkbox =

And here is the output with a checked box (yes, the default value of the checkbox is still set to "p" from my earlier example):

Array ( [@term-class_parent] => 427 <strong>[migrate-dates] => p<s/strong> [_wptoolset_checkbox] => Array ( [cred_form_1240_1_1_migrate-dates] => 1 ) [form_submit_8] => Confirm [_cred_cred_wpnonce_cred_form_1240_1] => d47b429d86 [_cred_cred_prefix_post_id] => 1201 [_cred_cred_prefix_cred_container_id] => 1201 [_cred_cred_prefix_form_id] => 1240 [_cred_cred_prefix_form_count] => 1 )

Migrate Dates Checkbox = p

As you can see from the array, it is clearly missing when unchecked. Now I know this, it is no longer a big problem, but I think there is definitely a discrepancy between the way your tools are showing you the information here and the way PHP is natively dumping it.

My direct issues have been resolved, but I wanted this to be fed back so you could continue to investigate as something is definitely different between what we're both seeing.

#2288105

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Dave,
I'm guessing you are using some kind of debug viewer to check PHP variables? Is this correct?

Actually what i'm doing is just checking the HTML payload being sent over the POST request using the Chrome debugging tool.

This allows me to see what exactly is being sent by the browser to the server.

If so, this is probably to reason why there's a difference, I'm just using an error monitor and print_r to examine variables, including $_POST.

This is perhaps why you're not seeing the 'migrate-dates' value when its not selected and that's because when its not selected the variable isn't sent in the POST request so you might need to check if it is actually there using

if(isset($_POST['migrate-dates']))

This should avoid the undefined index error that might come up if you're just checking if the value is empty.

but I think there is definitely a discrepancy between the way your tools are showing you the information here and the way PHP is natively dumping it.

Actually this is how it works if the field value isn't set then it is not added to the payload, I believe this is the default behaviour of HTML and how it handles forms.

Thanks,
Shane

#2288213

I think this is where the confusion has arisen. I was expecting the generic fields to work like Toolset custom fields, not standard HTML fields.

Couple this with the previously mentioned confusing looking entries in the $_POST data and I think it lead to a rabbit hole.

But this coupled with the checked property solves everything for me, thank you.

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.