+ Start a Discussion
RobinWRobinW 

Javascript button validation with Apex Class PageReference Constructor

Hi All,

We have a custom approval which is being carried by an Apex Class defening the logic behind it. The Apex Class gets the next approver based on certain Matrices in the system.

Now we would like to put in some validation when you click on the button. This button is a detail page button. Normally it just references a VF page. The VF page has an extension, calling the above class and firing a method.

The constructor of this Apex Class uses the ApexPages.StandardController method to get the current record from where the button was called. So without the need of creating separate query to get all the values of the fields referenced in the code.

So now we want to add the validation on the button using simple Javascript. The validation works, however, the Javascript will open up the location of the VF page. The VF page will call the method referenced in it's action. However, because of the Javascript, the ApexPages.StandardController references a null record.

Any ideas how we can get this done?

Following is the simple example of how the Javascript could look like:
{!REQUIRESCRIPT("/soap/ajax/24.0/connection.js")}

var result = sforce.connection.query("SELECT Id, StageName FROM Opportunity WHERE Id = '{!Contract_Approval__c.OpportunityId__c}' LIMIT 1");

records = result.getArray("records");

for(var i=0;i<records.length;i++) {
var record = records[i];

if(record.StageName == 'Not Won') {
window.location = '/apex/ApprovalButtonPage';
} else {
alert("Some Error Message.");
}
}

The VF page could look like this:

<apex:page standardController="Contract_Approval__c" extensions="ApprovalButtonController" action="{!submitApprovalProcess}">
    <apex:pageMessages />
</apex:page>
The Apex Class coud look like this:
public class ApprovalButtonController {
private final Contract_Approval__c conapp;

public ApprovalButtonController(ApexPages.StandardController controller) {
this.conapp = (Contract_Approval__c) controller.getRecord();
}

public PageReference submitApprovalProcess() {
// Logic
// Logic
}
}


How can I now make sure I can use the StandardController method via my Javascript validation?

Thanks!
Robin

Best Answer chosen by RobinW
Jim JamJim Jam
OK, as you're getting the id from a merge field I think the only thing you need to do is ..

window.location = '/apex/ApprovalButtonPage?Id={!Contract_Approval__c.Id}';

ie. no need to concatenate the string.


All Answers

Jim JamJim Jam
what if you change line 11 of your Javascript line to pass the id of the record as a page parameter ?.. like so ..

window.location = '/apex/ApprovalButtonPage?Id=' + record.Id;


RobinWRobinW
Hi Frank,

Thanks for your input!
But doesn't work. The following error message shows up: 

"A problem with the OnClick JavaScript for this button or link was encountered:

a0Y11000000APLS is not defined".

So it's not taking the Id..
Jim JamJim Jam
That's a little odd, can you paste your code again as it stands now?
RobinWRobinW
Hi Frank, I have the following now:
{!REQUIRESCRIPT("/soap/ajax/24.0/connection.js")}

var result = sforce.connection.query("SELECT Id, StageName FROM Opportunity WHERE Id = '{!Contract_Approval__c.OpportunityId__c}' LIMIT 1");

records = result.getArray("records");

for(var i=0;i<records.length;i++) {
var record = records[i];

if(record.StageName == 'Not Won') {
window.location = '/apex/ApprovalButtonPage?Id='+{!Contract_Approval__c.Id};
} else {
alert("Some Error Message.");
}
}

Is seems like it doesn't want to take the Id. Trying to convert the Id first to text using the TEXT() function doesn't help either.
Jim JamJim Jam
OK, as you're getting the id from a merge field I think the only thing you need to do is ..

window.location = '/apex/ApprovalButtonPage?Id={!Contract_Approval__c.Id}';

ie. no need to concatenate the string.


This was selected as the best answer
RobinWRobinW
Thanks Frank! 
That was indeed the solution. Lesson learned :)