Skip Navigation

[Resolved] Use a CRED generic select field to save a User ID as a post custom field

This thread is resolved. Here is a description of the problem and solution.

Problem: I have a CRED form that includes a generic select field. The options for this select field are generated by a View. When the post is created by CRED, the User ID value is saved correctly in my custom field. However when I edit the post with CRED, the correct User ID is not selected in the generic field, and changes to the User ID do not get saved correctly in the post.

Solution:
Use a custom shortcode to determine the custom field value based on a URL parameter, and set the default value of your generic field.

In functions.php:

function get_field_from_parent_by_url_param_func($atts) {
  $param = $atts['param'];
  $field = 'wpcf-' . $atts['field'];
  $value = get_post_meta($_GET[$param], $field, true);
  return $value;
}
add_shortcode('get_field_from_parent_by_url_param', 'get_field_from_parent_by_url_param_func');

add_action('cred_save_data', 'sauver_responsable_projet',10,2);
function sauver_responsable_projet($post_id, $form_data){
    if ($form_data['id']==87 OR $form_data['id']==565){
        if (isset($_POST['responsable-projet'])){
            update_post_meta($post_id, 'wpcf-responsable-projet', $_POST['responsable-projet']);}}}

In the CRED form:

[cred_generic_field field='responsable-projet' type='select' class='' urlparam='']
      {
      "required":1,
      "validate_format":0,
      "persist":1,
      "default":["[get_field_from_parent_by_url_param field='responsable-projet' param='numero']"],
      "options":[json-users-list]
      }
      [/cred_generic_field]<br />

Relevant Documentation:
https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data
https://codex.wordpress.org/Shortcode_API
https://toolset.com/documentation/user-guides/cred-shortcodes/#cred_generic_field

This support ticket is created 6 years, 11 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
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 13 replies, has 2 voices.

Last updated by romanB-3 6 years, 11 months ago.

Assisted by: Christian Cox.

Author
Posts
#607593

Hello,

I have a multiselect field filled by this function :

function wpmania_json_users_list( $atts ) {
    extract( shortcode_atts(
        array( 'role' => 'respprojet', 'label' => 'display_name', 'orderby' => 'display_name' ), $atts )
    );
    $args = array(  'role'=>$role, 
                    'fields' => array('ID',$label),
                    'orderby' => $orderby);
    $users = get_users( $args );
    $json = json_encode($users);
    $json = str_replace('"ID"','"value"',$json);
    $json = str_replace('"display_name"','"label"',$json);
    return $json;
}
add_shortcode( 'json-users-list', 'wpmania_json_users_list' );

The form where appears the field is

[credform class='cred-form cred-keep-original']

	[cred_field field='form_messages' value='' class='alert alert-warning']

<div class="row">
  <div class="col-sm-4">
    <div class="form-group">
      <label>Nom du Projet</label>
      [cred_field field='post_title' post='projet' value='' urlparam='' class='form-control' output='bootstrap']
    </div>
  </div>
  <div class="col-sm-4">
    <div class="form-group">
      <label>Responsable projet</label>
      [cred_generic_field field='responsable-projet' type='select' class='' urlparam='']
      {
      "required":1,
      "validate_format":0,
      "default":[[types field='responsable-projet'][/types]],
      "options":[json-users-list]
      }
      [/cred_generic_field]
    </div>
  </div>
  <div class="col-sm-4">
    <div class="form-group">
      <label>Client</label>
      [cred_field field="_wpcf_belongs_client_id" value="" select_text="--- not set ---" class="form-control" output="bootstrap"]
    </div>
  </div>
</div>

<div class="row">
  <div class="col-sm-3">
    <div class="form-group">
      <label>Numéro d'imputation</label>
      [cred_field field='numero-d-imputation' post='projet' value='' urlparam='' class='form-control' output='bootstrap']
    </div>
  </div>
  <div class="col-sm-3">
    <div class="form-group">
      <label>Début</label>
      [cred_field field='debut' post='projet' value='' urlparam='' class='form-control' output='bootstrap']
    </div>
  </div>
  <div class="col-sm-3">
    <div class="form-group">
      <label>Fin</label>
      [cred_field field='fin' post='projet' value='' urlparam='' class='form-control' output='bootstrap']
    </div>
  </div>
  <div class="col-sm-3">
    <div class="form-group">
      <label>Budget</label>
      [cred_field field='budget' post='projet' value='' urlparam='' class='form-control' output='bootstrap']
    </div>
  </div>
</div>

<div class="row">
  <div class="col-sm-12">
    <div class="form-group">
      <label>Description</label>
      [cred_field field='description-du-projet' post='projet' value='' urlparam='' class='form-control' output='bootstrap']
    </div>
  </div>
</div>

[cred_field field='form_submit' value='Enregistrer les modifications' urlparam='' class='btn btn-primary btn-lg' output='bootstrap']

[/credform]

Then I save the user ID in the wpcf-responsable-projet field thanks to this function :

add_action('cred_save_data', 'sauver_responsable_projet',10,2);
function sauver_responsable_projet($post_id, $form_data){
    if ($form_data['id']==87 OR $form_data['id']==565){
        if (isset($_POST['responsable-projet'])){
            update_post_meta($post_id, 'wpcf-responsable-projet', $_POST['responsable-projet'], true);}}}

But it actually don't seem to work and I don't understand why ; could a recent update corrupted something here ?

Thank you.

#607688

Can you provide some more information so we can debug this together?
- When you look at the form on the front-end of your site, are the options in the generic select field correct?
- Are the option values correct?
- Insert some logs and turn on server logging so we can see what is failing:

add_action('cred_save_data', 'sauver_responsable_projet',10,2);
function sauver_responsable_projet($post_id, $form_data){
error_log('cred_save_data sauver_responsable_projet called');
error_log('post id: ' . $post_id);
error_log('form data: ');
error_log(print_r($form_data, true));
    if ($form_data['id']==87 OR $form_data['id']==565){
    error_log('if form id is a match');
        if (isset($_POST['responsable-projet'])){
            error_log('if responsable-projet is set');
            update_post_meta($post_id, 'wpcf-responsable-projet', $_POST['responsable-projet'], true);}}}
#607711

Hello and thank you,

- When you look at the form on the front-end of your site, are the options in the generic select field correct?
No. The field is always "not set" on front end...

- Are the option values correct?
Yes, the list is OK, with the right values.

- Insert some logs and turn on server logging so we can see what is failing:

[18-Jan-2018 17:43:05 UTC] cred_save_data sauver_responsable_projet called
[18-Jan-2018 17:43:05 UTC] post id: 1430
[18-Jan-2018 17:43:05 UTC] form data: 
[18-Jan-2018 17:43:05 UTC] Array
(
    [id] => 565
    [post_type] => projet
    [form_type] => edit
    [container_id] => 566
)

[18-Jan-2018 17:43:05 UTC] if form id is a match
[18-Jan-2018 17:43:05 UTC] if responsable-projet is set
#607770

Okay the logs show the code is triggered as expected. It sounds like the main problem is the generic field default value is not set correctly. Please add some tests to the CRED form after the generic field, and tell me the output on the front-end:

      [cred_generic_field field='responsable-projet' type='select' class='' urlparam='']
      {
      "required":1,
      "validate_format":0,
      "default":[[types field='responsable-projet'][/types]],
      "options":[json-users-list]
      }
      [/cred_generic_field]
      <br />
      Types field: [types field='responsable-projet'][/types]<br />
      Views field: [wpv-post-field name='wpcf-responsable-projet']<br />
      Post ID: [wpv-post-id]<br />
      Current page ID: [wpv-post-id id="$current_page"]
#607879

Here it is :
"Types field:
Views field:
Post ID: 566
Current page ID: 566"

#608334

The post ID shortcode shows 566, and that means the Types field shortcode assumes post ID 566 as well. I do not think this is correct, because the post being edited by CRED is post ID 1430:

[18-Jan-2018 17:43:05 UTC] post id: 1430

So the issue seems to be the context of the Types field shortcode. Can I log in and see how this form is configured? I will activate private reply fields here. Please tell me which CRED form to look at, and also where I can see the form on the front-end of the site.

#608602

Okay, you passed the projet ID into the CRED form shortcode using the wpv-search-term shortcode:

