Archive

Archive for the ‘Apex’ Category

Salesforce.com Workflow to the Second

December 22nd, 2011 6 comments

I recently came across the requirement for a workflow rule to fire on the update of a record but only if the update occurred more than a couple seconds after the record was created. Why this crazy requirement? Here is a example of the problem I was faced with.

Image you have two custom objects, Exam and Question. There is a master detail relationship between the two where many Questions can be associated with one Exam. There are also some roll-up summary fields on the Exam that count number of questions, number answered correctly, etc. Now also image (lots of imagining today so I hope you can harness your inner child imagination skills) you have a Visualforce page that assigns exams to users. This Visualforce page essentially clones a an Exam and Questions and assigns these to a user. First it inserts the Exam and then all related Questions. On the Exam object there is a workflow rule that need to execute when an Exam is updated. The problem is this workflow rule kept firing every time I inserted Exams and Questions for a user. Why is this happening? I am only inserting records, right? Wrong-a-long-a-ding-dong!!!

So what is happening here? Why is an update occurring on the Exam record when all I am doing is inserting records? The culprit are those very cool, but pesky, roll-up summary fields. When you have a roll-up summary field on a record any time you insert or update a child record an update will occur on the parent. So in the example above every time I would insert the the Questions it would cause on update action on the Exam. This is documented but it might not be something you come across every day. It’s also not obvious as everything happens so fast in the code the Created Date and Last Modified Date on the Exam show the same values in the user interface. If you queried these two date fields you would see they are milliseconds apart.

So how to solve this? There are a few options. We could set a flag, a checkbox field, on the Exam called Disable Workflow that we set to true on the insert of the Exam and then after inserting the Questions we could uncheck this box. In our workflow rule we could prevent the rule from executing by referencing this field. This would work but I don’t like it for a couple reasons. The first is that I hate adding fields to the database that aren’t really needed. Secondly, it’s less efficient as it requires multiple DML (update) operations to make everything flow smoothly. Another options is to get super crafty with our workflow rule.

The insert of the Exam and Questions is going to be finished in milliseconds. What if we make the rule fire on updates but only on updates a few seconds after the record is created. What we need to do is determine the time between the created date of the record and now in seconds. When working with formula fields or validations rules the duration of one day is represented as the value of 1. If we know this we can use our superior deductive reasoning skills to figured out the value for one second.

1 / 24 = 0.0416667 is one hour
0.0416667 / 60 = .00069444 is one minute
0.00001157 = one second

Now in our workflow rule we have have a formula like this:

…and it will evaluate to true on updates but only if those updates are greater than 1 second after the record was created.

Categories: Apex, salesforce

August Force.com Developer Meetup

August 1st, 2011 No comments

The Seattle Force.com User Group is back in business. Let’s get together to discuss anything related to force.com/salesforce.com development.

When: Thursday, Auguest 4th, 4:00pm

Where:
F5 Networks
401 Elliott Avenue West
4th Floor, Einstein conference room
Seattle, WA 98119

Google maps link

I wanted to get this notice out as soon as possible and currently there are no specific demos or speakers planned so it will be more of an open forum. If you have something awesome you’d like to show off please let me know. I could always whip something up as well if we want to get down and dirty with some code dives.

Hope to see you there!

Categories: Apex, Technology, Visualforce

Dynamic Visualforce Components, why they scare the ish out of me

June 8th, 2011 19 comments

Dynamic Visualforce Components are coming and they scare me…a lot. Before we can even begin to discuss why we need to review the basics of the model-view-controller pattern. If you aren’t familiar with the MVC pattern here is the basic run down when it comes to web apps that use MVC. Model, this represents your database and contains information on they fields in your database, validation rules, relationships, etc. View, this is the visual display of a model or many models. It says output the fields of a record in HTML on some web page and style them this way. This is where you can visually control how the data is displayed to the user. Controller, this is the code that retrieves and manipulates data from the Model and then prepares it for the View to use. A web app will most likely consist of many Models, Views, and Controllers. Some people may want to overcomplicated the MVC pattern, and it does vary slightly based on the platform or framework, but for the most part this is exactly how it works 97% of the time. So in the force.com world it looks a little like this:

