The Silver Lining

Lessons & Learnings from a salesforce certified technical architect.

Archive for the ‘VisualForce’ Category

Salesforce JavaScript Remoting: Using Apex and JavaScript objects to pass data from client- to server-side and vice versa

with 13 comments

I’ve spoken about how to do this at a high-level during Cloudstock London and there are hints at how it can be done but no formal documentation that I’ve found, so here we are :)

Quite simply JavaScript Remoting will transform Apex objects and classes (or collections of these types) into JavaScript objects for you. The opposite is true too but there are some rules you need to observe.

Apex Types to JavaScript Equivalents

This is the easier of the type conversions in that you don’t have to really do anything to make it happen. The code below uses a custom class that I’ve defined but you can do the same with any sObject too. Let’s have a look at the code.

The Controller

public with sharing class RemotingObjectsController {

    /* The remoting method simply instantiates a two custom types, puts
       them into a list and then returns them. */
    @RemoteAction
    public static List<CustomClass> getClassInstances(){
        List<CustomClass> classes = new List<CustomClass>();

        CustomClass me = new CustomClass('Wes');
        CustomClass you = new CustomClass('Champ');

        classes.add(me);
        classes.add(you);

        return classes;
    }

    /* My custom type */
    public class CustomClass{
        public String firstName{get;set;}

        CustomClass(String firstName){
            this.firstName = firstName;
        }
    }
}

The Visualforce

<apex:page controller="RemotingObjectsController">
  <script>
      // Will hold our converted Apex data structures
      var classInstances;

      Visualforce.remoting.Manager.invokeAction(
        '{!$RemoteAction.RemotingObjectsController.getClassInstances}',
        function(result, event) {
          // Put the results into a var for pedantries sake
          classInstances = result;

          console.log(classInstances);

          // Assign the first element of the array to a local var
          var me = classInstances[0];

          // And now we can use the var in the "normal" JS way
          var myName = me.firstName;
          console.log(myName);
        });
  </script>
</apex:page>

The Output

Console output from the JS code.

JavaScript Types to Apex Equivalents

This is a little tricker, especially when it comes to sObjects. Note that the approach below works for classes and sObjects too.

The Visualforce Page

<apex:page controller="RemotingObjectsController">
  <script>
      /* Define a JavaScript Object that looks like an Account */
      /* If you were using custom objects the name must include the "__c" */
      function Account(){
          /* Note the field names are case-sensitive! */
          this.Id = null; /* set a value here if you need to update or delete */
          this.Name = null;
          this.Active__c = null; /* the field names must match the API names */
      }

      var acc1 = new Account();
      acc1.Name = 'Tquila';
      acc1.Active__c = 'Yes';

      var acc2 = new Account();
      acc2.Name = 'Apple';
      acc2.Active__c = 'Yes';

      var accounts = new Array(acc1, acc2);

      Visualforce.remoting.Manager.invokeAction(
        '{!$RemoteAction.RemotingObjectsController.insertAccounts}',
        accounts,
        function(result, event) {
          console.log(result);
        });
  </script>
</apex:page>

The Controller

There not much to the controller in this case.

public with sharing class RemotingObjectsController {

    @RemoteAction
    public static void insertAccounts(List<Account> accounts){
        insert accounts;
    }

}

Why is this cool?

Good question. If the Force.com Platform didn’t do this for you then we – the developer – would need to convert ours types explicitly on both the server-side and the client-side, and man-oh-man is that boring, error-prone work. Yet again the guys at salesforce.com have built in a convenience that saves us time and let’s us get on with the work of building cool apps.

Written by Wes

June 22, 2012 at 11:06 am

Salesforce: JavaScript Remoting – a different way of thinking

with 6 comments

 

Remoting is awesome.

JavaScript Remoting for Apex operates in a very different paradigm from what you might be used to i.e. Visualforce pages have controllers and the two interact through action methods – where this might be a full form submission or some neat AJAX functionality. Remoting also calls controller methods but there is a gaping maw in terms of how the two work under the hood.

I’ve seen a few great articles on the syntax and example usage of JavaScript Remoting for Apex but when I started using it I came across a number domain differences that weren’t documented anywhere. Hopefully my list here will help you in the learning process. The best way to describe the new way of thinking is to examine the features set in contrast to “normal” Apex and Visualforce.

