Setting up jQuery with salesforce.com

February 3rd, 2010

My posts have been lacking lately but in the next few weeks I plan on creating some super slick demos that mix jQuery and Force.com into a delicious concoction of wonderfulness. Before I do this I’d like to go over the basics of setting up jQuery to play nice with Force.com (or salesforce.com, all the same).

If all we need is jQuery, the first thing we need to do is download it here here: http://jquery.com/.

There will be two versions, one is considered production and the other development. These actually contain the same code but the production file removes all unnecessary spaces.

mr-t_bigger

This smaller version allows the script to be downloaded quicker by users viewing the page and will provide a better user experience to those with less bandwidth.

jQuery lets you do a lot of sweet stuff, manipulate the DOM, change styles, basic animations, etc, but to provide an even richer user experience there is jQueryUI. This allows you to do all sorts of visual awesomeness with very little code.

jQueryUI can be downloaded here: http://jqueryui.com/download

When downloading jQueryUI you need to select theme (styles) and all the necessary components. For the sake of demoing and developing it makes sense download all of the components. Once again the reason to leave components out would be to decrease download size.

uidown

When you download jQueryUI you will be provided a zip with several files. This contains all sorts of demos and documentation but the only folders we care about are /css and /js. One very important thing to note when downloading jQueryUI is that it automatically downloads the regular jQuery (jQuery Core) to the /js folder.

Since we are going to upload these files as a .zip static resource to force.com I don’t even bother extracting the contents. Simply delete everything but the /js and /css folders. When this is done we should have a zip file called jquery-ui-1.7.2.custom.zip (or whatever the most current version is). Next we head off to Force.com.

In Force.com navigate to Setup>Develop>Static Resources and hit the New button. Make the name jquery and upload the zip file. If this resource is going to be used with force.com sites be sure Cache Control is set to public.

capture

Now create a new visualforce page called jQueryTest. At the very top of the page we need to include the correct script and styles that jQuery has provided. We can do this with the following Visualforce tags:

<apex:includeScript value="{!URLFOR($Resource.jquery, 'js/jquery-1.3.2.min.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jquery, 'js/jquery-ui-1.7.2.custom.min.js')}"/>
<apex:stylesheet value="{!URLFOR($Resource.jquery, 'css/ui-lightness/jquery-ui-1.7.2.custom.css')}"/>

With jQuery you will see a lot of examples including the $ symbol. This is basically a shortcut when calling jQuery functions. The problem is that force.com also includes a lot of javascript libraries that also may use this $ symbol as a shortcut and this can cause all sorts of problems. There is a simple fix as we can give jQuery it’s own special name.

var j$ = jQuery.noConflict();

Now where ever you would normally use $, use j$.

Finally we make sure it is all working correctly with this simple page. When you click on the link you should see a pop up alert. If you don’t something isn’t right so check for typos in the includeScript tags.

You can check out my working demo here: http://tehnrddemos-developer-edition.na7.force.com/jqueryTest

<apex:page >
    <apex:includeScript value="{!URLFOR($Resource.jquery, 'js/jquery-1.3.2.min.js')}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery, 'js/jquery-ui-1.7.2.custom.min.js')}"/>
    <apex:stylesheet value="{!URLFOR($Resource.jquery, 'css/ui-lightness/jquery-ui-1.7.2.custom.css')}"/>
 
     <script type="text/javascript">
         var j$ = jQuery.noConflict();
 
        j$(document).ready(function(){
            j$("#ninjaLink").click(function() {
                alert("NINJA STAR TO FACE!!!!!");
            });
        });
     </script>        
 
    <a id="ninjaLink" href="">NINJA ATTACK!</a>
 
</apex:page>

After this you are set to start making awesome sauce with jQuery and Force.com.

If Visualforce Blows, This Sucks

January 11th, 2010

I recently saw a tweet that included nothing but a link and a lot of salesforce.com related tags.

Visual Force Blows (link was shortened in original tweet so I couldn’t see title)

What could this be I pondered? A new product announcement? A glowing review of the force.com platform? Upon clicking the link I entered the “I hate Apex and Visualforce Zone” (Dun Dun Dunnnnnnnnnnn). Some dude on a blog (man, everyone has a blog now days) is trying to build a dynamic link menu with data pulled from salesforce objects and using visualforce to display. This seems pretty normal right? Let us check out some excerpts first:

On Apex and Visualforce:

Sounds great in theory, however in reality it makes you want to stab yourself. A lot.


I on the other hand would bathe in it if I could. Oh ya….Visualforce and Apex, sooo bubbly clean. Ya, that was weird. Let’s move on.

Problem is, it uses what is called MVC (Model View Controller, or some shit like that) which divides your logic code, from your design code (oh my god, they invented the idea of functions that can be called, how fucking astounding). Seems like a solid plan, cause your design team and your programming team get to work separately and not step all over each others code. Problem is, I am the design team, and the coding team. That means I get to deal with the whole project from the ground up and deal with all the over engineered bs.


Whoa whoa whoa! The harshness, it hurts, but wait a second, isn’t the MVC concept pretty common. Isn’t this what all of those crazy iPhone apps use? And about a gazillion other languages.

