Category Archives: Javascript Remoting

Sortable, searchable table with pagination using knockout.js in Salesforce

This is a demo using knockout.js to create a table for listing records of any object custom, standard or combinations of data from multiple objects.  The table is sortable and searchable using a typeahead search field.  It also includes a dropdown to limit the number of records visible as well as pagination.

This is what it looks like in its most basic styling:

This is the link to the working demo

 

This is the component that holds the knockout code:

This is the controller to retrieve the records using a remote action:

The visualforce page:

 

Get and pass date from Controller and pass to knockout

Javascript remote on site:

Visualforce.remoting.Manager.invokeAction(
  	'{!$RemoteAction.ApplicationController.getStudentInfo}',    
  	    function(student){                        	                        	                       	                                                                              		
    		Application.studentLastName(student.LastName); 
    		Application.studentFirstName(student.FirstName);
    		Application.studentPhone(student.Phone);
    		Application.studentAltPhone(student.OtherPhone);
    		Application.studentEmail(student.Email);   		
    		Application.studentHomeAddress(student.MailingStreet);			    		
    		Application.studentCity(student.MailingCity);			    		
    		Application.studentZip(student.MailingPostalCode);
    		Application.studentCountry(student.MailingCountry);
    		if(student.Birthdate != null){
    			var dob = normalizeDate(student.Birthdate);
	    		var dobAlt = normalizeDate2(student.Birthdate);
	    		Application.studentDOB(dob);
	    		document.getElementById('studentDOB_alternate').value = dobAlt;
	    }
  	},{escape : false});

Script to convert date from controller to mm-dd-yyyy

function normalizeDate(dateVal){ 
	mydate = new Date(dateVal);
    data = new Date(mydate -  mydate.getTimezoneOffset() * 60000);
    var d = mydate.getDate()+1;
    var m = mydate.getMonth()+1;
    var y = mydate.getFullYear();
    return (m<=9?'0'+m:m) +'-' + (d<=9?'0'+d:d)+'-' + y;		
}

Script to convert date from controller to yyy-mm-dd to send back to controller

function normalizeDate2(dateVal){ 
	mydate = new Date(dateVal);
    data = new Date(mydate -  mydate.getTimezoneOffset() * 60000);
    var d = mydate.getDate()+1;
    var m = mydate.getMonth()+1;
    var y = mydate.getFullYear();		    
    return y + '-' + (m<=9?'0'+m:m) +'-' + (d<=9?'0'+d:d);		
}

Knockout send to controller

self.goToParentSection = function(){
    			if (studentInfoValidation().length === 0) {		
					var parentIsEdit = self.parentIsEdit();
					var studentDetails = {
						representativeId : self.representativeId(),						
						applicationId : self.applicationId(),										
						studentFirstName : self.studentFirstName(),
						studentLastName : self.studentLastName(),
						studentDOB : (j$('#studentDOB_alternate').val()),
						studentPhone : self.studentPhone(),
						studentOtherPhone : self.studentAltPhone(),
						studentEmail : self.studentEmail(),
						studentCountry : self.studentCountry(),
						studentHomeAddress : self.studentHomeAddress(),
						studentCity : self.studentCity(),
						studentState : self.studentState(),
						studentZip : self.studentZip(),
						studentId : self.studentId(),
						studentInfoComplete : self.studentDetailsComplete(),
						householdId : self.householdId()																																	
					}
					Visualforce.remoting.Manager.invokeAction(
	                	'{!$RemoteAction.ApplicationController2.studentInfo}',studentDetails,   
	                        function(results){                        	
	                        	self.studentId(results.Id);	                            				                
	                        },{escape : false});
																
				}
				else {
		            alert('Please check your submission.');
		            studentInfoValidation.showAllMessages();
		        }		        					
			}			

Controller

@RemoteAction
    public static object studentInfo(Map<string, string> studentDetails){
		Date dt = Date.valueOf(studentDetails.get('studentDOB'));  
        studentId = studentDetails.get('studentId');
		Contact studentToUpdate = [SELECT id,AccountId, Name FROM Contact WHERE Id =: studentId];
		string contactRecordTypeId;    		
		RecordType rt = [select Id, Name from RecordType where DeveloperName = 'Student_Master' and SobjectType = 'Contact' limit 1];
		contactRecordTypeId = rt.Id;
		studentToUpdate.RecordTypeId = contactRecordTypeId;
		studentToUpdate.LastName = studentDetails.get('studentLastName');
		studentToUpdate.FirstName = studentDetails.get('studentFirstName');
		studentToUpdate.Phone = studentDetails.get('studentPhone');
		studentToUpdate.OtherPhone = studentDetails.get('studentOtherPhone');
		studentToUpdate.Email = studentDetails.get('studentEmail');   		
		studentToUpdate.MailingStreet = studentDetails.get('studentHomeAddress');  		
		studentToUpdate.MailingCity = studentDetails.get('studentCity');
		studentToUpdate.MailingState = studentDetails.get('studentState');
		studentToUpdate.MailingPostalCode = studentDetails.get('studentZip');
		studentToUpdate.MailingCountry = studentDetails.get('studentCountry');    		
		studentToUpdate.BirthDate = dt;    			
		
		update studentToUpdate;

		return studentToUpdate;    
	}

