Tuesday, August 2, 2016

javascript code which solves focus of text issues on IOS device.

Several times I see when we are using IOS device especially Iphone , focus issues are rising up when some one try to edit the text area  inside the IOS device's. just add below peace of code inside your page and see the results. 

<script>
window.onkeydown=function(){window.focus();}
</script>

Wednesday, October 7, 2015

Salesforce: Pagination, search engine ,column sorting ,alphabetical sorting

------------------------------------------------------------------------------------------------------------
Vf  page
------------------------------------------------------------------------------------------------------------


<apex:page controller="FeedbackUserSelectionController1">
<apex:sectionHeader title="Feedback Form" subtitle="User Selection Page"  />
   <style type="text/css">
.loading-icon {
   background-image: url(/img/loading.gif);
   width: 16px;
   height: 16px;
}
a.alpha-link {
   font-weight: normal;
   font-size: 91%;
   padding: 0 4px;
   color: #015BA7 !important;
}
a.alpha-link+a.alpha-link {
   border-left: 1px solid #CFCECE;
}
a.alpha-link:hover {
   background-color: #e0f5fc !important;
}
a.alpha-select {
   font-weight: bold;
   text-decoration: none;
   background-color: #C6E1FF;
   color: #000000 !important;
}
.search-block {
   text-align: center;
}
.search-block input {
   margin: 0px 15px 0px 5px;
}
.search-block-button {
   min-width: 110px;
}
.process-block {
   text-align: center;
   margin-top: 10px;
}
.process-block input {
   margin: 0px 15px;
}
.process-block-button {
   min-width: 110px;
}
.page-buttons input {
   min-width: 110px;
}
</style>
   <apex:form id="TheForm">
      <!-- ***************************** -->
      <!-- Search Criteria               -->
      <apex:pageBlock mode="maindetail" >
         <div class="search-block">
            <div style="display: inline-table">
               <span>Name:</span>
               <apex:inputText value="{!SearchName}" />
            </div>
            <div style="display: inline-table">
               <span>Department:</span>
               <apex:inputText value="{!Searchdepartment}" />
            </div>
            <apex:commandButton styleClass="search-block-button" value="Search" action="{!Searchuser}" rerender="TablePanel"
               status="TableUpdateStatus" />
         </div>
         <div class="process-block">
            <apex:actionStatus id="ProcessButtonStatus">
               <apex:facet name="stop">
                  <apex:outputPanel >
                     <apex:commandButton styleClass="process-block-button" value="Process Selected" action="{!DoSomethingMany}"
                        status="ProcessButtonStatus" rerender="nothing" />
                     <apex:commandButton styleClass="process-block-button" value="Clear All" action="{!ClearAll}"
                        rerender="TheForm,TablePanel" />
                  </apex:outputPanel>
               </apex:facet>
               <apex:facet name="start">
                  <apex:outputPanel >
                     <apex:commandButton styleClass="process-block-button" value="Processing..." disabled="true" />
                     <apex:commandButton styleClass="process-block-button" value="Processing..." disabled="true" />
                  </apex:outputPanel>
               </apex:facet>
            </apex:actionStatus>
         </div>
      </apex:pageBlock>
      <!-- ************************* -->
      <!-- search results table      -->
      <apex:pageBlock id="TablePanel" title="Select Users to Give feedback ">
         <div>
            <span class="page-buttons" style="float: left; margin-bottom: 5px;"> <apex:commandButton disabled="{!!StdSetControllerUser.hasprevious}" value="Previous" action="{!StdSetControllerUser.previous}"
                  rerender="TablePanel" /> <apex:commandButton disabled="{!!StdSetControllerUser.hasnext}" value="Next"
                  action="{!StdSetControllerUser.next}" rerender="TablePanel" />
            </span>
            <!-- alphabet selection -->
            <span style="float: right; margin: 5px 5px 5px 5px;"> <apex:repeat value="{!AlphaList}" var="a">
                  <apex:commandLink value="{!a}" action="{!BuildQuery}" rerender="TablePanel"
                     styleClass="alpha-link{!if(AlphaFilter=a,' alpha-select','')}" status="TableUpdateStatus">
                     <apex:param name="AlphaFilter" value="{!a}" assignTo="{!AlphaFilter}" />
                  </apex:commandLink>
               </apex:repeat>
            </span>
         </div>
         <div style="clear: both;"></div>
         <apex:actionStatus id="TableUpdateStatus">
            <apex:inputHidden value="{!AlphaFilter}" id="hiddenField" />
            <!-- loading message -->
            <apex:facet name="start">
               <apex:outputPanel layout="block" styleClass="message infoM4">
                  <apex:panelGrid columns="2" styleClass="messageTable" columnClasses="messageCell" style="padding:0px;margin:0px;">
                     <apex:panelGroup >
                        <img class="loading-icon" src="/s.gif" />
                     </apex:panelGroup>
                     <apex:panelGroup >
                        <div class="messageText">Please wait...</div>
                     </apex:panelGroup>
                  </apex:panelGrid>
               </apex:outputPanel>
            </apex:facet>
            <!-- user table -->
            <apex:facet name="stop">
               <apex:pageBlockTable value="{!CurrentUserList}" var="a">
               
                  <apex:column >
                     <apex:facet name="header">
                        <apex:outputPanel id="SelectedCount">
                           <div style="text-align: center;">
                              <apex:outputText value="Selected" />
                              <br />
                              <apex:outputText value="{!UserSelectedCount}" />
                           </div>
                        </apex:outputPanel>
                     </apex:facet>
                     <div style="text-align: center;">
                        <apex:inputCheckBox value="{!a.aCheckBox}" id="check-box">
                           <apex:actionSupport event="onchange" rerender="SelectedCount" action="{!UpdateUserSelectedSet}" />
                           </apex:inputcheckbox>
                     </div>
                  </apex:column>
                  <apex:column >
                     <apex:facet name="header">
                        <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                           <apex:param name="SortField" value="Name" assignTo="{!SortField}" />
                           <apex:outputText value="{!$ObjectType.User.Fields.Name.Label}{!IF(SortField=='Name',IF(SortDirection='asc','?','?'),'')}" />
                        </apex:commandLink>
                     </apex:facet>
                     <apex:outputLink value="/{!a.aUser.Id}" target="_blank">{!a.aUser.Name}</apex:outputlink>
                  </apex:column>
                 
                  <apex:column >
                     <apex:facet name="header">
                        <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                           <apex:param name="SortField" value="Department" assignTo="{!SortField}" />
                           <apex:outputText value="{!$ObjectType.User.Fields.Department.Label}{!IF(SortField=='Department',IF(SortDirection='asc','?','?'),'')}" />
                        </apex:commandLink>
                     </apex:facet>
                     <apex:outputField value="{!a.aUser.Department}" />
                  </apex:column>
                  <apex:column >
                     <apex:facet name="header">
                        <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                           <apex:param name="SortField" value="CompanyName" assignTo="{!SortField}" />
                           <apex:outputText value="{!$ObjectType.User.Fields.CompanyName.Label}{!IF(SortField=='CompanyName',IF(SortDirection='asc','?','?'),'')}" />
                        </apex:commandLink>
                     </apex:facet>
                     <apex:outputField value="{!a.aUser.CompanyName}" />
                  </apex:column>
                  <apex:column >
                     <apex:facet name="header">
                        <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                           <apex:param name="SortField" value="Email" assignTo="{!SortField}" />
                           <apex:outputText value="{!$ObjectType.User.Fields.Email.Label}{!IF(SortField=='Email',IF(SortDirection='asc','?','?'),'')}" />
                        </apex:commandLink>
                     </apex:facet>
                     <apex:outputField value="{!a.aUser.Email}" />
                  </apex:column>
               
             
               
               </apex:pageBlockTable>
            </apex:facet>
         </apex:actionStatus>
         <div style="margin-top: 5px;">
            <apex:outputText value="Number of Records per Page: " />
            <apex:selectList value="{!RecPerPage}" size="1">
               <apex:selectOptions value="{!RecPerPageOption}" />
               <apex:actionSupport event="onchange" action="{!BuildQuery}" reRender="TablePanel" status="TableUpdateStatus" />
            </apex:selectList>
         </div>
      </apex:pageBlock>
   </apex:form>
