I've been trying to make the styling added to this flash message in my application layout work as desired:
<div id= "notice"><% flash.each do |key, value| %>
<%= value %>
<% end %></div>
Here's the CSS:
#notice {
background: #e6efc2;
color: #264409;
border-color: #c6d880;
padding: 0.8em;
margin-bottom: 1em;
border: 2px solid #ddd;
}
Now the problem with this is that the flash message is rendered with ajax, and so the styling is supposed to appear only when the flash message appears. However, this is not the case. A green div appears even when there is no flash message, and this looks rather awkward.
Now I've tried something like this:
<div id= "notice"><% flash.each do |key, value| %>
<div class="<%= key %>"><%= value %></div>
<% end %></div>
where I use the "<%= key%>" class for styling. I leave the <div id="notice"> on the outside for the ajax rendering because it doesn't seem to pick up the div within the ruby block. However, the CSS styling does not get rendered with the "<%= key%>" class. So it seems like i'm stuck between two bad options:
Have an awkward green div in my app at all times that only looks how it should when the flash message is rendered or
Not have the awkward green div, but then have no styling for the flash message so that it just looks like some awkward text.
Is there any way that I can get the best of both worlds?
I would setup display: none; for the #notice box and have this in the jQuery code
$('#notice').css('display', 'block')
You can have that right after you fill in the code and before you do the fadeIn, make sure you use callbacks so things don't jump around everywhere.
Can you share your AJAX that is generating this?
One thing I would try in your situation is using jQuery's append() method to add the flash DIV to the top of the page when the flash message is triggered, and then take it away after some timer.
--EDIT--
Here's a "for instance" example:
Let's just say your ajax call is hitting FoosController#Update, and is sent from the #show action.
In the show view I would have something like:
<div class="notices"></div>
I would put your flash messages in a partial (makes the ajax code easier), so something like
views/shared/_flash.html.erb...
<div class="flash"><% flash.each do |key, value| %>
<%= value %>
<% end %></div>
In jQuery + ERB I would write an update.js.erb file in the views/foos/
$('div.notices').append('<%= render 'shared/flash' %>');
Then to make it automatically fade out you could include a script (either in the specific view with flash messages or in the application.js file) like:
$(document).ready(function() {
$('div.flash').delay(5000).fadeOut();
});
That would make any div.flash fade out and disappear after 5 seconds. Alternatively you could make it go away after click using the jQuery click() method.
I hope that helps.
--EDIT AGAIN--
According to this railscast, to do this with RJS:
In your view create:
<div id="notices"></div>
In your RJS file do:
page.insert_html :bottom, :partial=>'shared/flash'
It's still a good idea to put your flash messages in a partial. Be sure and put the flash messages in div.flash as described in the first edit, and you should be good to go.
Yes. You can apply the styles with javascript when your ajax request comes in, or have the content of the request be wrapped in a container that has styles unique to it, which is not present on the original page.
Basically, hide the 'green box' until it is populated or send the 'green box' in with the ajax.
Related
I'm very new to Rails and I need to dynamically add/remove input fields on a "form_for" in Rails. I am using these inputs to alter a user's profile.
Here's the snippet I want to turn dynamic:
<%= f.label :languages, "Languages" %>
<%= f.text_field :languages, class: "shortInput", value: #parsed_json_user['user']['languages']%> <br />
I have seen many tutorials using nested attributes (I'm not even exactly sure about what those are) and such but I will not be using models. As you can see, I just want an object with a multitude of values (e.g. array) since I'll be using an API to update the "User" model.
I need something like:
Languages:
English remove
add new
Should I be using fields_for? Or somehow use JS or JQuery? Any help would be appreciated.
I searched everywhere for a similar question and haven't found any but if you actually know of or find one, pointing me in the right direction would be wonderful!
Thanks in advance
#languages = User's Languages
f.collection_select :user_languages[], #languages, :id, :name , {hide_label: true, :selected => #languages.first.id} , {:style => "width: 120px",:required => true}
Update: For single form, no nesting - one option is to hack together your own jquery. I had used a different site for my testing, but this Jquery example was the one I found easier. I removed the stuff about a counter for max fields ... it goes in the /app/assests/javascript/.js ...
$(document).ready(function() {
$(".add_field_button").click(function(e){ //on add input button click
e.preventDefault();
$('.input_fields_wrap').append('<div><input type="text" name="mytext[]"/>Remove</div>'); //add input box
}
});
$(".input_fields_wrap").on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove();
})
});
And the html code ...
<div class="input_fields_wrap">
<button class="add_field_button">Add More Fields</button>
<div><input type="text" name="mytext[]"></div>
</div>
If you're not having luck yet - Cocoon Gem or railscast 197/198 will do what you need with jquery which is dynamic. Ignore the parts about nesting and just take what you need from it.
Also, I'm still poking around in turbolinks which had an update recently...you might be able to find an answer there...probably not exactly what you would want...
From what I can tell is that is rely's on two paths you write in rails, that are then built upon via the jquery that acts on (add/delete) :before or :after the link_to_add_association or link_to_remove_association in order to add/hide fields from view on the dom & then the update button actually pushes the whole mess to through activeRecord into the database.
I was wondering if it possible to change the class of an image tag gotten from summernote.
Currently I am using summernote with rails4 and have implemented it the following way:
in creation of a new project
<%= form_for(#project, :html => { :multipart => true }) do |f| %>
<%= f.text_area :description, id:"summernote" %>
<script type="text/javascript">
$(document).ready(function() {
$('#summernote').summernote();
});
</script>
and when I show it
<%= #project.description.html_safe %>
If I insert an image like this it works but i would like to know two things:
1: Where does this image get stored? If I look at the source code generate it is just data:image/jpeg;base64,/9j/4S/(Bunch of random letters)
2:I would like give a class to all tags generated for images uploaded with summernote (and possibly save them using paperclip if possible)
Thanks for the help!
The "f.text_area" in your code will hold everything you enter in the summernote box entry. Once you submit the entry all images will be converted to base64 and stored directly in your database end server.
To apply your own tags on the images click on the "Code View" button found in summernote editing toolbar and locate your image code then manually place an opening <div class= "your-class"> before the image code and another closing <div> tag after your image code.
I have a simple app I'm following from a textbook. It's a store app and on the oft side of the page a shopping cart is shown. However, when the cart is empty it is supposed to be hidden. So I wrote a helper function to hide the cart whenever it is empty. This would have been east enough just to do in the html but it's how the book shows it. It works mostly. If I empty the cart it stops being displayed, but when I first open the page the cart will be invisible even if its not empty! Adding an item to it will then reveal it.
Here's the code:
application.html.erb
<div id="cart">
<% if #cart %>
<% hidden_div_if( #cart.line_items.empty?, id:"cart" ) do %>
<%= render #cart %>
<% end %>
<%end%>
</div>
application_helper.rb
module ApplicationHelper
def hidden_div_if(condition, attributes = {}, &block)
debugger
if(condition)
attributes["style"] = "display: none"
end
content_tag("div", attributes, &block)
end
end
Where I put the debugger statement, I checked the condition and it says it's false. So, I thin it's an issue with the html file. The controller sets the cart before hand with this code at the top.
include CurrentCart
before_action :set_cart
So, I'm not sure why it would show after a button is pressed but not on the initial page load. Any ideas?
thanks
You need to start with <%= in erb if you want to output the return value of a helper method. Change the line in which you call your helper method to:
<%= hidden_div_if(#cart.line_items.empty?, id: "cart") do %>
I am trying to give one of my views a background image. I have found info for rails three on how to do this, but it does not seem to work for me. Here is the link to the info I used: http://makandracards.com/makandra/2977-declare-different-css-background-images-for-different-locales
Here is my welcome.css.scss:
.container {
background-image: url(images/image.jpg)
}
here is welcome/home.html.erb:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= I18n.locale || 'en' %>"
lang="<%= I18n.locale || 'en'%>">
<body class="container">
</body>
</html>
Firstly, you won't need to determine a class for the body tag - just call body in your CSS (and override for the specific page you want the background image on)
Secondly, you need to use asset_path helpers:
#app/assets/stylesheets/application.css.sass
body
background:
image: asset-url("image.jpg")
This is the "correct" way to call this, as if you use .erb or any other other methods with the asset pipeline, you run the risk of losing your functionality when you precompile the assets for production
The trick is to use the rails asset preprocessors to allow the use of dynamic paths for your assets. The paths will be used depending on whether you're using your assets dynamically, or statically (in production)
Considering you have image.jpg in your /assets/images folder, the above code should work for you. The SCSS version would be:
#app/assets/stylesheets/application.css.scss
body
{
background: {
image: asset-url("image.jpg");
}
}
--
Update
You can call the welcome css like this:
#app/views/layouts/application.html.erb
...
<head>
<%= stylesheet_link_tag "welcome" if controller_name == "welcome" %>
</head>
CSS File name
welcome.css.scss -> welcome.css.scss.erb
Content
background-image: url("<%=image_path('image.jpg')%>");
I know this question was over a year ago, but none of the answers helped me so I figured out something more unorthodox in terms of managing the background image.
<% if action_name === "homepage" %>
<body class="body-change">
<% else %>
<body>
<% end %>
And then in the css.scss you could have something like:
.body-change {
background: red;
}
So I'm giving the body a certain class if a condition is met. So if I am on the homepage, the body's class will be something else and then I can add detail to that class in my CSS/SCSS. I hope this helps someone because it worked for me. You can also make the if statement more specific by also specifying a controller_name if you have multiple actions with the same name.
Please update your css file as
.container{
background-image: url("/assets/tooltip.png")
}
I have two forms in my rails app. They both exist in separate tabs and I when I submit one form I want the data in the other form to be saved as well. How should I do that? Or Is there a better way of doing this instead of using two separate forms? Is there a better way to spread a long form into multiple tabs and when I press submit all the data from all the tabs should reach my action. Thanks.
You can expand a single form to cover all elements of both forms.
This is perfectly ok, as long as the form tags fit validly into the X/HTML.
<form action='action1'>
<!-- All elements from both forms, plus tabs, etc. -->
</form>
The only thing to consider is if there will ever be another form inside that area that will need to go to another action. For example, if you add a third tab, in between the other two, that will have a different action.
You don't want to end up like:
<form action='action1'>
<!-- elements from the combined forms -->
<form action='action2'>
<!-- elements for a totally different form, not valid inside another form -->
</form>
<!-- more elements from the combined forms -->
</form>
In that case, it would be better to consolidate the two forms at submit time using JavaScript.
jQuery (jquery.com) would make this pretty easy. For example, you could serialize both forms, and then concatenate them and send the result to the server via post or get.
See http://docs.jquery.com/Ajax/serialize.
There might be better ways to do this, but I can't think of any off the top of my head.
I can't test if the concept work right now, but I believe that you could use jQuery to achieve that, its submit function will intercept all form submissions on any tab, something along these lines
$("form").submit(function(event){
event.preventDefault();
//serialize forms here and submit using jquery post
});
You should look into the fields_for method. You can do something like this:
<% form_for #house do |f| %>
<%= f.text_field :square_feet %>
<% fields_for #listing do |s| %>
<%= s.hidden_field :id %>
<%= s.text_field :asking_price %>
<% end %>
<%= f.submit %>
<% end %>
And then in your controller you'd do something like this:
house = House.find(params[:id])
house.update_attributes(params[:house])
listing = Listing.find(params[:listing][:id])
listing.update_attributes(params[:listing])
That's for an update, but you can do whatever you want in there.