大企業営業から未経験ITエンジニアを目指すブログ

アラサー大企業営業から未経験ITエンジニアを目指すブログ。日々学んだことを忘備録的に記します。

LaravelプロジェクトでjQuery+Ajaxを利用してリロードせずに自動計算

かろうじて動くものができたので、記録。

(処理を書く場所と長ったらしい書き方はこれから見直し)

jQueryCDNを利用。(ダウンロードしないやり方)

 

Bladeファイル(HTML)

<head>

<!-- ↓はAjax通信用に必要。jsファイルで呼び出せるように記載。-->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>○○○</title>

<!-- 必ずjsファイルを読み込む前にjQueryCDNを記載。 -->

<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<script src="{{ secure_asset('js/app.js') }}"></script>

<!-- Laravelは標準でデフォルトでhttpsで通信する(?)。asset()ではHTTP通信になってしまうので、secure_asset()を利用。-->
</head>

<body>

 <div>
  <table>
   <tbody>
    <tr>
     <th>税抜価格</th>
     <td><input type="text" name="price_without_tax1"></td>
     <td><input type="text" name="price_without_tax2"></td>
    </tr>
    <tr>
     <th>税込価格</th>
     <td><input type="text" name="price_with_tax1"></td>
     <td><input type="text" name="price_with_tax2"></td>
    </tr>
    <tr>
     <th>数量・容量</th>
     <td><input type="text" name="amount1" value="1" required></td>
     <td><input type="text" name="amount2" value="1" required></td>
    </tr>
    <tr>
     <th>単価(税抜)</th>
     <td name="unit_price1"></td>
     <td name="unit_price2"></td>
    </tr>
    <tr>
     <td colspan="3"><input type="button" id="calculate" value="自動計算"></td>
    </tr>
   </tbody>
  </table>
 </div>

</body>

 

/public/js/app.js

$(function(){

//Bladeファイルの<meta>タグの値を利用。これを書かないとLaravelの通信エラーに。
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

//最初の対象を '#calculate'にすると動かない(?)。

//同じ範囲内に変更対象とイベント対象を置き、その範囲を最初の()に記載。
$('table').on('click', '#calculate', function() {
var prices = new Object();
prices.price_without_tax1 = $('input[name="price_without_tax1"]').val();
prices.price_without_tax2 = $('input[name="price_without_tax2"]').val();
prices.price_with_tax1 = $('input[name="price_with_tax1"]').val();
prices.price_with_tax2 = $('input[name="price_with_tax2"]').val();
prices.amount1 = $('input[name="amount1"]').val();
prices.amount2 = $('input[name="amount2"]').val();

 

//$.postでも動作は同じらしい。記載方法が違うだけ。
$.ajax({
url: 'calculate', //データの送信先。Laravelのルートと紐づけ。
type: 'POST',
data: prices, //送信するデータは事前にObject化。
dataType: 'json' //受け取るデータのタイプ
})
.done(function(data) { //受け取ったデータを"data"と名付ける
$('input[name="price_without_tax1"]').val(data.price_without_tax1);
$('input[name="price_without_tax2"]').val(data.price_without_tax2);
$('input[name="price_with_tax1"]').val(data.price_with_tax1);
$('input[name="price_with_tax2"]').val(data.price_with_tax2);
$('input[name="amount1"]').val(data.amount1);
$('input[name="amount2"]').val(data.amount2);
$('[name="unit_price1"]').text(data.unit_price1);
$('[name="unit_price2"]').text(data.unit_price2);
})
.fail(function(data) {
var alertText = "";

//Laravelのバリデーションエラーは422 HTTPステータスコードで返ってくる

//バリデーションエラーのみ、アラートでエラーの中身を表示することに。
if (data.status === 422) {
for(var item in data.responseJSON.errors) {
alertText += data.responseJSON.errors[item] + "\n";
}
alert(alertText);
}
});
});
});

 

/routes/web.php

Route::post('calculate', 'CalculateController@calculate');

 

/app/Http/Controllers/CalculateController.php

class CalculateController extends Controller
{
public function calculate(Request $request)
{
$request->validate([
'price_without_tax1' => 'nullable|numeric|min:0',
'price_without_tax2' => 'nullable|numeric|min:0',
'price_with_tax1' => 'nullable|numeric|min:0',
'price_with_tax2' => 'nullable|numeric|min:0',
'amount1' => 'required|numeric|min:0.01',
'amount2' => 'required|numeric|min:0.01',
]);

$price_without_tax1 = $request->price_without_tax1;
$price_without_tax2 = $request->price_without_tax2;
$price_with_tax1 = $request->price_with_tax1;
$price_with_tax2 = $request->price_with_tax2;
$amount1 = $request->amount1;
$amount2 = $request->amount2;
$unit_price1;
$unit_price2;

$tax = 0.1;

if (is_null($price_without_tax1) && is_null($price_with_tax1)) {
 //税抜・税込両方nullならnullのままに。
} else {
if (is_null($price_without_tax1)) {
$price_without_tax1 = $price_with_tax1 / (1 + $tax);
}
if (is_null($price_with_tax1)) {
$price_with_tax1 = $price_without_tax1 * (1 + $tax);
}
$unit_price1 = $price_without_tax1 / $amount1;
}

if (is_null($price_without_tax2) && is_null($price_with_tax2)) {

} else {
if (is_null($price_without_tax2)) {
$price_without_tax2 = $price_with_tax2 / (1 + $tax);
}
if (is_null($price_with_tax2)) {
$price_with_tax2 = $price_without_tax2 * (1 + $tax);
}
$unit_price2 = $price_without_tax2 / $amount2;
}

$data = [
'price_without_tax1' => $price_without_tax1,
'price_without_tax2' => $price_without_tax2,
'price_with_tax1' => $price_with_tax1,
'price_with_tax2' => $price_with_tax2,
'amount1' => $amount1,
'amount2' => $amount2,
'unit_price1' => $unit_price1,
'unit_price2' => $unit_price2
];

//計算した後に全値を小数点第2位四捨五入。
foreach ($data as &$value) {
$value = round($value, 1);
}
unset($value);

//response()を通さないとエラーになる。
return response()->json($data);
}
}