Separating the design team and programming team is not really the purpose of this as both must work together to build awesome apps (even if it is the same person). The real advantage is that the styling/layout and logic are separate. This makes it much easier to code, debug, troubleshoot, and rework in the future. Anyone who has used the old s-controls can atest to this fact. Let us continue.

So what is the developer trying to do. He (she?) wants to simply create a navigation menu with links that have sub links. With his (we will assume it’s a he, sorry ladies) approach is that it stores all of the link relationships in one object. At first this may seem like a more simple and streamlined approach but this will soon spin out of controll as seen by the post in question.

In cold fusion he said he could do this in 6 lines but it doesn’t look like the example includes the sub links. So how about a Visualforce solution that includes sublinks in 10 lines of Apex and 11 lines of Visualforce (including class name, Visualforce page, and componenet tags)? Oh ya! It also only took me about 30 minutes to build. Double oh ya!

The first thing I would do differently is break this up into two objects. Link and Sub Link. Why more objects? We can then use the out of the box relationships to query all sub links when we query the links. This will actually significantly reduce the amount of required code. Each object has two text fields, URL and Label. The Sub Link object also has a lookup to the Link object. This approach also makes it much easier to maintain from a admin/user perspective. You can see all sub links for a link on one page.

links

Before we jump in to the code you can check out the snazzy demo here:

http://tehnrddemos-developer-edition.na7.force.com/linkmenu

First let’s look at the controller for the custom component we will be using. What we do is query the link object and all sub links related to the “parent” link at the same time. Technically I could make this class have even less lines but this example follows best practices so I won’t.

public class linkMenu{
    List<Link__c> links;
 
    public List<Link__c> getLinks(){
        if(links == null){
            links = [select Label__c, URL__c, (select Label__c, URL__c from Sub_Links__r) from Link__c];
        }
        return links;
    }
}

Next up is the component. This loops through all of the parent links and outputs a hyperlink. For each parent it will then loop through the sub links and create a link that is indented slightly for each.

<apex:component controller="linkMenu">
    <apex:repeat value="{!links}" var="l">
        <apex:outputLink value="{!l.Url__c}">{!l.Label__c}</apex:outputLink><br/>
        <apex:repeat value="{!l.Sub_Links__r}" var="sl">                
            <apex:outputLink value="{!sl.Url__c}" style="margin-left:10px;">{!sl.Label__c}</apex:outputLink><br/>
        </apex:repeat>
    </apex:repeat>
</apex:component>

And finally the page. This is were it gets sort of complicated. Sorry about that.

<apex:page >
    <c:linkMenu/>
</apex:page>

So what have we learned today? I think if the other post is accurate in its statement that Visualforce blows than I am going to assume that this post really really sucks.

Oh, and don’t worry Apex and Visualforce creators, PMs, and team. I will protect you.

Apex and Visual Force (they are the bane of my existence on this planet and I would die a happy man if their creator(s) where beaten with reeds to within an inch of their life).

But seriously, what is up with this guy? I’ll admit some rants are funny but this is going over the top and you should try to keep it a little professional. Bridge burned. This is that last time I will provide any type of assistance to this guy.

EDIT: Oh darn! Just realized I named this post “If Visualforce Sucks, This Blows”. That was backwards. It is fixed now.

Seattle Force.com Developer Meeting

January 6th, 2010

Tomorrow, January 7th, there will be another Force.com Developer Meeting in Seattle (first Thursday of every month). If you develop on the Force.com platform with Apex, Visualforce, use the API, or want to learn more about these topics please feel free to join us.

Date: Thursday, January 7th.

Time: 8:00 – 10:00 AM PST

Location: West Monroe Partners
1215 4th Ave Suite 1010
Seattle, WA 98109

The West Monroe Partners office is located on the 10th floor.

Public Parking garages are located in the building, as well as in a 1-2 block radius. The area is also well serviced by public transportation.

