【问题标题】:How to process a multi step form in controller? (When the user clicks "go to step 2" the form is not being processed in the controller)如何在控制器中处理多步骤表单? (当用户单击“转到步骤 2”时,控制器中未处理表单)
【发布时间】:2018-09-28 01:44:43
【问题描述】:

我有一个使用 bootstrap 和 jQuery 的多步骤表单。多步骤表单是供用户购买产品的。有 4 个步骤:第 1 步是用户输入他的信息(姓名、电子邮件等),第 2 步用户选择付款方式,第 3 步用户介绍付款数据,第 4 步为用户出示发票。因此,我尝试将表单分为 4 个步骤,每个步骤在控制器中使用相应的方法。

问题是,当用户单击提交输入“转到第 2 步”时,jquery 代码显示第 2 步的部分供用户选择付款方式,但第 1 步未在 PaymentController 中处理,即请求没有到达 PaymentController。

你知道问题出在哪里吗?

我在这个问题上的流程:

我创建了一个 PaymentController 来处理支付过程。

用户点击产品并进入产品详情页面。在产品详细信息页面中,用户选择数量。因此,在表单内有一个选择菜单,其中包含此操作“<form method="post" action="{{route('products.storeProduct', ['id' => $product->id, 'slug' => $product->slug])}}">”。

这个表格的路线是:

Route::post('/product/{id}/{slug?}/payment', [
    'uses' => 'PaymentController@storeProduct',
    'as'   =>'products.storeProduct'
]);

storeProduct 方法存储产品,从 db 获取一些信息,然后将用户重定向到 products.payment 路由以呈现支付页面页面:

class PaymentController extends Controller
{
    public function storeProduct(Request $request, $id, $slug = null){
        ...
        return redirect(route('products.payment',['id' => $id, 'slug' => $slug]));
    }

    public function presentPaymentPage(Request $request, $id, $slug=null){
      ...
        return view('products.payment',
            ['product' => $product, 'id' => $id, 'slug' => $slug]);
    }
}

presentPaymentPage() 的路由:

Route::get('/product/{id}/{slug?}/payment', [
    'uses' => 'PaymentController@presentPaymentPage',
    'as'   =>'products.payment'
]);

然后对于第 2 步,我在 PaymentController 中创建了以下两个方法,并在 web.php 中创建了两个路由:

在 PaymentController 中添加了两个方法(暂时没有任何内容):

public function storeUserInfo(Request $request, $id, $slug = null){
    dd($request->all()); // dont shows nothing
}
public function presentPaymentMethods(Request $request, $id, $slug=null){

}

以及方法的路线:

Route::post('/product/{id}/{slug?}/payment/storeUserInfo', [
    'uses' => 'PaymentController@storeUserInfo',
    'as'   =>'products.storeUserInfo'
]);

Route::get('/product/{id}/{slug?}/payment/paymentMethods', [
    'uses' => 'PaymentController@presentPaymentMethods',
    'as'   => 'products.presentPaymentMethods'
]);

在 payment.blade.php 我有如下表单步骤:

<div class="tab-content id="myTabContent">
    <div class="tab-pane fade show active clearfix" id="step1" role="tabpanel" aria-labelledby="home-tab">
        <form method="post" action="{{route('products.storeUserInfo', ['id' => $id, 'slug' => $slug])}}">
            <!-- form fields -->
            <input type="submit" href="#step2" data-toggle="tab" role="tab" class="next-step" value="Go to step 2"/>
        </form>
    </div>
    <div class="tab-pane fade clearfix" id="step2" role="tabpanel" aria-labelledby="profile-tab">
        <form method="post" class="clearfix">
            <!-- form fields -->
            <input type="submit" href="#step3" data-toggle="tab" role="tab" class="next-step" value="Go To step 3"/>
        </form>
    </div>
    ...
</div>

【问题讨论】:

    标签: php jquery laravel


    【解决方案1】:

    所以看起来多部分表单只在客户端处理,并没有返回到服务器。我相信这是 Bootstrap 中选项卡的预期行为。

    按照您设置代码的方式,这里有两个选项。

    选项 1:在客户端处理多部分表单

    您可以将所有需要的信息存储在页面上,既可以存储在 JS 对象中,也可以存储在隐藏的表单字段(甚至是常规表单字段)中。在最后一步,&lt;input type="submit" ... /&gt; 按钮将提交到后端PaymentController

    优点:不必在后端管理多部分状态。

    缺点:您将需要一些方法来检查产品是否仍然可用。例如,如果我在一两个小时后单击提交按钮,产品是否仍然可用?此外,将支付信息存储在客户端的某处可能不是一个好习惯,因为客户可能使用公共 PC。

    选项 2:在后端处理多部分表单

    修改您的视图文件,这样您就不会尝试在 JS 中纯粹在客户端处理多步骤功能。这似乎更符合您想要做的事情,因为您在 PaymentController 上有多个与每个步骤相对应的操作。

    为此,只需删除 Bootstrap 属性,即 roledata-toggle 等,然后在视图中使用良好的 'ol if/else 语句来切换要显示的页面部分。

    优点:似乎工作量更少,因为您已经完成了所有设置(除了您的视图文件)

    缺点:每次用户点击按钮进入下一步时都需要回发。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-05-08
      • 2014-01-10
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多