flatpickr via rails importmap not being generated - ruby-on-rails-7

Attempting to use flatpickr as a UI for setting a date field with Rails 7.0.1 and ruby 3.1. When clicking on the input field, the expected 2 months of calendars is not rendered & in fact, nothing is registered in the browser network tab.
After bin/importmap pin flatpickr rails pinned the library to the cdn in the importmap.rb file:
pin "flatpickr", to: "https://ga.jspm.io/npm:flatpickr#4.6.9/dist/flatpickr.js"
application.js has the initially generated import "controllers".
flatpickr_controller.rb was created in the javascript/controllers directory with
import { Controller } from "#hotwired/stimulus"
import flatpickr from "flatpickr"
export default class extends Controller {
connect() {
this.config = {
enableTime: false,
dateFormat: 'Y-m-d',
}
}
}
The view partial invokes:
<%= form_with model: promo do |f| %>
<%= f.text_field :date_from, placeholder: t(".select"), data: { controller: "flatpickr" } %>
<% end %>
while the controller sets
#promos = Promo.up_comings(60)
#promo = Promo.new
#next_promo = Promo.next
#dates_to_disable = #promos.pluck(:date_from)
Why is the calendar not rendering?
I am also confused as to where to place the different flatpickr options: in the controller, or straight into the form date element.

The issue is related to support for Stimulus 3. Pin as follows:
bin/importmap pin stimulus-flatpickr#beta
Also reference some css source, such as to the latest version
<link rel="stylesheet" href="https://ga.jspm.io/npm:flatpickr#4.6.9/dist/flatpickr.min.css">
otherwise the input field will be deemed as readonly...

Related

Uncaught Error: rails-ujs has already been loaded when calling a Stimulus controller on a field in simple_form

Hello everyone :) I'm building an application with Rails 6.1.6.
I am using select2 with simple_form like this:
<%= f.association :events, input_html: { data: { controller: 'select2' } } %>
My Stimulus controller is the following:
import { Controller } from "#hotwired/stimulus"
import $ from 'jquery'
import 'select2'
import "select2/dist/css/select2.min.css"
export default class extends Controller {
connect() {
const matchEvent = (params, data) => {
if ($.trim(params.term) === '') {
return data;
}
if (typeof data.text === 'undefined') {
return null;
}
if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
var modifiedData = $.extend({}, data, true);
modifiedData.text += ' ';
return modifiedData;
}
return null;
};
$(this.element).select2({
closeOnSelect: false,
placeholder: "Select an event from our Database",
minimumInputLength: 3,
selectOnClose: true,
allowClear: true,
matcher: matchEvent
})
}
}
For completeness, this is how my application.js looks like:
import Rails from "#rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "#rails/activestorage"
import "channels"
Rails.start()
Turbolinks.start()
ActiveStorage.start()
import "controllers"
import "bootstrap"
While, in the head of my application.html.erb, I have:
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload', defer: true %>
Any time I log in the application and go to the page when I have this simple_form, I see this error message in the console:
Uncaught Error: rails-ujs has already been loaded!
Which points to a conflict between my application.js calling Rails.start() and something inside node_module.
Ever seen anything like this?
Just to be clear, the form works perfectly but at each first visit to the page I see an annoying inline text-field beside the label and, moreover, this issue made my application lag in the other pages. Only a refresh of the browser fixes it.
What am I missing?
Thanks a lot for your help!
EDIT:
Issue fixed! It was showing up only when navigating through the app by links (not when typing the path in the address bar of the browser) so the problem was with turbolinks reload. By adding data: { turbolinks: false } to the link of the page, the issue has disappeared!

Can't get the `data-*-id` attribute to properly record the custom event name via ClickAnalytics plugin

