LoginSignup
1
3

More than 3 years have passed since last update.

LaravelでjQuery-UIのダイアログ(dialog)を使おうとすると「TypeError: $(...).dialog is not a function」エラーになる

Last updated at Posted at 2019-10-06

周知の通りLaravelにはビュー生成のエンジンとしてBlade機構が備わっています。ログなどを見ていると中身はVue.jsのようなのですが、とにかくこのBladeテンプレートの中でjQuery-UIのダイアログ機能を使おうとするとブラウザーコンソールに謎の(想定外の)「TypeError: $(...).dialog is not a function」というエラーが出て期待動作しない現象が起きました。

jQuery-UIを使おうとした際の謎の(想定外の)エラー
TypeError: $(...).dialog is not a function

playcode.ioにフィールドを移して少しずつLarabelの生成HTMLをシュリンクしていったところ、

Laravelによって生成されたHTML
    <!-- Scripts -->
    <script src="https://laravel-mysql-base.herokuapp.com/js/app.js"></script>

というフレームワークが提供しているJSスクリプトの参照が存在していると期待動作しないということが分かってきました。
これを手がかりに更に確認(検索)を進めたところ以下のようなissueエントリーを発見しました。同じ現象です。

https://github.com/laravel/framework/issues/28984
└─ jQueryUI incompatible with js/app.js #28984

image.png

残念ながらこのエントリーはクローズされていて、問題の根本解決には至っていないように見えました。

ここで注目したのは app.js への参照が app.blade.php の最後に記されている点です。勿論、JSの参照は最後に書くという作法もあるのですが今でも多くはheadに書く事が多いです。
実際、私が編集して管理していた app.blade.php も次のように app.js への参照を尊重して(?) app.js への参照よりも前に参照を書いていました。勿論、この場合競合する関数などがあれば app.js の内容が優先されます。

app.blade.phpの概要
    <!-- Custom Scripts Ref -->
    @yield('scripts')
....
    <!-- Custom Scripts -->
    @yield('postscripts')
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>

そこで、仕方ないので以下のjQUery-UI関連の記述を app.js への参照よりも後に記すことにしました。

jQUery-UI関連の記述
@section('scripts')
<noscript>You must <a href="https://www.enable-javascript.com/ja/" target="_blank">enable JavaScript</a> in your web browser in order to pay via Stripe.</noscript>
<script src="//checkout.stripe.com/v2/checkout.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
@stop
修正後のapp.blade.phpの概要
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
    <!-- Custom Scripts Ref -->
    @yield('scripts')
    <!-- Custom Scripts -->
    @yield('postscripts')

これで無事にダイアログを表示することが出来ました。ただ、オーバーライドの影響でLaravelのBlade(HTML)動作に何らかの悪影響が出る機能が今後確認されるかもしれません。

image.png

今回学んだ知見は以下の通りです。
1. 謎のJSエラーに遭遇したら app.js への参照との順番を疑ってみる。
2. 以下のように、app.blade.phpのセクションを分けておいて、テンプレートからJSの挿入位置をコントロールできるようにしておくと良い。

修正後のapp.blade.phpの概要
    <!-- Custom Pre Scripts Ref -->
    @yield('preScriptsRef')
    <!-- Custom Pre Scripts -->
    @yield('preScripts')

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>

    <!-- Custom Post Scripts Ref -->
    @yield('postScriptsRef')
    <!-- Custom Post Scripts -->
    @yield('postScripts')
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3