javascriptlaravellaravel-bladelaravel-livewirelivewire-3

Livewire 3 - Month picker / Datepicker Not Fired when using component lazy


My project using livewire 3 has a slight problem that occurs when my component uses lazy components.

<livewire:report lazy />

When I don't use lazy, monthpicker and datepicker don't have problems when I refresh the page manually or switch pages using the wire:navigate link.

But when I add lazy to my component, monthpicker and datepicker can't work.

My guess is because livewire uses placeholder before loading to my page which has monthpicker and datepicker.

My code:

<div class="row">
    <div class="col-md-8">
        <div class="card card-custom gutter-b example example-compact">
            <div class="card-header">
                <h3 class="card-title">Report</h3>
            </div>

            <form wire:submit.prevent="submit">
                <div class="card-body">
                    <div class="form-group">
                        <label>Pilih Bulan<span class="text-danger">*</span></label>

                        <input type="text"
                            class="form-control custom-width"
                            placeholder="Select month"
                            wire:model='bulan'
                            id="month_picker"
                            autocomplete="off"
                            />

                        @error('bulan') <span class="error">{{ $message }}</span> @enderror
                    </div>
                </div>

                <div class="card-footer">
                    <div class="text-center" wire:loading>
                        <button type="button" class="btn btn-primary spinner spinner-white spinner-right" disabled>
                            Validating
                        </button>
                    </div>

                    <button type="submit" class="btn btn-primary mr-2"
                            wire:loading.attr="disabled"
                            wire:loading.class="d-none">
                        Generate
                    </button>
                </div>

            </form>
        </div>
    </div>
</div>

@push('script')
<script>
var KTBootstrapDatepicker = function() {
    var arrows;
    if (KTUtil.isRTL()) {
        arrows = {
            leftArrow: '<i class="la la-angle-right"></i>',
            rightArrow: '<i class="la la-angle-left"></i>'
        }
    } else {
        arrows = {
            leftArrow: '<i class="la la-angle-left"></i>',
            rightArrow: '<i class="la la-angle-right"></i>'
        }
    }

    var demos = function() {
        $('#kt_datepicker').datepicker({
            rtl: KTUtil.isRTL(),
            todayHighlight: true,
            orientation: "bottom left",
            templates: arrows,
            autoclose: true,
            format: "dd-mm-yyyy"
        }).on("changeDate", function(e){
            @this.set('bulan', e.format());
        });

        $('#month_picker').datepicker({
            rtl: KTUtil.isRTL(),
            todayHighlight: true,
            orientation: "bottom left",
            templates: arrows,
            autoclose: true,
            format: "mm-yyyy",
            viewMode: "months",
            minViewMode: "months",
        }).on("changeDate", function(e){
            @this.set('bulan', e.format());
        });
    }

    return {
        init: function() {
            demos();
        }
    };
}();

jQuery(document).ready(function() {
    KTBootstrapDatepicker.init();
});
</script>
@endpush

I've tried reading and using Hook on livewire 3 as per documentation but still not able to solve this problem.

Livewire.hook('morph.added',  ({ el }) => {
    //
})

Maybe I missed something? Need your help


Solution

  • A possible solution is to use the syntax @script @endscript instead of @push('script') @endpush in this way Livewire will manage the component script and this will allow it to execute correctly:

    @script
    
    <script>
    
        const KTBootstrapDatepicker = function() {
    
            let arrows;
    
            if (KTUtil.isRTL()) {
    
       .....
    
    </script>
     
    @endscript
    

    Note that I used const instead of var to declare KTBootstrapDatepicker since the @script @endscript syntax has some issues with old constructs or comments when placed in the first position

    Some suggestions:

    <div wire:ignore>
    
        <input type="text"
               class="form-control custom-width"
               placeholder="Select month"
               id="month_picker"
               .....
        >
    
    </div>