+ Start a Discussion
trueSayertrueSayer 

Using jqGrid and JSON in Salesforce

Hello All,

 

I have a requirement to create a grid in Saleforce using jqGrid  and Json.   The jqGrid working example page http://www.trirand.com/blog/jqgrid/jqgrid.html has examples using MySQL and JSON.

 

Is there any examples using Salesforce along with JSON???

 

Any help will be greatly appreciated!!

 

Thanks

 

 

Best Answer chosen by Admin (Salesforce Developers) 
trueSayertrueSayer

Thanks for the reply.  I am following your advice but running to a problem.  The grid appears but no data from my controller. I am wondering if I have the URL (where the jqGrid calls for the data) is coded corrected.  Here is what I did:

 

 

<apex:pages>

 

....  various URLFOR to access jQuery and jqGrid - I left out...

...

<script type="text/javascript">
$(function(){
jQuery("#list2").jqGrid({
url:'https://c.cs3.visual.force.com/apex/ProjectSelectControllerExtension.getprojAssetsMap()',
datatype: "json",
colNames:['ID','Name', 'Amount1'],
colModel:[{name:'id',index:'id', width:80, sorttype:"int"},
{name:'name',index:'name', width:90},
{name:'Default_Amount__c',index:'Default_Amount__c', width:90, align:"right",sorttype:"float"}
],
rowNum:10,
rowList:[10,20,30],
pager: '#pager2',
sortname: 'id',
viewrecords: true,
sortorder: "desc",
caption:"JSON Example"
});
});

$(function(){
jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});
});
</script>

 

<table id="list2"></table>
<div id="pager2"></div>


</apex:page>

 

Here is my controller:

 

public with sharing class ProjectSelectControllerExtension {

private Account acct;
//Project
private AFIProject__c project;

public ProjectSelectControllerExtension(Apexpages.Standardcontroller stdController){


this.project = [SELECT id,Name, project_Status__c,project_Type__c, Grant_Number__c, Award_Date__c FROM AFIProject__c WHERE Id =:ApexPages.currentPage().getParameters().get('id')];
 
 
}

@RemoteAction
public static Map <id, Project_Asset__c> getprojAssetsMap(){
 
Map<id,Project_Asset__c> projAssetsMap = new Map<id, Project_Asset__c>();

for(Project_Asset__c pa : [SELECT id, Name, Default_Amount__c FROM Project_Asset__c WHERE project__c =:ApexPages.currentPage().getParameters().get('id')])
{
projAssetsMap.put(pa.id, pa);
}
system.debug('Map Size: ');
system.debug(projAssetsMap.size());
return projAssetsMap;
}

 

 

Am I accessing the remote method correctly in Apex?

 

Thanks

 

All Answers

bvramkumarbvramkumar

Create a @RemoteAction global method in your controller that will return the Map<Id, <Your custom object name>>. This will automatically return all your data in the form JSON data. Then all you need to do is,  Add that JSON received from controller to the configuration part requried for the jqGrid. that is it.

 

JS Remoting article is here:

http://www.salesforce.com/us/developer/docs/pages/Content/pages_js_remoting.htm 

trueSayertrueSayer

Thanks for the reply.  I am following your advice but running to a problem.  The grid appears but no data from my controller. I am wondering if I have the URL (where the jqGrid calls for the data) is coded corrected.  Here is what I did:

 

 

<apex:pages>

 

....  various URLFOR to access jQuery and jqGrid - I left out...

...

<script type="text/javascript">
$(function(){
jQuery("#list2").jqGrid({
url:'https://c.cs3.visual.force.com/apex/ProjectSelectControllerExtension.getprojAssetsMap()',
datatype: "json",
colNames:['ID','Name', 'Amount1'],
colModel:[{name:'id',index:'id', width:80, sorttype:"int"},
{name:'name',index:'name', width:90},
{name:'Default_Amount__c',index:'Default_Amount__c', width:90, align:"right",sorttype:"float"}
],
rowNum:10,
rowList:[10,20,30],
pager: '#pager2',
sortname: 'id',
viewrecords: true,
sortorder: "desc",
caption:"JSON Example"
});
});

$(function(){
jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});
});
</script>

 

