Search code examples
jquerylaravelvue.jsvue-componentsemantic-ui

Vue element not loading on hidden modal


I am trying to display a Vue component onto a modal controlled by semantic ui, however, the vue element is not loading/mounting. I am using Laravel & JQuery mainly with some vue elements.

I suspect this is due to the modal being hidden before the vue elements are loaded but I'm not sure how to rerender the vue elements when the modal is shown?

If I use the same code on a normal page with display: block the element is shown normally.

Loading the blade component:

@include('partials.forms.location',['name'=>'location', 'label'=>__(''),'style' => 'full'])

Blade component which should load the element:

@component('partials.forms.form-group',['style'=>isset($style) ? $style : null,'label'=>$label, 'name'=>$name])
    <drop-marker-map
        data-name="{{ $name }}"
        data-lat="{{ old($name) ? old($name)['lat'] : null  }}"
        data-lng="{{ old($name) ? old($name)['lng'] : null }}">
    </drop-marker-map>
@endcomponent

Vue template:

<template>
  <div class="drop-marker-map">
    <p>Navigate to your location or find the correct address in the drop down box.</p>
    <div class="map-wrapper">
      <div class="map" ref="map"></div>
    </div>
    <div class="map-utilities">
      <div class="ui grey basic button locate" @click="geoLocate">Find your location</div>
      <div class="ui grey basic button maker" @click="placeMaker">Place Marker</div>
      <div class="ui grey basic button clear-maker" @click="clearMaker" v-if="this.lat && this.lng">Clear Marker
      </div>
      <div class="ui grey basic button recenter" @click="recenter" v-if="this.lat && this.lng">Recenter Map</div>
    </div>
    <input type="hidden" :name="this.latName" v-model="this.lat">
    <input type="hidden" :name="this.lngName" v-model="this.lng">
  </div>
</template>

Solution

  • Figured this one out finally. Intercepted the modal 'onShow' and re-rendered the html content using Vue. If there is a better way I'd love to hear it still.

    $('#foundModal').modal({
        onShow: function() {
            const dropHtml = $('#map-container').html();
            let res = window.Vue.compile(dropHtml);
            new Vue({
                render: res.render,
                staticRenderFns: res.staticRenderFns
            }).$mount('#map-container');
        }
    }).modal('show');