Hi I have a VF Page and a controller which works fine on sandbox , But somehow they fails and give the following error on production which is due to view state Maximum view state size limit (135KB) exceeded. Actual view state size for this page was 198.516KB
Below is the view state of the page.
The Visualforce Page :
<script>
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: false,
events:[
<apex:repeat value="{!calendarEvents}" var="e">
{
title: '{!JSENCODE(calendarEvents[e].title)}',
start: '{!calendarEvents[e].startDate}',
end: '{!calendarEvents[e].endDate}',
url: '{!calendarEvents[e].url}',
allDay: {!calendarEvents[e].allDay},
color: '{!calendarEvents[e].color}',
customerName: '{!JSENCODE(calendarEvents[e].customerName)}',
address: '{!JSENCODE(calendarEvents[e].address)}',
phone: '{!calendarEvents[e].phone}',
owner: '{!calendarEvents[e].owner}',
leadSource: '{!JSENCODE(calendarEvents[e].leadSource)}',
type: '{!calendarEvents[e].type}',
},
</apex:repeat>
],
eventClick: function(event){
if(event.url){
window.open(event.url);
return false;
}
},
eventRender: function(event, element) {
element.qtip({
content: $('<div>' + event.customerName + '<br/>' + event.address + '<br/>' + event.phone + '<br/><br/>' + event.owner + '<br/>' + event.leadSource + '<br/>' + event.type + '</div>')
});
}
});
});
</script>
<apex:pageBlock title="Calendar">
<apex:pageBlockSection columns="1">
<apex:form >
<div id="cal-legend">
<ul>
<apex:repeat value="{!usrList}" var="usr">
<li><span style="background:{!usrList[usr].Color__c} !important; border-color:{!usrList[usr].Color__c};"></span>{!usrList[usr].Name}</li>
</apex:repeat>
</ul>
<div style="clear:both;"> <!--fix floats--></div>
</div>
<div style="clear:both;"><!--fix floats--></div>
<div id="calendar"></div>
</apex:form>
</apex:pageBlockSection>
</apex:pageBlock>
<apex:includeScript value="{!URLFOR($Resource.fullCalendarJS, 'fullcalendar-2.3.2/lib/moment.min.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.fullCalendarJS, 'fullcalendar-2.3.2/lib/jquery.min.js')}"/>
<apex:includeScript value="{!$Resource.jqueryui}"/>
<apex:includeScript value="{!URLFOR($Resource.qTip,'/jquery.qtip.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.fullCalendarJS, 'fullcalendar-2.3.2/fullcalendar.min.js')}"/>
<style>
#cal-legend { float:right;}
#cal-legend ul {margin:0;padding:0;list-style:none;}
#cal-legend ul li {margin:0;padding:5px;float:left;}
#cal-legend ul li span {display:block; height:16px; width:16px; margin-right:4px; float:left; border-radius:4px;}
#calendar {margin-top:20px;}
</style>
And the controller :
public class EventCalendar {
public Map<Id,User> usrList{get;set;}
public String events{get;set;}
public Map<Id,CalEvent> calendarEvents{get;set;}
set<String>setofeventCalnUser;
public EventCalendar(){
setofeventCalnUser = new set<string>();
for(string str : System.Label.EventCal.split(',')){
setofeventCalnUser.add(str);
}
if(setofeventCalnUser.size()>0){
usrList = new Map<Id,User>([SELECT Id,Color__c,Name FROM User WHERE Profile.Name = 'Sales User' OR Username IN :setofeventCalnUser ]);
}
else {
usrList = new Map<Id,User>([SELECT Id,Color__c,Name FROM User WHERE Profile.Name = 'Sales User']);
}
String dtFormat = 'EEE, d MMM yyyy HH:mm:ss z';
calendarEvents = new Map<Id,CalEvent>();
Map<Id,Id> evtOppMap = new Map<Id,Id>();
for(Event evt : [SELECT Id, Subject, isAllDayEvent, Owner.Name, OwnerId, StartDateTime, EndDateTime, Location, WhatId FROM Event WHERE OwnerId IN: usrList.keySet()]){
evtOppMap.put(evt.Id,evt.WhatId);
calendarEvents.put(evt.Id,new CalEvent(evt.Subject + (evt.Location == null?'':' - ' + evt.Location),evt.isAllDayEvent,evt.StartDateTime.format(dtFormat),evt.EndDateTime.format(dtFormat),'/' + evt.Id,usrList.get(evt.OwnerId).Color__c,evt.Owner.Name));
}
Map<Id,Opportunity> oppMap = new Map<Id,Opportunity>([SELECT Id, Name, Account.BillingStreet, Account.BillingCity, Account.BillingState, Account.BillingPostalCode,
Account.BillingCountry, Account.Phone, LeadSource, Type FROM Opportunity WHERE Id IN: evtOppMap.values()]);
for(Id evtId : calendarEvents.keySet()){
Opportunity opp = oppMap.get(evtOppMap.get(evtId));
if(opp != null){
calendarEvents.get(evtId).customerName = opp.Name;
calendarEvents.get(evtId).address = opp.Account.BillingStreet + ',<br/>' + opp.Account.BillingCity + ', ' + opp.Account.BillingState + ' ' + opp.Account.BillingPostalCode + ',<br/>' + opp.Account.BillingCountry;
calendarEvents.get(evtId).phone = opp.Account.Phone;
calendarEvents.get(evtId).leadSource = opp.LeadSource;
calendarEvents.get(evtId).type = opp.Type;
}
}
}
public class CalEvent{
public String title{get;set;}
public Boolean allDay{get;set;}
public String startDate{get;set;}
public String endDate{get;set;}
public String url{get;set;}
public String color{get;set;}
public String customerName{get;set;}
public String address{get;set;}
public String phone{get;set;}
public String leadSource{get;set;}
public String type{get;set;}
public String owner{get;set;}
public CalEvent(String title, Boolean allDay, String startDate, String endDate, String url, String color, String owner){
this.title = title;
this.allDay = allDay;
this.startDate = startDate;
this.endDate = endDate;
this.url = url;
this.color = color;
this.owner = owner;
}
}
}
Let me know what can be changes , I have checked the best practice But transient usage I am unable to understand and how the error can be resolved in production