use webpack JS package in twig file - javascript

I'm really beginner in twig and webpack.
I install some packages with yarn and use them inside app.js, but for some reasons I need some method of that packages inside of my twig files.
when I try to call a function, get error.
for example I install boostrap-select package and require that in app.js
// app.js
var $ = require('jquery');
require('bootstrap/dist/js/bootstrap');
require('bootstrap-select/dist/js/bootstrap-select');
$(document).ready(function () {
$('.selectpicker').selectpicker({});
})(jQuery);
everything is fine and work perfect but when call this package function inside of twig file like this
{% block javascripts %}
<script type="text/javascript" src="{{ asset('b/app.js') }}"></script>
<script>
$('.selectpicker').selectpicker({});
</script>
{% endblock %}
I get error.
Uncaught TypeError: $(...).selectpicker is not a function
after search in google for one day I found out can not do that ... and I must do some extra things ... every examples are around of jQuery.
what about other packages? how define a function from yarn packages globally and use that in twig file.
I try all of this solutions but not work for me
funtionName = require('package path')
window.functionName = functionName;
global.funtionNmae = functionName;
anyone has any solutions, I just need call a function in twig :(.

"This error happens when your code (or some library that you are using) expects $ or jQuery to be a global variable. But, when you use Webpack and require('jquery'), no global variables are set."
Symfony Frontend - FAQ and Common Issues
jQuery and Legacy Applications
// app.js
var $ = require('jquery');
// ...
global.$ = global.jQuery = $;

Related

Ruby on Rails 6 Webpack with Javascript libraries

I am building a new project in Rails 6. I have a front-end library I want to use (#tarekraafat/autocomplete.js) that is installed by yarn and exists in my node_modules directory, but is not being made available to other JS code in the browser. Here is what I have set up currently:
/package.json:
"dependencies": {
"#tarekraafat/autocomplete.js": "^8.2.1"
}
/app/javascript/packs/application.js:
import "#tarekraafat/autocomplete.js/dist/js/autoComplete.min.js"
/app/views/.../example.html.erb
<script type="text/javascript">
window.onload = () => {
new autoComplete({
[...]
});
};
</script>
I am getting an error in the browser pointing to the new autoComplete():
Uncaught ReferenceError: autoComplete is not defined
Some reading seems to indicate that I need to modify the /config/webpack/environment.js file, in which I have tried various versions of the following with no luck (including restarting the dev server):
/config/webpack/environment.js:
const { environment } = require('#rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
autoComplete: 'autocomplete.js'
})
);
module.exports = environment
First, what do I need to do to add this library so it can be used correctly? Second, as someone who has not directly used webpack previously, what is the function of adding this definition to the environments.js file, and why don't I need to do it for some libraries (bootstrap, popper) but I do for others (jquery, and maybe autocomplete.js)?
In Webpacker, the usage of this library would be as follows:
// app/javascript/src/any_file.js
import autoComplete from "#tarekraafat/autocomplete"
new autoComplete(...)
// app/javascript/packs/application.js
import "../src/any_file"
This alone does not import the autoComplete variable into the global scope. To do that, the simplest thing is assign the variable to window from within your webpack dependency graph.
// app/javascript/src/any_file.js
import autoComplete from "#tarekraafat/autocomplete"
window.autoComplete = autoComplete
As an aside, you don't need to use the ProvidePlugin configuration for this library. The ProvidePlugin says: “add this import to all files in my dependency graph.” This might be helpful for something like jQuery to make legacy jQuery plugins work in webpack. It is not necessary to make your autocomplete lib work

Importing and using NPM package

I am trying to use a node module called "tagify" in my node.js app. In the readme file for the package (https://www.npmjs.com/package/#yaireo/tagify#installation) it says to setup as follows:
npm i #yaireo/tagify --save
// usage:
import Tagify from '#yaireo/tagify'
var tagify = new Tagify(...)
I ran the npm command and it installed fine. My EJS file has this (not shown is the input name="tags" element):
<script>
import Tagify from '#yaireo/tagify';
var input = document.querySelector('input[name=tags]'),
// init Tagify script on the above inputs
tagify = new Tagify(input);
</script>
When I load the page, I get this in the console:
Uncaught SyntaxError: Unexpected identifier (reference to 'import' line)
I'm very new to this and very confused. I've been searching the internet for two hours and can't figure out the basic task of getting this package to work. If this questions is redundant, please direct me elsewhere, because I don't know where to go.
<script src="https://cdn.jsdelivr.net/npm/#yaireo/tagify#2.9.7/dist/tagify.min.js"></script>
<script>
var input = document.querySelector('input[name=tags]'),
// init Tagify script on the above inputs
var tagify = new Tagify(input);
</script>
This code is not raw. you need to use technologies like babel or webpack to use it. easy to run this link will be enough

Jquery plugins giving errors $(...).ionRangeSlider not a function

I am trying to use jquery plugins in my react application. Every time I try to use some jquery third party plugin, I get an error saying $(...).somePlugin not a function. Currently I am trying to use ionRangeSlider. It is giving me error
Uncaught TypeError: (0 , _jquery2.default)(...).ionRangeSlider is not a function
js file
import $ from 'jquery'
import 'bootstrap-tagsinput'
class AddTagSection extends Component {
componentDidMount=()=> {
this.slider = $(this.inputSlider).ionRangeSlider();
}
<div className="irs-wrapper">
<input type="text" ref={node=>this.inputSlider=node} className='input-slider' id="ionSlider-newTag" name="ionSlider"/>
</div>
Below is the function which is getting called in ionRangeSlider.js (plugin)
$.fn.ionRangeSlider = function (options) {
return this.each(function() {
if (!$.data(this, "ionRangeSlider")) {
$.data(this, "ionRangeSlider", new IonRangeSlider(this, options, plugin_count++));
}
});
};
As far as I have read on web, this is a multiple jquery clashes issue.
About my Application: My project has jquery installed via npm. So there is one jquery present in package.json. I have also included jquery in scripts in my index.jade file. So there is another one there.
This is not an issue of jquery placed after plugin's js file. I placed jquery at the top in the scripts of index.jade file.
block head_scripts
script(src='https://code.jquery.com/jquery-3.2.1.min.js')
script(src='/public/ion.rangeSlider.js')
link(href='/public/normalize.css' rel="stylesheet")
link(href='/public/ion.rangeSlider.css' rel="stylesheet")
link(href='/public/ion.rangeSlider.skinFlat.css' rel='stylesheet')
I also tried noConfilct. But that too didn't work.
var $ = jQuery.noConflict();
$( ".slider" ).ionRangeSlider();
I tried including jquery in my webpack config.js file
new webpack.ProvidePlugin({
React: 'react',
$: 'jquery',
jQuery: 'jquery'
}),
Nothing from the above worked. Everytime I got the same error.
How can I solve this?
If your project contains a different version of jQuery than the one specified in ionRangeSlider package.json dependencies and you're using yarn to install your project's dependencies and webpack to bundle the project, then this might be the source of the problem. Yarn will install node_modules even in ion-range-slider folder, which will cause that the webpack will build the project with your jQuery, as well as with the one in ion-range-slider/node_modules. Hence the jQuery versions clash. ionRangeSlider initiates with the first jQuery and your project's jQuery won't contain it.
It's kind of a fault of ionRangeSlider developer because he should not specify the jQuery in dependencies, but instead in peerDependencies.
try changing internal url to external url for rangeslider
<script src="http://ionden.com/a/plugins/ion.rangeSlider/static/js/ion-rangeSlider/ion.rangeSlider.js"></script>
<link rel="stylesheet" href="http://ionden.com/a/plugins/ion.rangeSlider/static/css/ion.rangeSlider.css" />
then do import Slider from 'react-rangeslider' if not using the es6 transpiler then do var Slider = require('react-rangeslider')
I also had this error, looks like a Jquery version conflict please try downgrading ion-rangeslider in package.json "ion-rangeslider": "2.2.0".

Integrate jQuery into a electron app

I'm trying to add jquery functionality to a desktop app written in electron
Using the electron-quick-start repo i'm adding the downloaded jquery file to the main.html file like so:
<script> require("./jquery.min.js"); </script>
or so:
<script>window.$ = window.jQuery = require('./jquery.min.js');</script>
Then in the index.js file i'm adding code in the createWindow function, since that seems the proper place, but to be honest any place i try gets me the same error more or less.
mainWindow.$ is undefined and the same goes for BrowserWindow and app
mainWindow is defined inside the createWindow function like so:
mainWindow = new BrowserWindow({width: 800, height: 600})
and BrowserWindow is declared on top of the file like so:
const BrowserWindow = electron.BrowserWindow
Any idea where i'm going wrong, what declarations i should change/add?
Thanks in advance
While using electron, some additional symbols are also inserted into DOM causing problems. So, you can use jquery as follow
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js" onload="window.$ = window.jQuery = module.exports;"></script>
Notice the code inside "onload".
When you call require inside index.js, or the main process, it's looking for the node module. So you'll need to install jQuery via npm and save it as a dependency in your apps package.json file.
npm install jquery --save
Then your index.js should theoretically see it just fine using
let $ = require('jquery');
mainWindow.$ = $;
Refer to the Node.JS section for installing jQuery. This is what Electron uses.
--
OLD ANSWER
Inside your main.html, just include the JavaScript like you would any traditional JS file.
<script src="./jquery.min.js"></script>
To integrate jQuery into your Electron Application follow these simple steps
Step 1: Run in terminal
npm install jquery --save
Step 2: Add this line to your angular.json or angular-cli.json file
"build": {
"options": {
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.js", //add this line
"node_modules/bootstrap/dist/js/bootstrap.min.js"
],
...
...
}
}
Step 3: Finally add this line to your index.html file
<!-- Need this for jQuery electron -->
<!-- Insert this line above script imports -->
<script>if (typeof module === 'object') {
window.module = module;
module = undefined;
}</script>
<!-- Insert this line after script imports -->
<script>if (window.module) module = window.module;</script>
</head>
You can also use this template

Run function loaded from ecmascript 6 module

I try to use ecmascript 6 modules system for first time. I use traceur compiler. Given two es6 files:
// app.js
export function row() {
alert('row');
}
// init.js
import { row } from 'public_js/app';
row();
Traceur (I use grunt-traceur task) compiles them to:
// app.js
System.register("public_js/app", [], function() {
"use strict";
var __moduleName = "public_js/app";
function row() {
alert('row');
}
return {get row() {
return row;
}};
});
// init.js
System.register("public_js/init", [], function() {
"use strict";
var __moduleName = "public_js/init";
var row = System.get("public_js/app").row;
row();
return {};
});
I include compiled version of init.js to my HTML via simple script tag:
<script src="/path/to/compiled/init.js" type="module"></script>
And nothing happens. I don't see my alert. What am I doing wrong?
By pre-compiling your code as modules to ES5, you are now taking it out of the world of the automatic import/module loading system in ES6 and you need to use ES5 mechanisms to load it. So, you need to include the compiled code without the type=module attribute and then get() the module that kicks off the rest of the world.
So, the following works for me:
<script src="/path/to/compiled/app.js"></script>
<script src="/path/to/compiled/init.js"></script>
<script>
System.get('public_js/init');
</script>
Since you are pre-compiling the code, I recommend that you concatenate all of the compiled code into a single JS file to avoid including them all.
If you use Traceur without compiling your code first, then you can live within the ES6 constructs. This includes type="module" and/or import 'module-name'.
Edit
Thinking about this further, app.js is correctly compiled as a module. init.js, however, doesn't need to be compiled as a module. You are compiling the code with the --module flag. If, instead, you compile init.js with the --script flag, it will not encapsulate the init code as a module, and you don't need to call System.get by hand. Just something to think about.

Categories

Resources