Wednesday, May 5, 2010

SD Forum Social CRM

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.

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

Thursday, December 17, 2009

Test the Email Bits

This is a test