追記
そもそも相性悪いのでこっちでやりましょう
はじめに
郵便番号から住所を自動入力してくれるライブラリYubinBango.jsをLivewireで開発中のプロジェクトで導入しようとした所、
自動入力された部分をlivewireが検知してくれなかったので詰まったポイントから解決までを記述します。
目次
環境構築
環境は下記の記事の環境とします。特殊な環境設定などは行っていないです。
AdminLteパッケージは画面を見やすくするのとコードの記述省略の為に入れているので無くてもかまいません。
【Laravel】Laravel-AdminLTEとlivewireを布教したい
> php artisan make:livewire Yubinbango
問題点
生成されたファイルに書き込みます。
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Yubinbango extends Component
{
public $postal_code, $region, $locality, $street_address, $extended_address;
public function render()
{
return view('livewire.yubinbango')
->extends('adminlte::page')
->section('content');
}
public function store()
{
dd($this->postal_code, $this->region, $this->locality, $this->street_address, $this->extended_address);
}
}
yubinbango.jsをCDNで読み込み、設定方法通りに記述します
YubinBangoリポジトリ【GitHub】
<div>
<script src="https://yubinbango.github.io/yubinbango/yubinbango.js" charset="UTF-8"></script>
<div class="pt-4 col-6 mx-auto ">
<form wire:submit.prevent="store" class="h-adr">
<span class="p-country-name" style="display:none;">Japan</span>
<div class="card card-info mt-4">
<div class="card-body">
<div class="row">
<x-adminlte-input name="postal_code" label="郵便番号" class="p-postal-code" id="p-postal-code"
wire:model.defer="postal_code" fgroup-class="col-6"
autocomplete="off">
<x-slot name="prependSlot">
<div class="input-group-text">
〒
</div>
</x-slot>
</x-adminlte-input>
<x-adminlte-input name="prefecture" label="都道府県" id="p-region" wire:model.defer="region"
class="p-region" fgroup-class="col-6" autocomplete="off"/>
</div>
<div class="row">
<x-adminlte-input name="municipalities" label="市区町村" id="p-locality" class="p-locality"
wire:model.defer="locality" fgroup-class="col-6" autocomplete="off"/>
<x-adminlte-input name="address" label="町域" id="p-street-address" class="p-street-address"
wire:model.defer="street_address" fgroup-class="col-6" autocomplete="off"/>
</div>
<div class="row">
<x-adminlte-input name="extended_address" label="その他住所" id="p-extended-address"
class="p-extended-address" wire:model.defer="extended_address"
fgroup-class="col-12" autocomplete="off"/>
</div>
<x-adminlte-button type="submit" class="col-4 mx-auto btn-lg btn-block" label="送信"
theme="success" icon=""/>
</div>
</div>
</form>
</div>
</div>
Route::get('/yubinbango', \App\Http\Livewire\Yubinbango::class);
フォームが出来たので試しにスカイツリーの住所を自動入力し、送信してみます。
手打ちで入力した郵便番号以外のフォームの値が同期出来ていません。
アクション時に同期を行うdeferで書いていますが駄目みたいです。
想定ですが、inputの値を見ているのではなくて、状態管理してる要素から同期を取っているみたいなのでそっちに検知されないと駄目そうです。
解決方法
結論:HTML要素からlivewireプロパティに同期させる
php側で各プロパティに値を入れる関数``inputYubinbango``を作り、 js側で要素から取得した住所情報を``inputYubinbango``の引数に入れ、実行する関数``inputAddress``を作成します。 ``inputAddress``をsubmit前に実行する事でバインドさせます。<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Yubinbango extends Component
{
public $postal_code, $region, $locality, $street_address, $extended_address;
public function render()
{
return view('livewire.yubinbango')
->extends('adminlte::page')
->section('content');
}
+ public function inputYubinbango($postal_code, $region, $locality, $street_address, $extended_address)
+ {
+ $this->postal_code = $postal_code;
+ $this->region = $region;
+ $this->locality = $locality;
+ $this->street_address = $street_address;
+ $this->extended_address = $extended_address;
+ }
public function store()
{
dd($this->postal_code, $this->region, $this->locality, $this->street_address, $this->extended_address);
}
}
<div>
<script src="https://yubinbango.github.io/yubinbango/yubinbango.js" charset="UTF-8"></script>
<div class="pt-4 col-6 mx-auto ">
- <form wire:submit.prevent="store" class="h-adr">
+ <form wire:submit.prevent="store" onSubmit="inputAddress();" class="h-adr">
<span class="p-country-name" style="display:none;">Japan</span>
<div class="card card-info mt-4">
<div class="card-body">
<div class="row">
<x-adminlte-input name="postal_code" label="郵便番号" class="p-postal-code" id="p-postal-code"
wire:model.defer="postal_code" fgroup-class="col-6"
autocomplete="off">
<x-slot name="prependSlot">
<div class="input-group-text">
〒
</div>
</x-slot>
</x-adminlte-input>
<x-adminlte-input name="prefecture" label="都道府県" id="p-region" wire:model.defer="region"
class="p-region" fgroup-class="col-6" autocomplete="off"/>
</div>
<div class="row">
<x-adminlte-input name="municipalities" label="市区町村" id="p-locality" class="p-locality"
wire:model.defer="locality" fgroup-class="col-6" autocomplete="off"/>
<x-adminlte-input name="address" label="町域" id="p-street-address" class="p-street-address"
wire:model.defer="street_address" fgroup-class="col-6" autocomplete="off"/>
</div>
<div class="row">
<x-adminlte-input name="extended_address" label="その他住所" id="p-extended-address"
class="p-extended-address" wire:model.defer="extended_address"
fgroup-class="col-12" autocomplete="off"/>
</div>
<x-adminlte-button type="submit" class="col-4 mx-auto btn-lg btn-block" label="送信"
theme="success" icon=""/>
</div>
</div>
</form>
</div>
+ <script>
+ function inputAddress() {
+ @this.inputYubinbango($('#p-postal-code').val(), $('#p-region').val(), $('#p-locality').val(), $('#p-street-address').val(), $('#p-extended-address').val());
+ }
+ </script>
</div>
ちゃんとバインド出来ました。解決解決