The agenda for this meeting will be as follows:

  • Presentation/Demo – Jason Venable (tehnrd.com) will be demoing his runner up application he created for the most recent Force.com Cloud Developer Challenge. The site is GameForce and includes two games: Blackjack and multiplayer connect four. (http://tehnrd-developer-edition.na7.force.com/gamehome). It was built with 100% Force.com, no flash or JavaScript. Jason is a Salesforce.com Admin and Developer at F5 focused mainly on process automation for the worldwide sales team.
  • Open forum – opportunity to discuss any questions/issues you may have about all things Salesforce

If you are planning on attending this month’s meeting, please send me an email (vgrasparil@westmonroepartners.com) to RSVP.

If you would like to present an application you have built or share some best practices you have learned with the group, please let me know so we can schedule it into a future meeting.

See you on January 7th!

Yup, thats me! I’ll be showing off the gaming site I built on force.com, http://www.tehnrd.com/gameforce/. I’ll show off the basic UI stuff but we will also peel back the covers to see how it works the magic on the back end.

A Nerd in Victoria’s Secret

January 4th, 2010

Tonight the wife and I did the after Christmas return run. If you did your return shopping last week you are nuts, unless for some completely logistical reason, you were forced to do it then. We were at the biggest and busiest mall in the state of Washington and it was not busy at all, yet most of the after Christmas sales were still going and merchandise stock was still decent.

One of our first stops was Victoria’s Secret for an exchange. If you have been shopping lately you know that there are two types of Victoria’s Secret stores. One, the not so man friendly, and two, the not man friendly at all. The latter are the older ones that still have the pink and gold decor splattered over every surface. The other is the newer remodeled stores which are more modern and use a white, black, and grey color scheme in the store. This particular store was the not so man friendly version.

Fortunately I was with my wife so I could play the part of being dragged into this store against my will, which is actually the preferred image I want to pass off to the other patrons. The other, and much worse image, is you alone. This is not good, as every other female in the store looks at you as if you are a pervert or some dumb husband/boyfriend trying to buy some super sexy outfit that your wife/girlfriend doesn’t even want. Even if in actuality you are simply purchasing a specific item on their Christmas list!

But I digress. Tonight we are looking to do a straight up exchange but the item was not in stock. We then proceeded to the teller to process the return. The teller, who was a lady in her late 30s, asked what was wrong with the item. We responded. She then asked if we looked for the item we wanted and we said yes. At this point she said, “Let me have the people in the back check the stock room”, and at this point used her super spy secret service microphone to ask for help in the back…….no response……..30 seconds…….no response. “I’ll just go check myself”, she says and walks off.

When we first approached the counter I notice something a little strange. All of the tellers had the keyboards for the point of sales system up on the counter facing the customer. I assumed this was for the swath of returns they needed to process which requires the address of the customer returning the item. I figured letting the customer input it themselves would be quicker.

As the lady walked off I turned to my wife and said, “Heh, suckers. I’m gonna hack there system”. “Don’t”, she said but my mind was already committed. What to do? It was just me and the keyboard, the room seemed to fade away, the ridiculous fruity smells vanish, there was silence…………….BAM!!!!!! CTRL-ALT-DELETE!!!!!!! WHAT NOW SUCKAS!!!!!!! “Dang it Jason”, I heard the wife say, but it was too late, it had been done.

I turned to her and said, “Don’t worry, they probably aren’t even running a system that responds to CTRL-ALT-DELETE. It is probably some Linux based program”. Or is it…….I slowly began to look over the top of the screen and low and behold the Windows login screen was there, not the Task Manager and not the normal point of sales system. I hacked it! Whuahahahaha! Ya, I know what your’re thinking, but whatever, let’s just say I did anyway.

As the lady returned she saw the screen and was sincerely surprised. It was clear the store doesn’t have the employees login with through windows as she had no idea what to do. At this point my wife was saying, “I told him not to do it, he is like a child, he has to touch everything”. The teller responded with, “Mine is too”, but she clearly didn’t know what to do and at this point I leaned over the counter, looked at her screen and then said with suave, “I’ll fix it”. Then with my ninja like computer skills, looking at the screen upside down, used the integrated track ball on the keyboard to move the mouse and hit the Cancel button. At this point my wife was super embarrassed and was blushing big time but everyone was laughing, no harm done. The teller then looked at me and asked, “You are one of the computer guys. Aren’t you?”. “Ya, something like that I responded”, and we then headed out of the store.

Categories: Life 2 comments

New Years Doesn’t Matter

December 31st, 2009

Watch out, I’m about to get all philosophical. New Years is pretty dumb. Yup, it’s dumb. There are many reasons but here are a few.

Time doesn’t really exist. Okay, maybe it does, but it is very complicated and thousands of bright minds haven’t really been able to define time in a way that is acceptable across all studies. But we travel around the sun every 365 days (approximately), hello Jason, that is a year, duh. Actually, that is a measure of rotations and distance that when completed gets a label slapped on it called a year. Oh ya, well there are 24 hours in a day, what about that? 24 is completely arbitrary. It could very well be 50, 20, or 100. They same logic follows for minutes and seconds.

And what is up with January 1st? It’s completely random and most likely had to do with some religious event back in the day when the church controlled the calendar. The new year could very well start on October 1st. January 1st isn’t even on a solstice or equinox! If it was, the date might make a little more sense. My years started on February 7th (birthday) an actual event….but then again what does February 7th even represent?

New years resolutions are also stupid. If you really want to do something do it today, don’t wait. Really, whats the point of waiting? “I’ll wait until the new year to do something”, blah blah blah, an excuse to be lazy.

So do I hate everything about new years? No, there are some good things. EXPLOSIONS!!!!!!!! Who doesn’t like fireworks?

seattlefireworks

So what will I be doing tonight when the clock hits 12:00AM…………… the same thing I do every year, hanging out with friends and watching a ball drop or something, just like everyone else.

p.s. Don’t take this post too seriously, I know my logic has many holes.

Categories: Life No comments

Batch Apex Status Bar

December 18th, 2009

Batch Apex is here and it is cool. In some of the demos and webinars salesforce.com has put together you may have seen a status bar that represents how far along a batch job has proceeded. This is useful as you only need but a quick glance to see how your batch jobs are doing. Below is an image of what this would look like.

batchstatus

All of this magic status bar stuff is pretty simple. You have two divs, an inner and an outer that construct the status bar, the inner being the percent complete. All of the info to construct this status bar is located in a sObject called AsyncApexJob. This stores information about your batch jobs and other asynchronous operations.

The two important fields in this object are JobItemsProcessed and TotalJobItems. When a batch job is executing it may process millions of records but it will break these up into batches of 200, or less if defined……hence the name Batch Apex. So if I have 5,000 records to be processed there would be 25 batches of 200. In the AsyncApexJob object these 25 batches would be the TotalJobItems. As the job runs the number JobItemsProcessed will increase as the batches are completed.

Now that we have these two number calculating the percent complete is an utterly simple division equation. JobItemsProcessed divided by TotalJobItems times 100 gives us the percent complete. We then pass this value to the width of the inner div and our status bar is complete! To give the status bar the appearance of being animated we add an actionPoller to the page and rerender the table of batch jobs every five seconds which will intern update that status bar with the new values.

As always there is a fun little demo to play with and you can access that here: Click here for nifty cool demo.

I’ve also packaged up this component so you can install it directly to your org. You can download it here.

Here is all the code and markup. First the page that will contain the batchJobs component.

<apex:page controller="batchStatus">
    <apex:form>
        <apex:commandButton value="Start Batch Job" action="{!startBatch}" reRender="jobs,error"/> 
        <apex:outputText id="error" value="{!error}" style="font-weight: bold; color: red"/>
 
        <br/><br/>
        <c:batchJobs id="jobs" numberOfJobs="20"/>
    </apex:form>
</apex:page>

Next we have the Visualforce component:

<apex:component controller="batchJobs" selfClosing="true">
    <apex:attribute name="numberOfJobs" type="Integer" assignTo="{!numberOfJobs}" description="The number of batch jobs to display in the table."/>
 
    <!-- Here is the css styles that will be used for the progress bars -->
    <style>
        .progressBar{
            background-color: #f8f8f8;
            border:1px solid #DDDDDD;
            height: 19px;
            width: 300px;
            -moz-border-radius: 5px; 
            -webkit-border-radius: 5px;
        }
        .progress{
            background-color: #F7B64B;
            border:1px solid #E78F08;
            height: 100%;
            margin: -1px;
            text-align: center;
            -moz-border-radius: 5px; 
            -webkit-border-radius: 5px;
            line-height: 18px;
        }
    </style>
 
    <!-- This action poller will check the status of the batch jobs every 5 seconds -->
    <apex:actionPoller rerender="jobs" interval="5"/>
 
    <apex:pageBlock title="Batch Apex Jobs">
        <apex:pageBlockTable value="{!batchJobs}" var="b" id="jobs">
            <apex:column headerValue="Apex Class" value="{!b.job.ApexClass.Name}"/>
            <apex:column value="{!b.job.CreatedDate}"/>
            <apex:column value="{!b.job.CreatedById}"/>
            <apex:column value="{!b.job.Status}"/>
            <apex:column width="320px" >
 
                <!-- Here with have two divs that construct our progresses bar. An outter which is the entire bar,
                and and inner that represents the percent complete. We simply pass the percentComplete value to
                the inner div width and this will show how far along the job is. Brilliant! -->
 
                <div class="progressBar">
                    <div class="progress" style="width: {!b.percentComplete}%;">
                        {!b.percentComplete}%
                    </div>
                </div>
 
            </apex:column>
            <apex:column value="{!b.job.CompletedDate}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
 
</apex:component>

And finally the custom controller for the component….. where all the magic happens:

public class batchJobs{
 
    public List<BatchJob> batchJobs;
    public Integer numberOfJobs {get; set;}
 
    public List<BatchJob> getBatchJobs(){
        //Create new list of BatchJobs, a wrapper class that includes the job and percent complete.
        batchJobs = new List();
 
        //If number of jobs was not defined, default to 20
        if(numberOfJobs== null || numberofJobs <= 0){
            numberofJobs = 20;
        }
 
        //Query the Batch apex jobs
        for(AsyncApexJob a : [select TotalJobItems, Status, NumberOfErrors, MethodName, JobType, JobItemsProcessed, Id, CreatedDate, CreatedById, CompletedDate, ApexClassId, ApexClass.Name From AsyncApexJob order by CreatedDate desc limit :numberOfJobs]){
            Double itemsProcessed = a.JobItemsProcessed;
            Double totalItems = a.TotalJobItems;
 
            BatchJob j = new BatchJob();
            j.job = a;
 
            //Determine the pecent complete based on the number of batches complete
            if(totalItems == 0){
                //A little check here as we don't want to divide by 0.
                j.percentComplete = 0;
            }else{
                j.percentComplete = ((itemsProcessed  / totalItems) * 100.0).intValue();
            }
 
            batchJobs.add(j);
        }
        return batchJobs;
    }
 
    //This is the wrapper class the includes the job itself and a value for the percent complete
    public Class BatchJob{
        public AsyncApexJob job {get; set;}
        public Integer percentComplete {get; set;}
    }
 
    /*--------------------TEST METHOD------------------------*/
    static testMethod void batchStatusBarTest(){
        batchJobs controller = new batchJobs();
        controller.getBatchJobs();
    }
}

I initially planned on adding all sorts of cool features to this component such as color coding the status bar based on the status of the job and estimated time to completion. These were axed in 1.0 as it was taking too long and there our some other cool posts I have lined up that I want to get working on. Maybe in the future I’ll post an updated version of this component with all the flair it deserves.

UPDATE:

I’ve been asked a couple times what exactly happens when a user clicks the <apex:commandButton value=”Start Batch Job” action=”{!startBatch}” reRender=”jobs,error”/> button. This calls a very simple method in the controller that starts a batch job.

public void startBatch(){
	error = '';
	batchJob job = new batchJob();
	List<AsyncApexJob> openJobs = [select Id from AsyncApexJob where Status = 'Processing' OR Status = 'Queued']; 
 
	if(openJobs.size() < 5){
	        ID batchprocessid = Database.executeBatch(job);
	}else{
		error = 'WHOA BUDDY! Only five batch jobs at a time.';
	}
}

And here is the batch apex job.

global class batchJob implements Database.Batchable<SObject>{
 
    global database.querylocator start(Database.BatchableContext bc){
        return Database.getQueryLocator('select Id, Name from Account where Type = \'Batch Test\'');
    }
 
    global void execute(Database.BatchableContext bc, sObject[] objects){
        List<Account> accns = new List<Account>();
 
        for(sObject s : objects){
            Account a = (Account)s;
            a.Description = 'batch testing. blah blah blah.  ' + system.now();  
            accns.add(a);
        }
        update accns;
    }
 
    global void finish(Database.BatchableContext bc){
       system.debug('all done');
    }
}
Categories: Apex, Visualforce 6 comments

How to disable Visualforce inputFields

November 25th, 2009

Visualforce as a whole is great and is super easy to use once you get the hang of it but every once in a while I come across an issue that makes me go, “What the huh?”. A perfect example of this is that fact that there is no attribute to disable apex:inputFields in Visualforce, what the huh?!? Exactly. You can disable apex:inputText but not apex:inputFields. This can be frustrating as inputFields give you enhanced functionality such as the date picker for date fields, help hovers, and cleaner error messages.

So how can you disable an apex:inputField tag? I don’t know. Just kidding ;-P. Nearly all apex:inputFields when rendered for the browser become HTML input tags and input tags have a disabled attribute. What we can do is manipulate this value with a combination of Apex and Javascript.

Check out the working demo here.

For all my demos I am now trying to build packages so you can install them in your own orgs to play around with. The package is available here.

First is a very simple class. It has one Opportunity that we will bind our inputFields to, a Boolean to determine if the inputField should be disabled, and two methods to set the boolean to true and false.

public class disableInputField {
 
    public Opportunity opp {get; set;}
    public Boolean disableInput {get; set;}
 
    public disableInputField(){
        opp = new Opportunity();
    }
 
    public void disableCloseDateInput(){
        disableInput = true;
    }
 
    public void enableCloseDateInput(){
        disableInput = false;
    }
}

Next up is the page. What we do is place some inline Javascript right next to the input field we want to disable. When clicking the Enable/Disable buttons this will set the boolean value and rerender the oppName panel. When this happens the disableInput boolean value is merged in to the Javascript and since this is a inline Javascript statement it will execute every time the rerender is performed.

<apex:page controller="disableInputField">
    <apex:form >
        <apex:commandButton value="Disable inputField" action="{!disableCloseDateInput}" rerender="oppName"/>
        <apex:commandButton value="Enable inputField" action="{!enableCloseDateInput}" rerender="oppName"/><br/><br/>
 
        Opportunity Name:
        <apex:outputPanel id="oppName">
            <apex:inputField value="{!opp.CloseDate}" id="oppNameInput" required="false"/>
            <script>document.getElementById('{!$Component.oppNameInput}').disabled = {!disableInput}; </script>
        </apex:outputPanel>
    </apex:form>
</apex:page>

And that is how you can disable an inputField. Nice!

Categories: Visualforce 8 comments

Why JavaScript Scares Me

November 11th, 2009

If you have read this blog before you will get the vibe that I am anti javascript. This is a fair assessment as I really don’t like using javascript. I can already hear the people yelling, “JavaScript is great! It can do so many cool things”. Yes, I know, but why add more complexity if I don’t need to? Here is the story of why JavaScript scares me.

This story starts back in my sophomore year of college when I took my first “programming” class. It was basically an intro to computers (easy peasy) but about half of the class was building websites with JavaScript applications. For these assignments we were required to use notepad to build the Javascript and websites. For someone that had never really done any sort of programming this was incredibly frustrating. One wrong character and you were hosed. Oh, and don’t forget this was in the dark ages before Firefox and Firebug. Make change, save, refresh Internet Explorer (blech!), repeat, repeat, repeat. Ugh, this was so lame and left a bad taste in my mouth when it came to “programming”.

screenhunter_13-nov-10-13-33

Next up was CSE142, the intro to programming class that is supposed to weed out computer science majors. This was all java programming and we actually got to use an IDE that would show syntax errors before you compiled. This was probably the hardest class I have ever taken but it has also been the most useful class I have ever taken. After this I was feeling better about programming and things were looking up…… enter the infamous s-control.

Once out of school and at my job, after having an admin role for about six months, I decided to take a stab at updating some s-controls. What a pain. Flashbacks of javascript notepad editing flashed through my head. S-controls are so messy. I wasted hours trying to add basic functionality. Once I got it to work in one browser I realized it didn’t work in another (guess which one). This only reconfirmed my thoughts that javascript is a time suck and a pain to work with. Thankfully Apex and Visualforce were soon released and s-controls with javascript were a thing of the past.

scontrolvs

So where do I stand today? When it comes to Force.com apps I still try to keep my javascript usage to an absolute minimum. I know a lot of the Visualforce pizazz is all based on Javascript but this is script I don’t have to manage. They make sure it works, and works across all browsers.

With all of this said and done I do have a confession to make. I feel like I am having an affair with my own beliefs but I am slowly falling in love with that little bundle of joy know as the jQuery and jQuery UI JavaScript libraries. Once you get over the learning curve of understanding the basics on how to using this library it makes working with JavaScript, dare I say, almost enjoyable. I am still a bit nervous about browser compatibility and the maintenance required but jQuery is lessening these fears. So yes, I am starting to open up a little more to JavaScript and I have some blog posts planned to demo the cool things jQuery can do in tandem with the Force.com platform.

Hello Twitter

November 6th, 2009

I am now on Twitter. Hello my little bird friend.

I put it off for a long time mainly because I don’t care what people are eating for lunch or what movie they just saw. At least this is what I figured most of Twitter was about (and a lot of it still is) but this view changed rather quickly just a few days ago.

My little blog here in the corner of the internet gets traffic mainly from the developer.force.com discussion boards, from links posted on other Force.com related blogs, and the occasional search engine hit (Visualforce Popup is a hot one from search engines). It’s not a lot of traffic, but it is steady. After my Dreamforce 2009 Predictions post I saw a significant spike it traffic coming from Twitter. That blog post was tweeted by two different people and I saw site traffic increase three fold. It was easy to see the benefits of Twitter. Digging into some of the tweets I discovered what is a nice little ecosystem of Force.com/Salesforce.com users that actually post, errr…tweet, about relevant topics.

I have actually had a Twitter account for about a year now but I was one in the masses that had no tweets and no followers. Okay, so I had one tweet, which ironically was about me eating some pie. I remember the post (fric!, tweet) exactly and I was trying to explain to my parents, aunts, and uncles what Twitter was. I went on to explain it’s some lame micro blogging site where people post about everything they do. So of course I made a useless post about what I was eating. Oh how naive.

My main use of  Twitter will be to take advantage of this Force.com community, follow some trends, and post (oh my goodness… tweet) about force.com topics. Heck, maybe I’ll even toss in what I’m eating once in awhile……just kidding.

Now I ask for your help. Who are some great people in the twitter community to follow? What are some good tags to follow? I’ve already got #dreamforce, #force.com, and #salesforce. Please help this Twitter noob.

Click here for my Twitter page.

Categories: Life, Technology 3 comments

Dreamforce 2009 Predictions

November 3rd, 2009

Dreamforce 2009 is fast approaching. Last year’s big announcement was Force.com Sites, before that Visualforce, and Apex code before that. What could be the next big announcement for salesforce.com? Here are my predictions.

New UI
Salesforce.com as been working on a new UI for several years now. There was even a chance to get a sneak peak at last years Dreamforce and there have been little teasers scattered through out salesforce presentations for some time now. Salesforce.com leans heavily on the ext JS framework and I fully expect the new UI to boast some of the cooler features this javascript framework can deliver. Another reason I think this may finally be announced is that this new UI will be built upon Visualforce and for the past several months the Visualforce team, which is usually very active, has been laying low on the forums which makes me think this department is cooking up something good.

Visualforce 2.0
This one I am hoping for more than I actually think may happen but there are a few reason I think this announcement could be a possibility. In the past two to three salesforce releases there has been very little progress in regards to enhancements and new features for Visualforce. Similar to my justification for a new UI the VF team has been less involved in the forums so I can only assume they are very busy at work on the next big thing. Another piece of evidence is this one forum post in particular that I still haven’t forgot about: “we are working on visualforce native drag and drop support”, straight from the PM of Visualforce. Drag and drop is a pretty advanced thing to do with javascript so I am hoping there is a new suite of advanced Visualforce components that take advantage of all the cool things javascript can now do but maintains the simplicity and scalability that makes Visualforce so easy to use.

These are my two guesses for the big announcement but I also anticipate smaller announcements such as new partnerships and new integration toolkits, but these are boring.

Do you have any predictions for salesforce.com’s big announcement?

Categories: Visualforce 8 comments

An Open Letter to Car Dealers

October 30th, 2009

Dear Car Dealers,

Get with the times. My wife and I have spent the last four weeks test driving 12 different cars. Some cars were good and others not so good. Yet the most annoying, not surprisingly, aspects of buying a car is dancing (not literally, that would be weird) with the dealers. Most dealers are still using the same old tactics they have since the begining of car sales. This is dumb. People aren’t stupid anymore when they walk on to a dealers lot. In fact, I can learn more about the car online than most of the salesman know. So dealers, let’s be real, here are a few tips.

Second sticker
Really? You are going to artificially inflate the price of a vehicle based on “adjusted market value”. And you are going to do this in a serious recession? What are you smoking? This is such a turn off and as soon as I see this sticker the chances of me buying a car from you go way down. What the heck is “adjusted market value” anyway? Last time I checked every single one of those cars cost about the same to make no matter where it is being sold. The only real variable here would be the shipping costs which strangely enough are the same in Miami as they are in Seattle. So just because I may live in an area with a higher average income that doesn’t mean you can raise the price. Oh and don’t forget about this thing called the internet where I can go buy a car from some place that has a “lower” adjusted market value with a few clicks while sitting in my pajamas.

Test Drives
Don’t come with me, you are most likely annoying. I do understand that you may need to ride along if I am driving a really expensive car, but please, don’t talk. Having you in the car makes everything so awkward. I just want to relax and get a feel for the car but I can feel you breathing down my back from the rear seat. Any questions I have I can ask when I return, but you know what, I probably already have the answer because of this little invention called the internet. If I crash the car we all have insurance so don’t worry about that. If you don’t come with me you will also get to stay at the dealer and potentially help multiple customers at once and improve your sales. You can’t do this sitting in the back seat.

Dickering
Don’t. Once again with this magical tool called the internet I have a pretty good idea what you paid for the car. Based on my recent experiences I can usually get within $200 of what you paid. Now that I know your purchase price you have very little negotiating power. Let’s not waist time, just give me your more lowest price. If it isn’t low enough I won’t buy it. If I think you are messing with me there are about 5 other dealers that sell the exact same car as you, and I have no loyalty to you, I will walk out the door to the next dealer. If it’s fair price I’ll buy it.

So in the end guess what? We ended up buying a car from a dealer that list the lowest price they are willing to sell it for, no negotiating, no dickering. And you know what? Out of all of the dealers we went to this was the busiest. There were more people in here on a week day than others had during the weekend. What a concept, set a price and let the market decide if this is fair, fundamental economics.

Sincerely,
Jason

Categories: Life No comments

Error Handling, Savepoints, and Inserts

October 19th, 2009

I’ve been working with Apex for a little over two years now and I still learn little tips and tricks all the time.

Today I ran in to a somewhat peculiar problem when trying to catch errors on the insertion of a record. Here is the scenario in super pseudo apex code.

1) Set a database save point with Apex
2) Insert a record with Apex
3) Some type of validation error prevents the record from being inserted
4) Using a try-catch statement catch the error and display it to user
5) Roll back to your Database savepoint
6) Allow the user to fix the error.
7) When the save occurs the second time I would receive this error: “cannot specify Id in an insert call”

