Skip to content

Modal window does not work #276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kollors opened this issue Apr 24, 2017 · 83 comments
Closed

Modal window does not work #276

kollors opened this issue Apr 24, 2017 · 83 comments

Comments

@kollors
Copy link

kollors commented Apr 24, 2017

When I copy example (https://jsfiddle.net/pi0/bofh9aaa) locally, it does not work on bootstrap 4.0.0-alpha.6 and bootstrap-vue 0.14.0. I get only a blackout of body.

@tmorehouse
Copy link
Member

There might have been some changes to the new V4-alpha-6 classes.

I will check on this later today.

@mosinve
Copy link
Member

mosinve commented Apr 24, 2017

It seems that you do soomething wrong, as jsfiddle uses bootstrap 4.0.0-alpha.6 and bootstrap-vue 0.14.0. So there's cannot be any new classes or whatever.
@kollors, please can you show your failing files please.

@tmorehouse
Copy link
Member

@mosinve, true, I just checked that the original fiddle is working with V4-alpha-6

@kollors
Copy link
Author

kollors commented Apr 25, 2017

package.json

{
  "name": "vue-seed",
  "version": "0.0.1",
  "scripts": {
    "build": "NODE_ENV=production webpack --progress",
    "postinstall": "bower i -F && typings i",
    "server:development": "HOST=$(hostname -I | grep -o '[0-9.]*' | head -1) npm run server:localhost",
    "server:localhost": "webpack-dev-server --progress",
    "start": "npm run server:localhost",
    "update": "ncu -a --packageFile package.json && ncu -a -m bower --packageFile bower.json"
  },
  "dependencies": {
    "bootstrap": "^4.0.0-alpha.6",
    "bootstrap-vue": "^0.14.0",
    "font-awesome": "^4.7.0",
    "jquery": "^3.2.1",
    "jquery-ui-dist": "^1.12.1",
    "socket.io-client": "^1.7.3",
    "vue": "^2.2.6",
    "vue-resource": "^1.3.1",
    "vue-router": "^2.5.1",
    "vuex": "^2.3.1"
  },
  "devDependencies": {
    "babel-core": "^6.24.1",
    "babel-loader": "^7.0.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-flow-strip-types": "^6.22.0",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.4.0",
    "babel-preset-stage-3": "^6.24.1",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.28.0",
    "debug": "^2.6.4",
    "extract-text-webpack-plugin": "^2.1.0",
    "file-loader": "^0.11.1",
    "html-loader": "^0.4.5",
    "html-webpack-plugin": "^2.28.0",
    "node-sass": "^4.5.2",
    "postcss": "^5.2.17",
    "postcss-cssnext": "^2.10.0",
    "postcss-loader": "^1.3.3",
    "rimraf": "^2.6.1",
    "sass-loader": "^6.0.3",
    "style-loader": "^0.16.1",
    "url-loader": "^0.5.8",
    "vue-loader": "^11.3.4",
    "vue-template-compiler": "^2.2.6",
    "webpack": "^2.4.1",
    "webpack-dev-server": "^2.4.4"
  }
}

index.html

<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>vue-seed</title>
    <link rel="icon" data-href="favicon.png" type="image/x-icon">
    <base href="/">
</head>
<body>
<div id="app">
    <b-btn @click="$root.$emit('show::modal','modal1')">Launch demo modal</b-btn>

    <!-- Main UI -->
    <div class="mt-3 mb-3">
        Submitted Names:
        <ul>
            <li v-for="n in names">{{n}}</li>
        </ul>
    </div>

    <!-- Modal Component -->
    <b-modal id="modal1" title="Submit your name" @ok="submit" @shown="clearName">

        <form @submit.stop.prevent="submit">
            <b-form-input type="text" placeholder="Enter your name" v-model="name"></b-form-input>
        </form>

    </b-modal>
</div>
<!--<router-view id="app"></router-view>-->
</body>
</html>

index.js

Vue.use(BootstrapVue/*, VueResource, VueRouter, Vuex*/);

window.app = new Vue({
    el: '#app',
    data: {
        name: '',
        names: []
    },
    methods: {
        clearName() {
            this.name = '';
        },
        submit() {
            if (!this.name) {
                alert('Please enter your name');
                return e.cancel();
            }

            this.names.push(this.name);
            this.name = '';
        }
    }
});

vendor.js

require('jquery');
require('jquery-ui-dist/jquery-ui');
require('bootstrap');

window.Vue = require('vue');
/*window.VueRouter = require('vue-router/dist/vue-router');
window.VueResource = require('vue-resource');
window.Vuex = require('vuex');*/
window.BootstrapVue = require('bootstrap-vue');

window.requireAll = requireContext => requireContext.keys().map(requireContext);
window.io = require('socket.io-client/dist/socket.io');
window.compose = (...fns) => value => fns.reduce((v, fn) => fn(v), value);

require('./vendor.scss');

vendor.scss

@import '~jquery-ui-dist/jquery-ui.theme.css';
@import '~bootstrap/scss/bootstrap';
@import '~bootstrap-vue/dist/bootstrap-vue.css';
@import '~font-awesome/css/font-awesome.css';

webpack.config.js

process.env.NODE_ENV = process.env.NODE_ENV || 'development';
process.env.HOST = process.env.HOST || 'localhost';
process.env.PORT = process.env.PORT || '8001';

const path = require('path');
const rimraf = require('rimraf');

const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');

const paths = {
    context: path.join(__dirname, 'sources'),
    dist: path.join(__dirname, 'dist'),
    static: path.join(__dirname, 'static')
};

const devHash = process.env.NODE_ENV == 'development' ? '.[hash]' : '';

const webpackConfig = {
    context: paths.context,
    entry: {
        vendor: './vendor',
        app: './app'
    },
    output: {
        path: paths.dist,
        publicPath: '/',
        filename: path.join('assets', `[name]${devHash}.bundle.js`),
        chunkFilename: path.join('assets', `[name]${devHash}.chunk.js`)
    },
    resolve: {
        modules: ['bower_components', 'node_modules'],
        descriptionFiles: ['bower.json', 'package.json'],
        extensions: ['.js', '.json', '.vue'],
        alias: {
            vue: 'vue/dist/vue.js'
        }
    },
    module: {
        exprContextCritical: false,
        rules: [
            {
                test: /\.js$/,
                exclude: /(bower_components|node_modules)/,
                loader: 'babel-loader'
            },
            {
                test: /\.html$/,
                loader: 'html-loader'
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader!postcss-loader'
                })
            },
            {
                test: /\.s[ac]ss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader!postcss-loader!sass-loader'
                })
            },
            {
                test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)([?]?.*)$/,
                loader: 'url-loader',
                options: {
                    limit: '100000', // > 100kb -> file
                    name: path.join('assets', `[name]${devHash}.[ext]`)
                }
            }
        ]
    },
    plugins: [
        {
            apply: compiler => (rimraf.sync(compiler.options.output.path))
        },
        new CommonsChunkPlugin({
            name: ['app', 'vendor'],
            minChunks: 2
        }),
        new HtmlWebpackPlugin({
            template: path.join(paths.context, 'index.html')
        }),
        new CopyWebpackPlugin([{
            from: paths.static
        }]),
        new ExtractTextPlugin({
            filename: path.join('assets', `[name]${devHash}.bundle.css`),
            allChunks: true
        }),
        new ProvidePlugin({
            jQuery: 'jquery',
            Tether: 'tether'
        }),
        new DefinePlugin({
            'process.env': JSON.stringify(process.env)
        })
    ]
};

