how to share code between Unobtrusive JavaScript in rails - ruby-on-rails

As the title, I want to abstract some function and share them between different unobtrusive javascript files. How can I do?
To be more specific, for example, I have two files: show.js.erb, create.js.erb in views/object/
When I response to ajax request, I will render them.
Now this two files share some same code, so I want to abstract them and put it to a new file.
How can I achieve this?

Like with html.erb files you can also have partial for js.erb files.
Just extract the common code into a partial (starting with a _, so e.g _common_code.js.erb in views/object/).
Then you can just use the render function in the show.js.erb or create.js.erb files like this to include your common code.
render "common_code"

try extract common logic to separate file, include it to layout and use common functions from *.js.erb files.

Related

How do I render an SVG inline in Rails?

I have an SVG file that's part of a template located at:
vendor/theme/assets/icons/icon-1.svg
How do I render that inline in my view? render partial: path fails and says it can't find a partial.
In your view insert the following:
<%= render inline: Rails.root.join('vendor/theme/assets/icons/icon-1.svg').read %>
If you're going to be doing this multiple times, you may want to refactor this into a helper.
Also, think about the following:
Are you okay with dumping third party code directly into your view?
Is the vendor SVG file updated automatically without review?
Are you sure the vendor SVG file will never contain malicious code?

Use Rails Sprockets directives when rendering js from controller

I want, from a controller, to render a .js.coffee view that includes another js file from the lib/assets/javascripts directory:
#= require doc_ready
Why a view rendered by a controller instead of a static asset?
Because I want to refer to the file through an absolute url, that doesn't changes. Rails 4.0 only compiles assets with a digest like embed-dc589fbef3832d9c38a4fbbc4b021f59.js and I want to use the same url (and possibly expire the cache file based on time), even if I make changes to the script.
Why an absolute url?
Because I want to use the script externally on another website, and the code I give to the webmaster of that site mustn't change.
Why do I want to include another js from the assets?
To keep the code DRY
To require a simple library that simulates the jquery ready event, used to create widgets on the page that included the script.
Can I achieve that by making a controller action that renders a .js.coffee view, which compiles and includes other needed js files from the library, just like sprocket does when compiling assets?
Use redirection like so:
def show
redirect_to view_context.javascript_path('embed.js.coffee')
end
There is a way to render whole js file:
def show
render text: Rails.application.assets.find_asset('embed.js.coffee').body
end
I managed to find a way to do it, by using this answer.
The controller is left untouched:
class Widgets::EmbedJsController < ActionController::Base
def embedded_script
end
end
In the coffeescript view, I have "required" the other file like this:
`<%= raw Rails.application.assets['doc_ready'].body %>`
Seems to work locally, I'll test in production soon.
This can also be refactored by just serving Rails.application.assets['widgets/embed'].body directly from the controller, which should compile coffeescript but have not tested it.
Another approach is to symlink or copy the digest version of the asset to some constant path (and give that to the 3rd party). This has the advantage that the requests shouldn't hit rails at all (since these should be served directly by the web server.
It is relatively simple to automate this - two libraries that I am aware of that do this are
non stupid assets
asset_symlink (I wrote this one)

How to register rb as a template handler in rails

Well since I am using a lot of helper methods in my view files and I avoid using html in most of my view files.
Example
myview.html.erb
<%=myhelper #myobject%>
so I end up using,the erb processing tags each time for each file.
<%=%>
I want to register .rb as a template handler or any other extention for that matter.
So my templates look like
myview.html.rb
myhelper #myobject
I am clueless on how to go ahead.
I found it,it seems railscasts already covered that part.
Its show notes,worth checking out.
https://github.com/railscasts/379-template-handlers/blob/master/store-after/config/initializers/ruby_template_handler.rb
Things without ruby are easy to read and render without those erb tags.

Moving unobtrusive javascript out of html.erb file

I have a html.erb file in one of my views. The file is pretty big and has about 2/3 javascript code and just 1/3 html. I dont like this file being too cluttered. The javascript part is mostly event handlers and usage of jquery UI components like date pickers, dialogs etc for the corresponding html elements in the page. I would like to separate the javascript part from the html part.
Can I move the javascript to a separate js.erb file and use it like a partial? What is the advantage of this?
How would I move the javascript to a static .js file when I use rails API like I18n.() and <%= form_authenticity_token %>. Should I pass them every time to the wrapping javascript function? Is there a better way to do this?
If I move javascript out of the html.erb file will it help in caching/rendering of html.erb page?
Interested to find out if there are any re-usable patterns
Sample code on the html.erb file:
<% content_for :javascript do %>
<script type="text/javascript">
$(document).ready(function()
{
$('#create_segment_dialog').dialog({
title: "<%= I18n.t("segment.create_segment_title") %>",
// lots of javascript
}
</script>
<%end %>
//HTML starts here
<div id="right-column">
My 2c, but I know there are differing opinions on this:
Try and separate out as much of your JS code into a function or functions and put them into JS files in your asset pipeline. Take advantage of the move to break your JS into re-usable components that could be used by other methods/controllers.
This means you get all the benefits of the asset pipeline for the JS you move there:
Caching & fingerprinting your JS assets
Minification & compression support to save bandwidth
Minification to obfuscate your code if that is something you want
Concatenation of JS files to reduce the number of requests a browser has to make
Possibility to serve the assets from another location (CDN, web tier vs app tier)
Improved DRYness if that JavaScript is used by other methods/controllers
The drawback? As you've pointed out, any Rails variables have to be passed in as parameters to the functions.
Moving your JavaScript to a .js.erb partial is an option, but if this code is very specific to a particular method or controller then it is not necessarily improving DRYness - it may make your code a little more readable, by separating HTML and JS.

Rails Routing INSIDE CSS

Is there any way I can route assets inside of my css to where the rest of the views are pulling them? I mean, inside the CSS can I call url_for or css_for or something like that in order to have the images go through the assets router?
Thank you in advance!
You can use a controller action to render your CSS (with an erb template) and set the content type to text/css.
Take a look at this blog post from Josh Susser on dynamically generated stylesheets. It is from 2006 but the technique described is still applicable.

Resources