Huh, wait….what? The insert failed because of the validation rule, right? Kinda, sort of, it’s not really clear. Even though the insert failed my object in memory was still being assigned an Id. This caused a problem when trying to insert the second time.

I’m guessing salesforce.com sets the ID of a record before the insert as you can’t set values after inserts as the object would become read-only. Similar to how triggers work, you can only write values before inserts and updates, not after. When the operation fails the Id in the code is not removed. This is a giant guess on how the process works and it could be totally wrong.

So how to get around this problem? The solution is fairly simple. In the catch section of the code we want to clone the record without preserving the Id and assign this clone back to the original object. Something like this:

Savepoint sp = Database.setSavepoint(); 
try{		
	insert object;
}catch(exception e){
	Database.rollback(sp); 
	object = object.clone(false);
	return null;		
}

The false parameter in the clone method makes an exact copy of the object without preserving the Id. So the next time the user attempts to save, the Id is null, and there should be no issues.

Categories: Apex 1 comment

Apex Flow Control – Preventing Infinite Loops

October 2nd, 2009

When you build your first few triggers everything is so peaceful. The grass is green, the birds are chirping, and everything is working wonderfully. You continue to develop more triggers, classes, batch jobs, @future classes, and then one day your realize, “Great Scott!, I have created a monster”. If you connected all the classes and triggers that were related it would look like a giant spaghetti dinner.