Model
These would be custom objects, you can add fields, create validation rules, and build relationships with other objects.

View
Visualforce pages are the view and allow you to output information from the model as an HTML webpage.

Controller
One or many Apex classes associated with a Visualforce page. Here you can query and manipulate data before it is sent to the view for output.

So what does any of this have to do with Dynamic Visualforce Components (DVCs)? The reason is that DVCs allow developers to completely mangle and destroy the model-view-controller design pattern. They allow you to completely define the display from the controller. So basically MVC becomes M(VehCiv) or perhaps Model Viewroller as the View and the Controller start to get all mixed up. Big flipping deal you might say, all of the other hip cool web technologies (Rails) allow you to inject markup from the controller. Yes, they do, and there are people in those communities that feel the exact same way I do about mixing aspects of MVC, just because you can doesn’t mean you should.

Here is a very basic example of how mixing up the MVC can cause trouble. Let’s say you are working on a project where you have a web designer who is great at making spiffy looking websites and a developer that understands all the back end work. If you keep the View and the Controller separate these people can work individually on their part of the project. When you start to combine the View and the Controller the web design guy might be waiting for the developer to get the output setup so he can style it. Or maybe even worse you end up have a web designer starting to poke around in controller code, not ideal.

Mixing the View and the Controller also makes things more complicated and difficult for others to understand. When looking through a controller you now have to start mentally separating the view code and the logic code. For the consultants out there that sometimes have to inherit other’s code I do not envy you when you have to dig through someone else messy code, DVCs will make it messier.

Okay Jason, we get the point, but there are times when we need DVCs to meet the project requirements! Are there? Do you really need to use them? Doubtful. Yes, there are some use cases out there that can only be solved with DVCs but these are actually pretty rare. So if you think you need to use DVC’s, think again, and the ask someone else, perhaps on the force.com developer forums, and then if you still think you need them go for it. Personally, I still can’t think of a super great example for DVCs, but I’m sure after this post I’ll be inundated with use cases where only DVCs can save the day!

So here is an example of using DVC vs not using them. This is actually the example taken from the recent Force.com Summer 11 webinar. The goal is to get an output that looks like this:

An unknown number of tabs is the dynamic piece that needs to be solved. Here is one way to do it with DVCs. First the page. One thing I will point out right way is that when you look at this page you have no idea what constitutes the dynamic components. There is nothing that lets you know if they are a table, a div, text, etc. You would need to go look in the controller to see exactly what the dynamic component is made of. It is less markup but it is also inherently less descriptive and as mentioned before more difficult to understand. This is one of the core advantages to staying true to the MVC pattern. On a View it should be dead simple to understand the generated markup and output.

<apex:page controller="TopOpportunityController">
    <apex:stylesheet value="{!$Resource.CustomTableCSS}"/>
    <apex:sectionHeader title="Top 10 Open Opprtunities"/> 
    <h1>Total Expected Revenue from Top 10 Opportunities:</h1> $
    <apex:dynamicComponent componentValue="{!OppTotal}"/><br/><br/>
    <apex:dynamicComponent componentValue="{!tabbedView}"/>
</apex:page>

Next the controller. Notice that we are querying the data but also directly manipulating and defining the view in this controller. For me, when these two areas start to combine it can become blurring on exactly what code is interacting with the Model and what code is interacting with the View.

