Select2 multiselect search in rails - ruby-on-rails

OK, I'm trying to wrap my head around using Select2, AJAX and Rails to do a multiselect search. I haven't gotten to the search part yet as I'm trying to get the multiselect part to work first.
My Controller:
class GamesController < ApplicationController
respond_to? :html, :JSON
def index
#games = Game.order('name').all
#respond_to #games
end
end
My application.js
//= require rails-ujs
//= require turbolinks
//= require select2
//= require_tree .
$('#mySelect2').select2({
placeholder: "Choose a game",
multiple: true;
ajax: {
url: <%= games_path(format: 'json') %>,
processResults: function (data) {
return {
results: data.items
};
}
}
});
My games/index.html.erb file
Still learning
<select class="#mySelect2"></select>
My application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Sonar</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= javascript_include_tag "application" %>
<%= yield %>
</body>
</html>
Routes.rb
Rails.application.routes.draw do
resources :games, only: [:index]
root to: 'games#index'
end
This presents the drop down box, but isn't populating it with the data from the database or presenting a search box to start typing for autocomplete searching.
If I'm understanding it properly, I should have the JS code in the applciation.js file, which is called from the select statement in the index.html file. The index action in the controller is pulling the data from the database in response to the json request and should then pass the info to the js function.
I do note that I don't have the JS to wait for the page to load before running though, but I tried putting that in the application.js file and it didn't change anything.
*edit - the game table has the ID column, name column and a category ID column.

Related

Loading position of javascript in rails app

There are two pieces of my application that seem to require that I load my javascript at different points.
Omniauth works when I place <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' within <head></head>.
Shubox (js library used to upload photos) works when I place <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' just before </body>.
Each of the two does not work when the javascript is loaded where the other requires. So, if I place the javascript line at the end of the body, omniauth does not work.
I can provide additional information if needed. Thank you in advance.
application.js
require("#rails/ujs").start()
require("turbolinks").start()
require("#rails/activestorage").start()
require("channels")
application.html.erb
<html>
<head>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
</head>
<body data-shubox="<%= Rails.application.credentials.dig(:aws, :secret_access_key) %>">
<% if flash.any? %>
<% flash.each do |key, value| -%>
<section class="flash flash__<%= key %>"><%= value.html_safe %></section>
<% end -%>
<% end %>
<%= yield %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</body>
</html>
Because of Turbolinks your application.js needs to be in the head tag, otherwise it is evaluated twice . This can cause a problem with libraries that expect your DOM to be loaded when you initialize them - which I think is your problem with shubox.
So you should put something like this in your application.js (if you are using Turbolinks 5, for earlier version the event is called page:load)
$(document).on('turbolinks:load',() => {
new Shubox('#avatar', { key: "abcde-qwerty-12345" })
}
);
You can always create 2 packs if you need them in different places:
javascript/packs/the_one_with_turbolink.js
javascript/packs/the_one_with_shubox.js
then you can do
javascript_pack_tag :the_one_with_turbolinks
and
javascript_pack_tag :the_one_with_shubox

How To load js only in one page of my app

I'm trying to load a js file into a single page of my app. But it is called in all and this ends up generating errors on my screen.
My application.js is:
//= require jquery
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
My application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Netshow</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<div class='cover-container d-flex w-100 h-100 p-3 mx-auto flex-column'>
<header class='masthead mb-auto'>
<%= render 'shared/navbar' %>
</header>
<%= yield %>
<footer class='mastfoot mt-auto'>
<%= render 'shared/footer' %>
</footer>
</div>
</body>
</html>
My js file is:
$(document).on("turbolinks:load", function() {
console.log('teste')
var player = videojs('my_video_1');
var options = {};
player.on('play', function() {
$.ajax({
type: 'POST',
url:"/video_clicks/",
dataType: 'json',
data: {
video_click: { video_id: window.location.pathname.split('/')[2] }
},
success: function(){
$('span.video-count')[0].innerText = parseInt($('span.video-count')[0].innerText) + 1
}
});
});
function showCount(){
var id = window.location.pathname.split('/')[2]
$.ajax({
type: 'GET',
url:"/video_clicks/"+id,
dataType: 'json',
success: function(data){
console.log($('span.video-count')[0])
$('span.video-count')[0].innerText = data
}
});
}
showCount()
});
I would like to load the js file only on one page of my app and not at all. How can I do this? I have already tried removing the require_tree add content in application.html.erb and set the content in my html file, but the rails speaks that I have to add the file in assets.erb for precompilation and when I do this the other pages reload my js file.
You have multiple options in that scenario:
You can check the params[:controller] and params[:action] in application.html.erb, if that matches the specific page controller+action then only load the JS. (Better Solution)
Like:
<% if params[:controller] == 'your_controller_name' && params[:action] == 'your_action_name' %>
<%= render partial: 'shared/custom_js' %>
<% end %>
Based on this code above, I'll create a new file named custom_js.html.erb in my views > shared folder. Then write the script in that file inside <script></script> tag. Also, you need to remove that script file from application.js file.
You can create a different layout for that specific page access method. Like the answer here.
You just simply include that page (erb file) with <%= javascript_include_tag 'js_file_name' %>
Add to you view and
<%= javascript_include_tag 'js_file_name' %>
config/initializers/assets.rb
Rails.application.config.assets.precompile += %w(js_file_name.js)

