I tried to require materialize in Vue and Laravel
in bootstrap.js I have
window.Materialize = require('materialize-css');
in App.vue component I have
mounted(){
Materialize.toast('I am a toast!', 4000)
}
and received
"Uncaught ReferenceError: Materialize is not defined"
message.
Either drop a script tag with materialize js or, make sure jquery is loaded before requiring materialize.
I suppose you have a browserify setup and if you do you can do something like that:
require('jquery')(window);
require('materialize-css')(window);
Or something like that:
global.jQuery = require('jquery')
global.Materialize = require('materialize-css')
Or import globally jQuery only then simply var Materialize=require('materialize-css') and use the variabile instead.
For webpack setups add a plugin for the stuff you have installed via npm and need globally:
plugins:[
new webpack.ProvidePlugin({
$: "jquery",
jQuery:'jquery',
jquery:'jquery'
}),
],
Related
I have a Rails 6 application working with the asset pipeline, which I'm trying to move to webpacker in order to use turbo. So far I've managed to correctly set up turbo. The app uses some bootstrap plugins though, hsSideNav among them, and I'm getting an error I haven't been able to solve: Uncaught TypeError: $(...).hsSideNav.
I've placed a copy of the hsSideNav file in app/javascript/hs-navbar-vertical-aside/hs-navbar-vertical-aside.js.
Here's my app/javascript/packs/application.js:
require("#rails/ujs").start()
import "#hotwired/turbo-rails"
require("#rails/activestorage").start()
require("channels")
require("jquery")
import 'bootstrap/dist/js/bootstrap'
import 'bootstrap/dist/css/bootstrap'
require("hs-navbar-vertical-aside/hs-navbar-vertical-aside")
And my config/webpack/environment.js:
const { environment } = require('#rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery/dist/jquery.min',
jQuery: 'jquery/dist/jquery.min'
})
)
module.exports = environment
What am I doing wrong? Is there another way to load jQuery plugins in webpacker?
It has been several days now that i've been trying to make work the easy-autocomplete package with my Rails 6 application.
I followed this tutorial.
I tried some solutions, like this one but it still doesn't work.
In all my attempts the error displayed on the web console is: Uncaught TypeError: $(...).easyAutocomplete is not a function.
Here is my application.js:
require("#rails/ujs").start();
require("turbolinks").start();
require("#rails/activestorage").start();
require("channels");
require("bootstrap");
// Stylesheets
require("../stylesheets/main.scss");
require("easy-autocomplete");
I don't need to require('jquery') since it's included with the Bootstrap package. I use JQuery functions all over my app and haven't got any errors.
My application.scss:
#import 'easy-autocomplete/dist/easy-autocomplete';
#import "variables";
* {
font-family: $syne-font
}
And my custom js code:
$(document).on("turbolinks:load", function () {
var options = {
data: ["otto", "hans", "paula"],
};
$("#city_search").easyAutocomplete(options);
});
I would advise that you install jQuery using the yarn and also do he configuration in the config/webpack/environment.js. once done require the jQuery as expected from the tutorial.
Try it and it should work.
So the easy-autocomplete lib is not maintained anymore.
I did find a workaround by using the webpack-jquery-ui lib, here's an example of implementation:
app/javascript/packs/application.js
require("#rails/ujs").start();
require("turbolinks").start();
require("#rails/activestorage").start();
require("channels");
require("bootstrap");
// Stylesheets
require("../stylesheets/main.scss");
global.$ = require("jquery");
require("webpack-jquery-ui");
require("webpack-jquery-ui/css");
$(function () {
$(".my-input-automcompleted").autocomplete({
source: "/autocomplete",
});
});
But IMHO it's better to use Stimulus and the stimulus-autocomplete lib now !
I'm using Laravel-mix and Webpack to combine and control scripts for a site.
I'm my main app.js I have these lines:
var jQuery = require( 'jquery' );
require( './vendor/polyfill-library.min.js' );
require( './vendor/polyfill-init.js' ); // which is using jQuery
In polyfill-init.js I'm doing this: jQuery( document ).ready( .... That results in this error:
Uncaught ReferenceError: jQuery is not defined
I also get this error if I try and mix it together using Laravel-mix, by adding this to my webpack.mix.js:
mix.js( [
'resources/js/app.js',
'resources/js/vendor/polyfill-library.min.js',
'resources/js/vendor/polyfill-init.js',
], 'assets/js/app.js')
I assume the error is because Webpack keeps the required/imported scripts in seperate namespaces/environments, so no conflicts occur. And that's all fine and dandy, - but I don't know how to combine two required/imported scripts, so they're using the same namespace/environment.
... If I copy all the code into app.js (instead of requiring it), then it works, but it's not pretty. Not pretty at all.
I looked at Webpack's documentation to see if there's a way to define a dependency for an imported/a required script, but either it's not there; or I'm not getting it.
I also looked at the 7 billion ways that this post suggest that I'd do it, - but I'm trying to figure out how Webpack/Laravel-mix want me to do it.
So my question is... Are there a way that I can do something like this:
var jQuery = require( 'jquery' );
require( './vendor/polyfill-library.min.js' );
require( './vendor/polyfill-init.js' ); // which is using jQuery
... and let Webpack know, that polyfill-init can use jQuery?
You can use provideplugin:
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
Try window.jQuery = require( 'jquery' );
polyfill-init.js probably looks for jQuery in global scope while the var jQuery is only available in the local scope of this module.
U should externalize JQuery from the webpack.
index.html
<script
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous">
</script>
webpack.config.js
module.exports = {
//...
externals: {
jquery: 'jQuery'
}
};
polyfill-init.js
import $ from 'jquery';
Refer more details here https://webpack.js.org/configuration/externals/
I'm trying to add popovers from bootstrap 4 into my vue.js app. I could probably use something like https://www.npmjs.com/package/vue-popperjs, but I'd like to make it work old way, without using additional libraries (just so I could figure out the principle on how to do that)
I have installed Popper.js with npm install --save popper
In my webpack.config.js I also have:
plugins: [
new WebpackNotifierPlugin(),
new webpack.ProvidePlugin({
_: 'lodash',
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
jQuery: 'jquery',
popper: 'popper'
})
],
Then I'm tring to build a vue component:
<template>
....
<button type="button" class="btn btn-link" title="" data-container="body" data-toggle="popover" data-placement="bottom" data-original-title="Connection String" aria-describedby="popover253231">
Click to show
</button>
....
</template>
<script>
const _ = require("lodash");
const $ = require("jquery");
// This doesn't work
//const poppper = require("popper");
var d = {
data() {
...
},
created: function() {
// Load data with $http module
},
updated: function() {
$(function () {
$('[data-toggle="popover"]').popover()
})
},
};
export default d;
</script>
The button will appear only after load, because it has a parent element that has v-for binding on the data loaded with ajax.
I don't know how to require popper, so the line $('[data-toggle="popover"]').popover() resolves (it cannot find function popover())
Also the line const popper = require("poppper") doesn't work either with the error Module parse failed: 'return' outside of function. My guess is that I can't load popper with require, because it is not built for it.
After some struggling and trying completely random ideas, I had the one that worked. Turns out the problem was that I was using bootstrap that is installed into ASP.NET MVC as a bundle (so it added it as <script src='..'/> to the page).
So after I:
npm install --save bootstrap
Added bootstrap: 'bootstrap' to ProvidePlugin definition in webpack.config.js
Added require("bootstrap") into my vue file
It started to work. I didn't even have to require 'popper' for some reason - probably because bootstrap already contains it?
Though I am still not sure whether this is a proper way to solve the problem
Using Vuejs Directive
const bsPopover = (el, binding) => {
const p = []
if (binding.modifiers.focus) p.push('focus')
if (binding.modifiers.hover) p.push('hover')
if (binding.modifiers.click) p.push('click')
if (!p.length) p.push('hover')
$(el).popover({
animation: false,
placement: binding.arg || 'top',
trigger: p.join(' '),
html: !!binding.modifiers.html,
content: binding.value,
});}
Vue.directive('tooltip', {
bind: bsTooltip,
update: bsTooltip,
unbind (el) { $(el).tooltip('dispose') }});
In my project I want to use RequireJS and bootstrap my app as follows:
requirejs.config({
baseUrl: 'scripts/vendor',
paths: {
jquery: [
'https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min',
'jquery'
],
angular: [
'http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min',
'angular'
],
app: '../app'
}
});
require(['require', 'jquery', 'angular', 'app'], function(require, $, angular, app) {
console.log(require);
console.log($);
console.log(angular);
console.log(app);
});
On my index.html only RequireJS is loaded via script tag, where the RequireJS loads the above code.
What works:
- in my Network monitor I can see that RequireJS, jQuery, Angular and app are loaded
- The console.log messages print correct for require, jQuery and app
The angular object is somehow undefined. But if I don't load it from CDN and use my local load, it works! The local file is a RequireJS wrapper that looks like this:
define(['/components/angular/angular.min.js'], function () {
return angular;
});
How do I get this work with Angular'S CDN? Or does this depend on support from Angular?
First, you are confusing "paths" with "shim"
Path is good, don't go for "shim" behavior. But, you need to make your "paths" proper:
paths: {
jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min',
// NOTE: angular is "plain JS" file
angular: 'http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min',
app: '../app'
}
Then, you need to let go of the need to have something returned to you... Just "use the force, Luke" :) and expect the right globals to be there when you need them:
require(['jquery', 'app', 'angular'], function($, app, thisValueDoesNotMatter) {
// you don't need to wrap "require" Just use global
console.log(require);
console.log($);
console.log(app);
// note, angular is loaded as "plain JavaScript" - not an AMD module.
// it's ok. It returns "undefined" but we just don't care about its return value
// just use global version of angular, which will be loaded by this time.
// because you mentioned it in your dependencies list.
console.log(window.angular);
});