I have a client React app I'm instrumenting in appinsights, and I'm using both the React plugin and the new ClickAnalytics plugin. Everything works, telemetry is flowing, however I'm having trouble getting the data-*-id custom event feature working properly.
The docs say:
The id provided in the data-*-id will be used as the customEvent name. For example, if the clicked HTML element has the attribute "data-sample-id"="button1", then "button1" will be the customEvent name.
I instrument an element as follows (using Semantic UI React):
<Button
data-custom-id="AddDealButton"
as={Link}
color="blue"
icon
labelPosition="right"
size="huge"
>
Clicking that button causes the custom event to record but the name, "AddDealButton", doesn't flow through. I always get not_specified as the event name:
Reading the docs, there is this warning regarding the plugin configuration:
If useDefaultContentNameOrId is false, then the customEvent name will be "not_specified".
So I am initializing the plugin this way:
...
extensions: [reactPlugin, clickPlugin],
extensionConfig: {
[reactPlugin.identifier]: { history: browserHistory },
[clickPlugin.identifier]: { autoCapture: true, useDefaultContentNameOrId: true }
}
...yet the name does not pass. Am I misconfiguring? Any idea what I'm doing wrong?
It turns out the problem was in the initialization configuration I showed above. It should be set up as follows:
...
extensions: [reactPlugin, clickPlugin],
extensionConfig: {
[reactPlugin.identifier]: { history: browserHistory },
[clickPlugin.identifier]: { autoCapture: true, dataTags: { useDefaultContentNameOrId: true } }
}
The resulting event name is not being pulled from my data-custom-id but rather pulled from the content of the Icon element of the Button component, so the event name becomes "Create new deal", but I can figure that out.
Microsoft's docs show a different samples for the npm install method vs the "snippet" method, and so I missed the dataTags sample.

Rails Variables inside the CSS file

I have CSS file that needs to be embedded by the user. Now for the user to customize the CSS file as he/she wishes (change the colors and font-size mainly) I have to store that information in database file, append that information to specfic CSS file and then enable that user to embed it.
I would get the id of the User that I wish to change. So color codes stored are basically extracted from,
User.find(params[:id]).main_color
# This would return => #fffff
This what my embed code looks like right now,
<link href="link.com/initial.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" data-user="18" src="link.com/some_file.js" />
Here data-user is the id of the user who is modifying the CSS file. (The IFrame is being embedded using the javascript file)
How should I modify my embed code and fetch the custom variables from my database in order to make the CSS cstomizable as the user wants?
Thanks in advance.
P.S I have thought of rewriting the CSS in the view(.html.erb file) and using !important there along with proper color codes selected by the user but that approach is not exactly very efficient.
I think the best way is to keep your script file at the server side, So you can easily modify your script depending on user database options
for example:
place a new route in routs.rb
post '/users/modify_style', :to => 'users#modify_style', :as => modify_style
then allow the route to respond to user by JavaScript file, for example if the user needs to change the main color of HTML template using a button or a link; so the form button in template may look like:
<%= button_to 'apply style', modify_style_path, :data => {:user_id => current_user.id}, :remote => true %>
or
<%= link_to 'apply style', modify_style_path(:user_id => current_user.id), :method => :post, :remote => true %>
so remote: true option will allow sending data to server through AJAX without refreshing the page.
at users_controller.rb
def modify_style
user = User.find(params[:user_id])
#main_color = user.main_color
respond_to do |format|
format.js { render 'some_file.js.erb' }
end
end
and in your js file:
$('#some_element_id_to_change_color_for').css('color', '<%= #main_color %>')
or you can add modify_style action code directly to the original action which load your page to appy user style once the page is loaded.
I would suggest you to directly use it in the erb file something like
my.html.erb
<html>
<!-- my html -- >
</html>
<style>
<%= my_css.html_safe %>
</style>

How can I use Angular 2 in a .NET 4 Web Forms project?

