I'm new in the php world and i'm trying to build something in wordpress by gravity forms.
Basicly for now I just playing around and try to create some codes I can use when I start building. My question is: I have a form 1 where I can enter a name e.g. Football,Baseball,Hockey and it get saved to my data base. Then I have another form with the id 2 where there is a drop down box, here i want those values(names) submitted in form 1 to be dynamically populated. I have been trying to create a code by finding pieces around some websites (you will properly discover I'm mixing everything together) and ended up with this:
add_filter("gform_pre_render", "test_task");
add_filter("gform_admin_pre_render", "test_task");
add_filter('gform_pre_submission_filter', 'test_task');
function test_task($entry, $form){
if($form["id"] != 2)
return $form;
$entry["1"];
$items = array();
$items[] = array("text" => "Choose Sport", "value" => "");
foreach($posts as $post)
$items[] = array("value" => $post->post_title, "text" => $post->post_title);
foreach($form["fields"] as &$field)
if($field["id"] == 2){
$field["choices"] = $items;
}
return $form;
}
Hope someone can show me how it should be done so I can learn to do it in the future.
Sincerely
Lars
I'm afraid the $entry object is not available to the gform_pre_render, gform_pre_submission_filter or gform_admin_pre_render hooks. Give the following a try.
add_filter( 'gform_pre_render', 'populate_sports_choices' );
add_filter( 'gform_pre_validation', 'populate_sports_choices' );
add_filter( 'gform_pre_submission_filter', 'populate_sports_choices' );
add_filter( 'gform_admin_pre_render', 'populate_sports_choices' );
function populate_sports_choices( $form ) {
// only run for form 2
if( $form['id'] != 2 )
return $form;
foreach ( $form['fields'] as &$field ) {
function populate_sports_choices( $form ) {
foreach ( $form['fields'] as &$field ) {
// only populate the field if it is a select and has the designated css class name
if ( $field['type'] != 'select' || strpos( $field['cssClass'], 'populate-sport' ) === false )
continue;
// get form 1 field 4 entry values
$sports = get_entry_field_values( 4, 1 );
// create the $choices array and set the placeholder choice
$choices = array( array( 'text' => 'Select a Sport', 'value' => '' ) );
// loop through each of the sports and add them to the $choices array
foreach ( $sports as $sport ) {
$choices[] = array( 'text' => $sport['value'], 'value' => $sport['value'] );
}
//replace the field choices with the contents of the $choices array
$field['choices'] = $choices;
}
return $form;
}
/**
* Allows you to retrieve an array of field values.
* Requires either the $field object or a field ID and a form ID.
*
* Example: $values = get_entry_field_values( 5, 113 );
*/
function get_entry_field_values( $field_id, $form_id ) {
global $wpdb;
if ( is_array( $field_id ) ) {
$field_id = rgget( 'id', $field_id );
}
$tablename = $wpdb->prefix . 'rg_lead_detail';
$sql = "SELECT value FROM $tablename WHERE form_id = %d AND CAST(field_number as unsigned) = %d";
return $wpdb->get_results( $wpdb->prepare( $sql, $form_id, $field_id ), ARRAY_A );
}
The above is based on examples from the following sources:
http://www.gravityhelp.com/documentation/page/Dynamically_Populating_Drop_Down_Fields
http://www.gravityhelp.com/forums/topic/drop-down-dynamic-population-from-single-line-text
I don't think you need to write any code at all. This is supported by Gravity Forms itself. In the form editor go to settings > confirmations, then choose redirect, enter the page form 2 is on and select Pass Field Data Via Query String then enter name={Name:1} or something similar depending on the name and id of the fields in Form 1. And then in Form 2, go to the field you want to populate and select advanced and dynamically prepopulate and enter what you typed to the left of the =, in this case name.
Related
I'm trying to dynamically populate the options available for selection in a dropdown menu using data from google sheets. The data is located on column A (A2:A4 at the moment, but this is subject to change) and will include the names of available employees.
So if:
A
1 name
2 jack
3 Bob
4 John
I need these 3 names to dynamically be available for selection in a dropdown menu within gravity forms. I also need the flexibility allowing there to be more or less names whenever an employees availability changes.
I've been trying to put something together using the gravity forms documentation, as well as taking bits and pieces from snippets I've found on github. This is what I have so far, but it is giving me a critical error:
$location_form_id = [FORM ID HERE];
add_filter( 'gform_pre_render_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_validation_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_submission_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_submission_filter_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_admin_pre_render_'.$location_form_id, 'populate_posts' );
function populate_posts($form){
foreach($form['fields'] as &$field){
if($field->id != [FIELD ID HERE] ) {
continue;
// Hook into Google Spreadsheets //
$url = 'http://spreadsheets.google.com/feeds/list/[SPREADSHEET ID HERE]/od6/public/values?alt=json';
$file = file_get_contents($url);
$json = json_decode($file);
$rows = $json->{'feed'}->{'entry'};
$names = array();
foreach($rows as $row) {
$name = $row->{'gsx$name'}->{'$t'};
$names[] = $name;
}
foreach($names as $single_name){
$choices[] = array('text' => $single_name, 'value' => $single_name );
}
$field['choices'] = $choices;
}
return $form;
}
You need to use few filters given by gravity forms to achieve this. Only four filters are required.
gform_pre_render_
gform_pre_validation_
gform_pre_submission_filter_
gform_admin_pre_render_
You need to get the loop through all the fields of your form id XX and check whether the field you are selecting is an actual dropdown field means a select field.
To push all the new found in the sheets we can use array_push method and then loop through that array to get all the names that were stored.
You can also add a placeholder if you want to to your select field and lastly just the return the $form
In the below code just add your own $form_id, select $feild_id and $gSheet_form_ID .
Add this code your active theme functions.php file. (Code tested and works)
$location_form_id = '62';
add_filter( 'gform_pre_render_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_validation_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_submission_filter_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_admin_pre_render_'.$location_form_id, 'populate_posts' );
function populate_posts( $form ) {
//the select feild id you want the names to load
$field_ID = '2';
//your g sheet ID
$gSheet_form_ID = 'your_public_google_sheet_id';
//get data
$url = 'https://spreadsheets.google.com/feeds/list/'.$gSheet_form_ID.'/public/values?alt=json';
$file = file_get_contents($url);
$json = json_decode($file);
$rows = $json->{'feed'}->{'entry'};
//get all the same from sheet
$names = array(); //store names in this array
foreach($rows as $row) {
$name = $row->{'gsx$name'}->{'$t'};
array_push($names, $name); //push data
}
//Go through each form fields
foreach ( $form['fields'] as $field ) {
//check if field type is a select dropdown and id is 2
if ( $field->type == 'select' && $field->id == $field_ID) {
//add name and value to the option
foreach($names as $single_name){
$choices[] = array('text' => $single_name, 'value' => $single_name );
}
//Add a place holder
$field->placeholder = 'Select a Name';
//Add the new names to the form choices
$field->choices = $choices;
}
}
return $form; //return form
}
Working Select Field Preview
Thank you for this great example. Initially, it did not work for me until I realized that the 'name' is the heading (name) of the column and is hard-coded - I modified that. I was also missing the ability to browse between lists, so I added a variable for that.
Lastly, if your side is running on WordPress, I recommend using the 'Code Snippets' plugin instead of directly adding code into the functions.php - it is cleaner + will not stop working if your theme is modified/changed.
See below:
$location_form_id = '21';
add_filter( 'gform_pre_render_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_validation_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_submission_filter_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_admin_pre_render_'.$location_form_id, 'populate_posts' );
function populate_posts( $form ) {
//the select feild id you want the names to load
$field_ID = 'FIELD_ID_HERE';
//your g sheet ID
$gSheet_form_ID = 'SHEET_ID_HERE';
// which column to scan - what is the heading name
$column_name = 'COLUMN_HEADING_NAME_HERE';
$placeholder = 'YOUR_PLACEHOLDER_HERE';
$list_number = '1';
//get data
$url = 'https://spreadsheets.google.com/feeds/list/'.$gSheet_form_ID.'/'.$list_number.'/public/values?alt=json';
$file = file_get_contents($url);
$json = json_decode($file);
$rows = $json->{'feed'}->{'entry'};
//get all the same from sheet
$names = array(); //store names in this array
foreach($rows as $row) {
$name = $row->{'gsx$'.$column_name}->{'$t'};
array_push($names, $name); //push data
}
//Go through each form fields
foreach ( $form['fields'] as $field ) {
//check if field type is a select dropdown and id is correct
if ( $field->type == 'select' && $field->id == $field_ID) {
//add name and value to the option
foreach($names as $single_name){
$choices[] = array('text' => $single_name, 'value' => $single_name );
}
//Add a place holder
$field->$placeholder;
//Add the new names to the form choices
$field->choices = $choices;
// Print out the contents of the array (troubleshooting only)
//echo '<pre>'; print_r($choices); echo '</pre>';
}
}
return $form; //return form
}
What can still be improved?
The URL used for retrieving the data via Google Sheets API is using API v3, which will be deprecated on June 8th, 2021. If anyone has thoughts on how to improve the code for APIv4, then please let us know!
If you are checking for a cell that is in a column that is 'shorter' than another one, you will end up with empty values in the array. There should be a check against empty values in the code (should be pretty simple to add).
GOAL
I currently have an acf field group with some fields for generic data like phonenumber, email, etc. (all simple text fields).
My goal is to have one function that will loop over all the fields and create a shortcode based on their respective name/label.
EDIT: PROGRESS
I think I am getting closer, simplified the whole thing and I believe I am on the right path..
I attached the field group to a post and if I log them like so:
$testing = get_field_objects(22);
do_action( 'php_console_log', $testing );
I get all the names, values etc. With the help of another snippet I found the shortcodes seem to be at least dynamic since they all stop showing just that there is no value somehow so it all stays blank.
This is the function now:
$hlfields = get_field_objects( 22 );
foreach ( $hlfields as ['name' => $name, 'value' => $value] ) {
${"{$name}_fn"} = function() {
$field = get_field($name, 22);
return $field;
};
add_shortcode($name, ${"{$name}_fn"});
}
Original attempt, not working and over complicated:
I currently have an acf field group with some fields for generic data like phonenumber, email, etc. (all simple text fields).
To be able to insert them all easily using a shortcode, I create one for each field like so:
function adresse_shortcode( $adresse ) {
$adresse = get_field( "adresse", 'option' );
return $adresse;
}
add_shortcode('adresse', 'adresse_shortcode');
While this works fine, I feel like I am repeating myself unnecessarily and also I need to add a function whenever I add a new field.
My goal is to have one function that will loop over all the fields and create a shortcode based on their respective name/label.
I found this snippet to get all fields of a field group by ID:
function get_specifications_fields() {
global $post;
$specifications_group_id = 13; // Post ID of the specifications field group.
$specifications_fields = array();
$fields = acf_get_fields( $specifications_group_id );
foreach ( $fields as $field ) {
$field_value = get_field( $field['name'] );
if ( $field_value && !empty( $field_value ) ) {
$specifications_fields[$field['name']] = $field;
$specifications_fields[$field['name']]['value'] = $field_value;
}
}
return $specifications_fields;
}
But I can't figure out how to create the shortcodes now, I have been trying everything I could think of along these lines:
function adresse_shortcode( $value ) {
$specifications_fields = get_specifications_fields();
foreach ( $specifications_fields as $name => $field ) {
$value = $field['value'];
$label = $field['label'];
$name = $field['name'];
return $name;
}
add_shortcode($value, 'adresse_shortcode');
}
I am not well versed in PHP so I am sure it's all sorts of wrong but I have been trying to figure it out for hours and was hoping someone might be able point me in the right direction.
Here's an example using anonymous functions that should do the trick
$hlfields = get_field_objects( 22 );
foreach ( $hlfields as ['name' => $name, 'value' => $value] ) {
$cb = function() use ($name) {
$field = get_field($name, 22);
return $field;
};
add_shortcode( $name, $cb );
}
Here's the sources i referred to while answering: Dynamic function name in php, Dynamic shortcodes and functions in WordPress, PHP: Variable functions
So, I was following this example on How to change the city field to a dropdown by Jeroen in my Billing/Shipping section of my site.
/**
* Change the checkout city field to a dropdown field.
*/
function city_to_dropdown( $fields ) {
$city_args = wp_parse_args( array(
'type' => 'select',
'options' => array(
'amsterdam' => 'Amsterdam',
'rotterdam' => 'Rotterdam',
'den-haag' => 'Den Haag',
'utrecht' => 'Utrecht',
'leiden' => 'Leiden',
'groningen' => 'Groningen',
),
), $fields['shipping']['shipping_city'] );
$fields['shipping']['shipping_city'] = $city_args;
$fields['billing']['billing_city'] = $city_args; // Also change for billing field
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'city_to_dropdown' );
Everything works as expected, but here is what I want to do different.
I want to be able to query all the list of cities from the from shipping rates based on city and display them in the dropdown code above.
So then I wouldn’t have to add the cities manually in multiple places. My list of cities will always be the cities added in using the shipping rates based on city functionality.
What do I need to do to be able to remove the manually entered cities and have something similar to the following :
‘options’ => get_list_cities_from_shipping_rate(),
Question :
What filters or hooks in woocommerce do I have to call to be able to return the list of cities in my function get_list_cities_from_shipping_rate() ?
I'm new to writing these custom codes in wordpress. Any help pointers on how to get this started would be appreciated.
Thank you in advance
Try this:
function get_list_cities_from_shipping_rate( $rate_id ) {
$cities = '';
$key = '_wafs_shipping_method_conditions';
$conditions = get_post_meta( $rate_id, $key, true );
foreach ( (array) $conditions as $group ) {
foreach ( (array) $group as $cond ) {
if ( ! isset( $cond['condition'] ) ) {
continue;
}
if (
'city' === $cond['condition'] &&
'==' === $cond['operator']
) {
$cities .= $cities ? ', ' : '';
$cities .= $cond['value'];
}
}
}
$cities = preg_split( '/, */', $cities );
return array_unique( array_filter( $cities ) );
}
Things to note:
On the WooCommerce → Settings → Advanced Free Shipping page, the $rate_id is the one after the post= as in http://example.com/wp-admin/post.php?post=123&action=edit. Hover on the Free shipping rates table rows and you'd see the Edit URL having that post query.
You must use the city's name and not its slug. E.g. Den Haag instead of den-haag. See the image you provided.
I am using gravity forms plugin, and I'm trying to display the categories as a drop down list in the form I have already created.
If required, please here's a link to my website
I've been on this for too long, and no way out. Kindly help me out.
add_filter( 'gform_pre_render_1', 'populate_categories' );
add_filter( 'gform_pre_validation_1', 'populate_categories' );
add_filter( 'gform_pre_submission_filter_1', 'populate_categories' );
add_filter( 'gform_admin_pre_render_1', 'populate_categories' );
function populate_categories( $form ) {
foreach ( $form['fields'] as &$field ) {
if ( $field->id != 1 ) {
continue;
}
// you can add additional parameters here to alter the posts that are retrieved
// more info: [http://codex.wordpress.org/Template_Tags/get_posts](http://codex.wordpress.org/Template_Tags/get_posts)
$categories = get_categories ;
$choices = array();
foreach ( $categories as $categories ) {
$choices[] = array( 'text' => $categories->name, 'value' => $categories->name );
}
// update 'Select a Post' to whatever you'd like the instructive option to be
$field->placeholder = 'Category';
$field->choices = $choices;
}
return $form;
}
You can dynamically generate drop downs for gravity forms using the syntax provided below in this link. You have to take control over the functions.php file of the theme to retrieve your output as per your requirement.
Here is the clear documentation provided and you can create in a simple manner using this methods. There are two methods available refer to it.
https://www.gravityhelp.com/documentation/article/dynamically-populating-drop-down-fields/
If you face any problem with creation let me know we shall solve it.
I have a code snippet that I use throughout my site, it reads the product IDs from a custom field "menu_listing" and displays content (like image, title, hyperlink, etc.) in an unordered list. I use this in various places on my site (ex. https://eatgoodathome.com/order/menu).
I am trying to get that list of product names to output next to customer order info in my Export Orders to CSV plugin. Here is the code pertaining to "menu_listing".
global $post;
// Date Range Parameters
$today = date("Y-m-d");
$next = date("Y-m-d", strtotime( "$today +2 weeks"));
// Query current menu based on date
$menu_args = array(
'post_type'=>'single_menu',
'posts_per_page' => 1,
'meta_query' => array(
array(
'key' => "delivery_date",
'value' => array( $today, $next ),
'type' => 'date',
'compare' => 'BETWEEN'
),
));
// Display custom field
$menu = new WP_Query( $menu_args );
if ( $menu->have_posts() ) {
while ( $menu->have_posts() ) {
$menu->the_post();
}
// This is the custom field, content looks like this: [{"id":"9115"},{"id":"8256"},{"id":"8539"},{"id":"5586"}]
$current_menu = json_decode( stripcslashes( get_post_field( "menu_listing", $post->id ) ) );
if( $current_menu ){
foreach( $current_menu as $single_block ) {
if( $single_block->id ) {
$dishes = get_post( $single_block->id )->post_title;
}}}}
//Output CSV cells
$row = array( $dishes );
In the state shown above, it loops through all the all the products, and only displays the name for the last one. I tried using implode(), explode(), an additional foreach() — those all seem to be a step in the wrong direction, outputting a blank column. What am I missing?
It looks like you're reassigning the value of $dishes with each iteration which is why you're only seeing the name of the last item. Try doing this instead:
$dishes[] = get_post( $single_block->id )->post_title;
This way, you'll be creating a new index of the $dishes array every iteration instead of reassigning its value. Then you can just assign $row = $dishes.
SOLUTION: The code in my question looped through the array and only gave the last item in the array. My goal was to loop through each key/value pair, convert the value ("id") to title, and have each title populate a column for my csv. My solution involved scrapping the foreach statement, and requesting each array in the loop by its offset, then assigning it a column in the csv file.
//Output for CSV
$output = fopen('php://output', 'w');
if ( $menu->have_posts() ) {
while ( $menu->have_posts() ) {
$menu->the_post();
}
// This is the custom field, content looks like this: [{"id":"9115"},{"id":"8256"},{"id":"8539"},{"id":"5586"}]
$current_menu = json_decode( stripcslashes( get_post_field( "menu_listing", $post->id ) ) );
$dish1 = get_post( $current_menu[0]->id )->post_title;
$dish2 = get_post( $current_menu[1]->id )->post_title;
$dish3 = get_post( $current_menu[2]->id )->post_title;
// Validate for 4th array item, if exists
if( sizeof($current_menu) === 4 ) {
$dish4 = get_post( $current_menu[3]->id )->post_title;
} else {
$dish4 = "";
}
}
//Output CSV cells
$row = array( $dish1, $dish2, $dish3, $dish4 );
fputcsv( $output, $row );