Laravel ActionSubmit
任意のアクションを実行するための Submit ボタンを生成できます。, (*1)
一つのフォームに複数の submit ボタンを作成して、押されたボタンによって実行されるアクションを選択します。, (*2)
Route, (*3)
\Route::post('user/list', ['uses' => 'UserController@search', 'as' => 'user.search']);
\Route::post('user/delete', ['uses' => 'UserController@delete', 'as' => 'user.delete'])
View (Blade), (*4)
{{Form::open('user/list', ['method' => 'post'])}}
{{Form::actionSubmitRoute('user.search', 'Search'))}}
{{Form::actionSubmitRoute('user.delete', 'Delete'))}}
{{Form::close()}}
Submit ボタン
ルート Route
Form::actionSubmitRoute($routeName, $value, $patemeters, $attributes), (*5)
| name |
type |
value |
| routeName |
string |
'sample.user.list', 'user.batch.delete' |
| value |
string |
'Search', 'Delete' |
| parameters |
array |
[route parameters] |
| attributes |
array |
submit tag attributes |
アクション Action
Form::actionSubmitAction($actionName, $value, $parameters, $attributes), (*6)
| name |
type |
value |
| actionName |
string |
UserController@search, Sample\UserController@delete |
| value |
string |
Search, Delete |
| parameters |
array |
[action parameters] |
| attributes |
array |
submit tag attributes |
パス Path
Form::actionSubmit($path, $value, $attributes), (*7)
| name |
type |
value |
| path |
string |
user/serach, user/delete |
| value |
string |
Search, Delete |
| attributes |
array |
submit tag attributes |
Usage
bootstrap/start.php, (*8)
\Laravel\Extension\ActionSubmit\ActionSubmit::register();
require $app;
(また地味なものを作ってしまった・・・。ここからは余談です。), (*9)
どのように実装されているか, (*10)
Laravel に取り込まなくても Submit ボタンの onclick で form.action を書き換えれば同じことができるため無用かもしれませんが、JavaScript でガチャガチャやるのがあまりお好きじゃないかた使ってみてください。, (*11)
任意のアクションをディスパッチするためルータを拡張しています。
Laravel のルータは以下の順序で実行するアクションを解決していました。, (*12)
-
\Route::add() などでルート定義 RouteCollections に登録
- リクエスト情報から以下の条件を全て満たすルートを取得
- HTTP メソッドが一致する
- スキーマ(https?://)が一致する
- ホスト名が一致する
- パスが一致する (/controller/action)
- 一致するルートが見つかれば uses で指定されたアクション (Controller@action) を実行する
ActionSubmit ではルートを取得する条件に Submit ボタンの name に埋め込まれたルートと一致するかどうかの条件を追加しています。, (*13)
はまりポイントいくつか。, (*14)
-
App::bind('router', 'MyRouter') しても MyRouter クラスが使われない, (*15)
-
Illuminate\Routing\Router が使われてしまう
- どうやら
global.php で filters.php がロードされる前に App::bind() しないといけない
-
App:bind() はどこでも実行できるが、router や request などは初期化前に実行しておかないと無意味
-
global.php でもだめなケースがあったので bootstrap/start.php に移動.
-
App::bind('router', 'Laravel\Extension\ActionSubmit\Router') が動かない, (*16)
-
router に拡張したクラスを登録すると全てのURLで404 Not Found になる
- デバッグするとルート初期登録はできているのに、ディスパッチするときにはルートが空になってる (artisan route は正常)
- どうやら
app('router') の呼出で毎回 Router インスタンスが生成されているもよう
-
App:bind('router', 'Hoge', true) 第3引数の true で Singleton にすることで解決
See Also
- Illuminate\Routing\Router
- Illuminate\Routing\Route
- Illuminate\Routing\RouteCollections