public with sharing class TopOpportunityController {
 
    private List<Opportunity> topOpportunities;
    public Double opportunityTotal {get;set;}
 
    public TopOpportunityController (){
        topOpportunities = [SELECT closeDate, TotalOpportunityQuantity, Id, Name,
                            AccountId, Account.Name, Probability, ExpectedRevenue, 
                            stageName, Amount, Account.Open_Opportunities_Total__c FROM 
                            Opportunity where isClosed=false ORDER BY  
                            Account.Open_Opportunities_Total__c DESC, Account.Name, 
                            ExpectedRevenue DESC LIMIT 10]; 
    }
 
    public Component.Apex.TabPanel getTabbedView(){
        Component.Apex.TabPanel panel = new Component.Apex.TabPanel(
                                                       switchType = 'client',
                                                       title = 'Top 10 Opportunities');
 
        String lastAccountId;
        opportunityTotal = 0;
 
        for (Integer i = 0; i< topOpportunities.size(); i++){
            Opportunity o = topOpportunities[i];
            opportunityTotal += o.ExpectedRevenue;
 
            //If we have a new Account record, need to create a new Tab
            if (lastAccountId != o.AccountId){
                Component.Apex.Tab acctTab = new Component.Apex.Tab();
                acctTab.label = o.Account.Name;
                panel.childComponents.add(acctTab);
            }    
 
            Component.Apex.OutputText oppText = new Component.Apex.OutputText(escape = false);
 
            oppText.value = '';
 
            //If this is a new tab, start a new <table>
            if (lastAccountId != o.AccountId){
                oppText.value += '<table class="customT"><thead class="customT"><tr class="customT"><th class="customT">Opportunity Name</th><th class="customT">Probability</th><th class="customT">Stage</th><th class="customT">Expected Revenue</th></tr><tBody class="customT"></thead><tBody class="customT">';
            }
 
            oppText.value += '<tr><td class="customT">' + o.Name + '</td>';
            oppText.value += '<td class="customT">' + o.Probability + '</td>';
            oppText.value += '<td class="customT">' + o.StageName + '</td>';
            oppText.value += '<td class="customT">' + o.ExpectedRevenue + '</td>';
            oppText.value += '</tr>';            
 
            if ( (i == topOpportunities.size() -1) || o.AccountId != topOpportunities[i+1].AccountId ){
                 oppText.value += '</tBody></table>';     
            } 
 
            panel.childComponents.get(panel.childComponents.size() -1 ).childComponents.add(oppText);
 
            lastAccountId = o.AccountId;
        }
        return panel;
    }
 
    public Component.Apex.OutputText getOppTotal(){
         Component.Apex.OutputText oppTotal = new Component.Apex.OutputText();
         oppTotal.expressions.value='{!opportunityTotal}';
         return oppTotal;
    }
}

So how would you do it mister smarty pants? Oh, I’m glad you asked. I would still use Dynamic Visualforce, just not Dynamic Visualforce Components. In my approach I want to look at the controller first. Notice that this controller has nothing related to the structure and style of the View. It only queries and process information from the Model. This should make it easier to understand exactly what the code is doing from a logic standpoint as you do not need to mentally separate the View logic. Some of the variables control how the information will be displayed on the page and this is okay, this is exactly what a controller should do. One thing to notice is the use of Maps. Map support was recently added to Visualforce as Dynamic Visualforce and is it is fan-freakin-awesome. I would bet it will solve 95% of your dynamic Visualforce needs. The other 5% is for Dynamic Visualforce Components.

public class TopOppsController {
 
    public List<Id> accountIds {get; set;}
    public Map<Id,String> acctIdNameMap {get; set;}
    public Map<Id,List<Opportunity>> acctIdToOppsMap {get; set;}
    public Opportunity totalOppAmount {get; set;} //User Opportunity object amount field as wrapper for total, outputField will format currency
 
    public TopOppsController(){
        buildOppList();
    }
 
    public void buildOppList(){
        //Instantiate variables
        accountIds = new List<Id>();
        acctIdNameMap = new Map<Id,String>();
        acctIdToOppsMap = new Map<Id,List<Opportunity>>();
        totalOppAmount = new Opportunity(Amount = 0);
 
        //Query the Opps
        List<Opportunity> opps =    [SELECT CloseDate, Id, Name, AccountId, Account.Name, Probability, StageName, Amount 
                                    FROM Opportunity 
                                    WHERE isClosed=false ORDER BY Account.Open_Opportunities_Total__c DESC, Account.Name, Amount DESC LIMIT 10]; 
 
        //Process the opps
        for(Opportunity opp : opps){
            //Increment total amount
            totalOppAmount.Amount += opp.Amount;
 
            //Add accountId and Name to map, these Id -> Name map values can be used in Visualforce page
            acctIdNameMap.put(opp.AccountId,opp.Account.Name); 
 
            //Add Opps to Account ID -> List<Opps> map, the List values in this map can be use in Visualforce datatables
            if(acctIdToOppsMap.get(opp.AccountId) == null){
                acctIdToOppsMap.put(opp.AccountId,new List<Opportunity>());   
                accountIds.add(opp.AccountId); //We add account Ids to list and then we can iterate over this in page and pull values from Maps in the controller
            }
 
            acctIdToOppsMap.get(opp.AccountId).add(opp);
        } 
    }
}