if (process.env.NODE_ENV == 'development') {
    webpackConfig.devServer = {
        contentBase: paths.dist,
        host: process.env.HOST,
        port: parseInt(process.env.PORT),
        stats: 'minimal',
        historyApiFallback: true
    };

    webpackConfig.devtool = 'source-map';
    webpackConfig.watch = true;
}

if (process.env.NODE_ENV == 'production') {
    webpackConfig.plugins.push(new UglifyJsPlugin({
        compress: {
            warnings: false,
            drop_console: true
        }
    }));
}

module.exports = webpackConfig;

@mosinve
Copy link
Member

mosinve commented Apr 25, 2017

Can't build your proj.. seems im lacking of a folder struct :) or maybe just git repo )

@mosinve
Copy link
Member

mosinve commented Apr 25, 2017

try to remove jquery and bootstrap imports. they don't needed with vue+bootstrap-vue

@pi0
Copy link
Member

pi0 commented Apr 25, 2017

Also it seems no js file in included in index.html

@nerdalertdk
Copy link

nerdalertdk commented Apr 26, 2017

Yes, its not me that's crazy
Found out the display is set to none for .modal

if i unclick it in Chrome inspecter i shows.

udklip

.modal {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1050;
    display: none;
    overflow: hidden;
    outline: 0;
}