When this happens you will undoubtedly run into one very specific problem. You have a piece of code A that causes code B to execute which then causes code A to execute which then causes code B to execute. OH NO! Infinite loop, governor limits AHHHHH!

Fear not! For there is a very simple solution to this problem. The extremely clear and concise diagram below shows a common scenario.

flowj

Let’s say we have an update trigger that sends a group of objects to be processed by an @future asynchronous method. There is a good chance this method will need to update the records. This would normally cause the trigger to execute and the @future method to be called again, hence our unstoppable loop. So how do we stop this loop? Before we perform the update on the records we need to say, “Hey, this is a update from a @future methods, don’t do anything”. We can do this by creating a simple Boolean value in a utility class and can be accessed by anycode in context of the update operation.

Below is the code of how something like this would work. First let’s look at the very simple solution. Yup, this is it. Some minor changes to our @future and trigger code and this is it.

public class utility{
 
    public static boolean isFutureUpdate;
 
}

Here is the trigger, we only want the code in this trigger to execute if the isFutureUpdate variable is not true.

trigger updateSomething on Account (after insert, after update) {
 
    /*We only want this trigger to perform it's logic when the
    update is not from an @future method */
    if(utility.isFutureUpdate == null || utility.isFutureUpdate == false){
 
        Set<Id> idsToProcess = new Se<Id>();
 
        for(Account acct : trigger.new){
            if(acct.NumberOfEmployees > 500){
                idsToProcess.add(acct.Id);
            }
        }
 
        //Send Ids to @future method for processing
        futureMethods.processLargeAccounts(idsToProcess);
 
    }
}