Next up is my Visualforce page. One of the first things you will notice is that I had to use a little bit if jQuery magic. In my first attempt I tried to use an apex:repeat component inside of an apex:tabPanel but this simply does not work. So a bit unwillingly I turned to jQueryUI to address the tab issue. The good news is that using the jQuery UI tab panel is ridiculous easy: 1) Create a div that will represent the tab panel. 2) In this div create list of <a> links where href is the Id of a seperate div representing the corresponding panel. 3) Four lines of jQuery javascript. I’ll admit this is not 100% native where as DVCs are but this approach is actually very simple. It also makes it easier to see what the view is doing, and actually provides complete control over the tab panel style, and interaction. Even if you did use the native tab panel, it is doing the tab switching with javascript anyway ;-P .

So all that aside the page should be pretty easy to understand. With out any type of inline comments you’d be able to see we have a list of <a> links that is outputting an account name. Then for each one of these names we also have a corresponding data table. Keeping the View out of the controller makes it much easier to see how the page is formatted….or at least I think it makes it easier. You lose this type of natural documentation when using DVCs.

You can see a working example by clicking here.

<apex:page controller="TopOppsController" >
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.12/jquery-ui.min.js"/>
    <apex:stylesheet value="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/ui-lightness/jquery-ui.css"/>
 
    <script type="text/javascript">
         var j$ = jQuery.noConflict();
 
        j$(document).ready(function() {
            j$("#tabs").tabs();
        });
    </script>
 
    <apex:sectionHeader title="Top 10 Opps!"/>
 
    <h1>Total Amount from Top 10 Opportunities: </h1> <apex:outputField value="{!totalOppAmount.Amount}"/><br/><br/>
 
    <div id="tabs">
        <ul>
            <apex:repeat value="{!accountIds}" var="acctId"> <!-- Loop through list of account Ids -->
                <li><a href="#tabs-{!acctId}">{!acctIdNameMap[acctId]}</a></li> <!-- use account Id to get values from acctIdNameMap -->
            </apex:repeat>
         </ul>
           <apex:repeat value="{!accountIds}" var="acctId"> <!-- Look through list of account Ids -->
               <div id="tabs-{!acctId}">
                   <apex:pageBlock mode="edit">
                       <apex:pageBlockTable value="{!acctIdToOppsMap[acctId]}" var="opp" width="100%" > <!-- use account Id to get list of opps from acctIdToOppsMap -->
                           <apex:column value="{!opp.Name}"/>
                           <apex:column value="{!opp.Probability}"/>
                          <apex:column value="{!opp.StageName}"/>
                          <apex:column value="{!opp.Amount}"/>
                     </apex:pageBlockTable>  
                 </apex:pageBlock>
             </div>
         </apex:repeat>
    </div>
 
</apex:page>

So in the end DVCs have a purpose but more often then not you will probably not need them to meet your specific requirements. The real danger is using them when you really don’t need to and I’m hoping everything I’ve listed in this post explains why you should make a conscious effort to only use them when absolutely necessary. In the end this will make your apps easier to understand and then when you leave your company to go start the next million dollar start up the poor sap that inherits your code won’t go insane trying to understand the mess that is your controllers.

Categories: Apex, Technology, Visualforce

Getting Crafty with Queries

May 12th, 2011 6 comments

I’ve recently found myself running into several pain points when it came to extracting data from salesforce.com using SOQL. Since salesforce.com/force.com runs on a shared infrastructure they don’t allow all the bells and whistles of traditional SQL as they need to protect their resources and prevent some crazy guy like me from bringing down then entire system with some redonkulous query. You may be thinking by now that I am referring to the specific governor limits salesforce.com imposes on your queries but I am actually talking about fairly simple extractions that don’t always have the most straight forward solution.

Let’s say that you have a table of data like this:

Now let’s also say the requirement is to query items from this table but only return items based on a unique Order_Number__c. If there are duplicate Order Numbers in the table return the oldest record based on create date. The records we need to return would be the ones highlighted green.

