Friday, October 31, 2014

Use Chrome for Development and Allow Cross-domain Javascript and AJAX


Use Another Instance of Chrome while Retrieving Content or Data from an Ajax Source on a Different Domain



If you are developing an application and calling a data source from another domain, you may encounter trouble when trying to use AJAX to retrieve a JSON data source from a service API for instance.


You may see an error message like the following:


Chrome

XMLHttpRequest cannot load [THE_URL_ENDPOINT].  No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

- OR -

IE

SEC7118: XMLHttpRequest for [THE_URL_ENDPOINT] required Cross Origin Resource Sharing (CORS). 

SEC7119: XMLHttpRequest for [THE_URL_ENDPOINT] required CORS preflight. 

SEC7120: Origin http://localhost:8080 not found in Access-Control-Allow-Origin header. 

SCRIPT7002: XMLHttpRequest: Network Error 0x80070005, Access is denied.




There are many solutions to this such as using JSONP or modifying the header, Access-Control-Allow-Origin, on the responding service.  If none of these options are feasible for you you can run Chrome with cross-domain AJAX calls enabled.

You will want to run a seperate instance of chrome with web security disabled so that you can still use your own version of Chrome for personal use.

Run Separate Instance of Chrome with Disabled Web Security to Execute AJAX Calls from Different Domains





There is a flag in:  chrome://flags/ that allows you to disable web security.


You can run chrome with this flag using the following command assuming a standard Chrome Install.

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:/Chrome dev session2" --disable-web-security


Example:

Run Chrome with web security disabled for cross-domain requests
Run Chrome with --disable-web-security flag enabled 


After running this command, a new folder should be created on your C:/ drive.  This folder will contain user settings unique to this chrome instance.

Therefore, you will be able to run your own instance of Chrome for secure web browsing and then this instance of Chrome for development.  All the settings in this version of Chrome will be independent from you primary Chrome Instance.


A new instance of chrome will open up with a warning message indicating web security is disabled and the --disable-web-security flag is being used.  You can set a new home page on the browser instance to the local URL of your page in development.

Independent instance of Chrome for Cross-domain Javascript/AJAX
New Instance of Chrome for testing Cross Domain AJAX Calls

You can have your normal personal instance of chrome running and then run this command whenever you need to test a web application that needs to access a cross-domain data source.


Monday, October 13, 2014

Disabled Save Button on Forms while Saving in Salesforce



How to Disable the Save Button on your Form while the Form is Saving to Prevent Multiple Submissions in a Custom Salesforce Visualforce Page



Salesforce default functionality on forms will disable the save button after the form is submitted to prevent multiple submissions.

The disabled Save button will look like:

Disabled save button after submitting a form in Salesforce
Disabled save button after form submit

When creating your own VisualForce page you can write custom code to mimic this functionality in your forms using just Javascript and modifying the button's CSS styles.





Create Javascript functions to disable and enable the save button




You will need to create 2 Javascript functions that will enable and disable the button by modifying the css and properties of the save button.

I am using jQuery but you can also do this with vanilla Javascript. I am currently using a unique style class attached to the button to look it up for convenience since this page does not get modified very often if ever and also because the element id is used by Salesforce for internal SFDC functionality.

    function disableSave() {
     j$(".saveButtonId").prop("disabled","true");
        j$(".saveButtonId").val("Saving...");
                
        j$(".saveButtonId").css( "border-color", "#c4c4c4" );
        j$(".saveButtonId").css( "color", "#909090" );
    }

    function enableSave() {
        j$(".saveButtonId").removeProp( "disabled" )
        j$(".saveButtonId").val("Save");
            
        j$(".saveButtonId").css( "border-color", "#7f7f7f" );
        j$(".saveButtonId").css( "color", "#333" ); 
    }    


Add events to the Salesforce save button on your Visualforce Page




You will then need to bind your Javascript functions to the onclick and oncomplete event on your save button. I am using binding within the tag since I am using a custom apex:commandbutton Visualforce tag to create the save button.

This will disable the save button on click and re-enable the button when the AJAX request completes that clicking your save button initiated.

<apex:commandbutton action="{!save}" onclick="disableSave()" oncomplete="enableSave()" status="savingStatus" styleclass="saveButtonId" value="Save"> 
</apex:commandbutton>