Rails - Linking to static files inside of controller views - ruby-on-rails

I have some static JS files I would like to include in a rails controller view, unfortunately simply placing them in the appropriate view folder gets me a 404 response. Is there a way to do this?

If you want to javascript inside your view file
<script type="text/javascript">
//code goes here
</script>
OR
If you want to load JS file then need to place them in app/assets/javascripts directory.
if you have a file your-js-file.js then place it under app/assets/javascripts directory
and add the below line in your application.js
//= require your-js-file
It will be loaded automatically by Rails

Related

Referencing a vendor js file directly from erb file

I'm trying to get rid of the asset pipeline altogether.
As part of this move I need to get rid of the application.js file under app/assets/javascripts/application.js
I have erb files that I want to specifically require my vendor files there, for example:
Instead of this line in application.js:
// = require jquery-2.2.3.js
I want to add something like this to application.html.erb:
<script src="vendor/assets/javascripts/jquery-2.2.3.js" type="text/javascript"></script>
This produces a 404 Error. How can I still do that?
If that matters, I have config.serve_static_assets = true in my config/application.rb

How to require custom JS files in Rails 6

I'm currently trying Rails 6.0.0.rc1 which seems to have moved the default javascript folder from app/assets/javascript to app/javascript. The application.js file is now located in app/javascript/packs. Now, I want to add a couple of js files, but for some reason they don't get imported and I can't find any documentation on how this can be done in Rails 6. I tried a couple of things:
Create a new folder custom_js under app/javascript/packs, putting all my js files there and then add a require "custom_js" to application.js.
Copy all my js files under app/javascript/channels (which should be included by default, since application.js has require("channels")).
Adding require_tree . to application.js, which was the previous approach.
How can I load my own js files inside a Rails 6 application?
Get better-organized code and avoid multiple javascript_pack_tags in your application.html.erb file with this approach:
Add your custom example.js javascript file to app/javascript/packs.
Add require("packs/example") to your application.js file.
I would have liked to add a comment to Asim Hashmi's correct answer. But I don't have enough reputation, so I'll add my suggestion as an answer instead.
It isn't necessary to include the ".js" extension inside of the require.
You need to do the following steps to add custom javascript file to rails 6 (webpacker)
1.Create your custom file named custom.js in app/javascript/packs directory.
For testing purpose, write any console.log in it.
// app/javascript/packs/custom.js
console.log("custom js file loaded")
2. Go to your application.html.erb and add the following line at the end of your <head></head>
<%= javascript_pack_tag 'custom', 'data-turbolinks-track': 'reload' %>
3. Now execute rake assets:precompile
This will pack your javascript code (including our custom file we just added)
Now reload your page and you should see the message
custom js file loaded
In your browser console.
My custom js has functions which will be called by embedded javascript of serveral html pages. Following snippet works in Rails6, compiled by webpacker:
put custom js file in folder app/javascript/packs e.g. app/javascript/packs/my_functions.js
say_hello = function(a_text){
console.log("HELLO "+ a_text);
}
add javascript_pack_tag in html file, e.g. index.html.erb .
<%= javascript_pack_tag 'my_functions' %>
<!-- html here -->
<script>
$(document).ready(function(){
say_hello('ABer')
});
</script>
Note : This line is inside html body, not in head
<script src="/packs/js/my_functions-1db66368ebbd2fe31abd.js"></script>

How to add jquery for specific pages only?

I would like to know where I need to place jQuery code written for specific controller action. For example I have two controllers Pets and Treats. Only the Index page for Treats controller needs to have an alert. Currently I have placed the jquery code in application.js and all my pages are pulling the alert.
If you do not want some script included by default, (in your own case, the script for index page for Treats), do the following:
Create a new file inside your javascript assets folder: app/assets/javascript/treats.js
put your script code inside here
Go into your application.js file and remove the //= require_tree . line.
NOTE that this will prevent any/all of your other js files from being loaded, so you will have to require all the other needed scripts individually.
Go into the view page where you want this one script called, (in your case, the Treats index.html.erb) and use a script tag to call this specific file (more accurately, the specific function inside the file).
By doing so, the script will not be available in your whole application, but will only be available where you want it, which is where you called it.

