This code assumes there will be a custom setting storingan object the ID of the last jobjobs*
//Only showing the area that needs to change
global void finish(Database.BatchableContext BC) {
string jobId = database.executeBatch(nextBatch);
customSetting__c myCs = customSetting__c.getOrgDefault();
if (myCs == null) {
object__c myCsmyObject = new customSetting__cobject__c();
}
csmyObject.Id__cJobId__c = jobId;
upsert cs;myObject;
}
<apex:page controller="myCont" action="{!scheduleJobgetJobs}">
<apex:form id="theForm">
<apex:pageMessages />
<apex:actionPollerrepeat action="value="{!checkCurrentJobtheJobs}" interval="5"var="job">
reRender="theForm" <!-- Add all needed fields and make this pretty, maybe a table -->
<apex:outputText value="{!job.Id}" /> -- <apex:outputText value="{!job.status}" />
<br/>
</apex:repeat>
</apex:form>
</apex:page>
public without sharing myCont() {
private string theId;
public voidList<AsyncApexJob> scheduleJob()theJobs {
theId = customSetting__c.getOrgDefault().Id__cget;set;
}
public void checkCurrentJob() {
if (String.isEmpty(theId)) { return; }
List<AsyncApexJob> theJobs = [SELECT Id, Status FROM AsyncApexJob WHERE Id = :theId LIMIT 1];
if (theJobs.isEmptygetJobs()) {
//Oops, I have the wrong one
} else {
AsyncApexJobSet<String> jobjobIds = theJobs[0];
//if it's cancelled or aborted, clear the record
if (job.Status == 'Aborted' || job.Status == 'Failed') {
//Aborted
ApexPages.addMessage(new ApexPages.MessageSet<String>(ApexPages.Severity.WARNING, 'Aborted'));
}
//if it is completed
For (object__c obj : if[select (job.StatusJobId__c ==from 'Completed'Object__c]) {
//Done
ApexPages.addMessage(new ApexPagesjobIds.Messageadd(ApexPages.Severityob.CONFIRM, 'Done')JobID__c);
}
//If it is alive, show progress
if (job.Status == 'Holding' || job.Status == 'Queued' || job.Status == 'Preparing' || job.Status == 'Processing') {
//In Progress
theJobs = ApexPages.addMessage(new[SELECT ApexPages.Message(ApexPages.Severity.INFOId, 'Info'));
}
Status FROM AsyncApexJob where Id in }:jobIds];
}