{empowering business}
Grouping fields together in Drupal Views
During a recent project, I needed to group several fields together within a Drupal view. I was creating a dissolving jQuery slideshow with a control panel. Each slide consisted of a fixed-size background image and a body field containing HTML on top of the image. In addition, there is a "counter" field that displays a control button for each slide. The control buttons for all slides are grouped together outside the area that dissolves. The user can see which slide is currently active and flip between slides using those buttons. Because I needed to dissolve the backgrounds images and body fields together, but leave all the control buttons visible, I wanted to group each background image with its corresponding body field.
Here is a screenshot of the final product:

It's a pretty typical slideshow: the right side is the slide (the part that dissolves), and the control buttons are on the bottom of the left pane. (We are currently on slide three.)
The control buttons change by the use of a background image sprite, controlled by an "active" class. But the buttons for all four slides need to be visible at all times, whereas only one slide is visible at once. The simplest way to do this is to group the body and background image together within a div, and hide that entire div for the slides not currently active.
Getting those three fields into our view is pretty simple:

Note the order of the fields. I put the background image before the body; the order is very important, and it will come into play below.
By default, here is what the HTML for the view looks like:
<ul>
<li class="views-row views-row-3 views-row-odd">
<div class="views-field views-field-field-feature-background">
<div class="field-content">
<img width="668" height="364" alt="" src="http://iasta.arsnova.cc/sites/default/files/whitepaper_0.jpg" typeof="foaf:Image">
</div>
</div>
<div class="views-field views-field-body">
<div class="field-content">
<div style="position: absolute; top: 248px; left: 116px;">
<div class="feature-arrow"> </div>
<h2>SOLVE your Procurement Problems </h2>
<p>How to integrate Contract Management within your strategy</p>
<a class="arrow views-ajax-processed-processed" href="#"> Get the eGuide </a>
</div>
</div>
</div>
<div class="views-field views-field-counter">
<span class="field-content"> 2 </span>
</div>
</li>
</ul>
Note: I'm showing just the one row here. In reality, this was the third of four rows.
This is one of the best uses I have for a "view results counter" in Drupal Views. It outputs an integer index for each row (0, 1, 2, 3, etc.). Via CSS, I just turn that number into a control button:
#block-views-features-block ul .views-row .views-field-counter {
display: block;
position: absolute;
text-indent: -9999px;
height: 16px;
width: 16px;
background-image: url(images/sprites.png);
background-repeat: no-repeat;
background-position: -365px -53px;
cursor: pointer;
}
#block-views-features-block ul .views-row .views-field-counter:hover,
#block-views-features-block ul .views-row .views-field-counter.active {
background-position: -336px -53px;
}
So, styling aside, the main thing I want to accomplish is to group the background image and body field together. That will make fading them in and out together without affecting the control buttons much easier. I'm guessing this could be done through PHP templates within the view. But there's a much simpler way to do it.
First, edit the background image field, selecting the option to "exclude from display":

Next, edit the body field, selecting to "rewrite results":

So we're rewriting this field, inserting tokens for both the body and field_feature_background fields. I've wrapped it within a <div id="fade-wrapper">. As it turns out, this was unnecessary. I'll probably take that div out at some point. But it serves to show that you can add markup and other fields to any single field.
Remember above where I said the original order of the fields is important? This is where that comes into play. If I had not arranged the fields such that the background image came before the body when I initially placed them in the view, the background image token would not show up here.
Now that I've saved these options, here is what the HTML looks like:
<ul>
<li class="views-row views-row-3 views-row-odd">
<div class="views-field views-field-body">
<div class="field-content">
<div id="fade-wrapper">
<div style="position: absolute; top: 248px; left: 116px;">
<div class="feature-arrow"> </div>
<h2>SOLVE your Procurement Problems </h2>
<p>How to integrate Contract Management within your strategy</p>
<a class="arrow views-ajax-processed-processed" href="#"> Get the eGuide </a>
</div>
<img width="668" height="364" alt="" src="http://iasta.arsnova.cc/sites/default/files/whitepaper_0.jpg" typeof="foaf:Image">
</div>
</div>
</div>
<div class="views-field views-field-counter">
<span class="field-content"> 2 </span>
</div>
</li>
</ul>
Because we excluded the background image field, it does not show up here as its own field. Rather, the image shows up within the body field (via the rewrite token). Again, the <div id="fade-wrapper"> is overkill, but hey, it fits in with all the other div bloat that we get with a CMS, right? :)



Comments
This rewrite trick is genius.
This rewrite trick is genius. It wouldn't have occurred to me otherwise. Thanks for the great blog post!
I'm glad it worked out for
I'm glad it worked out for you. It's amazing how the simplest things can sometimes take forever.