Tuesday 10 December 2013

How to get a map from database.query()

In salesforce doc you may found that it is possible to get a map from a query instead of a list like this:

Map<ID, Contact> m = new Map<ID, Contact>([SELECT Id, LastName FROM Contact]);

But you can also achieve this if you are using database.query() to run the select.This can be achieved like follows :
 String query = 'SELECT Id, LastName FROM Contact';
Map<id,Contact> mapCon = new Map<id,Contact>((List<Contact>)Database.query(query));

Monday 14 October 2013

How to validate empty field on visualforce page with standard errors

I have come across this situation more than often, and using the standard required=true on inputfield or inputText sometimes prevent any submission of the page, which is good for some reason, but will prevent also any refresh.Sometime also, using apex:inputText with required=true, doesn't work. Here is the solution with jquery :

1. First add a styleClass to your all your inputText you want to validate for blank.For this example, i will create only one picklist.

 <table class="detailList" cellspacing="0" cellpadding="0" border="0">
                                    <tr>
                                        <td class="labelCol">{!$ObjectType.HeaderVoucher__c.fields.numm__AccountingDate__c.label}</td>
                                        <td class="dataCol">
                                            <div class="requiredInput">
                                                <div class="requiredBlock"></div>
                                                <apex:inputField styleClass="jq_req" value="{!dummyPiece.AccountingDate__c}" required="false"/>
                                            </div>
                                        </td>
                                    </tr>

<tr>
                                <td class="pbTitle"></td>
                                <td class="pbButtonb">
                                    <apex:commandButton value="{!$Label.Button_Settlement}" action="{!Regler}" onclick="return validateReglementFields();"/>                                               
                                </td>      
                            </tr>        


note: the styleClass i always use is jq_req.

2. Now look at the jquery functions you need :

<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script>
 if(typeof jQuery != 'undefined'){
           $j =jQuery.noConflict();
        }

 //2.ADDING AND REMOVING ERRORS ON PAGE
function jq_addError(me,msg){
    if(!($j(me).hasClass('error'))){
        $j(me).addClass("error");
        $j(me).parent().append("<div class='errorMsg'>" + msg + "</div>");
     }
     else{
        $j(me).siblings('.errorMsg').remove();
        $j(me).parent().append("<div class='errorMsg'>" + msg + "</div>");
     }
}

function jq_removeError(me){
    if($j(me).hasClass('error')){
        $j(me).removeClass("error");
        $j(me).siblings('.errorMsg').remove();
     }          
}