I have a ASP.NET 4 Web Forms project written in C#. I would like to add Angular 2. I've seen a lot of examples on the web using ASP.NET 5 but I can't figure out how to do it in my project.
Have faced similar requirement and did some POC on this and definitely moving forward with it . I worked on with each .aspx page as stand alone angular 2 SPA app. This means each aspx page will have its own App.Component.ts and main.ts file(file name based on Angular 2 documentation). main.ts file contains the code to bootstrap the application (sample code below) so there will be a main.ts file for each .aspx page.
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_BINDINGS} from 'angular2/http';
import {HomeComponent} from './home.component';
bootstrap(HomeComponent, [HTTP_BINDINGS])
.catch(err => console.error(err));
There will be one app.component.ts(named it home.component.ts for my home.aspx) file for each aspx page.
Now in the config file which contains Sytem.config details i defined new map and package entry for my home.aspx as shown below:
System.config({
transpiler: 'typescript',
typescriptOptions: {
emitDecoratorMetadata: true,
experimentalDecorators: true
},
map: {
app: '../../Javascript/angular/app',
home: '../../Javascript/angular/home'
},
packages: {
app: { main: './main.ts', defaultExtension: 'ts'},
home: { defaultExtension: 'ts' }
}
});
And finally I moved the System.import code part to .aspx page(code below). Each page will import its own package defined in sytem.config.
<script>
System
.import('home/main-home')
.catch(console.error.bind(console));
</script>
here i have named my main.ts as main-home.ts.
Hopefully this helps you and others. Also i am open for suggestion and review/alternate solution of this approach.
For reference please see: bootstrapping-multiple-angular-2-applications-on-the-same-page
I totally agree with #pawan's answer but yes #pawan i found a nice solution of this. This solution definitely helped me and hope it will help all of you too.
We don't need to create main.ts and AppComponent.ts for each and every page.
We need to make our main component which we are bootstrapping dynamic. In our case, in app.component.ts, i am bootstrapping our component dynamically based on url of current page.
Let's say if your page is home.aspx then boostrap HomeComponent or about.aspx then boostrap AboutComponent
I am doing it by implementing ngDoBootstrap method as following.
export class AppModule {
url : string;
constructor(#Inject(DOCUMENT) private document: any){
this.url = this.document.location.href.toLowerCase();
}
ngDoBootstrap(app:ApplicationRef){
if(this.url.indexOf("home.aspx") > 0){
app.bootstrap(HomeComponent);
}
else if(this.url.indexOf("about.aspx") > 0){
app.bootstrap(AboutComponent);
}
}
}
This is how based on page url, we can dynamically bootstrap our Component and save a lot files of main.ts and app.component.ts for each page.
For this, you need to add entry for each component into entryComponents array of NgModule as below:
#NgModule({
entryComponents : [
HomeComponent,
AboutComponent,
]
})
Hope this helps.
change your index.html base route to your webpage
<base href="/YourWebPageRoute">
include the page inside the webform
<% Response.WriteFile("index.html"); %>

Middleman and Sinatra Contact Form rendering template

I'm trying to create a middleman site with a contact form using sinatra and pony gem
I'm having problems getting middleman and sinatra to play nicely together
THE ISSUE:
"
My Contact From is not rendering my header and footer and also does not like it when I try to include view helpers like = link_to tags When I try that I get this error
undefined method `link_to' for
Its also not picking up my stylesheets
"
Heres my Mailer.rb get method
class MailForms < Sinatra::Base
set :views, Proc.new { File.join(root)}
get '/' do
haml :contact, :layout => :'/contact'
end
end
and it lives in source/mailer.rb
when I go to website.com/contact.hml
I get the form but it has no header or footer all my other pages have them and is working
I can't use = link_to tags or image tags i get an undefined method error
Its also not picking up my styles
heres my config.rb
require 'source/mailer'
map('/contact.html') do
run MailForms
end
set :css_dir, 'stylesheets'
set :js_dir, 'javascripts'
set :images_dir, 'images'
set :relative_links, true
configure :build do
activate :relative_assets
end
heres my layout.haml with my stylesheet link
!!!
%html
%head
%meta{charset: "utf-8"}
%meta{content: "IE=edge,chrome=1", "http-equiv" => "X-UA-Compatible"}
%title= current_page.data.title || "Auto Tint Specalist"
%link{href: "//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css", rel: "stylesheet"}
= stylesheet_link_tag "normalize", "all"
%script{src: "//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"}
= javascript_include_tag "all"
%body{class: page_classes}
= partial 'layouts/header'
= yield
= partial 'layouts/footer'
all my styles are in all.scss in the stylesheets folder

Resources