Archive

Archive for the ‘Visualforce’ Category

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

IE9 & salesforce.com: When the cloud rains

April 1st, 2011 7 comments

UPDATE: See below.

If you don’t know already Internet Explorer 9 and Visualforce are a complete train wreck. Every single Visualforce page that performs a rerender (ajax operation) will not work with IE9. The operation appears to start and then never finishes. This has probably led to thousands of force.com developers scrambling around to find and implement a fix. The good news is fixes are pretty easy, you just need to force IE9 to run in IE8 compatibly mode. This page on developer.force.com has all of the dirty details.

So who’s is at fault for this? Microsoft’s IE9 or salesforce.com? Read more…

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

Dreamforce 2010, Meet jQuery

November 11th, 2010 14 comments

Many people reading this may already know what I am about to say but I’d like to announce some really exciting news. I will be co-presenting (with @JoshBirk) a session at Dreamforce 2010 on how you can use Visualforce with jQuery to build some wickedly awesome web apps.

I think this is really exciting for a few reasons. The first is that this particular session was chosen by the people for the people. On the Dreamforce Ideas website it is the most up voted session and all around idea. This means there are a lot of other people besides me excited about jQuery and how it can be used with the force.com platform.

Another reason I find this really exciting is that this will be my 4th Dreamforce and the first one I recall having a dedicated session to a JavaScript library like jQuery. One reason is that in the past 4 years JavaScript libraries have made HUGE gains in features and functionality. It will be great to see some alternatives to the typical *insert product name that rhymes with t-rex* session about building rich internet apps as I personally feel there are very few things *it* can do that most JavaScript libraries can’t.

I used to hate and despise JavaScript but jQuery has made be a believer. Rumor has it this session is filling up fast so if you are at all interested in learning more look for the session titled “Developing Applications with jQuery” in the Dreamforce agenda builder.

You can also follow the session in the Dreamforce Chatter app here: https://dreamevent.my.salesforce.com/a0930000006YhRa

UPDATE: Here is a package that includes all of the demos shown in this seesion.

UPDATED #2: Video has been posted here: http://www.youtube.com/watch?v=6je8AV6NuPM

Categories: jQuery, salesforce, 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

IP Address Geolocation with Force.com

July 9th, 2010 1 comment

If you have a website knowing where your visitors are located is a powerful feature. For starters it makes your website appear to have super powers if it automatically knows where the user is from. You can do all sorts of cool stalker stuff, and by cool stalker stuff, I mean customizing site content based on the visitors location.

iplocation

There are several different ways to figure out where a visitor is located, each with their pros and cons. The two main ways are IP address tracing and HTML5 geolocation. There is a great guide on developer.force.com about HTML5 geolocation that you should check out. HTML5 is all the rage these days but both methods have their advantages. In my testing HTML 5 was more accurate but it requires input from the user. The user must explicitly grant permission for the browser to find their location. Depending on the use case this may or may not work. IP address tracing on the other hand requires no input from the user and can be done completely behind the scenes unobtrusive to the user. The down side is that it is not as accurate. Another issue to consider is that some users (think your parents) will not want to click a button that gives away the location because they may think the internet is full of scams and the website will use this information to track them down and steal their identity….just sayin. So these are the two primary methods and choosing one really depends on the type of application you are building.

Read more…

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

Dreamforce 2010 and jQuery

April 22nd, 2010 8 comments

I finally got around to submitting a paper for Dreamforce 2010. The title…..wait for it……wait…..”Take Your Visualforce Pages to the Next Level with jQuery & jQuery UI”.

Visualforce is great for building solid and scalable web apps. Where it falls short is enhanced web 2.0 (I actually cringe at this term) usability. It lays a solid foundation but lacks slick UI features that users of today’s web expect and will soon demand. jQuery and jQuery UI make it incredibly easy to add enhanced functionality. In this presentation I will show best practices, pitfalls to watch out for, and of course show off some slick apps that use jQuery. What this won’t be is an advanced deep dive on jQuery. This presentation will show anyone who has a little web and Visualforce experience how to apply jQuery to projects they are working on as soon as they get back to work.

Salesforce has seriously pushed Flex the last few years but I guarantee you that 90% of the time I can build the exact same functionality in less lines of code with jQuery. It’s time to show some diversity at Dreamforce. Simply look at this trend for google searches.

jQuery is the most popular javascript library out there today and it even beats Adobe Flex in terms of people looking for more information. If Flex gets a dedicated session at Dreamforce so should jQuery!

If you are a regular reader of this blog you know I’ve got a quirky style with a touch of humor thrown in there. I’ll be sure to carry this over to my presentation unless salesforce makes me be all serious and professional, BORING.

If you like this idea please hit the link below and cast your vote.

Take Your Visualforce Pages to the Next Level with jQuery & jQuery UI

Categories: jQuery, salesforce, Visualforce

Override Visualforce Help Link with jQuery

April 12th, 2010 9 comments

Popups suck. Everyone hates them, but it wasn’t always like this. There once once a time long long ago when popup actually displayed relevant information related to the site you were browsing. This was in a time before tabbed browsing and advertising behemoths. Then came advertising on the web and popups galore. Here begins the downfall of the popup. It wasn’t long before popups became incredibly annoying and web users closed them without a glance. Popups were used, abused, and are now the scum of the internet user experience.

helplink

So why this brief, and quite frankly masterfully written story on the history of popups? The help link you can add to Visualforce pages is a popup. There are a few reasons I don’t like this. One, it is a popup, and people hate popups. Two, you also have to manage an entirely separate page for what could be a very simple help dialog. And 3, it just doesn’t provide a good user experience. It feels so 1999. Read more…

Categories: jQuery, salesforce, Visualforce

Salesforce Seizure

April 6th, 2010 2 comments

Here is a little jig i like to call the “Salesforce Seizure”.

Seriously, if you have photosensitive epilepsy I wouldn’t watch this.

Looks like it only happens in Firefox, possibly related to this and this.

Categories: salesforce, Visualforce