+ Start a Discussion
ColinKenworthy1ColinKenworthy1 

Can Visualforce display items horizontally

Nomal behaviour in vf tables is to display one object per row of a table, with your desired fields as columns.

I'm trying to create a page where only one field per object is shown but they are displayed horizontally.

 

<apex:dataTable id="teamtable" value="{!MyTeam}" var="person">
  <apex:column > <apex:image url="{!person.Photo_URL__c}" height="150" width="200" /> </apex:column>
  <apex:column > <apex:outputText value="{!person.Name__c}" /> </apex:column>
</apex:dataTable>

 

So this is displaying all the team members vertically with a lot of white space on the right. Ideally I'd like to have 4 or 5 team members photos on a line each with their name underneath. Is this possible in VF ?

 

Best Answer chosen by Admin (Salesforce Developers) 
wesnoltewesnolte

Ah, CSS can be really tough at times. I've been working with it for years and it can still be quite confusing. Try to float all your divs, that should work i.e.

 

on your outer div set style="float:left"

and on your repeated divs set style="float:left;width:50px;height:50px"

 

Tell me if you get any weird results.

 

Cheers,

Wes

All Answers

wesnoltewesnolte

Hi Colin

 

It should be:) There's a nifty component called <apex:repeat>. It works similarly to dataTable except that it simple moves through a list of values and you can choose the display.

 

Cheers,

Wes 

ColinKenworthy1ColinKenworthy1

Cheers Wes

The only drawback to that is that if you use it "within a pageBlockSection or panelGrid component, all content generated by a child repeat component is placed in a single pageBlockSection or panelGrid cell. This component cannot be used as a direct child of the following components: dataTable, pageBlockTable, panelBar, selectCheckboxes, selectList, selectRadio, tabPanel."

I would have preferred for this to be pure Visualforce, but for this I think you can only do it with HTML.

 

<table style="text-align:center;"> <tr> <apex:repeat id="myTeamRow1" value="{!Selected}" first="0" rows="4" var="person"> <td>
<apex:image id="piccy" url="{!person.Photo_URL__c}" alt="{!person.Name__c}" height="150" width="200" />
<br />
<apex:outputLabel for="piccy" value="{!person.Name__c}" />
</td>
</apex:repeat> </tr> <tr> <apex:repeat id="myTeamRow2" value="{!Selected}" first="4" rows="4" var="person"> <td>
<apex:image id="piccy" url="{!person.Photo_URL__c}" alt="{!person.Name__c}" height="150" width="200" />
<br />
<apex:outputLabel for="piccy" value="{!person.Name__c}" />
</td>
</apex:repeat> </tr> <tr> ...etc...

</tr>

</table>

 Though this means deciding up front how many rows you are going to display which may not be appropriate in the future.

 

 

angusgrantangusgrant
Thanks for this post it should be very usefull.
wesnoltewesnolte

Hey Colin

 

Why not use it within an outputPanel. Set the layout="block" and you have a div, and could repeat outputPanels(divs) inside that 'wrapper' div. Strictly speaking you shouldn't use tables for HTML structure.. according to my school of thought that is:)

 

Cheers,

Wes 

ColinKenworthy1ColinKenworthy1

 

My page is now set up as an outputPanel within a Repeat within an outputPanel to produce divs within a div.

<apex:page standardController="Personnel__c" recordSetVar="Persons"> <apex:outputPanel layout="block"> <apex:repeat id="myTeam" value="{!Selected}" var="person" > <apex:outputPanel layout="block"> <apex:image id="piccy" URL="{!person.Photo_URL__c}"/ width="50" height="50"> </apex:outputPanel> </apex:repeat> </apex:outputPanel>

</apex:page>

 

And in the VF output page:

... <table class="outer" width="100%" id="bodyTable" border="0" cellspacing="0" cellpadding="0"> <!-- Start page content table --> <tr><td class="oRight" id="bodyCell"> <!-- Start page content --> <a name="skiplink"><img src="/s.gif" height='1' width='1' alt="Content Starts Here" class="skiplink" title="Content Starts Here"/></a> <div id="j_id0:j_id1"> <div id="j_id0:myTeam:0:j_id2"><img id="j_id0:myTeam:0:piccy" src="/resource/1244482177000/ann" height="50" width="50" /></div> <div id="j_id0:myTeam:1:j_id2"><img id="j_id0:myTeam:1:piccy" src="/resource/1244482177000/abi" height="50" width="50" /></div> <div id="j_id0:myTeam:2:j_id2"><img id="j_id0:myTeam:2:piccy" src="/resource/1244482177000/col" height="50" width="50" /></div> <div id="j_id0:myTeam:3:j_id2"><img id="j_id0:myTeam:3:piccy" src="/resource/1244482177000/rich" height="50" width="50" /></div> <div id="j_id0:myTeam:4:j_id2"><img id="j_id0:myTeam:4:piccy" src="/resource/1244482177000/ivan" height="50" width="50" /></div> <div id="j_id0:myTeam:5:j_id2"><img id="j_id0:myTeam:5:piccy" src="/resource/1244482177000/bruce" height="50" width="50" /></div> <div id="j_id0:myTeam:6:j_id2"><img id="j_id0:myTeam:6:piccy" src="/resource/1244482177000/pam" height="50" width="50" /></div> <div id="j_id0:myTeam:7:j_id2"><img id="j_id0:myTeam:7:piccy" src="/resource/1244482177000/kev" height="50" width="50" /></div> </div> ...

 

 

So it's nesting a series of div blocks inside another div block but they display vertically one above the other, not side by side. VF is outputting the whole lot inside a table cell too. But this displays vertically one div above the other not side by side as intended. My only thought now is to check the css for the 'outer' and 'oRight' classes and see if there is something I should override.

 

 

 

 

wesnoltewesnolte

Ah, CSS can be really tough at times. I've been working with it for years and it can still be quite confusing. Try to float all your divs, that should work i.e.

 

on your outer div set style="float:left"

and on your repeated divs set style="float:left;width:50px;height:50px"

 

Tell me if you get any weird results.

 

Cheers,

Wes

This was selected as the best answer
ColinKenworthy1ColinKenworthy1

Yep, you are right, I have to drop my 'table' mentality. The floating divs work a treat.

The outer div is not really neccessary but if it is there it doesn't need the float:left. The inner divs do need float:left but the width/height is ignored by the images if they are larger than the dimensions specified, the images end up overlapping! Their top corners are positioned 50px apart but rendered at their full size. The width/height therefore has to go with the image and then let the div size itself to its child elements.

I've added a name under each corresponding image, but it always showed left aligned under the image. The only way to center it is to put it in another div with an align-text:center. After I got this working I found I could comment out 3 lines without affecting the page (this was in firefox, I haven't checked other browsers.)

My next task will be to try to make the image and name into a single component with the URL and Name as parameters.

Thanks for your help.

<apex:page standardController="Personnel__c" recordSetVar="Persons">
<!--  <apex:outputPanel layout="block"> -->
    <apex:repeat value="{!Selected}" var="person" >
      <apex:outputPanel layout="block" style="float:left;padding-top:10px;padding-left:10px">
        <apex:image URL="{!person.Photo_URL__c}" width="150" height="150" />
<!--        <br /> -->
        <apex:outputPanel layout="block" style="text-align:center">
          <apex:outputText value="{!person.Name__c}" />
        </apex:outputPanel>
      </apex:outputPanel>
    </apex:repeat>
<!--  </apex:outputPanel> -->
</apex:page>

 

wesnoltewesnolte

Cool beans.

 

It's tough to know how CSS will behave within Salesforce as there's alot of styling they perform too. I'd suggest getting firebug for firefox, it makes life a lot simpler.

 

Cheers,

Wes 

success22success22

Thank you so much for providing the solution. It helped me lot...

 

Thanks,

Success

DovaDova
apex:panelGrid could be an option.
Daniel RoblesDaniel Robles
Is there anything similar for lightning compents?