Visualforce page with datepicker


	

Datepicker date ranges with alt date to pass to controller

<script type="text/javascript">      
    j$ = jQuery.noConflict();       
    j$(document).ready(function() {
        j$( "#visaExpirationDate" ).datepicker({
            yearRange: "c:+10",//today plus 10 years
            //yearRange: "-25:c",//today minus 25 years
            changeMonth: true,
            changeYear: true,
            numberOfMonths: 1,
            dateFormat:"mm-dd-yy",
            altField: "#visaExpirationDate_alternate",
            altFormat: "yy-mm-dd",
            showAnim: "slide"
        })
    });                     
</script> 

How to: Visualforce Javascript Remoting

If you have done some Salesforce development, you have probably seen or heard of Visualforce Javascript Remoting.  If you haven’t heard of it, it is basically a way within Salesforce to call methods in a class via javascript.

You might be thinking to yourself “Hey, that sounds cool but why would I want to do that?”.  Well, there are a number of reasons.

No forms!
First of all, you are not required to use forms, Apex or otherwise.  This eliminates the need to keep viewstate.  By not keeping viewstate you are not passing or storing all of that data for the controller calls.  Your calls to the controller have a small footprint and become very efficient.  This is especially useful in mobile web development.

Blazing!
This leads to the second reason why you would want to use remoting, speed.  It is by far the fastest way of calling controller code and passing data to and from the page.  You are able to ensure that you are only passing the data you need each time you make a call.  Salesforce also bundles multiple subsequent calls by default with no work by you which also improves speed.

Asynchronous
The third reason why you might want to use remoting is because it is asynchronous.  Since it is asynchronous, you can load the initial page and data for the page and after that is all loaded you can start to lazy load data for the page that might not be prevalent for the inital load.  You can even use this method to start loading data for pages the user hasn’t even hit yet.  An example of this would be to load the first page and if there is a second page that you know if visited often you can load that in the background so if the user does switch to that second page all the data will be available which leads to an awesome user experience.

You are probably thinking, “This sounds awesome!  Why don’t I use this for everything?”.  Well, while it is pretty awesome it does take extra time to develop for and you also need to change how you develop and thinking about the flow of the page.  Since you aren’t using forms and there is no viewstate associated with it, you have to manage the state of the page on the client side.  On the other hand, there is nothing that says you can’t do a hybrid of using remoting with the standard MVC design paradigm with forms.  These are all things you need to consider when determining your design.  Remoting is just another tool in your belt.

So how do you use remoting?  It is actually pretty easy to do.  The definition for making a call in JS to a class is:

[namespace.]controller.method(
    [parameters…,]
    callbackFunction,
    [configuration]
);

That looks simple enough but what does it look like in practice?  Here you go:

MyController.methodOnMyController(
    firstParameter,
    secondParameter,
    function(results, event) {
        if(event.type === 'exception'){
            console.log("exception");
            console.log(event);
        }else if(event.status){
            $j.each(results, function(i, result){
                doSomethingWithTheResult(result);
            });
        }else{
            console.log(event.message);
        }
    }
);

This code is assuming I have a class called MyController and MyController has a method on it called methodOnMyController that takes two parameters.  If you have done ajax calls in jQuery this will look very familiar.  After the parameters, you have your callback function.  The callback function takes the results of the method call as well as the event object which has information on how the remoting call went.  If there is an exception it tells you so you can handle that in your JS otherwise you simply handle the results from the method call.

That’s all there is to it.  You can do what you will with the data depending on what you are trying to accomplish.  The nice thing about it is you can return standard and custom object as well as your own wrapper classes and reference the data just the same.

To complete the code on the controller, simply declare a public method in a public class as a remote action and make it static like so:

@RemoteAction
public static List<MyObject> methodOnMyController(String firstParemeter, String secondParameter){
    return new List<MyObject>();
}  

 

I hope this helps you will understanding remoting.  If you have any questions feel free to leave them in the comments below.  If you would like to learn more about JS remoting check out Salesforce’s docs.

Originally from :  Craig Isakson-Sundog Blog