Giter Site home page Giter Site logo

vuedals's Introduction

Vuedals

VueJS (2.x) Plugin for multiple modals windows with a single component instance.

DEMO

View demo on jsFiddle

What is this?

A plugin to open stocked modals windows, event based, with just one component in your DOM.

What do you mean with "just one component"?

e.g. if you want to have 3 modals, you don't need to add the component 3 times, just one (preferably in the root of your app) and open as many modals as you want by using an Event Bus

Install

Install with npm:

npm install --save vuedals

Example

import Vue from 'vue';
import {default as Vuedals, Component as Vuedal, Bus as VuedalsBus} from 'vuedals';

Vue.use(Vuedals);

var myComp = Vue.extend({
    template: `<div>
            <h1>Hello World!</h1>
            <button @click="showIt()">Show me the money</button>
        </div>`,

    methods: {
        showIt() {
            VuedalsBus.$emit('new', {
                name: 'showing-the-money',

                component: {
                    name: 'the-money',

                    template: `
                        <div>
                            <h1>THE MONEY!</h1>
                            <p>Money, money, money, moooneeyyy $ $ $ $</p>
                        </div>
                    `
                }
            });
        }
    }
});

var vm = new Vue({
    el: '#app',

    components: {
        myComp,
        Vuedal
    },

    template: `<div>
        <my-comp></my-comp>

        <vuedal></vuedal>
    </div>`
});

Usage

Opening a new modal window

You can emit an event in your component:

this.$emit('vuedals:new', { option });

or a method:

this.$vuedals.new({ options });

or the Vuedals Event Bus:

import {Bus as Vuedals} from 'vuedals';

...

methods: {
    openNewModal() {
        Vuedals.$emit('new', { options });
    }
}

Closing a modal

You can emit an event in your component:

this.$emit('vuedals:close'[, data]);

a method:

this.$vuedals.close([data]);

or the Vuedals Event Bus:

import {Bus as Vuedals} from 'vuedals';

...

methods: {
    openNewModal() {
        Vuedals.$emit('close'[, data]);
    }
}

Closing an especific modal

If you need to close a specific modal index, you can pass it as an $index property of the data.

this.$vuedals.close({
    $index: 3
})

$index can be an integer or a function. In case $index is a function, the additional data and all the vuedals that is currently present is index(data, this.vuedals) passed as argument so that you can determine the index of the vudedal to close and return the index of it

this.$vuedals.close({
    $index(data, vuedals) {
        // this will always close the latest modal
        return vuedals.length - 1;
    }
})

Events

Depending if you're creating the modal from the component or from the Vuedals Event Bus, these are the events (component / bus):

vuedals:new / new

Open a new modal window, with the given options

vuedals:close / close

Close the most recently opened modal window, if data is given, will pass it to the onClose option.

vuedals:opened / opened

When a modal was open. Returns an object with:

  1. The index of the recently opened modal
  2. The options passed to that modal instance

vuedals:closed / closed

When a modal was closed. Returns an object with:

  1. The index of the closed modal
  2. The options passed to that modal instance
  3. The data given when close was called

vuedals:destroyed / destroyed

Emitted when the last modal instance is closed. i.e. there's not more open modals left

  1. The index of the closed modal
  2. The options passed to that modal instance
  3. The data given when close was called

Options

When creating a new modal, you'll need to pass the given options:

name

A reference name of the modal. Use to define the css class of that modal

Default: null

component

A Vue component to display inside the modal

props

A props object that will be passed to the component inside the modal.

example:

import {Bus as Vuedals} from 'vuedals';

...

methods: {
    openModal() {
        this.$vuedals.open({
            name: 'test-component',

            // Pass these props to the component
            props: {
                firstname: 'John',
                lastname: 'Doe'
            },

            component: {
                name: 'show-john-doe',

                // Expect these props values
                props: ['firstname', 'lastname'],

                template: `
                    <div>
                        Hi {{ firstname }} {{ lastname }}
                    </div>
                `
            }
        });
    }
}

size

The size of the modal.

Possible values are:

  • xs: 350px width
  • sm: 550px width
  • md: 650px width
  • lg: 850px width
  • xl: 1024px width

Default: md

dismissable

Should the modal include an "X" to be closed?

Default: true

escapable

Can this modal be closed by pression the esc key?

Default: false

closeOnBackdrop

Optionally prevent closing when clicking on backdrop

Default: true

title

Title of the modal window

Default: ''

header

An object that will be used to generate a custom header

Default: null

header: {
    component: 'header-component',
    props: {
        custom: 'Props'
    }
}

onClose

Callback function to call when the modal is closed. Any given data is passed as a parameter for that callback. Example:

this.$vuedals.open({
    name: 'test-component',

    // Pass these props to the component
    props: {
        firstname: 'John',
        lastname: 'Doe'
    },

    component: {
        name: 'show-john-doe',

        // Pass these props to the component
        props: ['firstname', 'lastname'],

        template: `
            <div>
                Hi {{ firstname }} {{ lastname }}
            </div>
        `
    },

    onClose(data) {
        console.log('Data received from the vuedal instance': data);
    }
});