And here is our @future method. The only thing we need to add is one line of code to set the isFutureUpdate variable to true before we perform the update.

public class futureMethods{
 
    @future
    public static void processLargeAccounts(Set<Id> acctIDs){
 
        List<Account> acctsToUpdate = new List<Account>();
 
        /* Do awesome stuff with apex code */
 
        /*Before we perform this update we want to set the 
        isFutureUpdate boolean in our utility class to true */
        utility.isFutureUpdate = true;
 
        /*Now we can perform the update. The trigger will still 
        fire but none of the code inside of it will execute and
        this method will not be called again*/
        update acctsToUpdate;
    }
}

Now when the trigger is fired the @future method will not be called again.

This example shows the interaction between asynchronous operations but you can use this same solution if you have triggers that update triggers and cause a loop.

Categories: Apex 5 comments

Seattle Force.com User Group

September 29th, 2009

This is sort of a late notice but on October 1st there will be a Force.com user group in Seattle. If you are in the area and want to exchange ideas and best practices revolving around the Force.com platform please swing by.

Want to take a deeper dive into the technical capabilities of Salesforce? Would you like to meet other Force.com developers in the Seattle area? Interested in learning about new/different tools that will help you create and develop better solutions? A new Salesforce user group will be starting up on Thursday Oct 1. Meetings will be held on the first Thursday of every month.

We will try to cover a different range of topics at these monthly meetings such as:

  • Summary of new functionality in the upcoming release
  • Project spotlight where someone will demo their project and the technical details
  • Best Practices
  • 3rd Party development and integration tools
  • Apex and VisualForce
  • Open session to discuss specific questions you may have regarding your current projects

Time: 8-9am
Date: Oct 1, 2009
Location:

West Monroe Partners
1215 4th Ave Suite 1010
Seattle, WA 98161

Please contact Val Grasparil (vgrasparil@westmonroepartners.com) or Andrew Brown (abrown@westmonroepartners.com) if you have any questions.

Since it is in the morning, coffee and snacks will be provided. Please RSVP if you are planning on attending so we can make sure to have enough food for everyone.

Reach out directly to Val to RSVP. I’ve been told there is public parking available at the address above.

Gameforce

August 28th, 2009

Update: Video posted below.

This is my first post in nearly three weeks and my first Force.com related post in nearly a month. Where have I been you may wonder? Only working on the coolest Force.com site in the world :-P .  Haha, just kidding.  But yes, for the past 2 months I have been slowly chipping away on my entry for the Force.com Cloud Developer Challenge. So what did I build?

Gameforce - The Worlds 1’st online gaming site built upon the Force.com platform.

When I set out to build my entry I wanted to build something that had never been done before. We have all see the blogging, HR, accounting, shopping cart, content management, and many other traditional business apps. There is no doubt these can be super cool but in the end most of them have been done before. Salesforce.com and Force.com are typically viewed as a platform for business apps and I wanted to build something on the complete opposite end of the spectrum. I hope I have succeeded with building an online gaming site.

