Tuesday, January 2, 2018

Restricting User to Double Click on Button in VF

This post is regarding to avoid one small issue I have come across it.
Let say there is a visual force page where input fields and one button is present. When that button is clicked records are inserted in to the object. If button is clicked twice in same time(double click) then records(duplicate records ) are being created twice. 

How will we avoid that?
How will restrict user to do double click on button?

Here I am sharing some snippet of code.Hope It will help you.

Page:

<apex:page standardController="Account">
    <apex:form >
        <apex:pageMessages id="messages"></apex:pageMessages>
        <apex:pageBlock title="Avoid Doublle Click" >
            <apex:pageBlockButtons location="both">               
                <apex:actionStatus id="saveStatus">                   
                    <apex:facet name="stop">
                        <apex:outputPanel >
                            <apex:commandButton action="{!save}" value="save" reRender="messages" status="saveStatus"/>
                            <apex:commandButton action="{!Cancel}" value="Cancel" immediate="true" />
                        </apex:outputPanel>
                    </apex:facet>
                    <apex:facet name="start">
                        <apex:outputPanel >
                            <apex:commandButton value="Saving..." disabled="true" />
                            <apex:commandButton value="Saving..." disabled="true" />
                        </apex:outputPanel>                       
                    </apex:facet>                   
                </apex:actionStatus>               
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Account Creating">
                <apex:inputField value="{!Account.Name}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>   
</apex:page>

Preventing Right Click,Copy,Paste in VF Page

Everybody must have visited bank site there we can not do right click or copy Account number and paste in another field Retype Account Number. That means we should not give any chance to anybody to see page source. We do this for more security purpose. 
That made me to think and try to design same in visual-force page. Here I have only used JavaScript for this functionality. 
There are some snippet of code.Hopefully It will help you. 

Functionality 

  • Preventing to see the Page Source.
  • Preventing paste Email field value in Re Email field.
Here is the page:-


<apex:page StandardController="Contact">
  <script>
      function DisableRightClick(event){    
        if (event.button==2)
        {
            alert("Right Click is not Allowed");       
        }
      }
     function DisableCtrlKey(e){
        
        var code = (document.all) ? event.keyCode:e.which;
         if (parseInt(code)==17){
            alert("Please re-type your email address");           
        }   
    }
  </script>
  <apex:form >
      <apex:pageBlock title="Create Contact" onmousedown="DisableRightClick(event)">
          <apex:pageBlockButtons >
              <apex:commandButton value="Save" action="{!save}"/>
          </apex:pageBlockButtons>
          <apex:pageBlockSection columns="1">
              <apex:inputField value="{!Contact.Firstname}"/>
              <apex:inputField value="{!Contact.LastName}"/>
              <apex:inputField value="{!Contact.Email}"/>
              <apex:inputtext value="{!Contact.Email}" label="Re-Type Email Id"  onKeyDown="DisableCtrlKey(event)"/>              
              <apex:inputField value="{!Contact.Phone}"/>              
          </apex:pageBlockSection>
      </apex:pageBlock>
  </apex:form>
</apex:page>

Visualforce Page Exactly Same as Contact Edit Page

The question was there will be a link called "Copy Mailing Address to Other Address" when clicked that link all Mailing address will be copied to other address same as standard edit page of contact.
This can be done two ways. 
  • By using java script
  • By using Controller extension
In the command link we have to call java script method there we will get all the field value of mailing addresss using documnet.getElementByid() method in javascript and will assign to the other address field. 

Second approach is we will call extension method where will assign all the mailing address field to other address field and will reRender (refresh) the block. It will behave exactly like as standard edit page layout of Contact functionality.
Now the challenge is how will we display that command link inside that pagablock section header.


This is the page and controller 


