Seattle Force.com Developer Meeting

March 31st, 2010

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.

Serious Performance Issues with New Salesforce UI CSS

March 24th, 2010

To be honest I sort of feel bad about writing this post. I have already reviewed, ranted about, and tweaked the new salesforce.com UI, but here comes my third consecutive post related to this. I promise my next post will be about something super cool and radtaculous you can do with salesforce!

We hoped to enable the new UI in the next few weeks and like any good admin or developer I checked all of our custom Visualforce pages to make sure everything still looked and worked correctly. Everything started out so smooth. Everything was looking good. My basic, and for the most part, static Visualforce pages seem to work fine.

Read more…

Improve the New Salesforce UI with Greasemonkey

March 17th, 2010

In my last post (you can read it here) I was ranting like an angry hippopotamus about the new salesforce.com UI released with Spring 10 and what I think it should look like. This follow up post will show you how to make the changes I proposed in that post a reality.

Before we work the magic and make the new UI even better I want to expand on some of my thoughts regarding the new UI. Some may say it is “change” and change is hard, you just need to get used to it. Not true. Change should never be hard. Change should be something better. It should be a measurable improvement over the previous version. A perfect example of this was the recent redesign of cnn.com. This was a massive improvement and nearly everyone everyone applauded the changes. Change was easy because it made our user experience better. I don’t hate the new salesforce UI. I don’t even not like it. There is just something about it that doesn’t feel right. I can’t place my finger on it but I think the changes I’ve made below will make a huge improvement. Blah blah blah, enough pointless blabbering, let’s get to the good stuff.

Since the original post I have had some time to get comfortable with the new UI and several of the changes I initially proposed probably aren’t needed.  My first stab at changing the UI was also a bit bold, too bold. I took my changes of the UI to the extreme to really emphasize the direction I think the new UI needs to move. In reality the changes needed are much softer. What it came down to in the end was eliminating the massive amount of white space in the record detail section and bringing back the old style page block section separators. So how do we do this? Greasemonkey to the rescue!!!!

The first ingredient of awesomesauce is to install the Greasemonkey plugin for the Firefox browser. You can download that here. Greasemonkey allows you customize websites with fancy pants JavaScript.


Read more…

The New Salesforce UI Should Look Like This

March 11th, 2010

UPDATE: See the follow up post here: Improve the New Salesforce UI with Greasemonkey

The new salesforce.com UI has been rolled out to all instances as of March 6th and the feedback is starting to roll in. Based on the feedback I have heard, direct and indirect, is that there appears to be four groups of people. A few people that love it, a few people that like it, a lot of people that are undecided, and a lot of people that don’t like it. This is probably not the distribution of feedback salesforce was hoping for.

Read more…

Seattle Force.com Developer Group

March 3rd, 2010

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.

If Computers Could Barf – Salesforce Debug Log

March 1st, 2010

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 15 comments

Add Slider to a Visualforce Page with jQuery

February 16th, 2010

A while back Jeff Douglas posted on his blog how to embed a Flex slider into a visualforce page. This is pretty slick and can be really useful, but I’m not a really a fan of Flex (I’ll post about that later) so today let’s look at doing the same thing a little different.

Instead of using Flex to build the slider I will show you how to do this with javascript. This requires less code and I feel it is easier to implement.

We are going to add a super nifty ultra slick slider with only 16 lines of javascript code.

Read more…

How many lines of Apex code do you have?

February 9th, 2010

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 4 comments

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.
Read more…

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.
Read more…

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.

Read more…

Categories: Life 3 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 8 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 9 comments