onDismiss

Callback function to call when the modal is closed.

Please notice that even close and dismiss both close the active modal instance (closes the modal) only the close event accepts data argument that can be passed to the callback, while dismiss just send the modal to close.

The callback may prevent the modal closing by returning false.

Example:

this.$vuedals.open({
    name: 'test-component',

    // Pass these props to the component
    props: {
        firstname: 'John',
        lastname: 'Doe'
    },

    component: {
        name: 'show-john-doe',

        // expect these props
        props: ['firstname', 'lastname'],

        template: `
            <div>
                Hi {{ firstname }} {{ lastname }}
            </div>
        `
    },

    onDismiss() {
        console.log('The user dismissed the modal');
    }
});

vuedals's People

Contributors

46and2 avatar danielpe05 avatar dependabot[bot] avatar ishodnikov avatar jasonlfunk avatar javisperez avatar lsapan avatar msonowal avatar shelart avatar srichner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vuedals's Issues

(Fast) double-click on backdrop leads to an error

(Fast) double-clicking on the backdrop or programmatically closing the modal twice leads to a double execution of the dismissing function. Currently, it results in the following error:

vuedals.js:189 Uncaught TypeError: Cannot read property 'onDismiss' of undefined
    at c.dismiss (vuedals.js:189)
    at click (vuedals.js:265)
    at e (vue.esm.js:2027)
    at HTMLDivElement.t._withTask.t._withTask (vue.esm.js:1826)

dismissable bug

Hello

Thank you for the component.
One problem tho: your dismissable flag only hides the X button, you can still dismiss it.

You can add in component.vue around line 186

        // Check dismiss callback result for prevention
        if (this.vuedals[localIndex].onDismiss() === false)
          return;

Weird behaviour of <select> tag in Firefox

Hello.
Please look at this jsfiddle.

Press New Modal button, then try to select anything from select input. In Firefox the list with selectable options will appear not right under select input, but far to right side. In Chrome select input works normal.

duplicate events calling when navigate back and forth with vue router

Within an app with Vue router, as we navigate back and forth. a component that use vuedals, event bus always remember the previous push call back event such as new, close, dismiss and as we visit the component page that use vuedals again it will push that same event again and again.

this is due to whenever component.vue created() hook is called, it keep push event new, close, dismiss to the event bus which previously remembered.

so when we close a modal will call function onClose(data) many times.

How to close a specific vuedals?

How to close a specific vuedals?
I have a situation where I am showing mutliple instances of vuedals one over another but I want close/remove some specific vuedals, so is it possible?

Wrong behavior in Firefox with long sub-modal

Hello.
I use your jsfiddle example (by the way, it not works after breaking change with props in 1.3.0) and added long sub-modal. Here is my example: https://jsfiddle.net/brunen9/qrt5gawh/

Press "New Modal" button, then press "Open another modal" button, scroll to the bottom and press "Close" button. In Firefox you will not see first modal. Now scroll mouth wheel up about 10 times and first modal will appear from top. But in Chrome and Safari first modal will appear immediately after sub-modal closing.

Can you please fix this?

Logo proposal

Hello, i am a graphic designer and i would love to contribute a logo to your project, for free. Please Let me know if i can go ahead.

Key-event "esc" without focus on modal

Is there a reason why the key-event for "escape" just works if the user first clicks inside the modal? I think it would be better if you have a global key event listener which closes you the latest modal.

Something like:

mounted() {
      VuedalsBus.$on('opened', (modal) => {
        if (modal.options.escapable) {
          document.addEventListener('keydown', function dismissModal(event) {
            if (event.keyCode === 27) {
              VuedalsBus.$emit('close');
              document.removeEventListener('keydown', dismissModal, true);
            }
          }, true);
        }
      });
    },

closing modal when click on background

Vuedals.$emit("new", {
      title: title,
      dismissable: false,
      escapable:false,
      component: ccForm,
      props: {
        config: config
      },
      onClose(answer) {
        console.log("answer: ", answer);
      }
    });
  1. modal open
  2. user clicks to dark background around modal
  3. modal close

How to make the modal not closed?

Pass a slot to a modal?

Hi there,

im trying to build a wrapper modal component, which uses vuedals for showing the passed content. I've built a very basic example in the following jsfiddle: https://jsfiddle.net/Lju6y0vz/1/.

Is there any way to pass the slots content to vuedals open function in order to achieve the desired behaviour? Or is there any other way to do this?

Thanks in advance.

Cheers,
antony

Props passed are not reactive

I am seeing a behavior that I did not expect. I am calling a modal, passing props into the component. My call to open the modal looks like this:

this.$vuedals.open({
    title: 'Deliver List',
    component: 'modals-dnf-delivery-list',
    props: {
        deliveries: this.deliveries
    },
    escapable: true
});

In the scope of this caller, the local this.deliveries is working as expected, I can see values behind the modal update when I trigger changes to the underlying data via the UI the modal offers.

Is this expected, or am I perhaps passing this incorrectly?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.