How JavaScript Remoting Differs

  • Pass parameters naturally i.e. the call matches the method signature syntactically instead of requiring <apex:param/>.
  • Action methods when called in “normal” Visualforce can only return NULL or a PageReference. Remoting allows you to return a wider range of data types, even objects and collections.
  • Remoting methods have no access to the view state e.g. if a static variable is initialised to some value (outside the remoting method) a remoting method will see this as NULL unless it is re-initialised in that method! Conversely if a remoting method sets a state variable value the scope of that value is only within that method.
  • It’s much faster. I’m building an application at the moment that is 95% backed by JS Remoting and when I show it to other developers they are struck dumb for at least 3 hours because of the speed.
  • Neater debugging info in the browser console. Salesforce has done a great job of providing feedback directly to the browser’s console log.
  • Each method call gets its own executional/transactional context i.e. fresh governor limits per call!

If I’ve missed anything please let me know and I’ll add it. Viva la knowledge crowdsourcing!

Written by Wes

February 5, 2012 at 4:05 pm

Salesforce: A better way to work with jQuery selectors and Visualforce Component Ids

with 24 comments

Irregular Expressions

I get very sad when discussing this particular topic. There are a variety of ways of get Visualforce component Ids and using them in JavaScript but all of them keep me awake at night. Srsly. A commenter on one of my posts got me thinking about how we can do this better and I’ve come up with a way that I think is great. Hopefully you’ll agree.

This post means that my older posts here and here are now retired in favour of this method.

If the world was on the brink of nuclear war with no clear path to peace what could you count on to save the day? Regular Expressions of course. If a meteor the size of Pluto was about to crash into Earth and Bruce Willis was too old to land on it and blow it up what could we count on to rid us of the troublesome rock. Yes that’s right, Regular Expressions. I think you can guess where I’m going with this.

jQuery has the ability to understand very simple regular expressions in it’s attribute selectors. The full documentation can be found here.

To solve our particular problem however the code is simple:

<apex:page>
    <head>
        <style>
            a,span{
                display:block;
            }
        </style>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

        <script>
           jQuery(document).ready(function($){
               $('#btn').click(function(e){
                   e.preventDefault();

                   console.log('The following element was found when looking for an id of \'output1\':');
                   console.log($('[id$=output1]')); /* Here's where we're grabbing the element. */
               });
           });
        </script>

    </head>

  <apex:outputText value="She sells seashells by the seashore." id="output1"/>
  <apex:outputText value="Peter Piper picked a pack of pickled peppers." id="output2"/>

  <a href="" id="btn">Click me.</a>

</apex:page>

The important part here is the selector $(‘[id$=output1]’) which says, “Find the id value that ends with ‘output1′”. This comes with a warning though! Do not duplicate the Visualforce Id that you give to your elements otherwise this piece of code will find all of them.

When I first wrote this post I used a selector extension library that gives you the full power of JavaScript-based regular expression but Ryan Fritts has rightly shown that the above will deal with 99% of use cases and is simpler. For those of you that need to deal with the extra 1% I’ve implemented a wrapper to regex selector as an example. It does exactly what jQuery is doing above and gives you access to the regex flags as documented here.

Thanks again Ryan!

Written by Wes

June 24, 2011 at 2:36 pm

Salesforce: Force.com Sites and Google Analytics

with 3 comments

This is a cross-post from the Tquila blog.

My Favourite Chart Type

Not having analytics built into your public sites is much like having a Q&A site but not allowing people to answer. In this case some of the questions are:

  • Where did you come from?
  • How long did you stick around for?
  • Where did you hang out on your visit?

Now I’m not going to debate which set of analytics is best but I did come across a few quirks when setting Google Analytics (GA) up for wesnolte.com that I suspect are fairly universal.

Build a Site

This of course is quite a big step and I’m going to assume you’re just about done. To get analytics up and running though you’re going to have to do a few extra bits.

