自動見積もりフォーム
データの持たせ方
No | 変数名 | データ型 | 説明 |
---|---|---|---|
1 | taxRate | 数値 | 消費税率 |
2 | movieType | 文字列 | 制作したいムービーの種類 |
3 | basePrice | 数値 | 基本料金(税込) |
4 | addPrice1 | 数値 | 納期が1カ月未満の割増料金 |
5 | addPrice2 | 数値 | 納期が3週間未満の割増料金 |
6 | addPrice3 | 数値 | 納期が2週間未満の割増料金 |
7 | addPrice4 | 数値 | 納期が1週間未満の割増料金 |
8 | addPrice5 | 数値 | 納期が3日後の割増料金 |
9 | addPrice6 | 数値 | 納期が2日後の割増料金 |
10 | addPrice7 | 数値 | 納期が翌日の割増料金 |
11 | optPrice/td> | 数値 | オプション料金の合計(税込) |
12 | totalPrice | 数値 | 合計金額(税込) |
13 | announcement_date | 文字列 | 発表日(書式:YYYY-MM-DD) |
14 | delivery_date | 文字列 | DVD仕上がり予定日(書式:YYYY-MM-DD) |
15 | opt1_use | 真偽値 | BGM制作依頼のありなし |
16 | opt1_price | 数値 | BGM制作の税込料金 |
17 | opt2_use | 真偽値 | メイキング撮影のありなし |
18 | opt2_price | 数値 | メイキング撮影の税込料金 |
19 | opt3_use | 真偽値 | DVD盤面印刷のありなし |
20 | opt3_price | 数値 | DVD盤面印刷の税込料金 |
21 | opt4_num | 数値 | スキャニング写真の利用枚数 |
22 | opt4_price | 数値 | スキャニング写真の税込料金 |
日付の差を求めるgetDateDiff()関数は、methodsオプションにメソッドとして定義します。
dataオプションのプロパティや、算出プロパティ、メソッドなどは同じコンポーネント内ならthisで参照できます。
通貨書式のフィルターは汎用的なのでグローバルスコープに登録。グローバルに登録するフィルターの定義はコンポーネントよりも先に記述する必要がある。
dataオプションのプロパティや、算出プロパティ、メソッドなどは同じコンポーネント内ならthisで参照できます。
通貨書式のフィルターは汎用的なのでグローバルスコープに登録。グローバルに登録するフィルターの定義はコンポーネントよりも先に記述する必要がある。
HTML
<div id="app" v-cloak>
<div class="container bg-dark text-white p-5">
<h2 class="text-center border-bottom pb-3 mb-5">自動見積もりフォーム</h2>
<form>
<div class="form-group row">
<label class="col-md-3 col-form-label pt-0">希望する動画制作
<span class="badge badge-danger">必須</span>
</label>
<div class="col-md-9">
<div class="row">
<div class="col-md-5">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="movie_type" id="type1" value="余興ムービー" v-model="movieType">
<label class="form-check-label" for="type1">余興ムービー</label>
</div>
</div><!-- col-md-5 -->
<div class="col-md-5">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="movie_type" id="type2" value="広告用ムービー" v-model="movieType">
<label class="form-check-label" for="type2">広告用ムービー</label>
</div>
</div><!-- col-md-5 -->
<div class="col-md-5">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="movie_type" id="type3" value="プレゼン動画" v-model="movieType">
<label class="form-check-label" for="type3">プレゼン動画</label>
</div>
</div><!-- col-md-5 -->
<div class="col-md-5">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="movie_type" id="type4" value="会社紹介動画" v-model="movieType">
<label class="form-check-label" for="type4">会社紹介動画</label>
</div>
</div><!-- col-md-5 -->
</div>
</div>
</div>
<!-- 発表日 -->
<div class="form-group row">
<label class="col-md-3 col-form-label pt-0" for="announcement_date">発表日
<span class="badge badge-danger">必須</span>
</label>
<div class="col-md-9">
<input class="form-control" type="date" id="announcement_date" placeholder="日付を選びください" v-model="announcement_date">
<small class="form-text">動画発表の日にちを選択してください</small>
</div>
</div>
<!-- DVD仕上がり予定日 -->
<div class="form-group row">
<label class="col-md-3 col-form-label pt-0" for="delivery_date">DVD納品予定日
<span class="badge badge-danger">必須</span>
</label>
<div class="col-md-9">
<input class="form-control" type="date" id="delivery_date" v-bind:min="tommorow" placeholder="日付を選びください" v-model="delivery_date">
<small class="form-text">仕上がり予定日を発表日の1週間前に設定しております</small>
</div>
</div>
<!-- 基本料金 -->
<div class="form-group row">
<label class="col-md-3 col-form-label pt-0">基本料金(税込)</label>
<div class="col-md-9">
<div class="input-group">
<input type="text" class="form-control text-right" id="sum_base" v-bind:value="taxedBasePrice | number_format" readonly>
<div class="input-group-append">
<label class="input-group-text">円</label>
</div>
</div>
</div>
</div>
<!-- オプションメニュー -->
<div class="form-group row">
<label class="col-md-3 col-form-label pt-0">オプション(税込)
<span class="badge badge-info">任意</span>
</label>
<div class="col-md-9">
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="opt1" v-model="opt1_use">
<label class="form-check-label" for="opt1">BGM制作 +{{taxedopt1 | number_format}}円</label>
<small class="form-text">オリジナル楽曲を依頼される場合は1曲{{taxedopt1 | number_format}}円かかります</small>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="opt2" v-model="opt2_use">
<label class="form-check-label" for="opt2">メイキング動画 +{{taxedopt2 | number_format}}円</label>
<small class="form-text">メイキングムービーを依頼される場合の料金です</small>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="opt3" v-model="opt3_use">
<label class="form-check-label" for="opt3">DVD盤面印刷 +{{taxedopt3 | number_format}}円</label>
<small class="form-text">盤面デザインを希望される場合は{{taxedopt3 | number_format}}円(税込)がかかります</small>
</div>
<div class="form-row mb-3 align-items-center">
<div class="col-auto">
<label class="form-check-label" for="opt4">写真スキャニング +{{taxedopt4 | number_format}}円</label>
</div>
<div class="col-auto">
<div class="input-group">
<input class="form-control" type="number" id="opt4" v-model.number="opt4_num" min="0" max="30">
<div class="input-group-append">
<label class="input-group-text" for="opt4">枚</label>
</div>
</div>
</div>
<small class="form-text">プリントアウトした写真のスキャニング希望の方は1枚当たり{{taxedopt4 | number_format}}円にて承ります</small>
</div>
</div>
</div>
<!-- 小計 -->
<div class="form-group row">
<label class="col-md-3 col-form-label pt-0">オプション料金(税込)</label>
<div class="col-md-9">
<div class="input-group">
<input type="text" class="form-control text-right" id="sum_opt" v-bind:value="taxedOptPrice | number_format" readonly>
<div class="input-group-append">
<label class="input-group-text">円</label>
</div>
</div>
</div>
</div>
<!-- 合計 -->
<div class="form-group row">
<label class="col-md-3 col-form-label pt-0">合計(税込)</label>
<div class="col-md-9">
<div class="input-group">
<input type="text" class="fo-m-control text-right" id="sum_total" v-bind:value="taxedTotalPrice | number_format" readonly>
<div class="input-group-append">
<label class="input-group-text">円</label>
</div>
</div>
</div>
</div>
</form>
</div>
</div><!-- /#app -->
JavaScript
//通貨書式への変換フィルター
Vue.filter('number_format', function (val) {
return val.toLocaleString();
});
var app = new Vue({
el: '#app',
data: {
taxRate: 0.1,
movieType: '余興ムービー',
basePrice: 25000,
addPrice1: 5000,
addPrice2: 10000,
addPrice3: 15000,
addPrice4: 20000,
addPrice5: 30000,
addPrice6: 40000,
addPrice7: 45000,
optPrice: 0,
totalPrice: 0,
announcement_date: '',
delivery_date: '',
opt1_use: false,
opt1_price: 6600,
opt2_use: false,
opt2_price: 12500,
opt3_use: false,
opt3_price: 1200,
opt4_num: 0,
opt4_price: 320,
},
methods: {
//税込金額に変換
incTax: function (untaxed) {
return Math.floor(untaxed * (1 + this.taxRate));
},
//日付の差分を求める
getDateDiff: function (dateString1, dateString2) {
var date1 = new Date(dateString1);
var date2 = new Date(dateString2);
//二つの日付の差分(ミリ秒)を計算
var msDiff = date1.getTime() - date2.getTime();
//差分を日付に変換 差分÷(1000ミリ秒×60秒×60分×24時間)
return Math.ceil(msDiff / (1000 * 60 * 60 * 24));
},
//日付をYYYY-MM-DDの書式を返すメソッド
formatDate: function (dt) {
var y = dt.getFullYear();
var m = ('00' + (dt.getMonth() + 1)).slice(-2);
var d = ('00' + dt.getDate()).slice(-2);
return (y + '-' + m + '-' + d);
}
},
computed: {
taxedopt1: function () {
return this.incTax(this.opt1_price);
},
taxedopt2: function () {
return this.incTax(this.opt2_price);
},
taxedopt3: function () {
return this.incTax(this.opt3_price);
},
taxedopt4: function () {
return this.incTax(this.opt4_price);
},
taxedBasePrice: function () {
var addPrice = 0;
//納期までの残り日数
var dateDiff = this.getDateDiff(this.delivery_date, (new Date()).toLocaleString());
//割増料金
if (21 <= dateDiff && dateDiff < 30) {
addPrice = this.addPrice1;
} else if (14 <= dateDiff && dateDiff < 21) {
addPrice = this.addPrice2;
} else if (7 <= dateDiff && dateDiff < 14) {
addPrice = this.addPrice3;
} else if (3 <= dateDiff && dateDiff < 7) {
addPrice = this.addPrice4;
} else if (dateDiff == 3) {
addPrice = this.addPrice5;
} else if (dateDiff == 2) {
addPrice = this.addPrice6;
} else if (dateDiff == 1) {
addPrice = this.addPrice7;
}
return this.incTax(this.basePrice + addPrice);
},
taxedOptPrice: function () {
var optPrice = 0;
if (this.opt1_use) { optPrice += this.opt1_price; }
if (this.opt2_use) { optPrice += this.opt2_price; }
if (this.opt3_use) { optPrice += this.opt3_price; }
if (this.opt4_num == '') { this.opt4_num == 0; }
optPrice += this.opt4_num * this.opt4_price;
return this.incTax(optPrice);
},
taxedTotalPrice: function () {
return (this.taxedBasePrice + this.taxedOptPrice);
},
},
created: function () {
//今日の日付取得
var dt = new Date();
//発表日に2か月後の日付を初期設定
dt.setMonth(dt.getMonth() + 2);
this.announcement_date = this.formatDate(dt);
//DVD納品予定日をさらに1週間前に初期設定
dt.setDate(dt.getDate() - 7);
this.delivery_date = this.formatDate(dt);
},
//明日の日付をYYYY-MM-DDの書式で返すプロパティ
tommorow: function () {
var dt = new Date();
dt.setDate(dt.getDate() + 1);
return this.formatDate(dt);
}
});