Laravel 6.x  【JavaScript 】【jQuery】【 Laravel-mix】 a タグで POST 送信する方法

#制作環境

Windows 10
Laravel : 6.18.35
Laravel/ui : 1.0
Laravel-mix : 5.0.1
jQuery : 3.2
Bootstrap : 4.0.0
MDBootstrap : 4.19.1
chart.js : 2.9.3
XAMPP
PHP : 7.4.3
Visual Studio Code

#はじめに

この記事はプログラミングをはじめたばかりの素人が、できたことをメモするのに利用しています。
内容には誤りがあるかもしれません。

機能の確認のみに特化しているので、必要最低限の記述しかしていません。

#コントローラの作成

Laravelのプロジェクトのディレクトリでターミナルを起動し、以下を実行してください。

```PHP
php artisan make:controller PostController
```

処理が完了したら、作成された`PostController.php`を開き、以下のように記述してください。

```PHP:PostController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        return view('apost');
    }

    public function post()
    {
        return view('aposted');
    }
}
```

シンプルに、POST送信前に表示するページとPOST送信後に表示するページの２つの処理を記述しています。

#ルーティングの作成

`routes` 内の`web.php`を開き、以下のように記述します。

```PHP:web.php
Route::get('/apost', 'PostController@index')->name('apost');
Route::post('/apost', 'PostController@post')->name('aposted');
```

`->name()`とすることで、ルーティングに名前を付けています。

#ビューの作成

`resources>views` 内に`apost.blade.php` と`aposted.blade.php`の２つのファイルを作成します。
`apost.blade.php`が送信前のページで、`aposted.blade.php`が送信後のページです。

apost.blade.phpを開き、以下のように記述します。
<font color="red">※現時点でPOST送信はできません。</font>

```PHP:apost.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>a要素でPOST</title>
</head>
<body>
    <div>
        <a href="">a要素でPOST送信</a>
    </div>
    <form id="a-post" action="{{ route('aposted') }}" method="post" style="display: none">
        @csrf
    </form>
</body>
</html>
```

/apostにアクセスし表示を確認すると、下のような文字だけのリンクが表示されます。
![link.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/760252/8f901a8e-a9aa-d872-7b82-242e778faa33.jpeg)

次に`aposted.blade.php`を開き、以下のように記述します。

```PHP:aposted.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>a要素でPOST後</title>
</head>
<body>
    <p>送信に成功しました!</p>
    <a href="{{ route('apost') }}">戻る</a>
</body>
</html>
```

「送信に成功しました」の文字と、「戻る」のリンクがあるだけです。

#JavaScriptでPOST送信する

JavaScriptを使用し、POST送信を実装します。
やり方としては、JavaScriptで`<form id="a-post">`の要素を取得し、submitさせます。

`apost.blade.php`を開き、aタグの内容を以下のように修正してください。

```PHP:apost.blade.php
<a href="javascript:document.getElementById('a-post').submit()">a要素でPOST送信</a>
```

修正が完了したら、/apostにアクセスし動作を確認してください。
![link.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/760252/c4c3a29a-928b-6719-c164-d5a827c6aab7.jpeg)

「a要素でPOST送信」をクリック後、
![success.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/760252/68ffc34f-123e-f7fb-b8f2-3e9b38bbe865.jpeg)

「送信に成功しました!」と表示されたらOKです。

#jQueryでPOST送信する

jQueryを使用し、POST送信を実装します。
やり方はJavaScriptと一緒です。

`apost.blade.php`を開き、aタグの内容を以下のように修正してください。

```PHP:apost.blade.php
<a href="javascript:$('#a-post').submit()">a要素でPOST送信</a>
```

修正しただけでは機能しません。
jQueryが使えるようにしないといけません。

##方法① CDNを利用

jQueryを使うのにCDNを利用します。
`apost.blade.php`の`<head>`内に以下を記述してください。
<font color="blue">※`<body>`終了タグ直前でもいいです。</font>

```PHP:apost.blade.php
<script
    src="https://code.jquery.com/jquery-3.5.1.min.js"
    integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
    crossorigin="anonymous">
</script>
```

これで動作するようになります。

##方法② Laravel-mixを使用

npmで既にjQueryがインストールされているようであれば、以下の記述でjQueryが使えるようになります。

`apost.blade.php`の`<body>`終了タグの直前に以下を記述してください。

```PHP:apost.blade.php
    <script src="{{ mix('js/app.js') }}"></script>

</body>
</html>
```

記述が完了したらターミナルで以下を実行してください。

```PHP
npm run dev
```