What some of you are probably thinking is this is a totally unrealistic example because in any well designed system a field like Order Number should be unique. Well guess what? Not everyone gets to live this this happy database fairly land where duplicates don’t exist. If you you, whoop-di-do, hooray for you, click here for your prize. If you don’t live in fairy database land this example could be a totally realistic problem.

So how to solve it? Out of the box SOQL doesn’t have a solution for this problem (if it does I just wasted some time writing this) so we need to get crafty! You could maybe use aggregate queries to group by Order Number and then determine the oldest record. Or maybe query records, add them to unique Lists based on Order Number, sort these, and then return the oldest record. These are all good…well…they would work, not so sure about the “good” part. Below is the way I approached this problem and I’m sure there may be better ways to do this but I thought it was pretty slick.

We know one of the requirement is to use the oldest records if there is a duplicate. In our query we can sort by Created Date ascending so the oldest records a processed first. Before running this query we will also create a Map where the key is a Integer representing the Order Number and the value is a salesforce object, in this example Opportunity. Data returned would be processed in this order top to bottom:

As we process the returned results we will check to see if the Map contains a value for the given Order Number on the record we are currently processing. If it does not, it means this is the oldest record for this Order Number and we add it to the map. If the map does return a value for any given Order Number it means there was already an older record found and this record should not be used. In the end with have a nice clean map with the keys being the Order Number and the values being the oldest record with this Order Number. If we then need to add all these records to a list we can do that with a simple values() method called on the Map. Below is the code for this, it assumes the object being queried is an Opportunity but this logic could be applied to any object/table.

//Create the map Order => Opportunity
Map<Integer,Opportunity> oppMap = new Map<Integer,Opportunity>();
 
//Query the records and sort by CreatedDate ascending so oldest records are returned first
for(Opportunity opp : [select Id, Name, Order_Number__c, CreatedDate from Opportunity order by CreatedDate asc]){
 
    //Check if map contains Opportunity for given Order Number
    if(oppMap.get(opp.Order_Number__c) == null){
	//If null add opp to map, it is the oldest
	oppMap.put(opp.Order_Number__c,opp);
    }
 
    //Else do nothing, ignore the record as we already found an older one.
}
 
//If we need the opps in a list just do this	
List<Opportunity> opps = oppMap.values();

The one down side to this approach is that you are querying duplicate records that will never be used. Ideally you would only query the exact records needed without the duplicates even returned at all. I know of no way to do this but if you do please leave a comment below. Even with this added overhead of returned records that are never used I like this approach over the other described earlier because it is super simple and I am a big fan of simple.

UPDATE:
Based on some great comments below Greg has pointed that if you sort in desc order you don’t need the if() condition because the oldest records will be processed last and when you add them to the map it will replace any value that is currently there for the given key. The for loop could be simplified to this:

//Query the records and sort by CreatedDate descend so oldest records are processed last
for(Opportunity opp : [select Id, Name, Order_Number__c, CreatedDate from Opportunity order by CreatedDate desc]){
 
    //Add opp to map, it will replace any existing value in the map with the same key
    oppMap.put(opp.Order_Number__c,opp);
 
}
Categories: Apex, salesforce

To Query or to Loop, that is the question

February 23rd, 2011 16 comments

I know what you thinking. Where have you been!?! No decent posts in over three months! Nothing but promoting yourself and posting advertisements. What happen to the guy that used to post all sorts of sweet nuggets of goodness on his blog? Dreamforce 2010, the holidays, a ton of real job work, and this little guy….

photo

…all got in the way, but enough with the lame excuses. Let’s get down to business.

WARNING: This post is a bit long but I think it’s a good read so grab a coffee, get comfortable, and start making your brain grow.

I’m going to cover a topic I have wanted to look at in more detail for a long time. It revolves around Visualforce and more specifically the performance of Visualforce. Visualforce is great in that it allows you to build front end pages connected to a huge scalable database in less than a day. This ease of use does comes with a price. Visualforce is slow. Rerender operations can take way too long and latency to the servers is definitely not amazing. Depending on the use case latency may not be a huge problem but slow rerenders can make your app feel really sluggish. There are several reasons for this but the main issue is something called the viewstate. Queue ominous music now. Read more…

Categories: Apex, jQuery, Visualforce