CKEditor/vendor library: can it work when in vendor folder instead of public folder?

I have a working edit view to which I'm trying to add CKEditor. I've downloaded the CKEditor folder/files and placed them in my_app/vendor/assets/ckeditor/. I'm using Rails 4 and this folder is included in the asset pipeline. To application.js I've added //= require ckeditor.js and to application.css #import "contents";.
In my edit view I have (I'd like to use the inline option):
<%= f.text_area :page, contenteditable: 'true' %>
<script>
CKEDITOR.disableAutoInline = true;
CKEDITOR.inline( 'image_page' );
</script>
Problem: Now when loading the edit view, the text field is not displayed as an editable field but just as plain text. There's no way to edit this text and no sign of CKEditor. Any idea what I'm doing wrong?
The page's source code that is being generated, includes:
<textarea contenteditable="true" name="image[page]" id="image_page">
Arbor cubo vel.
</textarea>
<script>
CKEDITOR.disableAutoInline = true;
CKEDITOR.inline( 'image_page' );
</script>
Update: I got it working by moving the CKEditor files from the vendor folder to the public folder. Could someone perhaps confirm whether or not CKEditor is compatible with the asset pipeline?
I would prefer to place it in the vendor folder if anyway possible. This old post as well as this one refer to something similar (if I place <% var CKEDITOR_BASEPATH = '/ckeditor/'; %> as a header line in application.html.erb my app crashes with the error dynamic constant assignment '.freeze). Could someone with more experience with CKEditor provide a more definitive answer than these old posts?
Try adding the ckeditor assets under either vendor/assets/javascripts for the JavaScript files and vendor/assets/stylesheets for the CSS files (separate the ckeditor assets among those folders)
The whenever an asset is referring to another asset use the asset-url helper instead of url so that this asset is served through the asset pipeline
You also need to include all the assets that you'll put in vendor.... folders in the asset pipeline by //require or import
On a side not you can use the ckeditor gem https://github.com/galetahub/ckeditor it will save you a lot of time also it handles some features out of the box like images upload and gallery of ckeditor
May be the script is executing before the textarea is fully loaded on the DOM. Try to use a post load wrapper to your script like the jquery's:
$(function(){
// ... your code
})

Understanding require_tree load order

Dear all I have the following folders angular_components
Now for loading this files inside this folder I wrote
//= require_tree ./angular-components
The way files are loaded are
<script src="/assets/angular-components/mapAutoComplete/autoCompleteAddressApp.js?body=1"></script>
<script src="/assets/angular-components/mapAutoComplete/directive/controllers/googleAddressSuggestion.js?body=1"></script>
<script src="/assets/angular-components/mapAutoComplete/directive/googleAddressSuggestion.js?body=1"></script>
<script src="/assets/angular-components/mapAutoComplete/services/locationDataService.js?body=1"></script>
<script src="/assets/angular-components/stripePayment/lib/angularPayment.js?body=1"></script>
<script src="/assets/angular-components/stripePayment/services/stripeService.js?body=1"></script>
<script src="/assets/angular-components/stripePayment/stripePaymentApp.js?body=1"></script>
In the mapAutoComplete directory the file in the root folder autoCompleteAddressApp.js loaded before the other file however in the stripe payment the stripePaymentApp.js which is in the root folder loaded at the end. Why this is happening? How can I make sure in both cases the root file loaded before the child directory file?
The reason for this is require_tree loads the files or folders alphabetically whether it is a file or folder. One a way of solving your problem is individually loading the file without using require_tree. Another way you can achieve your goal is by adding _ underscore before the file you want to load first. Because require_tree will load the file prefixed with underscore before the other files. So in your case your directory structure would like following

Resources