function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
jldenningjldenning 

addMessage not displaying when called from Custom Button

I have a button on a VF page that calls a web service to create a record.  I would like to check if that record already exists, and if it does, display a message to the user.  I cannot get the message to display.  Could someone clue me in on what I need to do?

 

Code for the Button

{!REQUIRESCRIPT("/soap/ajax/10.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")}

sforce.apex.execute("WSClass", "runCourseAdd", 
{
DocId:"{!Controlled_Document__c.Id}" ,
}
);
window.location.reload();

 Pertinent Class Code

public void addCourse()
{
    if (Course != null)
    {
     String errMessage = 'Course already exists for Revision ' + Course.Revision__c;
     if (ApexPages.currentPage() != null) 
     { 
         ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, errMessage ));
     }
    }
}

 VF page

<apex:page standardController="Controlled_Document__c" title="Document Auto Log" sidebar="true" setup="false" >
   <apex:pageMessages />
   <apex:detail />
</apex:page>

 

sfdcfoxsfdcfox
The code is called in a non-Visualforce context, so the page won't automatically show the messages. Instead, use an actionFunction to call your function from JavaScript.
jldenningjldenning
Thanks for the insight. Where would the action function be defined and can it be called from a custom button?
Team WorksTeam Works

HI,

<apex:actionFunction>

A component that provides support for invoking controller action methods directly from JavaScript code using an AJAX request.

<apex:form>
        <!-- Define the JavaScript function sayHello and invoke in Button-->
        <apex:actionFunction name="sayHello" action="{!sayHello}" rerender="out" status="myStatus"/>
    </apex:form>

jldenningjldenning
Can the controller action be called from a custom button? I was under the impression apex methods couldn't be called directly from custom buttons and that was why I was using the web service call.
sfdcfoxsfdcfox

Let me show you a brief example:

 

<apex:page controller="msg">
    <apex:form id="form">
        <apex:pageMessages />
        <apex:actionFunction name="displayMessage" action="{!displayMessage}" reRender="form"/>
        <button onclick="displayMessage(); return false;">Display Message</button>
    </apex:form>
</apex:page>

 

public with sharing class msg {
    public void displayMessage() {
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'This is a demo message.'));
    }
}

As you have stated, you cannot call controller methods directly. However, by binding the function to an actionFunction, you can then access the function in JavaScript, and even manipulate the state of the page in JavaScript.

Team WorksTeam Works

About Message,Messages,pageMessage and pageMessages ---> actionFunction

Error Messages on Visualforce Pages:
<apex:message> 

A message for a specific component, such as a warning or error. If an < apex:message > or < apex:messages > component is not included in a page, most warning and error messages are only shown in the debug log.

for

 

The ID of the   component with which the message should be associated.

 

<apex:messages> 

All messages that were generated for all components on the current page. If an < apex:message > or < apex:messages > component is not included in a page, most warning and error messages are only shown in the debug log.

<apex:pageMessage> 

This component should be used for presenting custom messages in the page using the Salesforce pattern for errors, warnings and other types of messages for a given severity. See also the pageMessages component.

Severity,strength,summary<apex:pageMessages> 

This component displays all messages that were generated for all components on the current page, presented using the Salesforce styling.


<apex:page controller="TestMessageController">

        <apex:form >

        <apex:pageMessages />

 

        <apex:pageMessage severity="warning" strength="1" summary="This is the pageMessage Error-Warning 1"/>       

        <apex:pageMessage severity="info" strength="2" summary="This is the pageMessage Error Info 2"/>

        <apex:pageMessage severity="Error" strength="3" summary="This is the pageMessage Error-- Error 3"/>                       

 

        <apex:messages />

        <apex:outputLabel value="Test String1" for="test1"/>

        <apex:inputField value="{!test.Industry}" id="test1"/>   <br/>         

        <apex:outputLabel value="Test String" for="test"/>

        <apex:inputField value="{!test.Name}" id="test"/>

       

        <br/><apex:message for="test"/>

        <br/><apex:message for="test1"/>