Force.com + 500k emails = uh oh

October 4th, 2010 7 comments

Force.com has limits. These limits are in place to make sure you don’t bring down the entire force.com infrastructure. To me these limits are simply a challenge saying, “break me, I dare you”. Building apps that find innovative ways to get around these limits can be incredibly annoying but I also find these challenges quite satisfying when you finally come up with with a radtacular awesome solution that works within the limits. In coming up with these solutions I tend to push the platform to the max…to the breaking point…. and this is one of those stories.

Awhile back I was asked, “Any idea how you could let users subscribe to a topic and then get a daily email regarding this topic with content driven from force.com?” This also had to scale up to 1000s of emails. I thought about this for a little bit, approximately 653 nanoseconds, and then came up with an idea. It was and still is a little crazy. Thousands of emails in a day is nice but I had bigger plans. Plans of epic proportions. I was going to build a email system on force.com that could literally send millions of emails in one day. Whuauahahahahahahahah!!!! (< -evil laugh). I mean, nothing could go wrong, right? Salesforce.com would have some sort of controls in place to prevent some crazy guy like me from building this right.......right? Read more…

Getter Method Order and Visualforce Pages

August 24th, 2010 15 comments

I recently had a Visualforce page that was working perfectly for over two years. This thing was solid, a workhorse, one of the most used pages I have ever created. Then one day it stopped working as expected. It wasn’t a big deal really, simply an warning message wasn’t being displayed to the users. All unit tests still passed and I had made no major changes to the code. What the crazy I thought?!? The only thing I may have done at some point in the past was make minor changes to the the layout or updated the page API version.

The way I architected the page from the very first day created a ticking time bomb that would show up two years after the page was created. Enter the world of Visualforce page generation and getter method order. Before I get to the juicy good stuff I’ll briefly explain how Visualforce pages are created…at a very high level.

Read more…

Categories: Apex, Visualforce

Choose My Next Blog Posts

July 13th, 2010 2 comments

I’ve got a pretty decent back log of super awesome and overwhelmingly exciting blog posts. Some related to force.com and some not. I’ve got so many that I can’t decide what is next so I need your help. Below are a few of the top choices. The only teaser is the title of the post.

On this poll you can select two options so make your votes count!

What should be my next blog post?

View Results

Loading ... Loading ...
Categories: Apex, salesforce, Visualforce

Serious Force.com Cookie Security Issue

June 25th, 2010 13 comments

UPDATE:
Before you read the update I would encourage you to read the original article below first.

This is not a bug but an expected issue with the way force.com sites pages are cached. For some reason in my crazy head I thought the only items cached on pages where the html structure, images, css, etc. I thought that even on cached pages the controller would execute on every load of the page. This is not true. The controller will only execute once when a page is not cached. Any subsequent visits while the page is cached will not cause the controller to execute. So if you are populating dynamic data on the page with Apex it will stay there for the next 10 minutes.

This becomes a major issue with pages that depend on cookies and customizing the site content per visit.

I’ve recommended that salesforce.com update their documentation with two big red bold updates:
1) Cached pages will not execute the controller on load
2) Pages that use cookies to display dynamic data should never be cached

I hope this is helpful to someone out there as I definitely learned something today.

Additional info can be found here: dev board post.

-Jason


Original Post:

I have discovered a major bug with the new cookie feature released in the Summer 10 edition of salesforce.com. Let’s get straight to the point. Cookie data is being passed across different browsers, different computers, and different users. Yes, you heard this right. Sounds unbelievable so I created a video that shows this happening. Clearly this is a major issue if you are storing session or personal information in cookies.

Before anyone rips into me for blogging about what could be a very significant security issue I have already notified salesforce.com and it is a high priority issue. I also believe it is best to get this information out to other force.com developers before they build something that depends on this functionality and this issue causes major problems for them.

At this point I highly recommend not using the new cooking feature until more information about this issue or a fix is released.

Page:

<apex:page controller="CookieBug" expires="60">
    <apex:form >
        <apex:inputText value="{!input}"/>
        <apex:commandButton value="Update Cookie" action="{!updateCookie}"/>
    </apex:form>
</apex:page>

Controller:

public class CookieBug{
 
    public String input {get; set;}
 