Js file not being loaded on Rails application

Im doing a project from scratch and getting an anoying error that Im dealing without sucess.
Im trying to add a JS file to a page not having sucess.
Those are my files:
#application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Workspace</title>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
And my application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require welcome
//= require_tree .
My welcome.js inside /assets/javascripts:
#/assets/javascripts/welcome.js
$(document).ready(function(){
$('#present').mouseenter(function(){
alert("MouseEnter!"); // This will create an alert box
console.log("MouseEnter!"); // This will log to the JS console on your browser which is a bit nicer to read than alerts, you do not need both, just preference
$(this).fadeIn('fast',1);
});
$('#present').mouseleave(function(){
alert("MouseLeave!"); // This will create an alert box
console.log("MouseLeave!");
$(this).fadeIn('fast',0.5);
});
});
When I run the root page the JS is being shown looking at the inspector. But looks empty (i dont know if this is something usual)
src="/assets/welcome.self-877aef30ae1b040ab8a3aba4e3e309a11d7f2612f44dde450b5c157aa5f95c05.js?body=1"
If I open it using the browser it shows:
(function() {
}).call(this);
Well. Someone know what can I do to make my Javascript works?
Thanks
change your code in your application.html.erb
from:
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
to this:
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>

Rails generate a new layout file

I felt confused about the Rails layout. I have the home and video page, and I want to include their css and js relatively.
Therefore, after I used scaffold to create video, I created video.css and video.js.
Furthermore, I created a file in view/layouts/video_layout.html.erb and put the following code into it.
<!DOCTYPE html>
<html>
<head>
<title>Video</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'video', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'video', 'data-turbolinks-track': 'reload' %>
</head>
<body>
VIDEO BEGIN
<%= yield %>
VIDEO END
</body>
</html>
I thought it will include only video.css and video.js. However, when I accessed localhost:3000/videos, the video page was still in original condition (no VIDEO BEGIN and VIDEO END )
add the following line to app/controllers/videos_controller.rb
layout "video_layout"
eg
class VideosController < ApplicationController
layout "video_layout"
def index
end
....
end
also check this http://api.rubyonrails.org/classes/ActionView/Layouts.html

rails 4, turbolinks 3, partial replacement not working

I'm trying rails/turbolinks 3, and want to make partial replacement work, but no luck with that. Here is code:
gemfile
gem 'turbolinks', github: 'rails/turbolinks' (shows using 3.0.0 so problem not in that, turbolinks included in app..n.js).
router:
root 'home#index'
get '/partial1' => 'home#partial1', as: 'partial1'
get '/partial2' => 'home#partial2', as: 'partial2'
controller
class HomeController < ApplicationController
def index
end
def partial1
render change: 'partial1'
end
def partial2
render change: 'partial2'
end
end
layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Turbo</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<div>
this is home
<%= link_to("partial asd1", partial1_path) %>
<%= link_to "partial 2", partial2_path%>
</div>
<div id="partial1" data-turbolinks-temporary>
<p>her</p>
</div>
<div id="partial2">
<p>here is partial</p>
</div>
<%= yield %>
</body>
</html>
But it doesn't replace those partials, it works just as regular. I also tried to put turbolinks: true and it renders Turbolinks.replace('some html', {change: ['partial1']}), but also nothing happens. I also tried e.preventDefault and Turbolinks.visit('/partial1', {change: 'partial1'}), and it also not working as well as calling Turbolinks.replace('some html', {change: 'partial1'}). Turbolinks js loads in browser all right. And in dev it shows calling Turbolinks.visit. Tried on different machines.
If anyone made it work please tell me how you did it.

Resources