Monday, June 18, 2012

Using Javascript Remoting to populate data in JQGrid

Writing a post after quite some time, this requirement was given by a friend who is working on a POC for his project and I took it as a perfect opportunity to get some hands-on on JQuery :)

So, what was the requirement?
The requirement was simple, I needed to show contact data for a given account name in a JQuery grid.

What was the solution that came out after 8 hrs of research on JQuery and JS Remoting?
Surprisingly, the solution was pretty simple, I created a controller, a @RemoteAction annotated method that returned a List of Contacts to the Javascript being used on visualforce page. The callback remoting function converted the javascript array returned by the controller to the JSON which is then passed to the JQGrid.

What are the references being used for arriving at the solution?
1. http://www.tgerm.com/2010/02/visualforce-salesforce-jquery-ajax-how.html
2. http://www.trirand.com/blog/jqgrid/jqgrid.html
3. http://www.salesforce.com/us/developer/docs/pages/Content/pages_js_remoting.htm

What is the solution?
Here it is...

Working demo: http://testdomain5-developer-edition.na3.force.com/MySite/myp1__DeveloperPage3
Sample Data: Test Date Account 1


Visualforce page:

<apex:page standardController="Contact" showHeader="true" standardStylesheets="true" extensions="DeveloperExtension2" id="page1" >
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/themes/redmond/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="http://www.trirand.net/aspnetmvc/Content/themes/ui.jqgrid.css" />
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"/>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.7.1.min.js"/>
<script type="text/javascript" src="http://www.trirand.net/aspnetmvc/Scripts/trirand/i18n/grid.locale-en.js"/>
<script type="text/javascript" src="http://www.trirand.net/aspnetmvc/Scripts/trirand/jquery.jqGrid.min.js"/>
    
<script type="text/JavaScript">  
    function search(jsonString) {
        $("#pdata").jqGrid("GridUnload");
        var gridData;
        var obj;          
        gridData=JSON.stringify(jsonString);    
        obj = JSON.parse(gridData);      

        jQuery("#pdata").jqGrid({
        data: jsonString,
        datatype: 'local',
        colNames:['Name','Email'],
        colModel:[
            {name:'Name',index:'Name', width:40},
            {name:'Email',index:'Email', width:40}],
        rowNum:10,
        rowList:[5,10,20,30,50,100, 1000],
        pager: '#ppdata',
        sortname: 'name',
        viewrecords: true,
        sortorder: "desc",
        caption:"Contact Data",
        width: 800,
        height: 180,   
    });   
   $("#pdata").trigger("reloadGrid");
 }



function showDataInJqGrid(){
    var accName = document.getElementById("query").value;
    contactSearch(accName);
}

function contactSearch(name) {
    var jsonString;
    myp1.DeveloperExtension2.showContacts(name,handleContacts);
}

function handleContacts(result, event) {
    if(event.type == 'exception'){
        alert(event.message);
    }else{
        jsonString = result;
        search(jsonString);
    }
}
</script>

<apex:sectionHeader title="Contact Search using AccountID" subtitle="Search Contact" />
  <apex:pageBlock mode="maindetail">
    <apex:form id="qform" >
            <apex:pageBlockSection title="Search Contact for the Account" collapsible="false" columns="1" >
                <table width="100%">
                    <tr>
                        <td><h3>Enter Account Name </h3>&nbsp;&nbsp;<input type="text" id="query" />&nbsp;&nbsp;&nbsp;
                            <input type="button" value="Show Contacts " class="btn" onclick="showDataInJqGrid();" />&nbsp;&nbsp;&nbsp;
                        </td>
                    </tr>
                </table>
            </apex:pageBlocksection>
    </apex:form>

    <apex:pageBlockSection title="Contacts in Response" collapsible="false" rendered="true">               
        <div id="response" style="font-size: 16px;width: 300px;font-family: monospace; font-stretch: expanded" />               
        <table id="pdata"></table>
        <div id="ppdata"></div>
    </apex:pageBlocksection>
  </apex:pageblock>
</apex:page>


The controller extension:
global class DeveloperExtension2 {
    public DeveloperExtension2(ApexPages.StandardController controller){}

    @RemoteAction
    global static List<Contact> showContacts(String accName){
        accName = '%'+ accName+'%';
        List<Contact> lst_contacts = new List<Contact>([select id, name, email from contact where Account.Name LIKE : accName]);
        return lst_contacts;
    }
}

9 comments:

  1. SJ, I've copied your code directly into my dev environment and no results populated. I modified the query to pull in all contacts regardless of the search term to no avail. I did check, yes I did remember to seed some data in the dev environment so that there are contacts to find. Any help is appreciated.

    ReplyDelete
  2. Thanks Matthew for trying it out!!
    Are you able to see the grid on the page?
    If yes, can you try changing the below line in the contactSearch function:
    myp1.DeveloperExtension2.showContacts(name,handleContacts);
    with this one:
    DeveloperExtension2.showContacts(name,handleContacts);

    reason: myp1 is the namespace of the managed package in my Dev org.
    Hope it will help!!
    Regards,
    Sankalp

    ReplyDelete
  3. Hi sanklap
    i tried your code and got the same issue as mathew , then i removed mup1 namespace but still no result.. can you help me out

    ReplyDelete
  4. Hi,

    Thanks for trying it!!
    If you use Chrome, could you please do inspect element, check the JS console and see if any error is there?

    Also, could you plz post your code here? I will take a look.

    Regards,
    Sankalp

    ReplyDelete
  5. Hello Sankalp,

    I also tried to change the line to "DeveloperExtension2.showContacts(name,handleContacts);", however i'm getting a "DeveloperExtension2 Not Defined" error in the browser's developer console. Any ideas? This is a great solutions, and would like to get this working in the near future. Thanks!

    ReplyDelete
  6. Hi Mike,
    Thanks for trying it out. Could you please email the controller and visualforce page code to my email ID: sankalp.jhingran@gmail.com?

    I will take a look at it.

    ReplyDelete
  7. Sankalp What a great work :) .Just a quick note for those of you who are finding hard to get this for unmanaged package and getting not defined error ,here is the resolution

    function contactSearch() {
    var jsonString;
    Visualforce.remoting.Manager.invokeAction(
    '{!$RemoteAction.DeveloperExtension2.showContacts}',name,handleContacts);
    }

    ReplyDelete

Your feedback is always appreciated, thanks!!