2015-09-18 21 views
-3

我有一个我正在建设的网站的结帐页面,并且由于它的设置方式,我有多种表单进行不同的操作。我正在使用cakephp 3.x框架,我使用stripe api来允许某人为会员付费以及让该人在网站上注册成为会员。根据会员资格,客户可以向网站注册1或2个人。以下代码是我点击付费后获得所有表单的唯一方式。我对jQuery和Ajax调用以及一般编码相当陌生,所以我相信我的代码会更好。有关使这个更简单,更好或更具活力的建议吗?我得到它的工作,但我多次使用.submit()函数,我担心它会在未来导致问题。如何在向jQuery/ajax提交条带付款时张贴多个表单?

HTML/PHP:

<div class="page-wrap"> 
    <div class="checkout-form"> 
     <h3>Membership Level</h3> 
     <p>You have selected the <span class="bold"><?= $membershipLevel->name ?></span> membership level.</p> 
     <p><?= $membershipLevel->description ?></p> 
     <p>The price for this membership is <span class="bold">$<?= $membershipLevel->billing_amount ?> per <?= $membershipLevel->cycle_period ?>.</span></p> 
     <p>Membership expires after <?= $membershipLevel->expiration_number ?> <?= $membershipLevel->expiration_period ?>.</p> 
     <?php if (isset($logged_in)): ?> 
      <p>You are logged in as <span class="bold"><?= $current_user['username']; ?></span>. If you would like to use a different account for this membership, <?= $this->Html->link('log out now', ['controller' => 'users', 'action' => 'logout']); ?>.</p> 
     <?php //else: ?> 
      <?= $this->Form->create('user', ['url' => ['controller' => 'users', 'action' => 'add'], 'id' => 'userForm']) ?> 
       <?= $this->Form->input('full_name') ?> 
       <?= $this->Form->input('username') ?> 
       <?= $this->Form->input('email', ['data-stripe' => 'email']) ?> 
       <?= $this->Form->input('password') ?> 
       <?= $this->Form->input('password_confirmation', array('type' => 'password')) ?> 

       <?php if ($current_user['role'] === 1 && isset($logged_in)) { 
        echo $this->Form->input('role', ['type' => 'select', 'options' => ['1' => 'Admin', '2' => 'Editor', '3' => 'Author', '4' => 'Reader'], 'default' => '4']); 
       } ?> 
      <?= $this->Form->end() ?> 
      <?php if (in_array($membershipLevel->id, [2,4,5])) { ?> 
       <?= $this->Form->create(null) ?> 
        <p>You are entitled to add another user with this membership level.</p> 
        <p><?= $this->Form->input('Add Second User Now', ['type' => 'checkbox', 'class' => 'second_user_checkbox']) ?> (If you do not add a second user now you will receive an email to add a second user at a later time).</p> 
       <?= $this->Form->end() ?> 
       <div class="second_user_form" style="display:none;"> 
        <?= $this->Form->create('user', ['url' => ['controller' => 'users', 'action' => 'add'], 'id' => 'secondUserForm']) ?> 
         <?= $this->Form->input('full_name') ?> 
         <?= $this->Form->input('username') ?> 
         <?= $this->Form->input('email', ['data-stripe' => 'email']) ?> 
         <?= $this->Form->input('password') ?> 
         <?= $this->Form->input('password_confirmation', array('type' => 'password')) ?> 

         <?php if ($current_user['role'] === 1 && isset($logged_in)) { 
          echo $this->Form->input('role', ['type' => 'select', 'options' => ['1' => 'Admin', '2' => 'Editor', '3' => 'Author', '4' => 'Reader'], 'default' => '4']); 
         } ?> 
        <?= $this->Form->end() ?> 
       </div> 
      <?php } ?> 
     <?php endif; ?> 
     <?= $this->Form->create(null, ['controller' => 'membershipLevels', 'action' => 'charge', 'id' => 'payment-form']) ?> 
      <div class="payment-errors" style="color:red;font-size:12px;"></div> 
      <fieldset> 
       <legend><?= __('Billing Address') ?></legend> 
       <?= $this->Form->input('billing_name', ['label' => 'Name', 'name' => false, 'data-stripe' => 'name']) ?> 
       <?= $this->Form->input('billing_street', ['label' => 'Address 1', 'name' => false, 'data-stripe' => 'address_line1']) ?> 
       <?= $this->Form->input('billing_street_2', ['label' => 'Address 2', 'name' => false, 'data-stripe' => 'address_line2']) ?> 
       <?= $this->Form->input('billing_city', ['label' => 'City', 'name' => false, 'data-stripe' => 'address_city']) ?> 
       <?= $this->Form->input('billing_state', ['label' => 'State', 'type' => 'select', 'options' => $this->CustomFormOptions->states(), 'default' => 'UT', 'name' => false, 'data-stripe' => 'address_state']) ?> 
       <?= $this->Form->input('billing_zip', ['label' => 'Zip', 'data-stripe' => 'address_zip']) ?> 
       <?= $this->Form->input('billing_country', ['label' => 'Country', 'type' => 'select', 'options' => $this->CustomFormOptions->countries(), 'default' => 'US', 'name' => false, 'data-stripe' => 'address_country']) ?> 
       <?= $this->Form->input('billing_phone', ['label' => 'Phone', 'data-stripe' => 'address_phone']) ?> 
       <legend><?= __('Payment Information') ?></legend> 
       <?= $this->Form->input('billing_amount', ['type' => 'hidden', 'data-stripe' => 'amount', 'value' => $membershipLevel->billing_amount]) ?> 
       <?= $this->Form->input('Card Number', ['name' => false, 'data-stripe' => 'number']) ?> 
       <?= $this->Form->input('CVC', ['name' => false, 'data-stripe' => 'cvc']) ?> 
       <?= $this->Form->input('Month', ['type' => 'select', 'options' => ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'], 'empty' => '(choose one)', 'name' => false, 'label' => 'Expiration (MM/YYYY)', 'size' => '1', 'data-stripe' => 'exp-month']) ?>/
       <?= $this->Form->input('Year', ['name' => false, 'label' => false, 'size' => '4', 'data-stripe' => 'exp-year']) ?> 
      </fieldset> 
      <?= $this->Form->button(__('Pay'), ['id' => 'submitBtn']) ?> 
     <?= $this->Form->end() ?> 
    </div> 
</div> 

的jQuery/AJAX:

<?php $this->Html->script('//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js', ['block' => true]); ?> 
<?php $this->Html->script('https://js.stripe.com/v2/', ['block' => true]); ?> 
<?php $this->Html->scriptStart(['safe' => false, 'block' => true]); ?> 
$(function() { 
    $('.second_user_checkbox').click(function() { 
     $('.second_user_form').toggle(); 
    }); 
}); 
$(function() { 
    var submitAllForms = function() { 
     $('#userForm, #secondUserForm').submit(function(e) { 
      e.preventDefault(); 
      var formID = $(this).attr('id'); 
      var formDetails = $('#'+formID); 
      $.ajax({ 
       type: formDetails.attr('method'), 
       url: formDetails.attr('action'), 
       data: formDetails.serialize(), 
       success: function() { 
        console.log('user\(s\) have been added'); 
       }, 
       error: function(e) { 
        console.log(e); 
       } 
      }); 
      return false; 
     }); 
     $('#userForm, #secondUserForm').submit(); 
     $('#payment-form').get(0).submit(); 
    } 
    Stripe.setPublishableKey('<?= $keys[0]['publishable_key'] ?>'); 
    $('#payment-form').submit(function(e) { 
     $form = $(this); 
     $form.find('button').prop('disabled', true); 
     //async 
     Stripe.card.createToken($form, function(status, response){ 
      console.log(status); 
      console.log(response); 
      if(response.error) { 
       $form.find('.payment-errors').text(response.error.message); 
       $form.find('button').prop('disabled', false); 
      } else { 
       var token = response.id; 
       $form.append($('<input type="hidden" name="stripeToken"/>').val(token)); 
       submitAllForms();    
      } 
     }); 
     return false; 
    }); 
}); 
<?php $this->Html->scriptEnd(); ?> 
+0

我不明白你为什么要绑定提交事件,而不是简单地阻止默认的事件发生。所有这些逻辑都可以在'submitAllforms'函数中进行。 –

+0

这是事情...你没有提交表单,你发送一个Ajax请求,然后***防止表单提交。如果你没有调用.sumit(),你不需要防止它(或者甚至绑定到它) –

+0

你正在通过ajax将数据发布到数据库,而不是通过表单提交。你不需要一个表单提交发送一个Ajax请求。 –

回答

2

你重新提交付款形式之前,你的另外两种形式完成提交数据,这将导致一种或两种形式在完成之前可能或可能不会中止的竞争条件。为了解决这个问题,您需要使用承诺链来跟踪这些请求何时完成,以便您可以等到完成后才提交付款表单。

$(function() { 
    var submitAllForms = function() { 
     var promiseArr = $('#userForm, #secondUserForm').map(function() { 
      var formDetails = $(this); 
      return $.ajax({ 
       type: formDetails.attr('method'), 
       url: formDetails.attr('action'), 
       data: formDetails.serialize(), 
       success: function() { 
        console.log('user\(s\) have been added'); 
       }, 
       error: function(e) { 
        console.log(e); 
       } 
      }); 
     }).get(); 
     // wait until both of the other forms' data are submitted 
     $.when.apply(null, promiseArr).then(function() { 
      $('#payment-form').get(0).submit(); 
     });    
    } 
    Stripe.setPublishableKey('<?= $keys[0]['publishable_key'] ?>'); 
    $('#payment-form').submit(function(e) { 
     $form = $(this); 
     $form.find('button').prop('disabled', true); 
     //async 
     Stripe.card.createToken($form, function(status, response){ 
      console.log(status); 
      console.log(response); 
      if(response.error) { 
       $form.find('.payment-errors').text(response.error.message); 
       $form.find('button').prop('disabled', false); 
      } else { 
       var token = response.id; 
       $form.append($('<input type="hidden" name="stripeToken"/>').val(token)); 
       submitAllForms();    
      } 
     }); 
     return false; 
    }); 
}); 
+0

谢谢一吨我一直在这几天正试图找出如何得到的。它工作,我做到了,但我知道有什么地方是错误的,这不是一个正确的方法,我从来没有使用承诺链或听说过他们,就像我说的我是新来的jQuery和阿贾克斯,所以谢谢你。 – Battousai