Partial rendered via ajax does not contain javascript when it should - ruby-on-rails

I have a partial that is being rendered via ajax and the result used to replace a div's contents. This partial is rendering correctly but when I inspect the element the javascript tag and it's javascript is not rendered in the browser. The partial is similar to the following
<style>
/* some styles */
</style>
<script type="text/javascript">
alert("did it work");
</script>
<% #array.each do |el| %>
<!--make table w/ array -->
<% end %>
When i inspect the element everything is there but the javascript. and i have evalJS: true on my Ajax.Updater options (i'm using prototype but i don't think that makes any difference). The odd thing is that when i put the following in the action i can see the rendered template in the console w/ the js
test = render :partial => "my_partial.html.erb"
puts test
test
Any help would be greatly appreciated.

If you look here: http://api.prototypejs.org/ajax/Ajax/Updater/ you will notice that the correct option name is evalScripts (but read about its use, because it has some limitations).

Related

Rails 5.2: How do I use page specific JS scripts when using Turbolinks?

I am writing some exploratory javascript for a page. It includes the following line:
dashboard_settings.addEventListener('ajax:complete', function(){
...
I have placed the script just before the closing body tag.
I notice that when I navigate to the page, the JS works as I expect it to and there are no error messages in the console. However, when I navigate away from the page, an error message displays in the JS console:
Uncaught TypeError: Cannot read property 'addEventListener' of null
I understand that this is something to do with turbolinks. However, I am unsure how to go about avoiding it without turning turbolinks off.
Is there any way at all that I can specify that the script loads for the one page only?
I have tried the following without success:
<%= yield :page_scripts %>
<% content_for :page_scripts do %>
<script>
document.addEventListener('turbolinks:load', function(){
...
You can add the listener only if the element exists.
if (dashboard_settings)
dashboard_settings.addEventListener('ajax:complete', function(){...})
Or, if you wan't to add it only for a specific page, you could add a yield statement on your layout and only set it's content con the desired page
#layout
<html>
<body>
...
</body>
<%= yield(:after_body) -%>
</html>
#your view
<%= content_for :after_body do -%>
<script>
document.addEventListener('turbolinks:load', function(){
dashboard_settings.addEventListener('ajax:complete', function(){...})
})
</script>
<%- end -%>

Using devise gem, how does it prefill form values in the edit form and how can this be replicated elsewhere?

I am attempting to place the sign in, sign up and edit forms (from devise) into Bootstrap modals using partials. I have successfully done this by creating partials for the forms (wrapped in the modal code) and rendering them in application.html.erb as follows:
<%= render 'articles/sign_up_modal' %>
<%= render 'articles/sign_in_modal' %>
<%= render 'articles/edit_profile_modal' %>
At the top of application.html.erb I have:
<script type="text/javascript"> $(function () { $("#sign_up").modal({show:false });</script>
<script type="text/javascript"> $(function () { $("#sign_in").modal({show:false });</script>
<script type="text/javascript"> $(function () { $("#edit_profile").modal({show:false });</script>
Where "sign_up", "sign_in" and "edit_profile" represent the id's of the modals from the partials. The modal is then displayed by clicking a button in the _header.html.erb partial:
<%= link_to '<button type="button" class="btn btn-primary">Edit Profile</button>'.html_safe, "#edit_profile", "data-toggle" => "modal" %>
Everything works great except the Edit Profile modal form does not prefill the form with the appropriate values unless I am also on the edit page when I click the button to display the modal. How can I get the Edit Profile modal form to prefill the users data no matter which page they are on in the background?
Does this make sense? Please tell me how I might clarify my question. Thanks!
The answer was provided to me by u/alec5216 on reddit.
He said:
Take a look at the devise source.
https://github.com/plataformatec/devise/blob/master/app/views/devise/registrations/edit.html.erb
You'll see the form is bound to the "resource" variable which is going to be an instance of a user model. I bet if you use current_user in the partial instead of resource you'll have the desired effect.
This worked. See HERE for the full conversation.
In this case you will probably have to make an AJAX call to fetch the required data.
The data itself can either be JSON (for client-side rendering) or the complete html form rendered with the layout: false option. I usually go for the former because it is faster and easier to implement, unless your project is a single-page js application.
You can find more information on bootstrap ajax modals here on StackOverflow.

Rails - use code(css, js, html) from server on client side

I had a application rails built with bootstrap and simple form.
Here I have to show the UI patterns how they actually look like. That means I have to show the
patterns like menu bar, accordian patterns examples in my application. For that I am storing the pattern code html,css,js in database.
Here my requirement is I have to show the actual code pattern view from the stored record(css,js,html) without any css/js conflicts.
How can eneter the html,css,js code dynamically in a partial or page to show that
in a fancybox in rails.
Thanks for the help in advance.
just use html_safe or raw to render your content as a normal string on views. For instance:
in your controller:
#x = YOUR_CODE_FROM_DB
in your view:
<%= #x.html_safe %>
# <%= raw #x %> is also ok in this case
NOTICE: you can use html_safe on models, but raw is declared on a helper, so you can just use it on controllers and views.
-- edit --
more example:
on controller:
#hello = 'alert("hi");'
#body = 'body{ background: red; }'
on view:
<script type="text/javascript" charset="utf-8">
<%= raw #hello %>
</script>
<style type="text/css" media="all">
<%= #body.html_safe %>
</style>

Best way to include javascript in Rails via content_for

I have some pages in my Rails application that need one off bits of javascript to be included, ideally just before the </body> tag. There is no real need to have this javascript included on EVERY page since most don't use it. I've found a way to make this work, but I think the code is terrible.
How would you do the same thing or how would you refactor the existing code?
View simplified, sample code on gist.github.com:
https://gist.github.com/scottswezey/ffc7bf52041b976b710a
(Or see the same code below:)
application.html.erb (Layout):
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<script>
$(function() {
<%= yield(:js) %>
});
</script>
</body>
</html>
some_view_file.html.erb (View):
<%
str = <<END_OF_STRING
$('.modal').modal()
END_OF_STRING
content_for :js do
str.html_safe
end
%>
Don't ever do it this way: JavaScript doesn't belong in HTML. Just put an appropriate <script> tag in the page, referring to an external JS file, something like this:
application.html.haml
!!!
%html
%head
= yield :javascript
%body
= yield
view file
- content_for :javascript do
= javascript_include_tag 'modal'
app/assets/modal.js
$(document).ready(function() {
$('.modal').modal();
}
This keeps everything nicely separated.
Is it possible to add a .js.erb partial with your JS and render it under the body?
edit: Check out this answer: https://stackoverflow.com/a/10113547/1283742

Rails 3 - Simplemodal pop up with forms

I am trying to use Simplemodal as a pop up box on an index page and put a form to add a new user inside it. It's not working, says there is an undefined method. How do I make this work? Does it have to do with :remote?
EDIT - Here's some code to hopefully explain a little better - from index.html.erb
<div id='basic-modal'>
<input type='button' name='basic' value='Demo' class='basic'/>
</div>
<!-- modal content -->
<div id="basic-modal-content">
<%= render 'form' %>
</div>
My form is the standard scaffold form, my Client model has a place to add some basic information about a client. My controller is the standard controller that is generated with scaffold, and my application.html.erb adds the required .js files. When I take the
<%= render 'form' %>
out and put in just plain text, it works just fine. Does that help?
Although I haven't found the answer to using simplemodal for a modal box, I found this tutorial at Nettus which uses modalbox and facebox:
http://net.tutsplus.com/tutorials/ruby/how-to-build-an-unobtrusive-login-system-in-rails/
With a few changes for rails 3, this helped me put a form inside a modal box with no problems.

Resources