//3.VALIDATE FOR REQUIRED BLANK FIELDS
function validateReglementFields(){
    var b = true;
    $j('.jq_req').each(function(){
        if($j(this).val().length == 0){
            jq_addError($j(this),"<b>Erreur
:</b>Ce champ est obligatoire");
            b = false;
        }
        else{
            jq_removeError($j(this));
        }              
    });
    return b;
}


</script> 
   
For sure you can store the error message in a label and then reference the label in your javascript code. 

 Here is the resulted error :


 

Friday 26 April 2013

autocomplete with actionfunction

I saw several codes for autocomplete on salesforce, but none of them send the selected value to the server, thus i rewrite the code for it. In the example below, i am choosing an account and sending the selected account id to the server, thus you can use the below code to replace lookup field for auto complete functionality. Here it is , enjoy :








Page code:

<apex:page controller="DemoAutoComplete" showHeader="false">
 <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
   
    <script>
               
        if(typeof jQuery != 'undefined'){
           $j =jQuery.noConflict();
       }
         $j(function() {           
             $j("input.auto001").autocomplete({
                source: function(request, response){
                    getMyData(response ,request.term);
                },
                select: function(event, ui){
                    $j("input.auto001").val(ui.item.value);
                    $j('input.auto002').val(ui.item.id);
                    refresh();                   
                    return false;
                }           
            });           
           
        });
       

       
        function getMyData(response,param){
            Visualforce.remoting.Manager.invokeAction(
                '{!$RemoteAction.DemoAutoComplete.getAccounts}',
                param,
                function(result, event){
                    if (event.status) {                       
                        var objList = [];
                        for(var i = 0; i < result.length; i++){
                            var obj = new Object();
                            obj.label = result[i].Name;
                            obj.value = result[i].Name;
                            obj.id = result[i].Id;
                            objList.push(obj);
                        }
                        response(objList);
                    }else {
                        alert(event.message);
                    }
                },
                {escape: true}
            );
        }
</script>
   
    <apex:form id="mainForm">   
        <div class="filterOverview">
            <div class="bFilterView">
                <table border="0">                   
                    <tr>   
                        <td>Choose an account</td>                   
                        <td>
                            <div class="ui-widget">
                                <apex:inputText id="x_val" styleClass="auto001" value="{!accName}" />
                                <apex:inputText id="auto002" value="{!accId}" styleClass="auto002" style="visibility:hidden"/>                               
                            </div>
                        </td>               
                    </tr>               
                    <tr>   
                        <td>selected Id</td>                   
                        <td>
                            <apex:actionfunction name="refresh" action="{!Refresh}" rerender="pn1"/>
                            <apex:outputPanel id="pn1">
                                <apex:outputText id="x_id" value="{!accId}" />
                            </apex:outputPanel>
                        </td>               
                    </tr>                               
                </table>
            </div>
        </div>
    </apex:form>
</apex:page>


Controller code :

public class DemoAutoComplete {
    public String accName{get;set;}
    public Id accId{get;set;}
   
    public DemoAutoComplete(){
   
    }
    public PageReference refresh(){
        return null;
    }
    @RemoteAction
    public static list<Account> getAccounts(string s){
        list<Account>accList = new list<Account>();
        if(s != ''){
            String query = 'select name from account where Name like \'' + s + '%\'';
            accList = database.query(query);
        }   
        return accList;
    }
    }


Tuesday 16 April 2013

Passing variable in custom label

At a certain time, I thought it was impossible to do, then one day I came across, the way to do it, here and there. Here is the solution :
 suppose you want to add the connected user name dynamically

 1. Create the label  :

2. Now  add the label on your page like this :

<apex:page>
  <!-- Begin Default Content REMOVE THIS -->
  <h1>
      <apex:outputText value="{!$label.Hello}">
          <apex:param value="{!$user.userName}" />
      </apex:outputText>
  </h1>

  <!-- End Default Content REMOVE THIS -->
</apex:page>


There is some problem with this therefore, especially when the text in the custom label contains the ' (single quote) character . There is eventually, a way to bypass it, look at the example below :

Conformément à l'article 121 – II de la loi no. 2012-387 du 22 mars 2012, l'indemnité forfaitaire pour frais de recouvrement en cas de<br/>
40 euros par le décret no.2012-115 du 02/10/2012. Tout matériel ou logiciel reste la propriété de {0} jusqu'au paiement<br/>
Aucun escompte ne sera accordée pour paiement anticipé<br/>
'{1} au capital de {2}, No. Siren : {3}, TVA CEE : {4}


To bypass the ' (single quote)char , we use another '(single quote) in the right place, just that.

Sunday 14 April 2013

URLFOR examples and explanations

Here are some uses of the apex URLFOR function :
    //Use $Action global varialble to access the New action reference -->
    <apex:outputLink value="{!URLFOR($Action.Account.New)}">New</apex:outputLink>
    //View action requires the id parameter, a standard controller can be used to obtain the id -->
    <apex:outputLink value="{!URLFOR($Action.Account.view, account.id)}">View</apex:outputLink>
    //Edit action requires the id parameter, id is taken from standard controller in this example -->
    <apex:outputLink value="{!URLFOR($Action.Account.Edit, account.id)}">Edit</apex:outputLink> 
    //Delete action requires the id parameter, also a confirm message is added to prevent deleting the record when clicked by mistake -->
    <apex:outputLink value="{!URLFOR($Action.Account.delete, account.id)}" onclick="return window.confirm('Are you sure?');">Delete</apex:outputLink>
    //From all custom buttons, links, s-controls and visualforce pages you can use the following to get the link of the object's homepage -->
    <apex:outputLink value="{!URLFOR($Action.Account.Tab, $ObjectType.Account)}">Home</apex:outputLink>
    //If your file is in another ZIP file, then pass the path of the file as id to URLFOR -->
    <apex:image url="{!URLFOR($Resource.CorpZip, 'images/logo.gif')}" width="50" height="50" />
    //reference to a custom VF page
    <apex:commandButton action="{!URLFOR($page.UpdateCouponReponse)}" value="Voir les coupons-réponse"/>
    //overriding standard page to add defaulted values
    <apex:page standardController="Filleul__c" action="{!URLFOR($Action.Filleul__c.New,null, [Name=$label.GenererNomAuto,retURL=$ObjectType.Filleul__c.KeyPrefix + '/o'],true)}">

Formatting in apex:outputText

Here are some example of how to format apex:outputText values using  apex:param :
  • Date formatting :
<apex:outputText value="{0,date,dd/MM/yyyy}">
        <apex:param value="{!E.Date_du_collecte__c}"/>
    </apex:outputText>

 
the 0, tell to take the first parameter, the date keyword specify the type of data, and the third parameter specify how to format the data.

  • Number formatting :
<apex:outputText value="{0,number,integer}">
        <apex:param value="{!opp.Amount}"/>
    </apex:outputText> 


the 0, tell to take the first parameter, the number keyword specify the type of data, and the third parameter specify how to format the data.

Sunday 7 April 2013

How to display a salesforce page without headers

For VF, its simple, you just specify the showheader="false".But suppose you want to display a report on your VF, and you don't want the header and sidebar to appear.


 Just use the parameter isdtp=mn or isdtp=vw in the url parameter

Example :
<apex:iframe src="http://www.salesforce.com?isdtp=vw" 
scrolling="true" id="theIframe"/>