Thanks to AJ Chen for allowing me to present my take on Enterprise Social Networking at the Semantic Web SIG. It was a real pleasure and look forward to returning if asked.
I am making my presentation available since I didn't have time to make it to the end. Also, please check out Collaboration and the social enterprise, and article about salesforce.com's Chatter strategy and a great interview with Parker Harris, salesforce.com co-founder.
Wednesday, May 5, 2010
Monday, January 11, 2010
Simple Object Iteration for Visualforce
Although I haven't actually run this code and it should be considered psuedo code, this is a simple example of how to retrieve a parent and it's children and then bind the data to a nested list. You could adapt this to generating a navigation menu for instance.
public class WebsiteMenu {
public List<menuItem> menuItems {
get {
if (menuItems == null) {
menuItems = [Select Id, Page_Title__c, Action__c (Select Id, Page_Title__c, Action__c From Sub_Menus) From WebSite_Data__c];
}
return menuItems;
} set; }
}
<apex:page controller="Websitemenu">
<apex:repeat value="{!menuItems}" var="items">
<a href="{!items.Action__c}">{!items.Page_Title__c}</a>
<apex:repeat value="{!mentItems.Sub_Menus}" var="subs">
<a href="{!subs.Action__c}">{!subs.Page_Title__c}</a>
</apex:repeat>
</apex:repeat>
</apex:page>
A more concrete example is shown below. I've basically created a table for a top level menu called MenuItem and a table for sub menus called SubMenuItem. Each table has a name field that holds the label for the menu item and an action field to hold the link for the menu item. The sub menu table has a lookup relationship to the menu table allowing each sub menu item to be parented by only one menu item. This also allows me to, in a single query, select all the menus and sub menus.
Click "here to see a working sample".
The page uses a "custom component", a controller for the custom component and a simple page.
Component:
<apex:component controller="MenuController" selfClosing="true">
<apex:stylesheet value="{!URLFOR($Resource.menuStyle, 'menuStyle.css')}"/>
<apex:dataList id="cssdropdown" styleClass="headlink" value="{!topLevelItems}" var="topLevel">
<a href="{!topLevel.Action__c}">{!topLevel.Name}</a><br />
<apex:dataList value="{!topLevel.Sub_Menu_Items__r}" var="nextLevel">
<a href="{!nextLevel.Action__c}">{!nextLevel.Name}</a><br />
</apex:dataList>
</apex:dataList>
</apex:component>
Notice that the first line of the component pulls in a style sheet that handles the formatting of the lists.
CSS:
/* General */
ul.headlink,ul.headlink ul { list-style: none; }
ul.headlink, ul.headlink * { padding: 0; margin: 0; }
/* Head links */
ul.headlink li { width: 220px; float: left; margin-left: -1px; border: 1px black solid; background-color: #e9e9e9; text-align: center; }
ul.headlink li a { display: block; padding: 15px; }
/* Child lists and links */
ul.headlink li ul { display: none; border-top: 1px black solid; text-align: left; }
ul.headlink li:hover ul { display: block; }
ul.headlink li ul li a { padding: 5px; height: 17px; }
ul.headlink li ul li a:hover { background-color: #333; }
/* Pretty styling */
body { font-family: verdana, arial, sans-serif; font-size: 0.8em; }
ul.headlink a { color: white; }
ul.headlink ul li a:hover { text-decoration: none; }
ul.headlink li { background-color: white; background-image: url(bg.gif); }
ul.headlink li ul { background-image: url(bg.gif); background-position: bottom; padding-bottom: 0px; }
The css and the bg.gif are saved in a flat archive (no folders in the archive) and stored as a static resource.
The controller simply defines the SOQL used to pull the menu and sub menu items.
Apex Code:
public class MenuController {
public List<MenuItem__c> getTopLevelItems() {
return [Select Id, Name, Action__c, (Select Id, Name, Action__c From Sub_Menu_Items__r) From MenuItem__c];
}
}
Finally, the actual page implementation just adds the custom component.
Page:
<apex:page showHeader="false" >
<center>
<br/>
<c:Menu />
</center>
</apex:page>
To change the way the menu items or ordered, you could easily create a number field to use for sorting in the SOQL statement on both menu and sub menu. The dataList component renders a standard HTML ul element with an li element for each of the items that are iterated over.
Cheers
public class WebsiteMenu {
public List<menuItem> menuItems {
get {
if (menuItems == null) {
menuItems = [Select Id, Page_Title__c, Action__c (Select Id, Page_Title__c, Action__c From Sub_Menus) From WebSite_Data__c];
}
return menuItems;
} set; }
}
<apex:page controller="Websitemenu">
<apex:repeat value="{!menuItems}" var="items">
<a href="{!items.Action__c}">{!items.Page_Title__c}</a>
<apex:repeat value="{!mentItems.Sub_Menus}" var="subs">
<a href="{!subs.Action__c}">{!subs.Page_Title__c}</a>
</apex:repeat>
</apex:repeat>
</apex:page>
A more concrete example is shown below. I've basically created a table for a top level menu called MenuItem and a table for sub menus called SubMenuItem. Each table has a name field that holds the label for the menu item and an action field to hold the link for the menu item. The sub menu table has a lookup relationship to the menu table allowing each sub menu item to be parented by only one menu item. This also allows me to, in a single query, select all the menus and sub menus.
Click "here to see a working sample".
The page uses a "custom component", a controller for the custom component and a simple page.
Component:
<apex:component controller="MenuController" selfClosing="true">
<apex:stylesheet value="{!URLFOR($Resource.menuStyle, 'menuStyle.css')}"/>
<apex:dataList id="cssdropdown" styleClass="headlink" value="{!topLevelItems}" var="topLevel">
<a href="{!topLevel.Action__c}">{!topLevel.Name}</a><br />
<apex:dataList value="{!topLevel.Sub_Menu_Items__r}" var="nextLevel">
<a href="{!nextLevel.Action__c}">{!nextLevel.Name}</a><br />
</apex:dataList>
</apex:dataList>
</apex:component>
Notice that the first line of the component pulls in a style sheet that handles the formatting of the lists.
CSS:
/* General */
ul.headlink,ul.headlink ul { list-style: none; }
ul.headlink, ul.headlink * { padding: 0; margin: 0; }
/* Head links */
ul.headlink li { width: 220px; float: left; margin-left: -1px; border: 1px black solid; background-color: #e9e9e9; text-align: center; }
ul.headlink li a { display: block; padding: 15px; }
/* Child lists and links */
ul.headlink li ul { display: none; border-top: 1px black solid; text-align: left; }
ul.headlink li:hover ul { display: block; }
ul.headlink li ul li a { padding: 5px; height: 17px; }
ul.headlink li ul li a:hover { background-color: #333; }
/* Pretty styling */
body { font-family: verdana, arial, sans-serif; font-size: 0.8em; }
ul.headlink a { color: white; }
ul.headlink ul li a:hover { text-decoration: none; }
ul.headlink li { background-color: white; background-image: url(bg.gif); }
ul.headlink li ul { background-image: url(bg.gif); background-position: bottom; padding-bottom: 0px; }
The css and the bg.gif are saved in a flat archive (no folders in the archive) and stored as a static resource.
The controller simply defines the SOQL used to pull the menu and sub menu items.
Apex Code:
public class MenuController {
public List<MenuItem__c> getTopLevelItems() {
return [Select Id, Name, Action__c, (Select Id, Name, Action__c From Sub_Menu_Items__r) From MenuItem__c];
}
}
Finally, the actual page implementation just adds the custom component.
Page:
<apex:page showHeader="false" >
<center>
<br/>
<c:Menu />
</center>
</apex:page>
To change the way the menu items or ordered, you could easily create a number field to use for sorting in the SOQL statement on both menu and sub menu. The dataList component renders a standard HTML ul element with an li element for each of the items that are iterated over.
Cheers
Thursday, December 17, 2009
Subscribe to:
Posts (Atom)