I am modifying a WP plugin (PHP; latest version of WP). It has a form where a user can ask a question. It came with it's own submit button. I found an action hook where I can add my own code to the form, so I added Braintree's simplest payment form - the DropIn UI. This is a screenshot of what both forms look like when I set them up.
The problem:
The "Post question" button that came with the plugin is not working and I suspect that it is due to the presence of the second form.
What I've tried:
I removed bits and pieces of the code I added to try and single out what could be causing this and it came down to the DropIn's form code itself. The presence of a 2nd form on this page is causing an issue.
My question: What could cause submit issues when 2 forms are present on one page?
Note - I used an action hook to insert my code to a function that described itself as the main plugin's form footer. I am getting the feeling that this is a form nesting problem.
my function that creates the Braintree form:
class FD_Braintree_Form
{
public function fd_bt_form()
{
echo
'<form id="checkout" action="/process-trans.php" method="post">
<p>
<label><font size="5">Amount:</font></label>
<input type="text" size="4" name="amount" />
</p>
<div id="payment-form"></div>
<input type="submit" value="Pay" />
</form>';
}
}
my function that generates the Braintree form:
class Find_Do_For_Anspress
{
add_action('ap_form_bottom_ask_form', array( $this, 'fd_bt_form_html')); //This is where I use the action hook to insert my code into the plugin's form_footer()
public function fd_bt_form_html()
{
$class_bt_token = new Braintree_ClientToken();
$clientToken = $class_bt_token->generate();
?>
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
braintree.setup(
'<?php echo $clientToken ?>',
'dropin', {
container: 'payment-form',
});
</script>
<?php
$class_bt_form = new FD_Braintree_Form();
$bt_form = $class_bt_form->fd_bt_form();
echo $bt_form;
}
}
plugin's main code that generates the question form:
function ap_ask_form($editing = false){
global $editing_post;
$is_private = false;
if($editing){
$is_private = $editing_post->post_status == 'private_post' ? true : false;
}
$args = array(
'name' => 'ask_form',
'is_ajaxified' => true,
'submit_button' => ($editing ? __('Update question', 'ap') : __('Post question', 'ap')),
'fields' => array(
array(
'name' => 'title',
'label' => __('Title', 'ap'),
'type' => 'text',
'placeholder' => __('Question in one sentence', 'ap'),
'desc' => __('Write a meaningful title for the question.', 'ap'),
'value' => ( $editing ? $editing_post->post_title : sanitize_text_field( @$_POST['title'] ) ),
'order' => 5,
'attr' => 'data-action="suggest_similar_questions"',
'autocomplete' => false,
),
array(
'name' => 'title',
'type' => 'custom',
'order' => 5,
'html' => '<div id="similar_suggestions"></div>'
),
array(
'name' => 'description',
'label' => __('Description', 'ap'),
'type' => 'editor',
'desc' => __('Write description for the question.', 'ap'),
'value' => ( $editing ? apply_filters('the_content', $editing_post->post_content) : @$_POST['description'] ),
'settings' => apply_filters( 'ap_ask_form_editor_settings', array(
'textarea_rows' => 8,
'tinymce' => ap_opt('question_text_editor') ? false : true,
'quicktags' => ap_opt('question_text_editor') ? true : false ,
'media_buttons' =>false,
)),
),
array(
'name' => 'ap_upload',
'type' => 'custom',
'html' => ap_post_upload_form(),
'order' => 10
),
array(
'name' => 'parent_id',
'type' => 'hidden',
'value' => ( $editing ? $editing_post->post_parent : get_query_var('parent') ),
'order' => 20
)
),
);
if(ap_opt('allow_private_posts'))
$args['fields'][] = array(
'name' => 'is_private',
'type' => 'checkbox',
'desc' => __('Only visible to admin and moderator.', 'ap'),
'value' => $is_private,
'order' => 12,
'show_desc_tip' => false
);
if(ap_opt('recaptcha_site_key') == '')
$reCaptcha_html = '<div class="ap-notice red">'.__('reCaptach keys missing, please add keys', 'ap').'</div>';
else
$reCaptcha_html = '<div class="g-recaptcha" id="recaptcha" data-sitekey="'.ap_opt('recaptcha_site_key').'"></div><script type="text/javascript"
src="https://www.google.com/recaptcha/api.js?hl='.get_locale().'&onload=onloadCallback&render=explicit" async defer></script><script type="text/javascript">var onloadCallback = function() {
widgetId1 = grecaptcha.render("recaptcha", {
"sitekey" : "'.ap_opt('recaptcha_site_key').'"
});
};</script>';
if(ap_opt('enable_recaptcha'))
$args['fields'][] = array(
'name' => 'captcha',
'type' => 'custom',
'order' => 100,
'html' => $reCaptcha_html
);
/**
* FILTER: ap_ask_form_fields
* Filter for modifying $args
* @var array
* @since 2.0
*/
$args = apply_filters( 'ap_ask_form_fields', $args, $editing );
if($editing){
$args['fields'][] = array(
'name' => 'edit_post_id',
'type' => 'hidden',
'value' => $editing_post->ID,
'order' => 20
);
}
$form = new AnsPress_Form($args);
echo $form->get_form();
echo ap_post_upload_hidden_form();
}
the plugin's "form footer" code and the action hook I used:
private function form_footer()
{
ob_start();
/**
* ACTION: ap_form_bottom_[form_name]
* action for hooking captcha and extar fields
* @since 2.0.1
*/
do_action('ap_form_bottom_'. $this->name);
$this->output .= ob_get_clean();
$this->output .= '<button type="submit" class="ap-btn ap-btn-submit">'.$this->args['submit_button'].'</button>';
if(@$this->args['show_cancel'] === true)
$this->output .= '<button type="button" class="ap-btn ap-btn-cancel">'.__('Cancel', 'ap').'</button>';
$this->output .= '</form>';
}
the hidden upload function:
function ap_post_upload_hidden_form(){
if(ap_opt('allow_upload_image'))
return '<form id="hidden-post-upload" enctype="multipart/form-data" method="POST" style="display:none">
<input type="file" name="post_upload_image" class="ap-upload-input">
<input type="hidden" name="ap_ajax_action" value="upload_post_image" />
<input type="hidden" name="ap_form_action" value="upload_post_image" />
<input type="hidden" name="__nonce" value="'.wp_create_nonce( 'upload_image_'.get_current_user_id()).'" />
<input type="hidden" name="action" value="ap_ajax" />
</form>';
}
the HTML that houses the plugin's ask form code:
<div class="ap-tab-container">
<div id="ap-form-main" class="active ap-tab-item">
<?php ap_ask_form(); ?>
</div>
</div>