Rails 7 importmaps fullcalendar 5 - ruby-on-rails

I need help with following code:
Rails 7.0.3
view.html.erb
<div id="calendar"></div>
importmap.rb
pin "fullcalendar", to: "https://ga.jspm.io/npm:fullcalendar#5.11.0/main.js"
javascript/application.js
import "fullcalendar"
javascript/controllers/fullcalendar_controller.js
import { Controller } from "#hotwired/stimulus"
import FullCalendar from 'fullcalendar'
export default class extends Controller {
connect() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth'
});
calendar.render();
}
}
layouts/applications.html.erb
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
And the output... :(
Failed to register controller: fullcalendar (controllers/fullcalendar_controller)
ReferenceError: exports is not defined
at main.js? [sm]:20877:37*
Any help would be appreciated

The issue is with calendar js file, you can download the fullcalendar js file to your local project, ./bin/importmap pin fullcalendar --download and then you can see fullcalendar.js file under vendors directory vendors/javascript/fullcalendar.js then replace that js file content with the full_calendar source https://cdn.jsdelivr.net/npm/fullcalendar-scheduler#5.11.2/main.js finally add export line to end of the fullcalendar.js file export default FullCalendar;. Hope it may help you with your issue.

Related

Stimulus JS controllers not connecting. Rails 7 // importmap // stimulus

I recently got rid of webpacker and installed importmap and turbo. My Stimulus JS controllers are not rendering anything.
importmap.rb :
# Pin npm packages by running ./bin/importmap
pin "application", preload: true
pin "#hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "#hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "#hotwired/turbo-rails", to: "turbo.js", preload: true
typewriter_controller.js :
import { Controller } from "#hotwired/stimulus"
export default class extends Controller {
connect() {
// some code...
}
}
application.html.erb:
<head>
some stuff..
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag "turbo", type: "module-shim" %>
<%= javascript_importmap_tags %>
</head>
I tried to re-install the stimulus gem but it didn't work. I'm running out of ideas on this one.
As from the stimulus-rails installation guide, I would check the following files are configured this way:
In app/javascript/controllers/index.js
import { application } from "controllers/application"
// Eager load all controllers defined in the import map under controllers/**/*_controller
import { eagerLoadControllersFrom } from "#hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)
In app/javascript/controllers/application.js
import { Application } from "#hotwired/stimulus"
const application = Application.start()
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
export { application }
In app/javascript/application.js
import "controllers"
This assumes you are indeed using importmap and not some other JavaScript bundler (e.g., yarn).

Rails 7 accessing pinned libraries

importmap.rb includes
pin "javascript-autocomplete", to: "https://ga.jspm.io/npm:javascript-autocomplete#1.0.5/auto-complete.js"
And, following the rails guides, application.js was amended with
import "javascript-autocomplete"
although uncertainty about the syntax remains. Also attempted, as the script defines var autoComplete was
import autoComplete from "javascript-autocomplete"
in either instance, while the header shows:
<script type="importmap" data-turbo-track="reload">{
"imports": {
"application": "/assets/application-333b944449a4c540424142c36f01f97feebd58f2f41d10565ecfde32cb315110.js",
"#hotwired/turbo-rails": "/assets/turbo.min-e5023178542f05fc063cd1dc5865457259cc01f3fba76a28454060d33de6f429.js",
"#hotwired/stimulus": "/assets/stimulus.min-900648768bd96f3faeba359cf33c1bd01ca424ca4d2d05f36a5d8345112ae93c.js",
"#hotwired/stimulus-loading": "/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js",
"javascript-autocomplete": "https://ga.jspm.io/npm:javascript-autocomplete#1.0.5/auto-complete.js",
[...]
}
the body has
<%= javascript_tag do %>
var demo1 = new autoComplete({
[...]
});
<% end %>
which fails to run: Uncaught ReferenceError: autoComplete is not defined
so the script is not being accessed.
So where is this lacking?

I'm stuck trying to add Quilljs to a Rails 5.1 app via Webpack

I have been trying to add Quill editor to my app but it doesn't work.
I created a Rails 5.1 app with --webpack and then I ran rails webpacker:install
I ran yarn add quill and rails webpacker:compile
I added <%= javascript_pack_tag 'application' %> to layouts/application.html.erb
In packs/application.js I have:
import Quill from 'quill';
var quill = new Quill('#article_content', {
theme: 'snow'
});
In _form.html.erb:
<%= form.text_field :content, id: :article_content %>
I ran rails s and .bin/webpack-dev-server
In console i get an error: quill Invalid Quill container #article_content
What did I do wrong?
I'm assuming that you are using Turbolinks too. You need to make sure that you are wrapping the following script with:
document.addEventListener("turbolinks:load", function() {
var quill = new Quill('#article_content', {
theme: 'snow'
});
})
This solved the problem for me
It's not clear when _form.html.erb is being included but that error means when new Quill was run, there was no DOM element on the page that matched the input query. Specifically for your case, that means there was no element on the page that has an ID article_content.
var quill = new Quill('#article_content', {
theme: 'snow'
});
You can not use a css id selector here, just class works. So change id="article_content" to class="article_content" ad then your snippet to:
var quill = new Quill('.article_content', {
theme: 'snow'
});
and you are ready to go.

Need to render as a UMD module - rails-babel-transpiler gem

I am using rails-babel-transpiler gem mentioned in the official Babel site
Language API - ruby, for converting es6 code to es5.
The way I am transpiling, below is the erb file
<%
require 'babel/transpiler'
transfromed = Babel::Transpiler.transform("import HelloWrapper from '../assets/javascripts/components/HelloWrapper'; ReactDOM.render(<HelloWrapper />, document.getElementById('app'));")
%>
<%= javascript_tag do %>
<%= transfromed["code"].html_safe %>
<% end %>
It is getting rendered as
//<![CDATA[
'use strict';
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _assetsJavascriptsComponentsHelloWrapper = require('../assets/javascripts/components/HelloWrapper');
var _assetsJavascriptsComponentsHelloWrapper2 = _interopRequireDefault(_assetsJavascriptsComponentsHelloWrapper);
ReactDOM.render(React.createElement(_assetsJavascriptsComponentsHelloWrapper2['default'], null), document.getElementById('app'));
//]]>
Can the above code be rendered in UMD way? I have used the plugin "transform-es2015-modules-umd" in babelrc file but it is not getting converted as a UMD module. Help me in figuring this out! Thanks

Getting Dojo to Work with Ruby on Rails 4

I'm porting my symfony app to Ruby on Rails 4.2.0. My setup works fine in symfony. There is this old post on how to use dojo with RoR, but it uses deprecated code.
In my application.html.erb I have
<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
I replaced the symfony wrappers with Rails ones. I also changed the dojo version. I was using 1.9.1. Rails generates this html:
<script>
dojoConfig = {async: true}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js">
The last line is followed by a bunch of compressed javascript and the close script tag in Firebug.
I didn't make any changes in my home/index.html.erb where I'm testing this code. In app/assets/javaascipts/home.js, I have:
//require(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
define(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
{
ready(function()
{
var head = "<div class='footnote-text'>";
var tail = "</div>";
var fnt1 = head + dom.byId("fnb1").innerHTML + tail;
var fnt2 = head + dom.byId("fnb2").innerHTML + tail;
var fnt4 = head + dom.byId("fnb4").innerHTML + tail;
new Tooltip({ connectId: ["footnote1"],position:["after","above","below"],label: fnt1 });
new Tooltip({ connectId: ["footnote2"],position:["after","above","below"],label: fnt2 });
new Tooltip({ connectId: ["footnote4"],position:["after","above","below"],label: fnt4 });
new Tooltip({ connectId: ["footnote5"],position:["after","above","below"],label: fnt4 });
});
});
//require(["dojo/dom", "dojo/ready", "dijit/Dialog"], function(dom, ready, Dialog){
define(["dojo/dom", "dojo/ready", "dijit/Dialog"], function(dom, ready, Dialog){
ready(function(){
var fnt3 = dom.byId("fnb3").innerHTML;
myDialog = new Dialog({
title: "Contact Me",
content: fnt3,
style: "width: 300px"
});
});
});
The commented out require lines are what I use in my symfony app. As you can see, I replaced them with define as described on the dojo site. When I run it, I get the following error on the Firebug console:
ReferenceError: define is not defined
...define(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip
If I used require instead of define, I get require is not defined.
Update
I tried installing dojo into the app and made some progress. I copied the download from dojo to vendor/assets/javascript/dojo. The dojo directory contains the subdirectories dojo, dojox, and digit
I then added
//= require dojo/dojo/dojo.js
to app/assets/javascript/application.js. I also changed the define back to require in the home.js file. When I reloaded the page, I got an error complaining that it couldn't find Tooltip. I then added:
//= require dojo/dijit/Tooltip.js
On reload it complained about a bunch of other missing js files. This is the same problem I had using symfony, which is why I went to the google image. How can I get to rails to search for the files in the vendor directories? This is one of the errors:
"NetworkError: 404 Not Found - http://amcolan.loc/dijit/_base/manager.js"
Update 2
Since require_tree worked for app assets, I thought it might work to vendor as well. I added
//= require_tree ../../../vendor/assets/javascripts/dojo
to my application.js file. When I reloaded the page, it took about a minute. My guess is that it's loading everything in the dojo directory tree, which is not surprising. The page load completed without any errors. When I hovered over a tooltip item (the purpose of the code is to show tooltips), Firebug cranked out about two thousand errors and quit. All the errors appear to be "ReferenceError: define is not defined"
Update 3
I went back to using the googleapi. My application.html.erb header looks like this
<head>
<meta charset="UTF-8">
<title><%= content_for?(:title) ? yield(:title) : "American Colonial Ancestors" %></title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
I reversed the order of the javascript includes. The page reloaded without errors. The tooltip doesn't work, but it doesn't generate any errors when I hover over an item. I put a bad statement in the home.js code and it came up on the console so I know the code is being parsed. I may just have a bug in my page setup.
There may be more than one way to get Dojo toolkit to work with Ruby on Rails. This is the easiest if not the most efficient way. This works in Rails 4.2.0. I would imagine it would work in other versions as well.
In views/layouts/application.html.erb add the following prior to the inclusion of the site scripts:
<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
Change the version to the latest or to which ever one you want to use. Here I'm using version 1.10.3. The dojo site says there are other CDN's (Content Delivery Network) for the source code. I'm using google as it was in their example. Here are the pertinent parts of my head section:
<head>
<meta charset="UTF-8">
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dijit/themes/claro/claro.css" %>
<script>dojoConfig = {async: true}</script>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js'%>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= content_for :page_script %>
<%= csrf_meta_tags %>
</head>
If you are going to use any of the toolkit's dialog boxes, tooltips, etc, you will need to include a stytlesheet by adding something like this:
<%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dijit/themes/claro/claro.css" %>
Change the version and the theme to your own requirements. Here I'm using the claro theme. You can see it in my head section above. I don't think placement is critical. You also need to declare your theme class in the body statement. Here's mine:
<body class="claro">
An older post on the subject had different javascript formatting. I don't think anything special is needed. Here's an example of a working script:
require(["dojo/dom", "dojo/ready", "dijit/Tooltip"], function(dom, ready, Tooltip)
{
ready(function()
{
var head = "<div class='footnote-text'>";
var tail = "</div>";
var fnt1 = head + dom.byId("fnb1").innerHTML + tail;
var fnt2 = head + dom.byId("fnb2").innerHTML + tail;
new Tooltip({connectId: ["footnote1"], position:["after","above","below"], label: fnt1 });
new Tooltip({connectId: ["footnote2"], position:["after","above","below"], label: fnt2 });
});
});
As mentioned in my question, I tried placing the Dojo Toolkit source in vendor/assets/javascript. Starting with with version 1.7, dojo started using Asynchronous Module Definition (AMD). It may be the case that the AMD loader is incompatible with the Rails pre-compile feature. I don't know enough about it to say for sure.

Resources