[cred_form form='modifier-le-projet' form_name='Modifier le Projet' post="[wpv-search-term param='numero']"]

You must use the same wpv-search-term shortcode to provide the post ID to each types field shortcode inside the CRED form:

[wpv-post-field name='wpcf-responsable-projet' id="[wpv-search-term param='numero']"]

I think the wpv-post-field shortcode will be best here instead of the types field shortcode.

#608700

Hello,
Thank you but I don't understand.
Where should I make these changes ?
Thnak you.

#609057
Screen Shot 2018-01-23 at 1.54.07 PM.png

Hi, I made the necessary change in your CRED form here:

[credform class='cred-form cred-keep-original']

	[cred_field field='form_messages' value='' class='alert alert-warning']

<div class="row">
  <div class="col-sm-4">
    <div class="form-group">
      <label>Nom du Projet</label>
      [cred_field field='post_title' post='projet' value='' urlparam='' class='form-control' output='bootstrap']
    </div>
  </div>
  <div class="col-sm-4">
    <div class="form-group">
      <label>Responsable projet</label>
      
      [cred_generic_field field='responsable-projet' type='select' class='' urlparam='']
      {
      "required":1,
      "validate_format":0,
      "default":[wpv-post-field name="wpcf-responsable-projet" id="[wpv-search-term param='numero']"],
      "options":[json-users-list]
      }
      [/cred_generic_field]
      
<br />
      
    </div>
  </div>

However, no option is selected by default here:
hidden link
This is because the generic field options have the values '21' and '26' (see the screenshot). However, the responsable-projet value is 4 here:
hidden link

I'm confused. Which option should be selected by default, and why is the responsable-projet value 4?

#609677

There are two problems :

1- The field is not defautly set :
As you may see here, the responsable-projet is 21 : URL/wp-admin/post.php?post=1349&action=edit
But still, editing the project still shows empty field : URL/modifier-projet/?numero=1349

2- The field is not well saved :
This other project URL/modifier-projet/?numero=1430 has a wrong responsable-projet, so it is normal the field is empty, but then, when I select the right one (which is Aminata) and save, the changes are not saved...

#609821

Okay I see what you mean. It looks like the "default" option in the generic field has trouble interpreting nested shortcodes like this:

"default":[wpv-post-field name="wpcf-responsable-projet" id="[wpv-search-term param='numero']"],

To get around that, I created a new custom shortcode that performs the same functionality of the two nested shortcodes - it allows you to pass in a field slug and a URL parameter name to get the value of a custom field in another post. I have added the following code to functions.php, so please be sure to update your local files as needed:

function get_field_from_parent_by_url_param_func($atts) {
  $param = $atts['param'];
  $field = 'wpcf-' . $atts['field'];
  $value = get_post_meta($_GET[$param], $field, true);
  return $value;
}
add_shortcode('get_field_from_parent_by_url_param', 'get_field_from_parent_by_url_param_func');

Then I updated the generic field to use the new shortcode, which helps it display the correct default value:

[cred_generic_field field='responsable-projet' type='select' class='' urlparam='']
      {
      "required":1,
      "validate_format":0,
      "persist":1,
      "default":["[get_field_from_parent_by_url_param field='responsable-projet' param='numero']"],
      "options":[json-users-list]
      }
      [/cred_generic_field]<br />

The "persist" option should be added to ensure this field gets saved correctly. Please try it out and let me know if this does not fully resolve the problem.

#610429

Hello and thank you,
It seems in deed to work for saving and restoring the project selected, but it seems to be stored elsewhere than in the dedicated custom field.
Thank you.

#610509

I have removed the 4th parameter - "true" - from this code:

update_post_meta($post_id, 'wpcf-responsable-projet', $_POST['responsable-projet'], true);}}}

The 4th parameter passed into update_post_meta specifies which value should be replaced in case there are multiple values. I removed it because there is only one value, and we always want to replace it:

update_post_meta($post_id, 'wpcf-responsable-projet', $_POST['responsable-projet']);}}}

https://codex.wordpress.org/Function_Reference/update_post_meta

#610521

Great, thank you very much ; I would never have seen this... !
Thank you.