修正とjQueryを使えるようにしたら、/apostにアクセスし動作を確認してください。
JavaScriptの時と同じであればOKです。

#nameを使用しての記述

ここまでは`<form>`にidを設定し、idを指定して要素を取得しました。
今度は`<form>`にnameを設定し、動作するようにしてみます。

#nameを指定しJavaScriptでPOST送信する

`apost.blade.php`を開き、内容を以下のように修正してください。

```PHP:apost.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>a要素でPOST</title>
</head>
<body>
    <div>
        <a href="javascript:document.apost.submit()">a要素でPOST送信</a>
    </div>
    <form name="apost" action="{{ route('aposted') }}" method="post" style="display: none">
        @csrf
    </form>
</body>
</html>
```

`getElementById`がないので、ちょっとスッキリします。

/apostにアクセスし動作を確認してください。

<font color="red">**★ポイント★**</font>
<font color="blue">`a-post`のように「-」が入るとうまくいかないため、名前をapostに変更してます。

#nameを指定しjQueryでPOST送信する

`apost.blade.php`を開き、aタグの内容を以下のように修正してください。

```PHP:apost.blade.php
<a href="javascript:apost.submit()">a要素でPOST送信</a>
```

<font color="red">**【注意事項】**</font>
<font color="red">このままでは動作しません。必ずjQueryを使えるようにしてください。</font>

/apostにアクセスし動作を確認してください。

#Laravel-mixでPOST送信する

今度はLaravel-mixを使用してPOST送信してみたいと思います。
※今回はLaravel-mixを使用するので、jQueryもLaravel-mixを使用します。

##①JavaScriptを使用

`apost.blade.php`を開き、以下のように修正してください。

```PHP:apost.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>a要素でPOST</title>
</head>
<body>
    <div>
        <a class="a-submit" href="#">a要素でPOST送信</a>
    </div>
    <form id="a-post" action="{{ route('aposted') }}" method="post" style="display: none">
        @csrf
    </form>
    <script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
```

次に`resources>js` 内に新しく`apost.js`ファイルを作成してください。
作成したら次に`resources>js` 内にある`app.js`を開き、`require('./bootstrap');`の下に以下を追記します。

```JavaScript:app.js
require('./apost');
```

記述し終えたら、先ほど作成した`apost.js`ファイルを開き、以下のように記述してください。

```JavaScript:apost.js
document.getElementsByClassName('a-submit')[0].addEventListener('click', function() {
    document.getElementById('a-post').submit();
}, false);
```

記述が完了したら、ターミナルで以下を実行してください。

```PHP
npm run dev
```

処理が完了したら、/apostにアクセスし動作を確認してください。

##②jQueryを使用

ビューの記述、app.jsの記述はJavaScriptと一緒です。

`apost.js`ファイルのみ修正します。
<font color="blue">※JavaScriptの記述はコメントアウトするか、削除してください。</font>

```JavaScript:apost.js
$(function() {
    $('.a-submit').click(function() {
        $('#a-post').submit();
    });
});
```

記述が完了したら、ターミナルで以下を実行してください。

```PHP
npm run dev
```

処理が完了したら、/apostにアクセスし動作を確認してください。

##③nameを指定しJavaScriptを使用

`apost.blade.php`を開き、以下のように修正してください。

```PHP:apost.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>a要素でPOST</title>
</head>
<body>
    <div>
        <a name="asubmit" href="#">a要素でPOST送信</a>
    </div>
    <form name="apost" action="{{ route('aposted') }}" method="post" style="display: none">
        @csrf
    </form>
    <script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
```

次に`apost.js`以下のように修正します。
<font color="blue">※必要のない記述はコメントアウトするか、削除してください。</font>

```JavaScript:apost.js
document.getElementsByName('asubmit')[0].addEventListener('click', function() {
    document.getElementsByName('apost')[0].submit();
}, false);
```

記述が完了したら、ターミナルで以下を実行してください。

```PHP
npm run dev
```

処理が完了したら、/apostにアクセスし動作を確認してください。

##④nameを指定しjQueryを使用

ビューの記述、app.jsの記述はJavaScriptと一緒です。

`apost.js`ファイルのみ修正します。
<font color="blue">※JavaScriptの記述はコメントアウトするか、削除してください。</font>

```JavaScript:apost.js
$(function() {
    $('a[name="asubmit"]').click(function() {
        $('form[name="apost"]').submit();
    });
});
```


#まとめ

**aタグに直接処理を書くなら、jQueryでnameを指定する方が記述が少なくてすむ。**
**複数ページで同じ事をやるなら、使用したい箇所で同じidやclassを指定するだけで済むLaravel-mixの方が便利。**