0

I have a model called a package with a number of attributes (package resources). I want to display the content of the package in a set of tabbed fields - with one for each selected resource.

If a resource is not involved in a project, then there won't be a tab for it displayed in the view.

I have set up the tabs so they only display if the resource is selected as true. That is done as follows:

<div class="dp-tab-1">
    <ul class="dp-tab-list row" id="myTab">
       <% if @project.package.has_background_ip == true %>
         <li class="col-md-2 col-xs-6 active" >
              <a href="#tab-content-first">
                 <span class="glyph-item" data-icon="&#xe043;"></span> 
              </a>
         </li>
      <% end %>

      <% if @project.package.has_data == true %>    
          <li class="col-md-2 col-xs-6">
             <a href="#tab-content-second">
                 <div class="glyph-item" data-icon="&#xe05c;"></div>
             </a>
          </li>
      <% end %>

      <% if @project.package.has_material == true %>   
          <li class="col-md-2 col-xs-6">
              <a href="#tab-content-third">
                   <div class="glyph-item" data-icon="&#xe04c;"></div>
              </a>
          </li>
      <% end %>
 </ul>

The problem with the bit above is that the active tab is designated inside the first tab. If the first tab is not a required resource, then the next two tabs may be included (if required) but the first of them to be true will not have the designation of true.

How do I dynamically allocate 'active tab' status to the first true condition so that the tab content displays for the active tab.

  <div class="dp-tab-content tab-content">
                                        <div class="tab-pane row fade in active" id="tab-content-first">
                                            <% if @project.package.has_background_ip == true %>
                                                <div class="col-md-6 text-center">
                                                    <%= image_tag(@project.package.background_ip.bip_image, :class=>"wow fadeInLeft img-responsive", :alt=>"123") %>

                                                </div>
Mel
  • 2,481
  • 26
  • 113
  • 273

1 Answers1

0

First, you don't have to compare to true explicitly using == true. Go straight.

<% if @project.package.has_background_ip %>

Second, why not implement a very simple check in the helper to define which tab should be active and then use that index. Helper:

# will return 1 if has_background_ip is true
# if not, will return 2 if has_data is true
# if both are false, will return 3 if has_material is true
# return -1 if all are false
def firstActiveTab 
  return case
  when @project.package.has_background_ip
     1
  when @project.package.has_data
     2
  when @project.package.has_material
     3
  else
     -1
  end
end

And then in the view (erb), code will add active class for first tab only, if firstActiveTab method returned 1 (which means has_background_ip is true).

<li class="col-md-2 col-xs-6 <%= 'active' if firstActiveTab == 1 %>" >
  ... first tab content for background_ip...
</li>
<li class="col-md-2 col-xs-6 <%= 'active' if firstActiveTab == 2 %>" >
  ... second tab content for has_data...
</li>

use == 1 for first tab code, == 2 for second, etc.

Pavel Bulanov
  • 933
  • 6
  • 13
  • Hi Pavel, but what about where background ip is not true, then data should be the active tab, but if it's number is 2, then the tab won't be active if I use the view code you suggest. – Mel Jun 04 '16 at 00:18
  • Why not? if @ project.package.has_background_ip is false and @ project.package.has_data is true the return result of firstActiveTab will be 2. (try running the code). Then if you write
  • > for your second tab in .erb file, it will have active attribute.
  • – Pavel Bulanov Jun 04 '16 at 06:46
  • Isn't the problem that this process identifies the active tab, where the code, the way I have it (albeit wrong) is on the tab content? – Mel Jun 04 '16 at 07:33
  • Pls clarify what you mean. You can easily put this code to .erb file if you want (although not convenient). Rather put it in [helper](http://stackoverflow.com/questions/3992659/in-rails-what-exactly-do-helper-and-helper-method-do). Also see [here](http://mixandgo.com/blog/the-beginner-s-guide-to-rails-helpers) for helpers – Pavel Bulanov Jun 04 '16 at 07:44
  • I mean that if background_ip is not true, how does the helper know to make data = 1? – Mel Jun 05 '16 at 23:47
  • It seems that I completely misunderstand your question, what you're trying to achieve. Please update the question so it's clear what is the active tab (what is active? css class? name? focus?), what is the structure of tabs (you have tabs inside tabs? you have multiple tabs inside multiple tabs? how are the layed?) what is designation of true? (is it css class? smt?) what should happen in which case? (what happens if has_background_ip is true? what if not? how this works). – Pavel Bulanov Jun 06 '16 at 09:16
  • The first
  • tag in my extracted code above includes an 'active' tab. That is fine if background_ip is true. It's not fine if background_ip is not true because, the next tab that is true (suppose has_data were also not true, but has_material is true, then the active tab should be on the has_material list item. That's what I'm trying to achieve.
  • – Mel Jun 06 '16 at 23:03
  • Ok. Then the code provided should work for you. Review the method definition - it returns 1 if has_background_ip is true. If it's false _and_ has_data is true, it will return 2. If both has_background_ip _and_ has_data are false _and_ has_material is true, it will return 3. If all properties are false, it will return -1. – Pavel Bulanov Jun 07 '16 at 09:44
  • Thanks very much again for the help and the explanation – Mel Jun 08 '16 at 02:32
  • Actually, I've just realised that this solution creates a new problem. The tab content is now hidden until I click on the tab label. I'll make a new post to try to find some help solving that problem. – Mel Jun 08 '16 at 02:42