The site consists of two games: blackjack and LineUp4 aka Connect 4.

Blackjack
Place your bets and play against the dealer.

blackjack

LineUp4

A true online multiplayer game where two people can play against each other anywhere in the world. It also has the ‘Smack Talker’ which is live chat between the players. You can see more features listed on the about page located here.

lineup4

This site may not have the coolest graphics or the trendiest web design but when it comes to taking the Force.com platform to the limit I have used every trick in the book that I know about. When checking out this site keep in mind it was built with 100% Force.com. There is no extra javascript, flash, or any other web technology.

Video update:
After seeing how cool some of the videos were that other people created showing of their site  I created one as well. It gives a great overview in about 5 minuets. The one feature I forgot to mention in the video is that if you are playing a game of LineUp4 and are not logged in, you can log in, and will be returned to the game right where you left off. The game state will be saved.

http://tehnrd.com/gameforce.swf (if the video is to large for your screen, right click on the video and select ‘Show All’)

Now we wait for the results of the contest. I’m hoping this site puts me in contention for the Mac Book prize. I’m sure there are going to be some great entries but I’m hoping for the best since this site is like nothing I have ever seen before. My current computer is also 5 years old so a new pc definitely wouldn’t hurt. With so many entries in this contest perhaps salesforce could give away a more than one Mac Book ;-) ?

Also, due to the very dynamic nature of this site and the fact that it is currently hosted on a developer edition account I fully expect to exceed the site limits if this site gets popular. I have mirrored this site an a Force.com Free Edition account located here but it does not have the log in ability.

And one more thing. Thanks to my awesome wife for putting up with me while I constantly snuck away to work on this site.