Don't hack me pls.

  1. Sign up for a GA account, create a Website Profile and you’ll receive an Analytics Code. My code has been blocked out in orange in the image alongside, your code should appear in it’s place.
  2. Insert the standard Google Analytics Visualforce component into your page.
  3. Enter the same Analytics Code as above on the Force.com Site Detail page – the field is called “Analytics Tracking Code”.

If you go back to your Analytics home page and refresh you’ll see a little warning sign that tells you something is amiss – and it is but it’s difficult to figure out just what that something is.

S.O.S

The problem in this case is that the default robots.txt file for Force.com Sites blocks all bots. This is not a bad idea but it’s not obvious when setting all this up.

Michaelforce and myself seemed to have had these pains at the same time and he posted his findings here. You’ll need to apply step 3 from his post to allow GA to peek at your site.

Now in my particular case I did all of this and GA was still not able to access my site so I threw in the towel and coded the GA JavaScript straight into my page. A few days later however I realised that the robots.txt was probably caching so I ripped out that funky ol’ JavaScript, plugged the Visualforce component back in and BHAM! It worked. Now I know that exactly 5 people visit my site per day, and that 4 of them of from the UK :P

Some Advice

My analytics are working a charm but I’ve realised there’s a snag. Since salesforce.com doesn’t allow you access to their nameservers you have to point your root domain to your Force.com Site using URL forwarding at the domain registrar’s side i.e. I can use a CNAME to point www.wesnolte.com to my Force.com site but wesnolte.com has to bounce to my registrars forwarding server before it finally hits the real site. What this means is that – to GA – the traffic directly to wesnolte.com looks like it’s all coming from one source, that is the forwarding server. The only way that I know to work around this is to get people to only use the http://www.domain.com form of your URL – not ideal I know.

Written by Wes

March 11, 2011 at 7:26 pm

Announcing the Salesforce Handbook

with 6 comments

Recently, Jeff Douglas and I saw the potential for a beginner’s book – aimed at business owners, analysts and developers, that comprehensively documents Salesforce and Force.com. There is a tonne of documentation out there and we thought “Wouldn’t it be nice to have a handbook that lightly summarised the most important areas of the platforms as well as offering some best practise advice”. We mulled it over for a time, and today we’d like to announce that we’re currently writing:

The Salesforce Handbook

A newcomer’s guide to building applications on Salesforce.com and the Force.com Platform.

Hand-in-hand with the book we’ll be publishing content from the book on a WordPress site. Here you can expect to find excerpts from the book, but also content that supplements the book e.g. areas that’ll serve as best-practice hubs with links to official documentation, blog posts that rock the party, and even superb discussion forum threads.

We’d love to get your feedback on the book as it progresses, but for now you can checkout the announcement and let us know what you think of the idea.

Client-Side VisualForce Pagination with Pajinate

with 9 comments

Pajinated DataTable

Pagination is an essential, and not so easy to implement user interface device that allows the developer to break long lists of items, or one very long item into sub-pages. I love the challenge that pagination brings (who doesn’t really) when developing efficient and reusable server-side code, but this article isn’t about that. Sometimes I need things done quickly, easily, and preferably with as little compromise as possible, and that’s what client-side pagination is all about. Read the rest of this entry »

Written by Wes

April 21, 2010 at 9:20 pm

Friends Romans Country[wo]men

with 24 comments

In an attempt to attend DreamForce this year – I will conquer the Atlantic! – I’ve written up a white paper on a set of tools and workflows that I’ve found superb in more ways than one. I’d be happy & ecstatic(hapstatic?) if you could take a gander at my paper and, if it tickles your fancy, give it your vote. The idea itself describes the paper, but I failed to proof read it (and shock! Horror! There is no edit capability) so I’ll post a more refined version here,

Rapid application development is one of the strongest selling points of Salesforce and Force.com Platform; one that I’ve personally experienced time and time again. However, when it comes to translating that beautiful design document into a VisualForce interface, going from the design bits

The design document built from the 960.gs template

to a cross-browser, standards-compliant site prototype can be troublesome and often takes several days… and let’s be honest, potentially weeks. Read the rest of this entry »

Written by Wes

April 11, 2010 at 9:52 pm

Follow

Get every new post delivered to your Inbox.

Join 2,206 other followers

%d bloggers like this: