Livewire で Fomantic-UI のカレンダーを使うには?calendar
カレンダーのポイントは、wire:ignore を使うところと、カレンダーが消えるタイミングで イベントを発火 するところです。
手順
Laravel と Livewire をインストールして、Fomantic-UI の カレンダーを使う手順。
- プロジェクト名(calendar)を決めて以下のコマンドを実行します。
curl -s https://laravel.build/calendar | bash
インストール時にプロジェクト名のディレクトリが作成されます。
- インストールの最後に sudo でパスワードの入力を求められます。
↓下のメッセージが表示されてインストールは終わります。
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Get started with: cd calendar && ./vendor/bin/sail up
- sail のエイリアスを定義します。
echo "alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'" >> ~/.bashrc
source ~/.bashrc
Laravel のインストールはここまで。
- 「sail up」でコンテナを起動します。
cd calendar && sail up -d
- ララベルのトップディレクトリで、Livewireパッケージ をインストールします。
sail composer require livewire/livewire
- 次のコマンドを実行して、calendarコンポーネント を生成します。
sail artisan make:livewire calendar
$ sail artisan make:livewire calendar
COMPONENT CREATED ?
CLASS: app/Http/Livewire/Calendar.php
VIEW: resources/views/livewire/calendar.blade.php
次の 2つ のファイルが生成されます。
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Calendar extends Component
{
public function render()
{
return view('livewire.calendar');
}
}
<div>
{{-- The whole world belongs to you. --}}
</div>
※因みに、renderメソッド を定義しなくても livewire.calendar は呼び出されます。
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Calendar extends Component
{
}
- 生成された calendarコンポーネント のクラスとビューを次のように置き換えます。
app/Http/Livewire/Calendar.php
<?php
namespace App\Http\Livewire;
class Calendar extends \Livewire\Component
{
public $date = '2022-10-25';
public function dehydrate() {
\Log::debug($this->date);
}
}
resources/views/livewire/calendar.blade.php には以下の4つのやり方があります。
① onHide で inputイベント を上げる方法
<div wire:ignore>
<div class="ui calendar date">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input wire:model="date" id="calendar">
</div>
</div>
<script>
$('.calendar.date').calendar({
type: 'date',
text: {
days: ['日','月','火','水','木','金','土'],
dayNamesShort: ['日','月','火','水','木','金','土'],
dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],
months: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
monthsShort: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
today: '今日',
now: '今',
am: '午前',
pm: '午後'
},
formatter: {
date: 'YYYY-MM-DD'
},
onHide:function(val) {
//document.getElementById('calendar').dispatchEvent(new Event('input'))
document.querySelector('#calendar').dispatchEvent(new Event('input'))
}
})
</script>
</div>
ポイントは「wire:ignore」と「document.getElementById(‘calendar’).dispatchEvent(new Event(‘input’))」です。id を指定しなければならないので↓下の方法の方が良いです。
② wire:focusoutで $set で設定する方法
<div wire:ignore>
<div class="ui calendar date">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input wire:model="date" wire:focusout="$set('date',$event.target.value)">
</div>
</div>
<script>
$('.calendar.date').calendar({
type: 'date',
text: {
days: ['日','月','火','水','木','金','土'],
dayNamesShort: ['日','月','火','水','木','金','土'],
dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],
months: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
monthsShort: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
today: '今日',
now: '今',
am: '午前',
pm: '午後'
},
formatter: {
date: 'YYYY-MM-DD'
}
})
</script>
</div>
ポイントは「wire:ignore」と「wire:focusout=”$set(‘date’,$event.target.value)”」です。
③ onFocusout で @this.set() で設定する方法
<div wire:ignore>
<div class="ui calendar date">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input wire:model="date" onFocusout="@this.set('date',this.value)">
<div>
</div>
<script>
$('.calendar.date').calendar({
type: 'date',
text: {
days: ['日','月','火','水','木','金','土'],
dayNamesShort: ['日','月','火','水','木','金','土'],
dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],
months: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
monthsShort: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
today: '今日',
now: '今',
am: '午前',
pm: '午後'
},
formatter: {
date: 'YYYY-MM-DD'
}
})
</script>
</div>
ポイントは「wire:ignore」と「@this.set(‘date’,this.value)」です。
④ onFocusout で @this.プロパティ で設定する方法
<div wire:ignore>
<div class="ui calendar date">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input wire:model="date" onFocusout="@this.date=this.value">
<div>
</div>
<script>
$('.calendar.date').calendar({
type: 'date',
text: {
days: ['日','月','火','水','木','金','土'],
dayNamesShort: ['日','月','火','水','木','金','土'],
dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],
months: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
monthsShort: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
today: '今日',
now: '今',
am: '午前',
pm: '午後'
},
formatter: {
date: 'YYYY-MM-DD'
}
})
</script>
</div>
ポイントは「wire:ignore」と「@this.プロパティ=this.value」です。
- resources/views/index.blade.php ファイル を作成します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.0/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.0/dist/semantic.min.js"></script>
<livewire:styles />
</head>
<body>
<div class="ui basic segment">
<livewire:calendar />
</div>
<livewire:scripts />
</body>
</html>
- routes/web.php に Livewireコンポーネント のルートを追加します。
Route::get('/', fn() => view('index'));
- ブラウザで確認します。
tail でカレンダーを閉じるタイミングで通信していることを確認しましょう。
tail -f storage/logs/laravel.log
以上