Rails: Rendering Multiple index.html.erb on a Single Page - ruby-on-rails

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.

Related

Is there any elegant way to show active hyperlink style?

Maybe I've missed something, but I've found that it's quite difficult to show conditional attributes in rails. Many programmers use helper methods to achieve this, but it still seems like a tedious task. I wonder if anyone has an elegant method of achieving this.
To be clear, let's say we have some css component as below (this example comes from a github opensource css framework: https://primer.style/css/components/navigation), So how would I change an 'aria-current': 'page' attribute?
<nav class="UnderlineNav UnderlineNav--right">
<div class="UnderlineNav-body">
<a class="UnderlineNav-item" href="#url" aria-current="page">Item 1</a>
<a class="UnderlineNav-item" href="#url">Item 2</a>
<a class="UnderlineNav-item" href="#url">Item 3</a>
<a class="UnderlineNav-item" href="#url">Item 4</a>
</div>
</nav>
Finally, I solve it by a helper method as the follow. If you guys have some other simple way, please let me know. Many thanks.
def active_header_link(text, slug, options)
if current_page? slug
link_to text, slug, {'aria-current': 'page'}.merge(options)
else
link_to text, slug, options
end
end
then, just call it when necessarily like this
<%= active_header_link node.name, node_path(node.slug), class: 'UnderlineNav-item' %>

How to render each views without reloading in rails?

I have a problematic to render my views in my rails app.
I try to create a home page who load each tools of my app (5 - 6 different) but I want to allow users to call them one by one and without reloading the page (like some saas apps).
I tried with a welcome/index.html.erb page that render each views with ajax:
<button class="button1"></button>
<button class="button2"></button>
<button class="button3"></button>
<%= render "tools1/index %>
<%= render "tools2/index %>
<%= render "tools3/index %>
...
How could I do to show only tools 1 if the user click on button1, and then hide tools1 and show tools2 when the user click on button2, etc. ?
Another question, is it an efficient way to do that ?
Edit:
My fault, it wasn't clear. The point is that I don't want to render each page at the beginning, the perfect stuff will be to load (not just show) them page by page, just when the user call them
Thanks
A quick AJAX loader example
Add some links/buttons to your HTML:
<a class="ajax-load" href="/url1">Page 1</a>
<a class="ajax-load" href="/url2">Page 2</a>
<a class="ajax-load" href="/url3">Page 3</a>
<div class="ajax-content"></div>
Add this jQuery code:
$(document).ready(function(){
$('.ajax-load').on('click', function(e){
e.preventDefault();
$('.ajax-content').load($(this).attr('href'));
});
});
Now, when users click on any link, the content will be AJAX loaded.
Previous answer
Since you are rendering your pages in your view, you don't need to ajax load them again. I would suggest using some jQuery plugins to do this for you.
For example: tabs or accordion.

personalize the view related to one action

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.

Inserting HTML elements on rails view

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.

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