</apex:page>

------------------------------------------------------------------------------------------------------------
Controller...
------------------------------------------------------------------------------------------------------------



public with sharing class FeedbackUserSelectionController1 {
    // User and selection set/variables
    private list<UserSubclass> Userlist {get; set;}
    private set<Id> UserSelectedSet;
    public Integer UserSelectedCount {get; set;}
    public String SelectedOneUser {get; set;}
    // selection and filter
    public list<String> AlphaList {get; set;}
    public String AlphaFilter {get; set;}
    public String SearchName {get; set;}
    public String Searchdepartment {get; set;}
    private String SaveSearchName;
    private String SaveSearchdepartment;
    private String Queryuser;
    // display sort and number
    public String RecPerPage {get; set;}
    public list<SelectOption> RecPerPageOption {get; set;}
    public String SortFieldSave;
    /***
    * FeedbackUserSelectionController - Constructor initialization
    ***/
   
    public FeedbackUserSelectionController1(){
        Userlist = new list<UserSubclass>();
        UserSelectedSet = new set<Id>();
        //records for page initialization
        RecPerPageOption = new list<SelectOption>();
        RecPerPageOption.add(new SelectOption('10','10'));
        RecPerPageOption.add(new SelectOption('25','25'));
        RecPerPageOption.add(new SelectOption('50','50'));
        RecPerPageOption.add(new SelectOption('100','100'));
        RecPerPageOption.add(new SelectOption('200','200'));
        RecPerPage = '10'; //default records per page
        // initialization alpha list
        AlphaList = new list<String> {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Other', 'All'};
            SortFieldSave = SortField;
        // alpha filter, use page parameter or set default to all
        if (apexpages.currentpage().getparameters().get('alpha') == null) {
            AlphaFilter = 'All';
        } else {
            AlphaFilter = apexpages.currentpage().getparameters().get('alpha');
        }
        // list generation
        BuildQuery();
    }
    /***
    * StdSetControllerUser - paging through the User list
    ***/
   
   
    public ApexPages.StandardSetController StdSetControllerUser {
        get {
            if(StdSetControllerUser == null) {
                StdSetControllerUser = new ApexPages.StandardSetController(Database.getQueryLocator(Queryuser));
                // sets the number of records in each page set
                StdSetControllerUser.setPageSize(Integer.valueOf(RecPerPage));
            }
            return StdSetControllerUser;
        }
        set;
    }
   
   
    /***
    * getCurrentUserlist - return an User list for the table
    ***/


   
    public list<UserSubclass> getCurrentUserlist() {
        UpdateUserSelectedSet();
        Userlist = new list<UserSubclass>();
        for (User a : (list<User>)StdSetControllerUser.getRecords()) {
            Userlist.add(new UserSubclass(a, UserSelectedSet.contains(a.Id)));
        }
        return Userlist;
    }
   
   
    /***
    * UpdateUserSelectedSet - add/remove Users from the selected User id list
    ***/
    public void UpdateUserSelectedSet(){
        for(UserSubclass a : Userlist ){
            if(a.aCheckBox == true) {
                UserSelectedSet.add(a.aUser.Id);
            } else {
                if(UserSelectedSet.contains(a.aUser.Id)) {
                    UserSelectedSet.remove(a.aUser.Id);
                }
            }
        }
        UserSelectedCount = UserSelectedSet.size();
    }
    /***
    * ClearUserSelectedSet - remove selected Users and initialize counter
    ***/
    public PageReference ClearAll(){
        Userlist.clear();
        UserSelectedSet.clear();
        UserSelectedCount = 0;
        SearchName = '';
        Searchdepartment = '';
        SaveSearchName = '';
        SaveSearchdepartment = '';
        AlphaFilter = 'All';
        BuildQuery();
        return null;
    }
    /***
    * Searchuser - set search criteria fields and refresh User table
    ***/
    public PageReference Searchuser() {
        SaveSearchName = SearchName;
        SaveSearchdepartment = Searchdepartment;
        BuildQuery();
        return null;
    }
    /***
    * BuildQuery - build query command for list selection change
    ***/
    public void BuildQuery() {
        StdSetControllerUser = null;
        String QueryWhere = '';
        if (AlphaFilter == null || AlphaFilter.trim().length() == 0) {
            AlphaFilter = 'All';
        }
        Queryuser = 'SELECT Department,FirstName,LastName,Name , CompanyName, Email, LOB__c ' +
            ' FROM User';
        if (AlphaFilter == 'Other') {
            QueryWhere = BuildWhere(QueryWhere, '(' + String.escapeSingleQuotes(SortField) + ' < \'A\' OR ' +
                                    String.escapeSingleQuotes(SortField) + ' > \'Z\') AND (NOT ' +
                                    String.escapeSingleQuotes(SortField) + ' LIKE \'Z%\') ');
        } else if (AlphaFilter != 'All') {
            QueryWhere = BuildWhere(QueryWhere, '(' + String.escapeSingleQuotes(SortField) + ' LIKE \'' + String.escapeSingleQuotes(AlphaFilter) + '%\')' );
        }
        if (SaveSearchName != null) {
            QueryWhere = BuildWhere(QueryWhere, ' (Name LIKE \'%' + String.escapeSingleQuotes(SaveSearchName) + '%\')');
        }
        if (SaveSearchdepartment != null) {
              QueryWhere = BuildWhere(QueryWhere, ' (Department LIKE \'%' + String.escapeSingleQuotes(SaveSearchdepartment) + '%\')');
        }
        Queryuser += QueryWhere;
        Queryuser += ' ORDER BY ' + String.escapeSingleQuotes(SortField) + ' ' + String.escapeSingleQuotes(SortDirection) + ' LIMIT 10000';
        system.debug('Queryuser:' + Queryuser);
    }
    /***
    * BuildWhere - build soql string for where criteria
    ***/
    public String BuildWhere(String QW, String Cond) {
        if (QW == '') {
            return ' WHERE ' + Cond;
        } else {
            return QW + ' AND ' + Cond;
        }
    }
    /***
    * SortDirection - return sort direction. Default ascending(asc)
    ***/
    public String SortDirection {
        get { if (SortDirection == null) {  SortDirection = 'asc'; } return SortDirection;  }
        set;
    }
    /***
    * SortField - return sort by field. Default to Name
    ***/
    public String SortField {
        get { if (SortField == null) {SortField = 'Name'; } return SortField;  }
        set;
    }
    /***
    * SortToggle - toggles the sorting of query from asc<-->desc
    ***/
    public void SortToggle() {
        SortDirection = SortDirection.equals('asc') ? 'desc NULLS LAST' : 'asc';
        // reset alpha filter and sort sequence when sorted field is changed
        if (SortFieldSave != SortField) {
            SortDirection = 'asc';
            AlphaFilter = 'All';
            SortFieldSave = SortField;
        }
        // run the query again
        BuildQuery();
    }
    /***
    * DoSomethingOne - do something with one selected User
    ***/
    public PageReference DoSomethingOne() {
        system.debug('SelectedOneUser: ' + SelectedOneUser);
        return null;
    }
    /***
    * DoSomethingMany - do something with many selected Users
    ***/
    public PageReference DoSomethingMany() {
        for (Id UserId : UserSelectedSet) {
            system.debug('Checked: ' + UserId);
        }
        return null;
    }
 
    public class UserSubclass {
        public Boolean aCheckBox {get;set;}
        public User  aUser {get;set;}
        // sub-class initialization
        public UserSubclass(User a, Boolean chk){
            aUser = a;
            aCheckBox = chk;
        }
    }
}

Monday, September 28, 2015

How to expose restapi class to the Legacy systems ?

By using @RestResource class and annotations like @httppost, @httpget ,@httpput, @httpdelete..etc

we need to place these annotations before the Methods which we want to expose..

ex:  @RestResource(urlMapping='/Merchandise/*')
global with sharing class MerchandiseManager {
  
    @HttpGet
    global static Merchandise__c getMerchandiseById() {
        RestRequest req = RestContext.request;        
        String merchId = req.requestURI.substring(
                                  req.requestURI.lastIndexOf('/')+1);
        Merchandise__c result = 
                       [SELECT Name,Description__c,Price__c,Total_Inventory__c
                        FROM Merchandise__c 
                        WHERE Id = :merchId];
        return result;
    }
  
    @HttpPost
    global static String createMerchandise(String name,
        String description, Decimal price, Double inventory) {
        Merchandise__c m = new Merchandise__c(
            Name=name,
            Description__c=description,
            Price__c=price,
            Total_Inventory__c=inventory);
        insert m;
        return m.Id;
    }
}

What is UrL class in Sfdc ?

// Create a new account called Acme that we will create a link for later.
Account myAccount = new Account(Name='Acme');
insert myAccount;

// Get the base URL.
String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
System.debug('Base URL: ' + sfdcBaseURL );       

// Get the URL for the current request.
String currentRequestURL = URL.getCurrentRequestUrl().toExternalForm();
System.debug('Current request URL: ' + currentRequestURL);        

// Create the account URL from the base URL.
String accountURL = URL.getSalesforceBaseUrl().toExternalForm() + 
                       '/' + myAccount.Id;
System.debug('URL of a particular account: ' + accountURL); 

// Get some parts of the base URL.
System.debug('Host: ' + URL.getSalesforceBaseUrl().getHost());   
System.debug('Protocol: ' + URL.getSalesforceBaseUrl().getProtocol());

// Get the query string of the current request.
System.debug('Query: ' + URL.getCurrentRequestUrl().getQuery());

Sunday, September 13, 2015

Rollup summary for lookup relationship

trigger Rollup on Concur_Reports__c (after insert, after delete, after undelete,after update) {
boolean delflag=false;
Set<Id> crids=new Set<Id>();


Map<Id,List<Concur_Reports__c>> rollup=new Map<Id,List<Concur_Reports__c>>();
List<id> opplist= new List<id>();

if(Trigger.isInsert || Trigger.isUndelete || Trigger.isUpdate ){
For(Concur_Reports__c  con1 : Trigger.new){
crids.add(con1.id);
opplist.add(con1.Opportunity__c);
 if(rollup.containsKey(con1.Opportunity__c)){
rollup.get(con1.Opportunity__c).add(con1);
 }
else{
rollup.put(con1.Opportunity__c,new list<Concur_Reports__c>{con1});
}
}
}
 else if(Trigger.isDelete){
 delflag=True;
 For(Concur_Reports__c con1 : Trigger.old){
crids.add(con1.id);
opplist.add(con1.Opportunity__c);
if(rollup.containsKey(con1.Opportunity__c)){
rollup.get(con1.Opportunity__c).add(con1);
 }
else{
rollup.put(con1.Opportunity__c,new list<Concur_Reports__c>{con1});
}
}
}


    


    system.debug('%%%%%%%%%%%%%%%%%%%%%%%%%%'+rollup);


    List<Opportunity> OppUpdateList = New List<Opportunity>() ;


     Map<Id,Opportunity> oppidsfilter=new  Map<Id,Opportunity>([SELECT AccountId,Total_Expense__c,Amount,CampaignId,CloseDate,CreatedById,CreatedDate,CurrentGenerators__c,DeliveryInstallationStatus__c,Description,develoepername__c,ExpectedRevenue,Expense__c,Id,IsClosed,IsDeleted,IsPrivate,IsWon,LastActivityDate,LastModifiedById,LastModifiedDate,LastReferencedDate,LastViewedDate,LeadSource,MainCompetitors__c,Name,NextStep,OrderNumber__c,OwnerId,Pricebook2Id,Probability,RecordTypeId,StageName,SystemModstamp,TotalOpportunityQuantity,TrackingNumber__c,Type FROM Opportunity where id in:opplist]);


   Integer total;


   if(rollup.keyset()!=Null)


   {


  for(Id ids:rollup.keyset())


  {


  total=0;


   List<Concur_Reports__c> cr3=rollup.get(ids);


   Opportunity oppr=oppidsfilter.get(ids);


  


   for(Concur_Reports__c cr4:cr3)


   {
   total=total+Integer.valueof(cr4.ReportTotal__c);


    system.debug('%%%%%%%%%%total%%%%%%%%%%%%'+total);


   }

   if(oppr!=Null){
 if(delflag!=True){
oppr.Expense__c=oppr.Expense__c+total;

  }

  else{

   oppr.Expense__c=oppr.Expense__c-total;


  }


  OppUpdateList.add(oppr);


   system.debug('%%%%%%%%%%OppUpdateList%%%%%%%%%%%%'+OppUpdateList);


    }


  }

try{
    if(OppUpdateList.size()>0){


    Update OppUpdateList;


} else  {

}


}


catch(exception ex){
}


}




 }


Pagination

-----------------------------------------------------------------------------------------------------------------------
Pagination controller

--------------------------------------------------------------------------------------------------------------------------


public with sharing class PagingController {

    List<categoryWrapper> categories {get;set;}

    // instantiate the StandardSetController from a query locator
    public ApexPages.StandardSetController con {      
        get {
            if(con == null) {
                con = new ApexPages.StandardSetController(Database.getQueryLocator([Select Id, Name FROM Account Order By Name Asc limit 100]));
                // sets the number of records in each page set
                con.setPageSize(10);
            }
            return con;
        }
        set;
    }

    // returns a list of wrapper objects for the sObjects in the current page set
    public List<categoryWrapper> getCategories() {
        categories = new List<categoryWrapper>();
        for (Account category : (List<Account>)con.getRecords())
            categories.add(new CategoryWrapper(category));

        return categories;
    }

           
    // indicates whether there are more records after the current page set.
    public Boolean hasNext {
        get {
            return con.getHasNext();
        }
        set;
    }

    // indicates whether there are more records before the current page set.
    public Boolean hasPrevious {
        get {
            return con.getHasPrevious();
        }
        set;
    }

    // returns the page number of the current page set
    public Integer pageNumber {
        get {
            return con.getPageNumber();
        }
        set;
    }

    // returns the first page of records
     public void first() {
         con.first();
     }

     // returns the last page of records
     public void last() {
         con.last();
     }

     // returns the previous page of records
     public void previous() {
         con.previous();
     }

     // returns the next page of records
     public void next() {
         con.next();
     }

     // returns the PageReference of the original page, if known, or the home page.
     public void cancel() {
         con.cancel();
     }
       // displays the selected items
  /*   public PageReference process() {
         for (CategoryWrapper cw : categories) {
             if (cw.checked)
                 ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,cw.cat.name));
         }
         return null;
     } */
       

}
--------------------------------------------------------------------------------------------------------------------------
supporting wrapper class
---------------------------------------------------------------------------------------------------------------------

public class CategoryWrapper {

    public Boolean checked{ get; set; }
    public Account cat { get; set;}

    public CategoryWrapper(){
        cat = new Account();
        checked = false;
    }

    public CategoryWrapper(Account c){
        cat = c;
        checked = false;
    }

   

}


--------------------------------------------------------------------------------------------------------------------------
pagination page
-------------------------------------------------------------------------------------------------------------------------

<apex:page controller="PagingController" tabStyle="Account">
  <apex:form style="style='color: #78bf3a;'" title="Pagination">
    <apex:pageBlock title="Pagination"  >

      <apex:pageBlockButtons location="top">
     <!--   <apex:commandButton action="{!process}" value="Process Selected"/> -->
        <apex:commandButton action="{!cancel}" value="Cancel" style="color:#78bf3a;font-weight: normal;font-size:15px;height:30px;text-align:center;font-weight:bold;font-family:Arial,Helvetica,sans-serif;"/>
      </apex:pageBlockButtons>
      <apex:pageMessages />

      <apex:pageBlockSection title="Category Results -  Page #{!pageNumber}" columns="1">
        <apex:pageBlockTable value="{!categories}" var="c">
          <apex:column width="25px">
            <apex:inputCheckbox value="{!c.checked}"/>
          </apex:column>
          <apex:column value="{!c.cat.Name}" headerValue="Name"/>
        </apex:pageBlockTable>
      </apex:pageBlockSection>
    </apex:pageBlock>

    <apex:panelGrid columns="4">
    <apex:commandLink action="{!first}">First</apex:commandlink>
    <apex:commandLink action="{!previous}" rendered="{!hasPrevious}">Previous</apex:commandlink>
    <apex:commandLink action="{!next}" rendered="{!hasNext}">Next</apex:commandlink>
    <apex:commandLink action="{!last}">Last</apex:commandlink>
    </apex:panelGrid>

  </apex:form>
</apex:page>

Dynamic Search Engine

-----------------------------------------------------------------------------------
Controller

------------------------------------------------------------------------------------


public class SearchEngine1 {

    public String name { get; set; }
   
    public String firstname {get;set;}                                    
 
   public String LastName{get;set;}  
   public String Title{get;set;}  
    public List<contact> searchResults {get;set;}
    private boolean firstFilterApplied = false;
   
    public SearchEngine1(){
        searchResults = new List<contact>();
    }

    public PageReference search(){
        searchResults.clear();
        firstFilterApplied = false;
        try{
            //Create the dynamic SOQL query
           
            String queryString = 'SELECT FirstName,LastName,Title '+ 'FROM contact';
   
         
           
            if (LastName!= null && LastName!= ''){
                LastName= String.escapeSingleQuotes(LastName); //To avoid SOQL injection
               
                LastName= lastname.startsWith('%') ? LastName: '%' + LastName;
                LastName= lastname.endsWith('%') ? lastname : lastname + '%';
               
                queryString += whereOrAndClause() + ' LastName like \''+LastName+'\'';
            }
             system.debug('##########'+queryString );
         
         
           
           
            searchResults = Database.query(queryString);
            system.debug('##########'+searchResults);
        }
        catch(QueryException e){
            //If the query returns more than 1000 records, display an error to the user
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'No records found with this criteria'));
            return null;
        }
        catch(Exception e1){
             ApexPages.addMessages(e1);
             return null;
        }      

        if (searchResults.size() == 0){
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'No records found with this criteria'));
        }
               
        return null;

    }
   
     
 
   
    private String whereOrAndClause(){
        String queryClause;
        if (firstFilterApplied){
            queryClause = ' AND ';
        }
        else{
            queryClause = ' WHERE ';
        }
        firstFilterApplied = true;
        return queryClause;
    }
}