<apex:page standardController="Contact" extensions="contactEditPageExtension">
    <apex:sectionHeader title="Contact Edit" subtitle="New Contact"/>
    <apex:outputText value="Contacts not associated with accounts are private and cannot be viewed by other users or included in reports."> 
    </apex:outputText><br/><br/>
    <apex:form >
        <apex:pageBlock title="Contact Edit" id="test">
            <apex:pageBlockButtons location="both">
                <apex:commandButton value="Save" action="{!Save}"/>
                <apex:commandButton value="Save & New" />
                <apex:commandButton value="Cancel" action="{!Cancel}"/>
                
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Contact Information">
                <apex:inputField value="{!contact.FirstName}"/> 
                <apex:inputField value="{!contact.LastName}"/>       
            </apex:pageBlockSection>
            <apex:pageBlockSection title="Test">
                   <apex:facet name="header">
                        <apex:pageBlockSectionItem >
                        <apex:outputText value="Address Information" style="float:left;"></apex:outputText>
                        <apex:commandLink value="Copy Malling Address to Other Address" style="float:right;" action="{!test}" reRender="test"/>
                        </apex:pageBlockSectionItem>
                    </apex:facet>
             
                    <apex:inputField value="{!contact.MailingCountry}"/> 
                    <apex:inputField value="{!contact.otherCountry}"/>  
                    <apex:inputField value="{!contact.MailingStreet}"/> 
                    <apex:inputField value="{!contact.otherStreet}"/>   
                    <apex:inputField value="{!contact.MailingState}"/> 
                    <apex:inputField value="{!contact.otherState}"/>    
                  
            </apex:pageBlockSection>
             
        </apex:pageBlock>
    </apex:form>
  </apex:page>



My controller 


public with sharing class contactEditPageExtension {
    public Contact contact{get;set;}
    public contactEditPageExtension(ApexPages.StandardController controller) {
        //this.contact = (Contact )controller.getRecord();
        contact = new Contact();
    }
    
    public void test(){
         contact.otherCountry  =  contact.MailingCountry;
        contact.otherState  =   contact.MailingState;
        contact.otherStreet  =   contact.MailingStreet;
        //return null;
    }


}

Add/Remove Functionality in a VF page pageblock table for Creating Multiple Records For a Particular Object.

I had come across a scenario where I was asked to develop some functionality where user can create list of records at a time(clicking on save button on one time) and can remove row.
Here I have created a pageblock table and there I am displaying 5 rows to enter data and there column, Name , Phone and Action. In Action column Delete link is present.When that link(Delete) is clicked then particular row will be removed. Two button is there Add Row and Save.
Add Row-->  When that button is clicked one more row will be created in the pagablock table
Save--> It will save the record.

Here is the page


<apex:page controller="creatingListOfRecordsController">
    <apex:form >
    
        <apex:pageBlock title="Creating List Of Account Records">
        <apex:pageMessages></apex:pageMessages>
            <apex:pageBlockButtons location="top">
                <apex:commandButton value="Add Row" action="{!addRow}" reRender="table" immediate="true"/>
            </apex:pageBlockButtons>
                <apex:pageBlockTable value="{!accountwrapperList}" var="page" id="table"> 
                    <apex:column headerValue="Name">
                        <apex:inputField value="{!page.account.name}"/>
                    </apex:column>
                    <apex:column headerValue="Phone">
                        <apex:inputField value="{!page.account.Phone}" />
                    </apex:column>
                    <apex:column headerValue="Action">
                        <apex:commandLink value="Delete" action="{!removingRow}" immediate="true">
                            <apex:param name="index" value="{!page.counterWrap}"/>  
                        </apex:commandLink>
                    </apex:column>
                </apex:pageBlockTable>
                <apex:commandButton value="Save" action="{!saving}" />
            
        </apex:pageBlock>
    </apex:form>
</apex:page>

Here is the Controller


public with sharing class creatingListOfRecordsController {
    
    public list<Account> accountList{get;set;}
    public list<Accountwrapper> accountwrapperList{get;set;}
    public Integer counter{get;set;}
    
    public creatingListOfRecordsController(){
           counter = 0;
           accountList = new list<Account>(); 
           accountwrapperList = new list<Accountwrapper>();
           for(Integer i=0;i<5;i++){
               Accountwrapper actWrap = new Accountwrapper(new Account()); 
               counter++;
               actWrap.counterWrap = counter;
               accountwrapperList.add(actWrap); 
               
           }
       
    }
    
    public PageReference addRow(){
        //accountList.add(new Account());
        Accountwrapper actWrap = new Accountwrapper(new Account()); 
        
        counter++;
        actWrap.counterWrap = counter; 
        accountwrapperList.add(actWrap); 
        return null;    
    }
    public PageReference removingRow(){
    
        Integer param = Integer.valueOf(Apexpages.currentpage().getParameters().get('index'));
        
        for(Integer i=0;i<accountwrapperList.size();i++){
            if(accountwrapperList[i].counterWrap == param ){
                accountwrapperList.remove(i);     
            }
        }
        
        
        counter--;
        return null;    
    }
    
    public PageReference saving(){
        list<Account> updateAccountList;
        updateAccountList = new list<Account>();
        if(!accountwrapperList.isEmpty()){
            for(Accountwrapper accountWrapper:accountwrapperList){
                updateAccountList.add(accountWrapper.account);
            }
        }
        if(!updateAccountList.isEmpty()){
            upsert updateAccountList;
        }
       ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.Info,'Record Saved Successfully.');
       ApexPages.addMessage(myMsg); 
        return null;
    }
    
    public class Accountwrapper{
        public Account account{get;set;}
        public Integer counterWrap{get;set;}
        
        public Accountwrapper(Account act){
            this.account = act;  
             
        }
    }
    
}
The out put will be exactly like this image 

