0

I have some buttons on my visualforce page which onclick, run a javascript function.

Sometimes however, the javascript function will need to run without the user actually clicking on the button. I need to call the javascript function from an apex method. How can I achieve this?

6
  • As written and without knowing more - you can't. Controllers cannot execute javascript on the vf page directly - however they can run the code in the controller that the javascript does (if thats what is happening) – Eric Nov 20 '15 at 20:18
  • do you mean when you click on button first apex method called and after that javascript? – Ratan Paul Nov 20 '15 at 20:19
  • I just need a way to to activate my javascript when one of my apex method variables becomes a certain number. ex) if (variable == 10) {activate javascript function} @Eric – Alex Brigham Nov 20 '15 at 20:21
  • @Ratan see my most recent comment. – Alex Brigham Nov 20 '15 at 20:22
  • 1
    How is your variable value being changed? You might be able to accomplish this with the oncomplete event of your apex tag, but knowing when the variable has become a value will require using a re-render to update the page's DOM, then a query selector to find the updated value. There is no direct way for Apex (server side) to invoke javascript (client side) and pass it a value. – dsharrison Nov 20 '15 at 20:39
4

You can reRender scripts that should be run when conditions are met. I wrote up an arbitrary example where you have (approximately) a 50% chance of getting a popup dialog, and 50% chance of just plain text. Every five seconds, the server is called again, and you may get a dialog popup. This requires no user interaction.

public class showAlertRandom {
    public boolean showAlert { get; set; }
    public Decimal numberValue { get; set; }
    public showAlertRandom() {
        doRandomAlert();
    }
    public void doRandomAlert() {
        numberValue = Math.random();
        showAlert = numberValue < 0.5;
    }
}

<apex:page controller="showAlertRandom" showHeader="true">
    <apex:form id="form">
        <apex:outputText rendered="{!showAlert}" id="alert">
            <script>
            alert('Hello World');
            </script>
        </apex:outputText>
        <apex:outputText rendered="{!not showAlert}" id="noAlert">
            No alert this time, sorry. Random value was: {!numberValue}.
        </apex:outputText>
        <apex:actionPoller interval="5" action="{!doRandomAlert}" reRender="form" />
    </apex:form>
</apex:page>

How it works:

Though Apex Code can't call JavaScript directly, it can set a variable to render a script block that can run arbitrary code. On each render, when the variable is true, an alert is produced. I wouldn't try doing this inside a closure or the middle of a script block, as you'll probably get very unpredictable results. You could dispatch a custom event or call some global function, if you prefer. You can use this technique anywhere reRender is supported, such as on a commandLink, commandButton, and actionFunction.

5
  • Great answer @sfdcfox. I have used this in the past. I always feel guilty using this though as it seems like an odd design pattern to have a self-executing script block get called by the DOM when salesforce does a rerender rather than using a callback (or oncomplete) pattern, but I haven't come up with something better. TL;DR: This seems a bit dirty but it is quick and gets the job done. – dsharrison Nov 20 '15 at 21:12
  • Interesting... I have never heard of actionPoller before. So this works because the javascript is contained within an apex block? – Alex Brigham Nov 20 '15 at 21:14
  • It's an interesting approach. It's too bad that the minimum interval allowed on the actionPoller is 5 seconds. Still, it may be my only option. Thanks a lot! – Alex Brigham Nov 20 '15 at 21:23
  • @AlexBrigham I don't think you need the actionPoller; you need any action. This could be a commandButton, commandLink, etc. – dsharrison Nov 20 '15 at 21:24
  • @AlexBrigham You said, for example, you have a variable incremented by 1 on each button press, with each 10th call doing something. You can do that by reRendering the block with something like rendered="{!someVarabiable/10==0}". – sfdcfox Nov 20 '15 at 21:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.