Using Vue slot to render component within base component - javascript

I'm trying to create a re-usable base modal component and make use of slots to provide the modal content... It creates the application and modal. On button click the modal displays, but without the content. How can I get my content to display within the content specified slot? Am I using slot's incorrectly?
Here's a fiddle to help illustrate my problem : https://jsfiddle.net/70yyx8z2/19/
// register base modal component
Vue.component('modal', {
template: '#modal-template'
})
// register content component for modal
Vue.component('modal-content', {
template: '#modal-content'
})
// start app
new Vue({
el: '#app',
data: {
showModal: false
}
})
<modal v-if="showModal" #close="showModal = false">
<h3 slot="header">Header here</h3>
<!--
How can I use slot to render the modal content component?
-->
<modal-content></modal-content>
</modal>

JsFiddle Working Example
You can't specify a slot name inside the component as it won't be mounted before the slot replacement takes place. Instead you can assign the component to the slot
<!-- modal content component -->
<script type="text/x-template" id="modal-content">
<form>
<h2>This should show...</h2>
<input type="text" placeholder="user name" />
</form>
</script>
<!-- app -->
<div id="app">
<button id="show-modal" #click="showModal = true">Show Modal</button>
<!-- use the modal component, pass in the prop -->
<modal v-if="showModal" #close="showModal = false">
<h3 slot="header">Header here</h3>
<!--
How can I use slot to render the modal content component?
-->
<modal-content slot="body"></modal-content>
</modal>
</div>
EDIT: Fixed a small bit of nomenclature related issue as noticed by #thanksd

Technically all you need to do is this.
<modal-content slot="body"></modal-content>
You probably want to remove the modal-container from the modal-content component.
Here is your fiddle updated.

Related

Trying to make Vue Modal

Im making my first vue modal and I want to make a simple pop up window when you click on a button. I followed a tutorial but it wouldnt work. Then I tried others and... same result. I have no idea what I'm doin wrong!
My modal component code in the template:
<div class="save-btn">
<button #click="showModal = true">Save</button>
</div>
<transition name="modal-fade">
<div class="modal-overlay" #click="$emit('close-modal')">
<div class="modal" #click.stop>
<h6>Saved!</h6>
<p>Your Details have been saved Successfully</p>
<button>Go Home</button>
</div>
<div class="close" #click="$emit('close-modal')">
<img class="close-img" src="" alt="" />
</div>
</div>
</transition>
My modal compant code in the script:
data () {
return {
showModal: false
}
}
When I click the button :
<div class="save-btn"><button u/click="showModal = true">Save</button></div>
absolutely nothing happens and I have no idea why!
You are missing v-if for your Transition
<div v-if="showModal" class="modal-overlay" #click="$emit('close-modal')">
Also you should stick to the regular syntax so use Transition instead of transition since it is a component.
Here is the working demo of your code

Prevent Vue.Js replace Twig content in mounting DOM element

Version: Vue 3.0.5
index.html.twig
<div id="app">
<div class="text-center">
<h3>My text rendered in Twig</h3>
<div class="jumbotron text-center">
<example></example>
</div>
</div>
</div>
</div>
entry-file.js
import { createApp } from 'vue';
import Example from './components/Example.vue'
createApp(Example).mount('#app');
components/Example.vue
<template>
<div>
<p>This is text from VueJs component</p>
</div>
</template>
<script>
export default {
name: 'example'
}
</script>
Currently, when I access the page Vue completely removes Twig content inside #app div and replaces it with text from the component.
My question are,
How can I keep initial #app content rendered by Twig and additionally compile <example></example> component by Vue?
Is it OK practice to mix it this way? The problem is that I already have blocks/widgets and custom logic based on backed variables in Twig and it will be far too long to rewrite everything in Vue

Vue.js remove div from component

I'have this template in my vue.js 2.0 app:
<template>
<div>
<button class="xs:w-full md:w-auto button-main" #click="show = true">
Open filters
</button>
<portal to="port-details">
<div class="modal" v-if="show">
<p>jow</p>
</div>
</portal>
</div>
</template>
I need to remove the surrounding div because otherwise my markup looks weird. But if I remove that I obviously will get this error:
Component template should contain exactly one root element
How could I accomplish this?

How to create a modal using angular components?

I'm pretty new to angular, and I'm trying to create a modal as a component (trying not to use ui-bootstrap or libraries) and I'm having trouble wrapping my head around it. My code:
App.component('modal', {
templateUrl: '../modal.html',
controller: ChocoListCtrl
});
I have a modal.html which I want to reference my controller which displays items inside a cart:
<h2>Your Cart</h2>
<div ng-if="!cart.length">
There are no items in your cart
</div>
<div class="col-lg" ng-repeat="item in cart | unique : 'type'">
<div class="col-md">
<span>Type: </span>
<strong>{{item.type}}</strong>
</div>
<div class="col-md">
<strong>${{item.price}}</strong>
</div>
<div class="col-md">
<span>Quantity: </span>
<strong>{{item.quantity}}</strong>
</div>
<div class="col-md">
<button ng-click="removeItem()">Remove</button>
</div>
</div>
However that's really the extent of my knowledge. I'm not sure how to make the modal popup work or even start it. Any guidance would be greatly appreciated!
It looks like you've defined your component well, all you have left to do is rig up the trigger:
<modal ng-if="showModal"></modal>
<button ng-click="showModal = !showModal">Show Modal</modal>
This may change based on the configuration of the parent element, but it's the same idea.
Then style the modal in such a way that it pops up in the desired location. position:fixed, etc.
You may want to consider dropping a backdrop behind the modal that has an ng-click attached to it to close the modal.

How do you load a dynamic template into $uibModal.open( ) ( Angular UI bootstrap)?

I am using angular ui bootstrap. I want to define a generic Modal Window to provide some default buttons, like close, ok, title etc.
The user's modal body template is provided as a template url. How can I merge the user's modal body template into my generic modal window template?
Below is my generic Modal Window template,
modal-window.tpl.html
<div class="modal-header"><h3>{{ ctrl.headerText }}</h3></div>
<div class="modal-body">
<<<< The user's template provided as URL should be embedded in here >>>
</div>
<div class="modal-footer">
<button type="button" class="btn" data-ng-click="ctrl.close()"> {{ctrl.closeButtonText}} </button>
<button class="btn btn-primary" data-ng-click="ctrl.ok();"> {{ctrl.actionButtonText}}</button>
</div>
Thanks.
You should be able to use ng-include for that.
If you put the users template url on the scope in your controller:
userTemplate='users/template.html' . Then you could do something like:
...
<div class="modal-body">
<div ng-include="ctrl.userTemplate"></div>
</div>
...
If you also need a custom controller you can define one like this:
users/template.html:
<div ng-controller="CustomModalController as modalCtrl">
{{modalCtrl.foo}}
</div>
The only drawback is that this controller needs to be defined in the parent controller. In this case the controller were userTemplate='users/template.html' is defined.

Categories