jQuery UI widgets stop working after minifying - jquery-ui

Recently I had to update our jquery version from 1.x to 3.5. With that I also had to update Jquery UI to 1.12. I used the opportunity to import our js dependencies as node_modules instead of just having a copy in our repository.
When running our WebApp within the IDE everything works fine and as expected. However, as soon as I build the .exe with pyInstaller (running a grunt task to minify everything into a single app.min.js), I get the error message "g.sortable is not a function". The same problem occurs with jquery.transit.
package.json:
{
"dependencies": {
// snip
"jquery": "3.5.1",
"jquery-ui": "1.12.1",
"jquery.iframe-transport": "1.0.0",
"jquery.transit": "0.9.12",
}
}
configuration.js:
require.config({
paths: {
// snip
'ui.sortable': '<...>/3rdparty/js/node_modules/angular-ui-sortable/dist/sortable',
'jquery': '<...>/3rdparty/js/node_modules/jquery/dist/jquery',
'jquery.transit': '<...>/3rdparty/js/node_modules/jquery.transit/jquery.transit',
'jquery-ui': '<...>/3rdparty/js/node_modules/jquery-ui-dist/jquery-ui',
}
})
Gruntfile.js:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('<...>/3rdparty/js/package.json'),
requirejs: {
compile: {
options: {
baseUrl: '<...>/js',
mainConfigFile: '<...>/js/configuration.js',
optimize: 'none'
}
}
},
ts: { ... },
sass: { ... },
uglify: {
'js': {
files: [
{
expand: true,
src: [
'app/**/*.js',
'!app/**/3rdparty/**/*.js',
'!app/<...>/js/configuration.js',
'!app/<...>/js/patch.js'
]
}
],
options: {
compress: true,
mangle: false
}
}
}
});
};
Again, the javascript files seem to work together properly as there is no problem when I start the webservice in pycharm. It's only when I compile and minify everything that the jquery UI widgets stop working. Other external libraries for whose I started using npm work perfectly fine.
I am kinda clueless at this point.

So, the solution to my problem was to just
import 'jquery.transit';
import 'jquery.ui';
In one of my TypeScript files. Apparently in the whole project that never happened anywhere. It worked before my updates because the jqueryUI version we used had the AMD part of it commented out.

Related

Is it possible to use webpack dynamic imports with rails asset pipeline?

My problem is that after the bundles are emitted by webpack, rails assets pipeline adds hashes to the file names so it's impossible to dynamically import them
My current setup is
import modal from "./modal"
button.addEventListener("click", () => {
new modal().open();
}
While I want:
button.addEventListener("click", () => {
const modal = (await import(/* webpackChunkName: "modal" */ "./modal")).default;
new modal().open();
}
But in this case, a request would fire to get dist/modal.bundle.js, without rails hash, while its under dist/modal.bundle-g454545g4v45geg.js. The bundle names are resolved with asset_path(...) in the html,
But I don't think there is a way of telling js code what the hash is... Am I missing something? Is there any way to use dynamic imports with Rails Asset Pipeline?
My webpack.config.js:
module.exports = [
{
entry: {
main_layout: "./app/assets/layouts/main_layout.ts",
home_page: "./app/assets/pages/home/home.ts"
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "app", "assets", "dist")
},
...
I've never tried this but the docs are clear webpacker supports erb.
Run rails webpacker:install:erb
Change your appliaction.js pack to application.js.erb
You should now be able to call <%= asset_path("modal.bundle.js") %> within your pack.

RAILS 6 - how to use EasyAutocomplete

I try the last hours to integrate EasyAutocomplete into RAILS 6. But not so easy.
What I did :
Install Javascript Package with yarn:
# yarn add easy-autocomplete
Add this in the file app/javascript/packs/application.js
import “easy-autocomplete”
Add this in the file app/assets/stylesheets/application.css
*= require easy-autocomplete
*= require easy-autocomplete.themes
Then start the Rails Server and refresh the Web Page.
Then try to use it. Go into the developer console and type :
var options = {
data: ["otto", "hans", "paula"]
};
$("#task_name_search_field").easyAutocomplete(options);
task_name_search_field was previously defined as id :
<input type="search" class="form-control" id="task_name_search_field">
I got this message:
TypeError: $(...).EasyAutocomplete is not a function
Any idea ?
I had the same problem. Turbolinks does not give access to the script, the code needs to be run after it is loaded, something like this:
document.addEventListener("turbolinks:load", function() {
var options = {
data: ["otto", "hans", "paula"]
};
$("#task_name_search_field").easyAutocomplete(options);
});
In order for the autocomplete to work, you need to add a script file to the application.js like this:
require("packs/youfile")
If it helps you, here is an example of my code:
document.addEventListener("turbolinks:load", function() {
$input = $("[data-behavior='autocomplete']")
var options = {
getValue: "full_name",
url: function(phrase) {
return "/search.json?q=" + phrase;
},
categories: [
{
listLocation: "cameras",
header: "<strong>Cameras</strong>",
}
],
list: {
onChooseEvent: function() {
var url = $input.getSelectedItemData().url
$input.val("")
Turbolinks.visit(url)
}
}
}
$input.easyAutocomplete(options)});
I suppose you wouldn't have included jquery in your application.js. You need to do explicitly as it doesn't get included automatically with rails 6 app.
I ran into a similar issue. I'm a n00b at Webpacker, but by default it doesn't seem to compile in the same order in which plugins are included.
To get around the issue I did this workaround which just wraps the plugin code in an anonymous jQuery function, like so:
(function($) {
//Eac plugin code
})(jQuery);
https://github.com/pawelczak/EasyAutocomplete/issues/200#issuecomment-212277620
Maybe there is a way in the configs to force compilation in the correct order. This looks promising https://stackoverflow.com/a/43005332/148390
Add script-loader to package.json then add
import 'script-loader!jquery/dist/jquery.min'
in app/javascripts/application.js
Check in your browser that $().jquery yields a proper result.

Need help importing Electron in Aurelia app

I'm using one of the skeleton-navigation, skeleton-typescript.
I'm trying to import Electron.remote so I can close the electron window from within the JS. This is what I have in config.js:
paths: {
"*": "dist/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*",
"node_modules:*": "node_modules/*"
},
map: {
"electron": "node_modules:electron/index.js",
}
and in my JS file I import like this:
import * as electron from 'electron';
but I get error regarding fs.js not found in path:
Error: (SystemJS) XHR error (404 Not Found) loading http://localhost:9000/dist/fs.js
Can someone help on how I can fix this issue?
depends on the loader/bundler strategy you picked
electron has nodes require() defined.
you want to redefine that before booting up your app that relies on AMD require
https://github.com/electron/electron/issues/303
TL;DR
you want to assign nodes require to another variable
window.node_require = require
and then delete the original
delete require
only after this you reference a script with your app
and inside your app you use node_require() to load node modules
here is the relevant comment on: supporting electron modules in aurelia
This is how I fixed my issue for Aurelia Skeleton Typescript with JSPM & SystemJS: I put in index.html head which is my entry:
<script type="text/javascript">
window.node_require = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
Then I set nodeIntegration: true for BrowserWindow.
And in my TS file:
declare global {
interface Window {
node_require: any;
}
}
var remote: any;
if (typeof window.node_require == "function") {
remote = window.node_require('electron').remote;
}
closeApp() {
var window = remote.getCurrentWindow();
window.close();
}

Swagger UI - Hide definition URL path

Using Swagger - UI 3XX
I would like to simply know if this is possible and if so, how:
We currently have a need to hide the definition URL path that Swagger - UI displays.
I know it's not possible to remove this URL and I'm not looking to do that, all I'm wanting to do is to hide /mask the text box from the client viewing this page.
Looking at the new Swagger docs here, there are some awesome tricks and extras you can add, however - nothing I can see in relation to my query.
I'm pretty sure, I could interrogate the HTML, find the id of the element in question and manually change the display of it within the index.html, I would much rather prefer using a build in method, if one exists before getting to that possible solution.
i.e. Something like this is possible and works:
<style> .download-url-input { display: none !important; } </style>
Is this even possible?
In Swagger UI 3.x, you can hide the top bar in one the following ways.
Option 1
Edit dist\index.html and find this code:
const ui = SwaggerUIBundle({
url: "http://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
Remove layout, SwaggerUIStandalonePreset and SwaggerUIBundle.plugins.DownloadUrl, so that the constructor looks like this:
const ui = SwaggerUIBundle({
url: "http://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis
]
})
(Source)
Option 2 - Recompile Code
You can also recompile Swagger UI without the top bar plugin as explained here and rebuilding it. You will need Node.js 6.x and npm 3.x.
Edit src/standalone/index.js and remove TopbarPlugin from presets:
// import TopbarPlugin from "plugins/topbar" // <----------
import ConfigsPlugin from "plugins/configs"
// the Standalone preset
let preset = [
// TopbarPlugin, // <----------
ConfigsPlugin,
() => {
return {
components: { StandaloneLayout }
}
}
]
Rebuild Swagger UI – in the project's root directory run
npm install
then
npm run build
Now your dist\index.html does not have a top bar.
For the version 3.x add slice function to:
SwaggerUIStandalonePreset.slice(1)
In the version 4.x (inside swagger-initializer.js file) set layout to "BaseLayout"
window.ui = SwaggerUIBundle({
url: "./swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "BaseLayout" // <<< here
});

How to shim jQueryUI with RequireJS?

I prefer to use the require, jQuery and jQueryUI as seperate scripts without modifying them.
I get the error: (inside jquery-ui.min.js:6)
Uncaught ReferenceError: jQuery is not defined
jQuery itself works and can be used, however jQuery-UI doesnt work.
How can I solve it without using require-jquery by just modying main.js
Here my current main.js
requirejs.config({
paths: {
'jquery': 'lib/jquery/jquery',
'jqueryui': 'lib/jquery-ui/jquery-ui.min'
},
shim: {
'jquery': {
exports: 'jQuery'
},
'jqueryui': {
deps: ['jquery']
}
}
});
require([
"jquery",
"jqueryui"], function(jQuery) {
});
I experimented with various things like the shim init function, which however is not even called before the exception happens.
Any ideas, or impossible?
Update: fixed the code above. Its working now!
The error is in your code, you wrote this
'jqueryui:': {
deps: ['jquery'],
}
do you notice the extra : . Remove it and then your code is working

Resources