---------------------------------------------------------------------------------------------------------------
Dynamic Controller Page
-------------------------------------------------------------------------------------------------------------

<apex:page controller="SearchEngine1" tabStyle="Account" showHeader="true" sidebar="true" >
    <apex:form >
        <apex:pageMessages />
        <apex:pageBlock title="Search Criteria">
             <apex:pageBlockSection >
           
                   <apex:inputText value="{!LastName}" label="Last Name"/>
       
               
            </apex:pageBlockSection>
           
           
           
            <apex:pageBlockButtons location="bottom">
                    <apex:commandButton action="{!search}" value="Search"/>
            </apex:pageBlockButtons>
           
           
        </apex:pageBlock>
       
       
        <apex:pageBlock title="Search Result">
            <apex:pageBlockTable value="{!searchResults}" var="res" rendered="{!searchResults.size > 0}">
                <apex:column title="Final result">
                    <apex:outputLink value="/{!res.Id}" target="_blank">{!res.FirstName}</apex:outputLink>
                </apex:column>    
               
                 <apex:column title="Final result">
                    <apex:outputLink value="/{!res.Id}" target="_blank">{!res.LastName}</apex:outputLink>
                </apex:column>    
               
                 
               <!-- <apex:column title="Celebrity">
                    <apex:outputLink onmouseover="" value="/{!res.LastName__c}" target="_blank">{!res.celebrity__r.name}</apex:outputLink>
                </apex:column> -->
             
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>  
</apex:page>