@mosinve
Copy link
Member

mosinve commented Apr 26, 2017

it's strange, because this must be fixed by .modal{display:block} rule in bootstrap-vue/dist/bootstrap-vue.css

@pi0
Copy link
Member

pi0 commented Apr 26, 2017

@nerdalertdk Can you please create and share us a repo which can be used to reproduce that?

@nerdalertdk
Copy link

Hi

Since I use Coreui as style framework I don't thinit will help, fixed it by add .modal .show { display:block;}

So think it bootstrap related since both this and coreui have the bug

@mosinve
Copy link
Member

mosinve commented Apr 27, 2017

@kollors , once more, if you don't need of the original Bootstrap js in your project, try to remove it and check the issue, please.

@alexsasharegan
Copy link
Member

alexsasharegan commented Apr 28, 2017

Having the same issue. Not sure why the lib's .modal{display:block;} css is loading after the bootstrap css despite importing it last. I just fixed it by adding the d-block in yet another bunch of css that was loaded after bs & bs-vue.

P.S. I removed bootstrap.js as a dep as well, and continued to have the d-none override problem.

@alexsasharegan
Copy link
Member

P.S. Mad props for removing the jQuery + Tether dependencies native to bootstrap!!!!! Got so excited when I read that.

Many people may be coming from my position--normal bootstrap app, then add Vue, then add bootstrap-vue. This might be a good documentation addition: migrating plain bootstrap app to bootstrap-vue. Sounds like a short section (just remove bootstrap.js and it's dependencies if you're not using them, and add css), but could save some little gotchas and potential non-issues.

@pi0
Copy link
Member

pi0 commented Apr 28, 2017

@alexsasharegan Happy hearing problem fixed :) If you can add some notes about that in docs/setup.md
file we can add it to docs helping others :)

@alexsasharegan
Copy link
Member

I'll check it out and submit a PR!

@alexsasharegan
Copy link
Member

It looks like you're referring to the GitHub pages repository. House is that built? Plain html?

@pi0
Copy link
Member

pi0 commented Apr 28, 2017

@alexsasharegan Docs are written in Markdown (https://github.com/bootstrap-vue/bootstrap-vue/blob/master/docs/SETUP.md) and will be rendered/published to gh-pages.

@alexsasharegan
Copy link
Member

Sweet! I'm on my phone at the moment, so it can be hard to tell. Thanks again for the awesome lib!

@kollors
Copy link
Author

kollors commented Apr 29, 2017

Yes, it all worked after I replaced bootstrap/scss/bootstrap.scss on bootstrap/dist/css/bootstrap.css. Original bootstrap.js, Tether and jQuery is left

@tmorehouse
Copy link
Member

So is everything working correctly now?

@kollors
Copy link
Author

kollors commented May 9, 2017

Only if include bootstrap.css, not bootstrap.scss

@alexsasharegan
Copy link
Member

alexsasharegan commented May 9, 2017

I second that. I'm pulling in the bootstrap scss file before I pull in the bootstrap-vue css, and I still have to manually repeat the .modal { display: block; } rule to override bootstrap. Perhaps that is a webpack loader issue—when mixing scss and css together the order may not be guaranteed or configurable (or most likely I don't have the correct webpack config to load in the right order).

@tmorehouse
Copy link
Member

Maybe if the modal CSS in the modal.vue component used scoped CSS? which would ensure that the display block applied to the modal?

@alexsasharegan
Copy link
Member

That actually seems like a smart move to avoid collisions for any .modal stylings.

@tmorehouse
Copy link
Member

Scoped CSS does have it's shortcomings (doesn't always fix everything), but it might work in this case.

@alexsasharegan
Copy link
Member

I'm certainly no expert on css, but I know that our offending css rule here is a flat class. Scoped css should offer enough specificity to create a sure override.

@tmorehouse
Copy link
Member

The only other thing I can think of is debouncing/throttling the transition handlers for the duration of the longest transition duration. :(

@alexsasharegan
Copy link
Member

I've played that game before. My suggestion is not to even go down that road!

@alexsasharegan
Copy link
Member

So here's what I proposed on the vue issue (we'll see if Evan chimes in now that the issue is closed):

Perhaps using namespaced keys and filtering through vm.$children and checking for a match with the vm.$vnode.key? Although you can have regular HTML elements as children, so that would have to be checked as well.

@alexsasharegan
Copy link
Member

alexsasharegan commented May 18, 2017

Think like so: every transition element needs a unique key, so prefix it with trans- or whatever. Then loop like so:

import Vue from 'vue'
const transitionRegex = /^trans-.+/

{
  computed: {
    numTransitionEls() {
      return this.$children.filter(node => node instanceof Vue && transitionRegex.test(node.$vnode.key)).length
    }
  }
}

Now you don't have to manually keep track of how many transition elements there are. But can't regular HTML elements also get keyed for transitions?

@alexsasharegan
Copy link
Member

Yeah, it gets way more tricky when you dive in. The vm's child will be the transition-group. Manually is probably the easiest thing you can do.

@alexsasharegan
Copy link
Member

There's some good stuff inside the transition group at transitionGroupVM.$options._renderChildren, but best to respect those props as private.

@tmorehouse
Copy link
Member

Yeah, the only private prop you should trust is this.__vue__

@tmorehouse
Copy link
Member

The original might be due to scoped CSS and certain bundlers not "scoping" the CSS.

Maybe if we add a new class to the component and CSS (say .b-modal), to "scope" the CSS display property.

@riker09
Copy link
Contributor

riker09 commented Jun 1, 2017

Hello there. I recently made it back from my parent time (Elternzeit) which was basically a two month break from work. I used version 0.9.x before and modals were working fine. Now I updated this library on my project and modals don't work anymore? Is there a workaround yet?

@alexsasharegan
Copy link
Member

@riker09, I think the thing that is still broken is CSS for the .modal display property. The rollup bundling doesn't seem to respect the scoped attribute for me. Are you getting the backdrop working on show, but no modal content? If so, add this to your CSS (that's loaded after bootstrap):

.modal { display: block; }

@tmorehouse
Copy link
Member

tmorehouse commented Jun 23, 2017

@mosinve @alexsasharegan @pi0

Just thinking... rather than using v-show on modal, what about using :style= to set display to none or block, which might negate the need for the scoped CSS?, or would this break the transitions?

@mosinve
Copy link
Member

mosinve commented Jun 23, 2017

v-show or v-if - allow to use native Vue transitions.
If we set style directly, then we must implement custom transitions.
Such solution was at the beginning of the modal component.

@tmorehouse
Copy link
Member

Ah, I wasn't sure about that. good to know.

@mosinve
Copy link
Member

mosinve commented Jun 23, 2017

i think, what if we will change display to block not at the <style>, but at some code point (dynamically)?

@tmorehouse
Copy link
Member

Hmmm.... that might work.

@tmorehouse
Copy link
Member

@kollors are you still having this issue with the latest release (v0.17.2)?

@sushain97
Copy link

sushain97 commented Jul 3, 2017

I'm experiencing this issue with v0.17.1. My workaround is as described above but it of course borks the pretty transition :(

@alexsasharegan
Copy link
Member

I don't believe the slide from top transition is built into the component due to using Vue transitions. It might be possible, but I believe the complication is Vue's show directive uses inline display: none

@alexsasharegan
Copy link
Member

Perhaps I can look into the rollup plugin responsible for bundling the CSS. It isn't currently respecting the scoping.

@mosinve
Copy link
Member

mosinve commented Jul 6, 2017

Slide from top transition is a default behavior from BS4.
Vue v-show uses inline display:none to hide element, and just remove it to show.
Otherwise at BS4 inline style display:none used to hide modal, and inline display:block used to show with class .show

@alexsasharegan
Copy link
Member

Looks like the current version of the rollup-plugin-vue now supports generating the pseudo-scoped css. I would wager the issues around .modal {display: block;} should now be gone due to the scoping specificity.

I'm going to close this as the problem should be solved, and this issue is overcrowded and stale. If your problem persists, please upgrade to the latest version of bootstrap-vue v0.18.0. If your problem still persists, please open a new issue with any updated details.

@riker09
Copy link
Contributor

riker09 commented Jul 26, 2017

I just wanted to confirm that updating to 0.18.0 fixed the issue, my modals are working again. yay!

@mariusa
Copy link
Contributor

mariusa commented Sep 3, 2017

Got the same issue with 1.0.0-beta.7, fixed by adding
.modal.show { display:block; }

@lakshyabatman
Copy link

Hello, I'm facing the same issue with the 2.13 version.

vue-issue

@tmorehouse
Copy link
Member

@lakshyabatman Make sure you are including BootstrapVue's custom SCSS/CSS after Bootstrap's SCSS.

@lakshyabatman
Copy link

Both Scss files are in order and placed on the global style sheet. @tmorehouse

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants