istvan-ujjmeszaros / bootstrap-touchspin

A mobile and touch friendly input spinner component for Bootstrap.
Other
501 stars 155 forks source link

How to use in electron app? #107

Open chinenual opened 4 years ago

chinenual commented 4 years ago

I believe this is due to the way jquery initializes itself when running in electron. I am able to use TouchSpin when I test in a static page directly from a browser ("file:///mytest.html"), but when I run in my Electron based application, it seems that touchspin has not properly initialized itself -- the console shows:

Uncaught TypeError: $(...).TouchSpin is not a function

I am able to use jquery in my other js files by using the onload technique mentioned in a comment in this post: https://techsparx.com/nodejs/electron/load-jquery-bootstrap.html

My header:

    <link rel="stylesheet" href="static/css/bootstrap.min-darkly.css">
    <link rel="stylesheet" href="static/css/jquery.bootstrap-touchspin.css"/>
    <link rel="stylesheet" href="static/css/base.css">

    <!-- jQuery/Electron "bug": https://techsparx.com/nodejs/electron/load-jquery-bootstrap.html -->
    <script src="static/js/jquery-3.4.1.min.js" type="text/javascript"
        onload="window.$ = window.jQuery = module.exports;"></script>
    <script src="static/js/popper.min.js"></script>
    <script src="static/js/bootstrap.min.js"></script>
    <script src="static/js/jquery.bootstrap-touchspin.js"></script>

and I'm calling TouchSpin from one my scripts like this:

$('.ts').TouchSpin({ 
    min: 0, max: 10
});

I am not enough of a javascript programmer to debug how the closure works in touchspin's js.

Ideas for how I can get touchspin to initialize itself under electron?

istvan-ujjmeszaros commented 4 years ago

I am not using electron, but can you try this instead of adding onload to the jQuery script tag?

<link rel="stylesheet" href="static/css/bootstrap.min-darkly.css">
<link rel="stylesheet" href="static/css/jquery.bootstrap-touchspin.css"/>
<link rel="stylesheet" href="static/css/base.css">
<script src="static/js/jquery-3.4.1.min.js"></script>
<script>
window.jQuery = window.$ = require('jquery');
</script>
<script src="static/js/popper.min.js"></script>
<script src="static/js/bootstrap.min.js"></script>
<script src="static/js/jquery.bootstrap-touchspin.js"></script>

You can also try to move all the script tags to the end of the html document if this doesn't work..

chinenual commented 4 years ago

Additional debugging details - hope this helps someone who better understands how the module initializes itself.

I moved the import of touchspin's js to the bottom of the page and added some console logging to see if I could figure out what was wrong about the values it seems to be using on init -- I don't see anything wrong... jQuery is set and module.exports isnt null:

    <script type="text/javascript">
          console.log("before $: " + $);
      console.log("before jQuery: " + jQuery);
      console.log("before typeof define: " + typeof define);
      console.log("before typeof module: " + typeof module);
      console.log("before module.exports: " + module.exports);
          console.log("make sure jquery selector works: " + $('body'));
          require("./static/js/jquery.bootstrap-touchspin.js");
      console.log("AFTER");
    </script>

emits this to the log:

before $: function(e,t){return new k.fn.init(e,t)}
index.html:210 before jQuery: function(e,t){return new k.fn.init(e,t)}
index.html:211 before typeof define: undefined
index.html:212 before typeof module: object
index.html:213 before module.exports: function(e,t){return new k.fn.init(e,t)}
index.html:214 make sure jquery selector works: [object Object]
index.html:216 AFTER
index.html:217 Uncaught TypeError: $(...).TouchSpin is not a function
    at index.html:217
chinenual commented 4 years ago

@istvan-ujjmeszaros - I tried changing the onload attribute to the inline script as you suggested (I tried both require('jquery') and require('jQuery')). This generates an error

Uncaught Error: Cannot find module 'jquery'
Require stack:
- /Users/tynor/src/synergize/output/darwin-amd64/Synergize.app/Contents/MacOS/resources/app/index.html
    at Module._resolveFilename (internal/modules/cjs/loader.js:798)
    at Function../lib/common/reset-search-paths.ts.Module._resolveFilename (reset-search-paths.ts:40)
    at Module._load (internal/modules/cjs/loader.js:691)
    at Module._load (electron/js2c/asar.js:717)
    at Function.Module._load (electron/js2c/asar.js:717)
    at Module.require (internal/modules/cjs/loader.js:853)
    at require (internal/modules/cjs/helpers.js:74)
    at index.html:17

is this a clue?

chinenual commented 4 years ago

Found an entry in the electron faq (https://www.electronjs.org/docs/faq) -- this works for me:

<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
<script type="text/javascript" src="jquery.js"></script>
... rest of jquery dependent js imports....
</head>

@istvan-ujjmeszaros Thanks for the help - and the great spinner library!

istvan-ujjmeszaros commented 4 years ago

Thanks for sharing the solution that works for you. I will look into it when I have time, maybe it can be properly fixed in the plugin, so leaving the issue open.