Is there a way to personalize the view related to only one action?
For instance I have the action campaigns#index and I want index.html.erb only to have an image background, because all the csss are included in one file how can I work out this problem?
Have you tried something like
<% if (params[:action] == "index") %>
...your code here, setting class="special-background"
<% else %>
...alternate code here, not setting the class
<% end %>
Then all you need to so is set the css for that class to show your background.
You can use css selectors to specify a background for just the index page. For instance, if you wanted to have a background on just the content of the index page, you could have your view look something like:
<div id='campaigns-index'>
<!-- some content -->
</div>
And then in your css do something to the effect of:
div#campaigns-index {
background-image: ...
}
I suggest you read up on css selectors (particularly ids). Here's a link.
Related
Using Rails (4.1.4) and Ruby (2.1.2), what would be the most DRY way to implement different background images based on different controller actions? Would I need to move HTML code tags out of /app/views/layouts/application and move them into the separate view pages or is there a better way to do it?
You could use the content_for method. described here
Essentially, in your layout you might have
<body class="<%= yield #body_class %>">
Then in your views you could do
<% content_for :body_class do 'class-name' end %>
<!-- regular view HTML -->
Just use different classes on your element based on your action name and then apply different background images on those classes
Rails has controller_name and action_name helpers to get your controller name and action name so you can do:
<div class="<%= 'class_name' if action_name == 'show' %>">
</div>
And if you want to use the same class name as your controllers action then you can do
<div class="<%= action_name %>">
</div>
If you are using same layout for different controllers then you can utilize rails controller_name with action_name to make a unique class, something like:
<div class="<%= controller_name action_name %>">
</div>
Then use css accordingly, lets say you have home controller and new and show action then you can do
.home.show{
background: image-url("pic1.png");
}
.home.new{
background: image-url("pic2.png");
}
You can add dynamic class name on the element (which should have bg img)
# your '.html.erb' template
<body class="<%=controller_name%>-<%=action_name%>">
...
</body>
# your css file
// for user_controller's 'new' action
body.user-new {
background-image: url(http://cdn.topshelfcomix.com/catalog/covers/any_empire_cover_sm_lg.jpg);
}
// for profiles_controller's 'show' action
body.profile-show {
background-image: url(http://mrzine.monthlyreview.org/2011/images/latuff_egypt_by_any_means_necessary_a.gif);
}
That's it.. Enjoy!!
the problem is this:
I have my application layout file looks like this:
app/views/layouts/application.html.erb
...
<section>
<%= yield %>
</section>
...
Now what I would like to do is set the class of the section element dynamically, depending on what view I'm rendering
for instance, if I'm rendering a Dashboard view from:
/app/views/admin/news_items/index.html.erb
I would like the class of the section element dynamically be set to "dashboard":
<section class="dashboard">
<%= yield %>
</section>
Is this possible with Rails?
thanks for your help,
Anthony
As far as i can understand you want specific namespaces to have different layouts right?
You can achieve easily this by specifying different layout for different controllers/namespaces
# In DashboardController
layout 'dashboard'
The above will use the dashboard.html.erb under app/views/layouts for all the actions that are inside the DashboardController or inherit from it.
I hope that helps
Maybe you could do something like this?
<section class="<%= controller.controller_name %>-<%= controller.action_name %>">
This will add a class like so
<section class="dashboard-show">
Source: https://stackoverflow.com/a/16813823/3651372
I have a view with a bunch of elements in it.One of them (a div) is shown depending of a value that changes inside a select_tag (also within the same page).
I'm getting the selected ID from the select_tag element
$('#some_id').on('change',function(){
//$(this).val()
})
but then just don't know how to fetch the object and check for one of its properties and that way know if I should show the div or not?.
I thought of sending that id to the server...do whatever I need over there and then come back to the view and try something like this
<% if some_condition %>
<div>
...
</div>
<% end %>
This (of course) might not be the way.I'd be glad to understand how this happens
You way of doing it after getting some data from the server onChange of the select would work. You might also consider this approach.
But if you could pre-populate the divs and add a class or some other attribute it with which you could relate to the chosen option in the select field, then you can prevent the server call entirely.
<div class="opt1Val selectOptsDiv"> </div>
<div class="opt2Val selectOptsDiv"> </div>
<div class="opt3Val selectOptsDiv"> </div>
hide all these divs initially with css display: none;.
$('#some_id').on('change',function(){
var selectedOptionVal = $(this).find("option:selected).val();
$("." + selectedOptionVal).show();
})
But I guess you would be able to do this if the showing and hiding of the div's depend only on the selected option value and do not have to go through some other processing at the server end.
I am using tabs and want to load multiple index pages into tabs. For instance:
class AnimalsController < ApplicationController
def index
#dogs = Dog.all
#cats = Cat.all
end
end
Then in my views/animals/index.html.erb
<ul class="tabs">
<li>Dogs</li>
<li>Cats</li>
</ul>
<div id="#dogs">
<%= render #dogs %>
</div>
<div id="#cats">
<%= render #cats %>
</div>
Is refactoring out into a partial the only way to achieve this?
I'd like to have them loaded statically at once and not have to resort to doing an Ajax.load() when the tab is clicked.
You have your answer in the question itself. Why don't you just use javascript to hide the two partials and call them when their respective tab is clicked? You don't need ajax for this at all :)
Since you did not mention the javascript library that you use, I will give a generic solution using jquery:
Also you need not add a # to your respective div's ids. Change it to this:
<ul class="tabs">
<li id="dogs">Dogs</li>
<li id="cats">Cats</li>
</ul>
<div id="dogs" class="subTabs">
<%= render #dogs %><hr />
</div>
<div id="cats" class="subTabs">
<%= render #cats %><hr />
</div>
$(document).ready(function() {
$('.subTabs').hide(); //Hide the subTabs as soon as the DOM is loaded.
$('li').live('click', function(e) {
$('.subTabs').hide(); //Calling this again so as to remove an already loaded
tab, if any. You can refactor this part to make it
even simpler.
$('body').find('.subTabs').attr('id',$(this).attr('id')).show();
//This finds the ".subTabs" whose id is the same as the "li" id that
was clicked and shows it. Ofcourse, even this can be made even more
compact had i known your entire DOM structure.
});
});
Edit:
You also have to make sure that you style it using CSS to make it look more like tabs if you haven't already. :)
Hope this helps. :)
You typically only want to use a partial if you are using the same or almost the same code in more than one place.
When you say "index page", do you really want to use the same code that is used in an index of another controller? If so, then a partial is the best strategy.
Don't use JavaScript to solve a layout / code organization problem.
I am aware that views should not have code in them but in a project I am working on I have a lot of logic in the views.
My home page has
<% Html.RenderPartial("SearchResults"); %>
Now in the partial view I have an aweful lot of logic like this;
<div id="RestaurantsList">
<%if (Model.restaurantsList.Count() > 0)
{
foreach (var item in Model.restaurantsList)
{ %>
<% Html.RenderPartial("SearchResult", item); %>
<%
} %>
<%
}
else
{
Html.RenderPartial("NoResults");
} %>
Now I could make the home controller return a different view based on the list being empty but I don't really want that as the Index view has a few things that I want displayed no matter if there are results or not.
The only other thing I can think of here is to encapsualte this in a helper method like Html.SearchResults. But then I would need the helper to call the renderPartial for each search result also. That doesn't seem like clean seperation of concerns.
I would still have to have the first if statement in the partial view though.
How would you best handle this?
My personal opinion is that this is okay. The logic that you've used is totally related to how the model needs to be displayed.
You just need to be aware and make sure that you're never mixing in business logic, data access logic or anything else that isn't strictly tied in to the display of the model.
I agree with Praveen Angyan's answer. The only thing I could say to extend his answer is to put some of the logic in the ViewModel.
For example in the ViewModel you could hide
Model.restaurantsList.Count() > 0
behind a method or property.
E.G.:
<%if (Model.HasResturant){...}%>
this answer has nothing to do with your question.
However, I just want to let you know that calling Html.RenderPartial() inside a loop is not efficient.
ASP.NET MVC - For loop inside RenderPartial or Outside RenderPartial
Changing it to something like below would be better.
<%if (Model.restaurantsList.Count() > 0)
{
// render the Restaurant item right away
foreach (var item in Model.restaurantsList) { %>
<div>
<%= Html.Encode(item.RestaurantName); %><br />
<%= Html.Encode(item.Address); %>
</div>
<% }
}
else
{
Html.RenderPartial("NoResults");
} %>
Praveen Angyan is correct - that's view logic and it's fine that it is where it is.
But that does not change need for tidier views.
Just wanted to share small improvement.
If we attach tiny HtmlHelper method, we can shorten view to something like this:
<div id="RestaurantsList">
<% if (Model.HasRestaurants)
Html.RenderPartialForEach("SearchResult", Model.restaurantsList);
else
Html.RenderPartial("NoResults"); %>
</div>
For some - it might not look readable and nice, but it fits for me good enough.