Contact Form 7 (CF7) is a popular plugin for the WordPress CMS. It supports a few basic form components that allows user building a form quickly. One particular problem I had is to
populate a drop down selection box from content stored in the database (e.g., a list of vacant positions). To dynamically populate dropdown options is not an uncommon task for site builders. And if you know something about programming, this wouldn't be hard either.
With CF7, you can only fill your options by hand. I have looked around for solutions, and found this
post on the forum. However, it only appears to be working but not quite -- every time it rebuilds the options from database regardless user input, and nothing will be sent on submission (see the last comment in this
post).
I then had to worked out my way; I believe this is original, so copy right reserved *_^. Here is how. (By the way, the version I am using is Contact Form 7 3.0.1).
In the wp-content\plugins\contact-form-7\modules\ folder, find the
select.php. This is the file to be modified. (In general, I do NOT like to hack into the plugin source code. This will make upgrade difficult.)
1.
In function
wpcf7_select_shortcode_handler, $values, $labels and $defaults need to be redefined for your customised dropdown. They are arrays for dropdown values, dropdown texts and default selection respectively. I have the following snippet right after $options are parsed (after line 50). Here my select field ID is "position".
if ($name == 'position') {
// query the positions
$positions = new WP_Query('YOUR_QUERY');
while( $positions->have_posts() ) : $positions->the_post();
array_push( $values, get_the_ID() ); // post ID as option value
array_push( $labels, get_the_title() ); // post title as option text
endwhile;
// set the key of the default selection
array_push( $defaults, 1 + array_search($YOUR_DEFAULT_VALUE, $values) );
}
2.
In function
wpcf7_select_validation_filter, you need to re-fill the dropdown option values before the post operation because they cannot be found in the shortcode. They will be needed in $_POST later. I have the following snippet right after the local variable definitions. The code is very similar.
if ($name == 'position') {
// query the positions
$positions = new WP_Query('YOUR_QUERY');
while( $positions->have_posts() ) : $positions->the_post();
array_push( $values, get_the_ID() );
endwhile;
}
And that is it.