    public CookieBug(){
        //Autofill input based on cookie value
        Map<String,Cookie> cookies = ApexPages.currentPage().getCookies();
        if(cookies.size() > 0){
            if(cookies.get('myCookie') != null){
                input = cookies.get('myCookie').getValue();
            }
        }
    }
 
    public void updateCookie(){
        List<Cookie> cookies = new List<Cookie>();
        Cookies.add(new Cookie('myCookie',input,null,15552000,false));
        ApexPages.currentPage().setCookies(cookies);
    }
}

Seattle Force.com Developer Meeting – June 2010

May 28th, 2010 No comments

UPDATE: I’ll be demoing how to authenticate with OAuth using Force.com and how this can be used with the Twitter API.

It’s that time again for the Seattle Force.com Developer Meetup. Details below…

When: 6/3/2010 4:00 PM – 6:00 PM Pacific Daylight Time
Where: 7 Simple Machines Office
Subject: Seattle Force.com User Group Meeting – June 3
Comments: This month, our meeting will be held in a new venue. 7 Simple Machines has offered up a change in venue for us in June.

Location:
Their office is located at:
800 Maynard Ave S, Suite 208
Seattle, WA 98134

http://www.7simplemachines.com/views/ContactUs.aspx

As always, bring your any ideas and questions to the meeting to discuss with everyone!

Seattle Force.com Developer Meeting – May 2010

May 5th, 2010 No comments

I really need to get better about posting these earlier but if you are able to make it to the Seattle Force.com Developer Meeting we would love to have you stop by. All are welcome, pros and noobs. Below is the info regarding the upcoming meeting.

Our next Force.com user group meeting will be held on Thursday, May 6th.

Time: 4:00pm – 5:00pm PDT
Location: WMP Seattle
1215 4th Ave, Suite 1010
Seattle, WA 98161

Richard Saunders and Evan Callahan will be presenting their Client Management System.

As always, we are looking for people to present at our future meetings, so please let me know if you would like to share something with the group.

Categories: Apex, Visualforce

Seattle Force.com Developer Meeting

March 31st, 2010 No comments

There is a another force.com developer meeting for Seattle coming up this Thursday. If you are in the Seattle area and want to meetup or learn more about developing on the force.com platform please stop by.

Just a friendly reminder that this Thursday, April 1st at 4:00pm will be the our monthly meeting.

The meetings as always will be held in the West Monroe Partners office located at:

1215 4th Ave, Suite 1010
Seattle, WA 98161

This session will be an open forum so bring any questions, problems, and/or issues you have so we can discuss with the group.

If you have something cool you’d like to show off or present let me know and we can arrange for you to speak at one of the upcoming sessions.

Seattle Force.com Developer Group

March 3rd, 2010 No comments

Heads up that if you are a Force.com/Salesforce developer or want to learn more about force.com development in the Seattle area there is a meeting this Thursday, the 4th.

The meetings as always will be held in the West Monroe Partners office located at:

1215 4th Ave, Suite 1010

Seattle, WA 98161

When:  Thursday, March 4th, 2010

Start Time: 4:00 PM

This session will be an open forum so bring any questions, problems, and/or issues you have so we can discuss with the group. If we finish early, we can maybe grab a beer at one of the local bars downtown.

If you are interested even a little please stop by.

Categories: Apex, Technology, Visualforce

If Computers Could Barf – Salesforce Debug Log

March 1st, 2010 17 comments

This story starts some time ago. I have been complaining about the system/debug log in salesforce.com ever since they released what I would consider version 1.1. You can see my post here, Please fix the Debug Log!, pleading for salesforce to fix the debug log. This was back in July of 2008! From what I can tell there has only been two noticeable changes with this debug log. I will refer to them as version 1.1 which was implemented around the time of the message board post above and the the most recent Spring ’10 incarnation which I will refer to as version 2.0.

Read more…

Categories: Apex

How many lines of Apex code do you have?

February 9th, 2010 6 comments

I have always been curious how many lines of Apex code I have written. Is it a couple hundred (haha, ya right), several thousand, a gazillion million trillion? There was never really a good way to figure this out unless you pulled down all of the data and inspected it file by file. Lame.

Read more…

Categories: Apex