</apex:form>

</apex:page>
public class TestMessageController{

    public Account test{get;set;}

    public TestMessageController(){

        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.info, 'This is apex:pageMessages'));

        //ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'This is apex:pageMessages'));     

        test = new Account();

        test.Industry.addError('apex:Message Correct');

        test.Name.addError('Apex:Message Wrong');

    }

}

 

==========================actionFunction======================================

) A component that provides support for invoking controller action methods directly from JavaScript code using an AJAX request. An < apex:actionFunction > component must be a child of an < apex:form > component.
action :The action method invoked when the actionFunction is called by a DOM event elsewhere in the page markup. Use merge-field syntax to reference the method. For example, action="{!save}" references the save method in the controller. If an action is not specified, the page simply refreshes.
name : The name of the JavaScript function that, when invoked elsewhere in the page markup, causes the method specified by the action attribute to execute. When the action method completes, the components specified by the reRender attribute are refreshed.
reRender The ID of one or more components that are redrawn when the result of the action method returns to the client. This value can be a single ID, a comma-separated list of IDs, or a merge field expression for a list or collection of IDs.

Unlike < apex:actionSupport >(uses event to call class method), which only provides support for invoking controller action methods from other Visualforce components, < apex:actionFunction > defines a new JavaScript function which can then be called from within a block of JavaScript code.
Example :
<apex:page standardController="Account" extensions="functionController" >

  <apex:form >

    <apex:actionFunction action="{!actionFunMethod}" name="actionFunMethod22"  reRender="outputtextId"/>

      <apex:pageBlock >

       <apex:outputLabel for="inputCheckbox" value="Check This box to call controller method from js using actionFunction"  style="color:green;"></apex:outputLabel>

       <apex:inputCheckbox onclick="javascript1()" id="inputcheckbox" /><br/>

       <apex:outputText value="{!OutputTextfromMethod}" id="outputtextId"></apex:outputText>

     </apex:pageBlock>

  </apex:form>

   <script >

   function javascript1(){

   actionFunMethod22();

   }

  </script>

</apex:page>
public with sharing class functionController {

    public String OutputTextfromMethod{get;set;}

    public functionController(ApexPages.StandardController controller) {

    }

public string actionFunMethod(){

       OutputTextfromMethod = 'Output text from Method called from js using actionFunction';

       return null;  

       } 

}

Clicking the checkbox calls the Javascript1  --Calling the ActionFuntion tag from the js actionFunMethod = Name attribute in the actionFunction tag. When ever the js javascript1 is invoked from this page , it looks for the Name attribute of the actionFunction tag. Once a actionFunction tag is found with the function name in javascript1 it invokes the controller method specified in the action attribute of the actionFunction.

jldenningjldenning

My final solution is below.  Custom button submits the form on the VF page.  Form calls the method in the extension and returns the message.  Thanks to all.

 

VF Page

<apex:page standardController="Controlled_Document__c" title="Document Auto Log" sidebar="true" setup="false" extensions="Training_AddCourse"  >
   <apex:pageMessages />

 <div id="divCheckbox" style="visibility: hidden">
  <apex:form id = "courseForm">
      <apex:actionFunction name="addCourse" action="{!addCourse}" reRender="form"/>
        <apex:commandButton   value="Create Training Records" id="createTrainingRecords"  action="{!addCourse}"/> <p/>
    </apex:form>
</div>

 Custom Button

{!REQUIRESCRIPT("/soap/ajax/10.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")}
document.getElementById("j_id0:courseForm:createTrainingRecords").click();

 Class 

public void addCourse()
{
    if (Course != null)
    {
     String errMessage = 'Course already exists for Revision ' + Course.Revision__c;
     if (ApexPages.currentPage() != null) 
     { 
         ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, errMessage ));
     }
    }