Innovative approach to rendering a popup component in Vue.js

I am in the process of developing a VueJS application and facing a particular challenge. I want to show different popups when right-clicking on various components within the app. My main concern is that each component should have its own unique popup. I have come across a solution using the component id, but I am unsure if it will fully address my issue.

For example:

Vue.component('component', {
 template: `<button v-on:click="showPopup()">Open popup</button>`
})

Vue.component('popup1', {
template: '<div>Some complex features ... </button>'
})

Vue.component('popup2', {
template: '<div>Another complex features ... </button>'
})

In this scenario, the 'component' does not determine which popup to display. It is the function showPopup that determines which specific popup to show based on the given component.

Answer №1

Check out this functional demo:
https://codesandbox.io/s/nervous-dew-kjb4ts


Step 1

To create a modal, refer to this example.

Utilize slots for inserting dynamic content, such as other components within each instance of the modal, and utilize named slots for multiple sections. The control of visibility will be managed in the outer component or mixin.

<template>
  <transition name="modal">
    <div class="modal-header">
      <slot name="header"> default header </slot>
    </div>

    <div class="modal-body">
      <slot name="body"> default body </slot>
    </div>
    <slot name="footer">
      Default Footer
      <button class="modal-default-button" @click="$emit('close')">
      🚫 Close
      </button>
    </slot>
  </transition>
</template>

<script>
export default {
  name: "Modal",
};
</script>

<style scoped>
// Refer to the link above for complete styles
</style>

Step 2

Develop a mixin that can be extended by all components containing a modal. This is where you should add methods for opening, closing, and any additional functionality required. Create a data attribute to indicate the modal state for use with v-if, then implement two methods for opening and closing the modal.

import Modal from "@/components/Modal";

export default {
  components: {
    Modal
  },
  data: () => ({
    modalState: false
  }),
  methods: {
    openModal() {
      this.modalState = true;
    },
    closeModal() {
      this.modalState = false;
    },
  },
};

Step 3

Design your components that extend from the mixin, and utilize the modal component to display desired content.

You can initiate right-click events using: @mouseup.right

<template>
  <div class="example-component comp1">
    <h2>Component 1</h2>
    <button @contextmenu.prevent
      @mouseup.right="openModal()"
      @click="tryRightClick()">
      Open Component 1 Modal
    </button>
    <Modal v-if="modalState" @close="closeModal()">
      <template v-slot:header>👉 Component 1 Modal</template>
      <template v-slot:body>
        Lorem ipsum 
      </template>
    </Modal>
  </div>
</template>

<script>
import modalMixin from "@/mixins/component-modal-mixin";

export default {
  mixins: [modalMixin],
};
</script>

Step 4

Lastly, import your components into your project.

<template>
  <div id="app">
    <h3>StackOverflow Answer for Terbah Dorian</h3>
    <i>Example of separate components opening separate modals</i>
    <Component1 />
    <Component2 />
    <Component3 />
  </div>
</template>

<script>
import Component1 from "@/components/Component1";
import Component2 from "@/components/Component2";
import Component3 from "@/components/Component3";

export default {
  name: "App",
  components: {
    Component1,
    Component2,
    Component3,
  },
};
</script>

If this information was helpful, feel free to give it an upvote!

Answer №2

If you want to determine which popup should be displayed to your client, you can send simple data for that purpose. Here's an example:

Within the setup() section of App.vue, include the following code:

const popup = reactive({
    type: "none",
    data: "hello world"
});

const popupToggle = ref(false);

function showPopup(type, data){
    popup.type = type;
    popup.data = data;
    popupToggle.value = true;
}
    
function closePopup(){
    popup.type = "none";
    popup.data = "empty";
    popupToggle.value = false;
}

To make these functions available throughout your project, use the following:

provide("popupFunctions", {showPopup, closePopup});

Then, in other child components, inject the provided functions like this:

const {showPopup, closePopup} = inject("popupFunctions");

All you need to do now is call the showPopup and closePopup functions to modify the popup variable in App.vue. Check the type of popup to display the appropriate component as a popup for your client.

In the <template> section of your App.vue file, you could have something like this:

<popup-component v-if="popupToggle">
    <popup-msgbox v-if="popup.type === 'msgBox'" :popup-data="popup.data" />
    <popup-formbox v-else-if="popup.type === 'formBox'" :popup-data="popup.data" />
    <popup-errorbox v-else-if="popup.type === 'errBox'" :popup-data="popup.data" />
</popup-component>

Make sure to import the necessary components and dependencies into your project. I hope this solution helps clarify things for you and allows you to solve your issue efficiently.

Answer №3

Check out this live example of dynamic popovers in action!

I created a demo showcasing how to utilize Slots in Vue components to display interactive popovers when hovering over buttons.

I trust that this demonstration will be beneficial for your project.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve: proper authentication credentials were not provided

