Skip to content

Instantly share code, notes, and snippets.

@recalde
Created July 20, 2011 17:38
Show Gist options
  • Save recalde/1095457 to your computer and use it in GitHub Desktop.
Save recalde/1095457 to your computer and use it in GitHub Desktop.
Salesforce_JQuery_Remoting
global with sharing class CPPBuilderRob {
public CPPBuilderRob() {
// Remember: @RemoteActions are static, hence controller has no state
}
@RemoteAction
global static CPP_Report_Poller GetReportGroups(string opportunityId) {
// Query from CPP_Report_Request__c
CPP_Report_Request__c[] reportRequest =
[select Id, Report_Name__c, Sort_Order__c, Status__c, IsStandard__c, IsManual__c, Source_System__c, ContentId__c, Proposal_Id__c, OpportunityId__c
from CPP_Report_Request__c
where OpportunityId__c = :opportunityId and IsIncluded__c = true
order by IsStandard__c desc, Sort_Order__c];
// Group by Proposal ID
List<CPP_Report_Group> reportGroups = new List<CPP_Report_Group>();
integer groupNumber = 1;
for (CPP_Report_Request__c request:reportRequest) {
CPP_Report_Group reportGroup = FindGroup(reportGroups, request);
// If group doesn't already exist then create one
if (reportGroup == null) {
reportGroup = new CPP_Report_Group();
reportGroup.ProposalID = request.Proposal_Id__c;
reportGroup.GroupName = 'Proposal ' + request.Proposal_Id__c;
reportGroup.GroupNumber = groupNumber;
groupNumber++;
reportGroups.add(reportGroup);
}
reportGroup.reports.add(request);
}
CPP_Report_Poller poller = new CPP_Report_Poller();
poller.LastModifiedDate = GetLastModifiedDate(opportunityId);
poller.Groups = reportGroups;
return poller;
}
@RemoteAction
global static CPP_Report_Request__c[] GetOptionalReports(string opportunityId, string proposalId) {
// Query from CPP_Report_Request__c
CPP_Report_Request__c[] reportRequest =
[select Id, Report_Name__c, Sort_Order__c, Status__c, IsStandard__c, IsManual__c, Source_System__c, ContentId__c, Proposal_Id__c, OpportunityId__c
from CPP_Report_Request__c
where OpportunityId__c = :opportunityId and Proposal_Id__c = :proposalId and IsIncluded__c = false
order by Sort_Order__c];
return reportRequest;
}
@RemoteAction
global static void AddOptionalReports(string reportIds) {
List<string> split = reportIds.split(',');
// Query from CPP_Report_Request__c
CPP_Report_Request__c[] reportRequest =
[select Id
from CPP_Report_Request__c
where Id in :split];
for (CPP_Report_Request__c r:reportRequest) {
r.IsIncluded__c = true;
}
update reportRequest;
}
@RemoteAction
global static void RemoveReport(string reportId) {
CPP_Report_Request__c report = [select Id from CPP_Report_Request__c where Id = :reportId];
report.IsIncluded__c = false;
Update report;
}
@RemoteAction
global static DateTime GetLastModifiedDate(string opportunityId) {
// Query from CPP_Report_Request__c
CPP_Report_Request__c[] reportRequest =
[select LastModifiedDate from CPP_Report_Request__c
where OpportunityId__c = :opportunityId
order by LastModifiedDate DESC limit 1];
if (reportRequest.size() > 0)
return reportRequest[0].LastModifiedDate;
else
return DateTime.now();
}
// Lookup a group based on its Proposal Id
global static CPP_Report_Group FindGroup(List<CPP_Report_Group> reportGroups, CPP_Report_Request__c reportRequest) {
for (CPP_Report_Group reportGroup:reportGroups) {
if (reportGroup.ProposalID == reportRequest.Proposal_Id__c)
return reportGroup;
}
return null;
}
// This is the page-level view-model
global class CPP_Report_Poller {
public DateTime LastModifiedDate { get; set; }
public List<CPP_Report_Group> Groups { get; set;}
public CPP_Report_Poller() {
}
}
// Groups are rendered as a tab in the visual force page.
global class CPP_Report_Group {
public string ProposalID { get; set; }
public string GroupName { get; set; }
public integer GroupNumber { get; set; }
public List<CPP_Report_Request__c> Reports { get; set;}
public CPP_Report_Group() {
Reports = new List<CPP_Report_Request__c>();
}
}
}
<apex:page title="CPP Builder (Rob)" controller="CPPBuilderRob" sidebar="false">
<!-- Get the session for connection.js -->
<script type="text/javascript">
var __sfdcSessionId = '{!GETSESSIONID()}';
</script>
<!-- jQueryUI Theme -->
<link rel="stylesheet" href="{!URLFOR($Resource.jQueryGridPre19, '/jquery-jquery-ui-b5c4529/themes/base/jquery.ui.all.css')}"/>
<!-- Script references -->
<apex:includeScript value="{!URLFOR($Resource.jQueryGridPre19, '/jquery-jquery-ui-b5c4529/jquery-1.5.1.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQueryGridPre19, '/jquery-jquery-ui-b5c4529/ui/jquery.ui.core.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQueryGridPre19, '/jquery-jquery-ui-b5c4529/ui/jquery.ui.widget.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQueryGridPre19, '/jquery-jquery-ui-b5c4529/ui/jquery.ui.button.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQueryGridPre19, '/jquery-jquery-ui-b5c4529/ui/jquery.ui.tabs.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQueryGridPre19, '/jquery-jquery-ui-b5c4529/ui/jquery.ui.dialog.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQueryGridPre19, '/jquery-jquery-ui-b5c4529/ui/jquery.ui.position.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQueryTemplateBeta, 'jquery.tmpl.js')}"/>
<script src="../../soap/ajax/22.0/connection.js" type="text/javascript"/>
<script type="text/javascript">
var opportunityId = '006Q0000008RIxL';
var lastModified = '';
var pollerTimeout = 5000;
// Page Load
$(function () {
// Load Page Content
loadTabs();
// Add OnClick Events
$('.viewReport').live('click', viewReport);
$('.uploadReport').live('click', uploadReport);
$('.removeReport').live('click', removeReport);
$('.addOptional').live('click', addOptional);
$('.autocheck').live('click', function() {
var checkbox = $(this).parent().find('.addOptionalCheckbox');
checkbox[0].checked = !checkbox[0].checked;
return true;
});
});
// Load Tabs on Page Load
function loadTabs() {
// Javascript remoting
CPPBuilderRob.GetReportGroups(opportunityId, function(result, event) {
if(event.type == 'exception') {
alert(event.message);
} else {
// Render Tabs
var render = $('#tabContainerTemplate').tmpl(result);
$('#tabs').empty();
render.appendTo('#tabs');
// Style with jQuery UI Widget
$('#tabs').tabs();
$('.addOptional').button();
// Set timeout
lastModified = result.LastModifiedDate;
setTimeout("pollUpdate()", pollerTimeout);
}
});
}
// Check for Refresh
function pollUpdate() {
// Javascript remoting
CPPBuilderRob.GetLastModifiedDate(opportunityId, function(result, event) {
if(event.type == 'exception') {
alert(event.message);
} else {
if (lastModified != result) {
// Only reload tabs if data is updated
reloadTabs();
} else {
// Set timeout
setTimeout("pollUpdate()", pollerTimeout);
}
}
});
}
// Refresh Tabs on Interval
function reloadTabs() {
// Javascript remoting
CPPBuilderRob.GetReportGroups(opportunityId, function(result, event) {
if(event.type == 'exception') {
alert(event.message);
} else {
// Refresh each individual tab by updating data item
for (var groupIndex = 0; groupIndex < result.Groups.length; groupIndex++) {
var group = result.Groups[groupIndex];
var tabName = '#reportTable-' + group.GroupNumber;
// Get the tmplItem
var tmplItem = $(tabName).tmplItem();
// Update the data and refresh
tmplItem.data = group;
tmplItem.update();
}
$('.addOptional').button();
// Set timeout
lastModified = result.LastModifiedDate;
setTimeout("pollUpdate()", pollerTimeout);
}
});
}
// Callback OnClick View Link
function viewReport() {
var tmplItem = $(this).tmplItem();
var report = tmplItem.data;
var url = "/" + report.Id + "/e";
var editWindow = window.open(url,'Upload','height=500,width=600,left=100,top=100,status=no,scrollbars=yes,resizable=yes');
editWindow.focus();
// Prevent browser location update
return false;
}
// Callback OnClick Upload Link
function uploadReport() {
var tmplItem = $(this).tmplItem();
var report = tmplItem.data;
var url = "/apex/cppUploadManualReport"
+ "?oppId=" + report.OpportunityId__c
+ "&repId=" + report.Id
+ "&prop=" + report.Proposal_Id__c
+ "&repName=" + report.Report_Name__c;
var uploadWindow = window.open(url,'Upload','height=350,width=600,left=200,top=200,status=no,scrollbars=no,resizable=no');
uploadWindow.focus();
// Prevent browser location update
return false;
}
// Callback OnClick Remove Link
function removeReport() {
// Retrieve the template/data item used to render the row
var tmplItem = $(this).tmplItem();
// Style while deleting
$(tmplItem.nodes).css('background-color', '#fbd');
$(tmplItem.nodes).css('font-style', 'italic');
// Delete from database
CPPBuilderRob.RemoveReport(tmplItem.data.Id, function(result, event) {
if(event.type == 'exception') {
alert(event.message);
} else {
// Remove row when complete
$(tmplItem.nodes).hide();
}
});
// Prevent browser location update
return false;
}
// Callback OnClick Add Optional Link
function addOptional() {
// Retrieve the template/data item used to render the row
var tmplItem = $(this).tmplItem();
// Delete from database
CPPBuilderRob.GetOptionalReports(opportunityId, tmplItem.data.ProposalID, function(result, event) {
if(event.type == 'exception') {
alert(event.message);
} else {
// Render Tabs
var render = $('#optionalTableTemplate').tmpl({ Reports: result });
render.appendTo('#tabs');
$('#optionalDialog').dialog({
title: 'Add Optional Reports',
width: 600,
height: 500,
modal: true,
close: function(ev, ui)
{
$(this).remove();
},
buttons: [{
text: "Add Selected Reports",
click: addSelectedReports
}]
});
}
});
// Prevent browser location update
return false;
}
function addSelectedReports() {
var dialog = $(this);
var selected = $('#optionalDialog').find('input:checked');
var ids = '';
selected.each(function(index) {
if (ids != '') ids = ids + ',';
var tmplItem = $(this).tmplItem();
ids = ids + tmplItem.data.Id;
});
$('#contentWrapper').append('<br/>addSelectedReports(' + ids + ');');
if (ids != '') {
CPPBuilderRob.AddOptionalReports(ids, function(result, event) {
reloadTabs();
dialog.dialog("close");
dialog.remove();
});
} else {
dialog.dialog("close");
dialog.remove();
}
}
// Simple timestamp string
function getTime() {
var dateTime = new Date();
return dateTime.toLocaleTimeString();
}
</script>
<!-- jQuery template - Tabs Container -->
<script id="tabContainerTemplate" type="text/x-jquery-tmpl">
<ul id="tabUl">
{{each Groups}}
<li><a href="#tabs-${GroupNumber}">${GroupName}</a></li>
{{/each}}
</ul>
{{tmpl(Groups) "#tabTemplate"}}
</script>
<!-- jQuery template - Tab -->
<script id="tabTemplate" type="text/x-jquery-tmpl">
<div id="tabs-${GroupNumber}">
{{tmpl "#reportTableTemplate"}}
</div>
</script>
<!-- jQuery template - Report Table -->
<script id="reportTableTemplate" type="text/x-jquery-tmpl">
<div id="reportTable-${GroupNumber}">
<h2>${Reports.length} Reports</h2>
<table class="dataTable">
<colgroup>
<col width="50%"/>
<col width="10%"/>
<col width="10%"/>
<col width="10%"/>
<col width="10%"/>
<col width="10%"/>
</colgroup>
<thead>
<tr>
<th>Report Name</th>
<th>Source</th>
<th>Status</th>
<th>View</th>
<th>Upload</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
{{tmpl(Reports) "#reportRowTemplate"}}
</tbody>
</table>
<br/>
<a class="addOptional" href="#optional">Add Optional Reports</a>
</div>
</script>
<!-- jQuery template - Report Row -->
<script id="reportRowTemplate" type="text/x-jquery-tmpl">
<tr class="dataRow {{if IsStandard__c}}dataStandardRow{{/if}}">
<td>${Report_Name__c}</td>
<td>${Source_System__c}</td>
<td>${Status__c}
{{if Status__c}}
{{else !IsManual__c}}
<img src="{!URLFOR($Resource.AjaxArrowsGif)}"/>
{{/if}}
</td>
<td><a class="viewReport" href="/${Id}">View</a></td>
<td>
{{if IsManual__c}}
<a class="uploadReport" href="#uploadReport">Upload</a>
{{/if}}
</td>
<td>
{{if !IsStandard__c}}
<a class="removeReport" href="#removeReport">Remove</a>
{{/if}}
</td>
</tr>
</script>
<!-- jQuery template - Report Table -->
<script id="optionalTableTemplate" type="text/x-jquery-tmpl">
<div id="optionalDialog">
<table class="dataTable">
<colgroup>
<col width="10%"/>
<col width="40%"/>
<col width="50%"/>
</colgroup>
<thead>
<tr>
<th>Include</th>
<th>Report Name</th>
<th>Source</th>
</tr>
</thead>
<tbody>
{{tmpl(Reports) "#optionalRowTemplate"}}
</tbody>
</table>
</div>
</script>
<!-- jQuery template - Report Row -->
<script id="optionalRowTemplate" type="text/x-jquery-tmpl">
<tr class="dataRow optionalRow {{if IsStandard__c}}dataStandardRow{{/if}}">
<td><input class="addOptionalCheckbox" type="checkbox" name="IncludeOptional" value="Include" /></td>
<td class="autocheck">${Report_Name__c}</td>
<td class="autocheck">${Source_System__c}</td>
</tr>
</script>
<!-- Simple stylesheets for the table and rows -->
<style type="text/css">
table.dataTable
{
width: 100%;
border-collapse: collapse;
}
table.dataTable th, table.dataTable td
{
border: 1px solid #888;
text-align: left;
vertical-align: top;
padding: 5px;
}
tr.dataStandardRow
{
background-color: #efedee;
}
tr.dataRow:hover
{
background-color: #cef;
}
</style>
<!-- Target div for rendered templates -->
<div id="tabs" />
<!-- Links to code -->
<br/><h2>See the code:</h2><br/>
<a href="/01pQ0000000DyxD/e">CPPBuilderRob : Apex Class</a><br/>
<a href="/066Q000000098u9/e">CPPBuilderRob : Visual Force Page</a>
</apex:page>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment