1
votes

I am trying to jQuery validation piece for an apex:commandbutton in visualforce (Salesforce). It's working fine if its not an AJAX call, I mean if dont set the oncomplete and rerender properties for the button. But if I do so, it makes the input type='button' instead of 'submit'. So whatever method I have specified in the action attribute of the apex:commandbutton is getting called irrespective of my validation result (true or false).

To do that I tried the following options and nothing worked out.

This is what I want :

  1. Fill the form fields
  2. On clicking the command button, it should validate using jQuery (as of now it's working if its type is submit but unfortunately if i change it to AJAX call it becomes type='button' and not working)
  3. call my action method action="{!SaveUserAndSendEmail}" (if validation passes creates the contact record)
  4. Oncomplete="clickCreateUserButton();" (this will create the user record once the contact record is created by action method.

Options I tried:

  • Method 1:

a. Adding the following JQuery Script inside document.ready():

j$('[id$=SaveUserAndSendEmail]').click( 
                    function() 
                    {
                        if (j$('[id$=theForm]').validate().form() == true)
                            {
                                isValid = true;
                                SetContinueProcess(true);
                                //callSaveUserAndSendEmailHidden();
                                //j$('[id$=SaveUserAndSendEmailHidden]').click();                                
                                return true;
                            }
                            else
                            {
                                isValid = false;
                                SetContinueProcess(false);                                
                                return false;
                            }
                    }
); 

b. As you can see I have called a function called setContinueProcess which calls the actionsupport function and sets a property ContinueProcess and if its false am blocking the action inside the action method in controller.

This didn't work because it goes to server side and clears the validation messages.

  • Method 2 :

a. Same Jquery method as mentioned above. Only change is that instead of calling the setContinueProcess, I tried having another button and made it hidden using display:none and tried clicking it from within the above if condition both using jquery and normal javascript document.getelementbyid("buttonid").click(); this called the action method and created the contact record but oncomplete method was not called.

  • Method 3:

a. Same Jquery method, instead of hiddenbutton, called an ActionSupport function and specified its action method in its action atttribute and oncomplete attribute as i did for the button. Even it called only the action method and did not call the oncomplete method

  • Method 4:

a. Same jquery method, instead of calling oncomplete method in actionsupport, called both the action support method and oncomplete method from within the above if condition itself :-

SaveandSend(); //Actionsupport method name which calls the controller's action method and creates the contact
CreateUser(); // Javascript method which clicks another button triggering the action method of that to create the user

even in this one, the second method didn't get called.

JavaScript Code:

 function callSimulateUserSave() {
                       var mybtn = document.getElementById('{!$Component.theForm.SimulateUserSave}');
                       mybtn.click();
                   }

Visualforce Code:

<apex:actionFunction name="SetContinueProcess">        
                <apex:param name="ContinueProcess" value="ArgValue" assignTo="{!ContinueProcess}" />
            </apex:actionFunction>
           --commented -- <apex:actionFunction name="SaveandSend"  action="{!SaveUserandSendEmail}" >        
            </apex:actionFunction> -- commented --
<apex:commandButton id="SaveUserAndSendEmail" value="Save and Send Activation Email" action="{!SaveUserandSendEmail}" rerender="junkpanel" oncomplete="if (j$('[id$=theForm]').validate().form() == true){callSimulateUserSave();}">

                            <apex:commandButton value="SimulateUserSave" id="SimulateUserSave" action="{!CreateUserRecord}" style="display:none;margin-left:5px;"/>

                            <apex:commandButton id="SaveUserAndSendEmailHidden" style="display:none;" value="Save and Send Activation Email"  action="{!SaveUserandSendEmail}" rerender="junkpanel" oncomplete="callSimulateUserSave()" >
                            </apex:commandButton>

-- I might have commented out some code, those are the ones I tried for different methods/approaches I tried to achieve the solution

3

3 Answers

0
votes

While this is not a direct answer to your question, in my experience, I minimize my use of Visualforce. It's slow and can be difficult to debug issues like this. Typically, the only thing visualforce about my visualforce pages is the use of the apex:page tag.

I would use HTML markup instead of visualforce markup, and your server side apex controller should only consist of remote actions to call from javascript. Store your state client side and inject it into your remoting calls.

If you start architecting your pages this way, I think you'll notice significantly better performance, you'll get to sidestep some governor limits, and issues like the one you are facing go away because you are no longer using visualforce, and instead writing javascript, a much more prominent language.

0
votes

Have you tried using a standard HTML button, firing the validation method onClick and then using an <apex:actionFunction> to make the call to the backend once you've verified everything you need to (i.e. at the end of the verification method or if it returns as valid)? This is the approach I've used in the past and I've never had any issues with it.

0
votes

You should be able to just have an anchor tag or button in HTML not via a Visualforce tag. Then use jQuery "on document ready" to tie a click event handler to the button / anchor tag. From that new function you should be able to call into jQuery Validation and only execute an action function if the form is valid. Be sure to have redundant validation on the server side Controller code. The trick here is to set a variable on the server side Controller code if an error occurs. Then in the action function code, use a rerender attribute to target an Output panel. Inside the output panel have some javascript that binds a local variable to a property in the controller (ie... var abc = {!errorHandlingProperty}. Then in the rerender javascript you can continue execution ONLY if the property in the controller is true. This is basically your halting mechanism. I know this is a long chain of code, but it seems to work from past experience.