Whenever I make a request, everything works fine and I receive the data: const get_players = async()=>{ const response = await fetch('http://127.0.0.1:8000/player_stats/api/players/') const data = await response.json() console. ...

Building a video component using vue-konva: step-by-step guide

By utilizing konva.js, you have the capability to generate video components directly on your canvas. An example can be found within the documentation (). I am currently exploring vue-konva and have encountered a challenge in creating a video component on ...

Using jQuery to toggle the visibility of table data cells across various tables on a single webpage

On my webpage, I have multiple tables and I'm trying to add more rows or close table data cells using jQuery. However, I seem to be encountering an issue as it's not working properly. <table class="table" ><tr> < ...

Is it possible to verify if a user is accessing a webpage through Electron?

If I were interested in creating a basic Electron application that notifies the user upon reaching example.com, is this achievable? If yes, then how can I determine if the user is on a particular webpage? ...

JQuery Chosen extension - Go back to "Choose an option"

This is a select element with the Chosen plugin applied to it: <label class="radio-inline"><input type="radio" name="reset" value="reset">Reset</label> <select id="listclient"> <option value=""></option> <option val ...

Mastering the Art of Live Search in Drop Down Multi Select

I need to develop a search functionality similar to the one found on . This search should allow users to select options from a dropdown menu or type their own search query, and provide live search results. I attempted to use the jQuery plugin https://www.j ...

Uploading files in javascript and PHP

I am currently utilizing an audio recorder provided by this source , However, instead of storing the file locally, I am interested in uploading it back to the server. My attempt involved adjusting the Recorder.setupDownload function within the recording. ...

How to utilize a Jquery loop, implement a condition, and store the results in

After using dd() in PHP, the array displayed is as follows: 1 [▼0 => "1,18,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,19,20,21,22,23,24"] I need to iterate through the array and o ...

How can Codeception/Selenium help in testing the tooltip or customValidity message?

I am trying to implement a feature in my Codeception scenario where I want to validate a form submission with user errors, such as confirming a wrong email address, and display a custom tooltip message in the browser. HTML <form ... > <label ...

Error 405 (Invalid Method) in VueJs: You are not allowed to use

I have a route defined in the group with 'prefix'=>'admin' in web.php Route::post('/slideUpdate/{id}','SlideController@postSlideUpdate') In Add.vue, I am calling the update() function in methods axios.patch(`/a ...

Tips for modifying the language of an Angular Application's OneTrust Cookie Banner

I'm currently developing an Angular application and utilizing OneTrust for managing cookie consent. The issue I'm encountering is that while the rest of the components on the login page are properly translated into the target language, the OneTru ...

Developing a Chrome browser extension tailored for parsing unique file formats

Currently, I am working on developing a compiler for a unique conditional formatting language. My aim is to enable the capability of opening files in my language directly in Chrome by simply double-clicking on them in File Explorer (I am currently using Wi ...

What is the process for displaying all cookies in node.js?

I recently wrote some node.js code to retrieve cookies for a specific route. router.get('/', function (req, res, next) { var cookies = req.cookies; res.render('cartoons', { Cookies: cookies, }); }); In my cartoons Jade file, the ...

Module not found: vueform.config

For my current project, I decided to integrate Vueforms into the codebase. However, when I pasted their installation code into both my .ts and .js files, I encountered errors during the import of vueformconfig and builderconfig. This is a snippet of my ma ...

Nested ng-repeat using td to display multiple items in AngularJS

I am having an issue with the code as it is producing a table with the elements all in a single column. Below is an example of the data: var data = [[{"id":"1","value":"One"},{"id":"2","value":"Two"},{"id":"3","value":"three"}],[{"id":"4","value":"four"} ...

Ways to retrieve the most recent message on WhatsApp Web

I'm currently developing a JavaScript script for WhatsApp Web that will automate responses to messages in a specific group. Here is a snippet of my code: console.log('WhatsappWeb On'); function sleep(num){ setTimeout(num); } var eve ...

When you open the link in a new tab, the form submission does not occur

I am currently working on a form that includes a JavaScript submit function. Within the form, there are 3 anchor tags that I want to use to set different values to a hidden parameter when submitted based on the link clicked. Although the form submission w ...

When a text is wrapped by an HTML div using absolute positioning, is there a way to prevent it from wrapping without relying on white space

I have a group of div elements positioned absolutely on the screen. If any div contains content that is too big for the screen, the browser wraps it into multiple lines to fit. However, I do not want this behavior. Instead, I want the overflowing content ...

Is there a way to access and invoke a exposed function of a Vue component within a default slot?

Exploring the realms of a vue playground. The functions interfaceFunction in both ChildA and ChildB are exposed. In App, these functions can be called by obtaining references to the components that expose them. This allows direct function calls from with ...

Jquery: Pressing Enter will cause the input field to lose

Take a look at this fiddle I created: http://jsfiddle.net/7wp9rs2s/. This is the progress I have made on my project so far. In the fiddle above, you can double click on one of the 4 items and a textbox will appear for editing. Instead of clicking out of t ...