Encryption and Decryption In Salesforce.

Encryption, is the process of changing information in such a way as to make it unreadable by anyone except those possessing special knowledge (usually referred to as a "key") that allows them to change the information back to its original, readable form.
To encrypt some value we have to use some key value that can be hard coded or we can generate key also by using this 

Blob cryptoKey = Crypto.generateAesKey(256);
We have to use same key to decrypt that value.

Here I am going to share some code.Hope it will help you. I have created one visualforce page and one controller. In the page only one field(Name) is there and two button(Save & Update).
When some value is entered in the name field and clicked on save button that value will be stored in the object encrypted format.
Now record id in the url and click on update button encrypted value will be converted in to original format.


Here is my page  


<apex:page standardController="Account" extensions="EncryptionandDecryptionExtension">
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockSection >
                <apex:inputField value="{!encrypt.Name}"/>
                <apex:commandButton value="Save" action="{!Save}"/>
                <apex:commandButton value="Update" action="{!test}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form> 
</apex:page>

Here is My Controller 


public class EncryptionandDecryptionExtension {
    public account encrypt{get;set;}
    //Blob cryptoKey;
    Blob cryptoKey = Blob.valueOf('380db410e8b11fa9');
    public Id recordId{get;set;}
    public EncryptionandDecryptionExtension(ApexPages.StandardController controller) {
        //cryptoKey = Crypto.generateAesKey(256);
        recordId = Apexpages.CurrentPage().getParameters().get('id');
        if(recordId !=null){
            encrypt = [SELECT id,Name From account 
                       WHERE id=:recordId];
        }
        else{
            encrypt = new account();
        }
    }
    
    public PageReference Save(){
        
        Blob data = Blob.valueOf(encrypt.Name);
        Blob encryptedData = Crypto.encryptWithManagedIV('AES128', cryptoKey , data );
        String b64Data = EncodingUtil.base64Encode(encryptedData);
        encrypt.name = b64Data ;
        
        insert encrypt;
        return null; 
    }
    public PageReference test(){
        
        //Blob cryptoKey = Crypto.generateAesKey(256);
        //Blob data = Blob.valueOf(encrypt.Name);
        Blob data = EncodingUtil.base64Decode(encrypt.Name);
        Blob decryptedData = Crypto.decryptWithManagedIV('AES128', cryptoKey , data);
        String dryptData = decryptedData.toString();
        System.debug('Printing dryptData '+dryptData);
        
        encrypt.name = dryptData;
        
        update encrypt;
        return null; 
    }
}

VF Using Action Global Variable Navigating to Standard Layout(Tab, Edit layout,List Layout)

$Action is a global variable. A global merge field type to use when referencing standard Salesforce actions such as displaying the Accounts tab home page, creating new accounts, editing accounts, and deleting accounts.
Here I am sharing some visualforce code for the same.

<apex:page standardController="Account">

       //Navigating to new record page of Account
       <apex:outputLink value="{!URLFOR($Action.Account.New)}">
               Creating New Account
       </apex:outputLink>

      //Navigating to Account list View 
      <apex:outputLink value="{!URLFOR($Action.Account.List, $ObjectType.Account)}">
              Go to the Account List View
      </apex:outputLink>

      //Navigating to Account tab page
      <apex:outputLink value="{!URLFOR($Action.Account.Tab, $ObjectType.Account)}">
             Go to the Account tab
      </apex:outputLink>

      //Cloening Account Record 
      <apex:outputLink value="{!URLFOR($Action.Account.Clone, id)}">
             Cloning record
       </apex:outputLink>

       //id  means record id
      //Here we have to give accountid in url.
 
      //Editing Account Record
     <apex:outputLink value="{!URLFOR($Action.Account.Edit, id)}">
          Editing record
      </apex:outputLink>

      //Deleting Account Record
      <apex:outputLink value="{!URLFOR($Action.Account.Delete, id)}">
              Deleting Account Record
      </apex:outputLink>

     //submitting account record for approval 
     <apex:outputLink value="{!URLFOR($Action.Account.Submit for Approval, id)}">
           Submitting Record for Approval
     </apex:outputLink>
</apex:page>