<table id="list2"></table>
<div id="pager2"></div>


</apex:page>

 

Here is my controller:

 

public with sharing class ProjectSelectControllerExtension {

private Account acct;
//Project
private AFIProject__c project;

public ProjectSelectControllerExtension(Apexpages.Standardcontroller stdController){


this.project = [SELECT id,Name, project_Status__c,project_Type__c, Grant_Number__c, Award_Date__c FROM AFIProject__c WHERE Id =:ApexPages.currentPage().getParameters().get('id')];
 
 
}

@RemoteAction
public static Map <id, Project_Asset__c> getprojAssetsMap(){
 
Map<id,Project_Asset__c> projAssetsMap = new Map<id, Project_Asset__c>();

for(Project_Asset__c pa : [SELECT id, Name, Default_Amount__c FROM Project_Asset__c WHERE project__c =:ApexPages.currentPage().getParameters().get('id')])
{
projAssetsMap.put(pa.id, pa);
}
system.debug('Map Size: ');
system.debug(projAssetsMap.size());
return projAssetsMap;
}

 

 

Am I accessing the remote method correctly in Apex?

 

Thanks

 

This was selected as the best answer
Jordan@BracketLabsJordan@BracketLabs

@trueSayer, 

 

Your not accessing the data correctly,

 

you can't set the URL of the method directly:

 

url:'https://c.cs3.visual.force.com/apex/ProjectSelectControllerExtension.getprojAssetsMap()',

 instead with JS Remoting, in Javascript use:

controllerName.methodName(param1, param2, function(e,r){
   if(result.status == true){
       /* ... process results ... */
   }
});

 Also, something to consider, currently, I'm using jQGrid in VF Pages, and I've been using 'addRowData' after I place my javascript remoting results into an array (as the JS has already been processed into a JS Object by the Remoting javascript from Salesforce), so you can insert it using the following: 

 

$j('#gridname').jqGrid('addRowData', record.Id, rowData[0]);

 This is supposedly not very efficient, and doesn't lend itself to paging well (per jQGrid creators comments): http://stackoverflow.com/questions/9778744/jqgrid-pagination-with-array-of-results

 

So I'm try to find a way to extract the 'JSON' string DIRECTLY from the @RemoteAction result...? 

trueSayertrueSayer

 

Thanks for the reply.   My next effort will be inLine editoring with jqGrid,  But in the meantime, load data and calling the method is beating me up.  Here is my latest call will not results.  The debugger log in SF does not show the call:

 

url:'
ProjectSelectControllerExtension.getprojAssetsMap(
function(result,event){
if(event.status==false){alert("error")}
},
{escape:true}
)'

 

I included an alert just to see if it is calling.

 

 

Jordan@BracketLabsJordan@BracketLabs

Your call looks pretty solid.

 

Except: in jqgrid, 'URL' is the URL of the service that directly returns JSON/XML/whatever data, but in JavaScript and JS Remoting for Apex, the call your making actually returns the data In a callback from the JavaScript function your invoking. So setting it as a URL won't work.

 

You can't make a HTTP request to a JS function...

 

You should invoke that JS function as you have it written and use the returned data in the callback to populate the grid. Fire up your JavaScript debugger and make sure the JavaScript can correctly find the function definition when it attempts to invoke the function, if it's correctly defined than you know you have it setup correctly in the controller, if not something is wrong with the way your setting it up on the controller/apex side of things...does that make sense?

trueSayertrueSayer

Thanks for your help.  

 

You were right.  My controller was causing the problem.  Its working now.

atidevatidev

Hi,

  Can you please post the code that works. I have a similar requirement.

Thanks

trueSayertrueSayer

Hi,

 

Instead of using a URL to suuply the grid with data,  I used an array supplied by the controller:

 

       j$(function(){       
            var objectList = jQuery("#objectList").jqGrid({
                datatype: 'local',
                width: '100%',
                loadui: 'enable',
                repeatitems:false,
                colNames: ['ID', 'Name'],
                colModel: [{
                    name: 'uniqueID',
                    align: 'left',
                    editable: true},
                {
                    name: 'name',
                    align: 'left'}
                   ],
                loadComplete: function(data) {
                   //alert('grid loading completed ' + data);
                },
                loadError: function(xhr, status, error) {
                    alert('grid loading error' + error);
                }
                ,
                editurl: "dummy.php", //dummy url
                pager: '#objectListpager2',
                caption: "objectList Details",
                rowNum:10,
                rowList:[10,20,30],
                cellEdit: true,
                cellsubmit:"clientArray"
                
            })

            // Create the collection
            var Collection = Backbone.Collection.extend();
      
            
            GridController.getobjectListArray(function (result,event){
                                    if(event.status) {
                                        var resultArrays = new Collection(result);
                                        resultArrays.each(function addToGrid(resultVal,i){
                                           objectList.jqGrid('addRowData', i,resultVal.toJSON());
                                        });
                            
                                       return result;
                                    
                                    } else {
                                        alert('failed');
                                    }
                                 }, {escape:false} );
           
        }),(jQuery);
        
        j$(function(){
            jQuery("#objectList").jqGrid('navGrid','#objectListpager2',{edit:false,add:false,del:false});
         });  

 

 

Your controller should supply am List<Object> array to the the grid. Like above GridController.getobjectListArray call

 

atidevatidev

THanks. But is it possible to have the column names dynamically generated. I have to show the grid with different columns depending on the user. 

Thanks,

atidevatidev

Hi,

 I tried this code. But it doesn't work. Please help.

 

<apex:page controller="GridController" sidebar="false">
<script src="{!URLFOR($Resource.jQueryFiles, 'js/jquery-1.5.1.min.js')}"/>
<script src="{!URLFOR($Resource.jQueryFiles, 'js/jquery-ui-1.8.14.custom.min.js')}"/>
<script src="{!URLFOR($Resource.jqGrid, 'js/jquery.jqGrid.min.js')}"/>
<apex:stylesheet value="{!URLFOR($Resource.jgGridcss, 'css/ui.jqgrid.css')}"/>

<script type="text/javascript">
j$(function(){
var objectList = jQuery("#objectList").jqGrid({
datatype: 'local',
width: '100%',
loadui: 'enable',
repeatitems:false,
colNames: ['ID', 'Name'],
colModel: [{
name: 'uniqueID',
align: 'left',
editable: true},
{
name: 'name',
align: 'left'}
],
loadComplete: function(data) {
//alert('grid loading completed ' + data);
},
loadError: function(xhr, status, error) {
alert('grid loading error' + error);
}
,
editurl: "dummy.php", //dummy url
pager: '#objectListpager2',
caption: "objectList Details",
rowNum:10,
rowList:[10,20,30],
cellEdit: true,
cellsubmit:"clientArray"

})

// Create the collection
var Collection = Backbone.Collection.extend();


GridController.getobjectListArray(function (result,event){
if(event.status) {
var resultArrays = new Collection(result);
resultArrays.each(function addToGrid(resultVal,i){
objectList.jqGrid('addRowData', i,resultVal.toJSON());
});

return result;

} else {
alert('failed');
}
}, {escape:false} );

}),(jQuery);

j$(function(){
jQuery("#objectList").jqGrid('navGrid','#objectListpager2',{edit:false,add:false,del:false});
});

});


</script>

<table id="objectList"></table>
<div id="objectListpager2"></div>
</apex:page>

 

-----Controller -----------------

Global with sharing class GridController {

public String contType { get; set; }
@RemoteAction
Global static List <Account> getobjectListArray (){


List<Account> projAssetsList = new List<Account>();

projAssetsList = [SELECT id, Name FROM Account];

return projAssetsList ;
}
}

trueSayertrueSayer

Instead pf sending back Account List.  Create a pojo of the Account object containing onl the columns you need.

 

global accountDetails class{

 global id uniqueID;

 global  String name;

}

@RemoteAction

Global static accountDetail [] getobjectListArray (){


List<Account> projAssetsList = new List<Account>();
accountDetail [] adArray = new accountDetail();
projAssetsList = [SELECT id, Name FROM Account];

for....

accountDetail ad = new accountDetail();

ad.unqueID = projAssetsList.id;

ad.name = projAssetsList.name.

adArray.add(ad);

,,,,

return adArray;

 

 

 Make sure use the same column names in javascript since its case sensitive.