• Krishnan Mishra
  • NEWBIE
  • 45 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 19
    Questions
  • 16
    Replies
Here, is a code example of lightning data table with keyfield attribute in it.
<lightning:datatable keyField=  "id" 
	    							data="{! v.Artifact }" 
	    							columns="{! v.columns }" 
	    							selectedRows="{! v.selectedRows }"
	    							showRowNumberColumn="true" 
	    							onrowselection="{!c.UpdateSelectedRows}"/>
In every example that i found the value of keyField attribute is always id. What is this id?
Also if keyField is used to uniquely identify a row, how to access it's value in onrowselection?
I tried the following but nothing worked:
UpdateSelectedRows: function(component,event,helper){
    	let selectedRows = event.getParam('selectedRows');
    	let setRows = [];
    	for (let i = 0; i < selectedRows.length; i++){
    		setRows.push(selectedRows[i].component.get('v.recordId'));

    	}
    	console.log('zzzzzzz ',setRows);
    	//component.set('v.rowsSelected',setRows);

    },

I want to get the row index/row id  to uniquely identify each row. 
I am iterating  a map using repeat on a vf page. I want to send the selected folder's id in the apex. I tried to use param but it is giving null values.Following is my code:
Page:
<apex:pageBlockSection id="FolderName" collapsible="true" title="Folder">
				<apex:repeat value="{!foMapNames}" var="fokey">
					<apex:commandLink value="{!foMapNames[fokey]}" action="{!folderIn}" reRender="none">
						<apex:param value="{!fokey}" assignTo="{!foId}"/>
					</apex:commandLink>
					<br/>
				</apex:repeat>
			</apex:pageBlockSection>

here fokey is null.
 
I am integrating Google Drive API with salesforce. I have created 2 classes here, one is the controller class for the page and another one is helper class. As soon as my page gets loaded I can see access token(after entering the crendials) in debug log but, when I click on a disp button then it gets nulled. I dont understand why is this happening and how to resolve it. Following is my code:

Controller code:
public class GDrive {
	public static String AccessToken;

	public GDrive(){
		System.debug('GDrive constructor called ');
	}

	public PageReference authentication(){
		System.debug('Authentication called');
		PageReference pg = GoogleDriveHelper.DriveAuth();
		return pg;
	}

	public void Files(){
		System.debug('Gdrive access token in gd is '+GDrive.AccessToken);
		System.debug('Files called in GDrive');
		//GoogleDriveHelper.AccessToken();
		//list<String> fList = new list<String>();
		/*String fList = GoogleDriveHelper.displayFiles();
		System.debug('>>> l is ' + fList);
		//return fList;*/
	}
}

Helper class code:
public class GoogleDriveHelper {
	// Stores authorization code.
	private static String code;
    //Client ID.
    private static string key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
    //Client secret key.
    private static string secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
    // Url to be redirected when authentication is done.
    private static string redirect_uri = 'https://c.ap5.visual.force.com/apex/googleDrive';
    private static String access_token;
    public static list<String> files;
    public GoogleDriveHelper()
    {
    	System.debug('Constructor of Helper class called ');
    	/*//code = ApexPages.currentPage().getParameters().get('code');
    	System.debug('constructor for helper class called');
        
        //Get the access token once we have code
        if(code != '' && code != null)
        {
            AccessToken() ;
        }*/
    }
    
    public static PageReference DriveAuth()
    {
        //Authorization
        code = ApexPages.currentPage().getParameters().get('code');
        if(code != '' && code != null){
        	System.debug('<<>>>><');
        	GDrive.AccessToken = GoogleDriveHelper.AccessToken();
        	System.debug('GDrive.AccessToken is '+GDrive.AccessToken);
        	return null;
        }
        else{
        	PageReference pg = new PageReference(GoogleDriveAuthUri (key , redirect_uri)) ;
       		return pg;
        }
        
    }
    
    // To redirect to OAuth server, google drive api here.
    public static String GoogleDriveAuthUri(String Clientkey,String redirect_uri)
    {
    	System.debug('Entered authorization ');
        String key = EncodingUtil.urlEncode(Clientkey,'UTF-8');
        String uri = EncodingUtil.urlEncode(redirect_uri,'UTF-8');
        String authuri = '';
        // Call the Google OAuth 2.0 endpoint directly, you'll generate a URL and set the parameters on that URL.
        authuri = 'https://accounts.google.com/o/oauth2/auth?'+
        'client_id='+key+
        '&response_type=code'+
        '&scope=https://www.googleapis.com/auth/drive'+	//Scope to access data on drive. This gives full access
        '&redirect_uri='+uri+
        '&state=security_token%3D138r5719ru3e1%26url%3Dhttps://oa2cb.example.com/myHome&'+
        //'&login_hint=jsmith@example.com&'+
        'access_type=offline';	//Indicates whether your application can refresh access tokens when the user is not present at the browse
        return authuri;
    }
    
    
    public static String AccessToken()
    {
    	code = ApexPages.currentPage().getParameters().get('code');
        //Getting access token from google drive api app
        System.debug('code in access_token is ' + code);
        HttpRequest req = new HttpRequest();
        req.setMethod('POST');	//http method of POST is used.
        req.setEndpoint('https://accounts.google.com/o/oauth2/token');	//URL from which you have to extract resources.
        req.setHeader('content-type', 'application/x-www-form-urlencoded');	//file type:application, extension:x-www-form-urlencoded
        String messageBody = 'code='+code+'&client_id='+key+'&client_secret='+secret+'&redirect_uri='+redirect_uri+'&grant_type=authorization_code';
        req.setHeader('Content-length', String.valueOf(messageBody.length()));
        req.setBody(messageBody);
        req.setTimeout(60*1000);	//Time out is for 60 secs.

        Http h = new Http();
        String resp;
        HttpResponse res = h.send(req);
        System.debug('access token request is ' + res);
        resp = res.getBody();
        Map<String,object> m = (Map<String, Object>)Json.deserializeuntyped(resp);	// Stores JSON string values in a map
        access_token = (String)(m.get('access_token'));	//Retrives the value of access token from map and stores it.
        //We have to pass this access token everytime when a hit is made.
        System.debug(' access Token is ' + access_token);
        return access_token;
        
   	}

   	public static String displayFiles(){
   		System.debug('access_token is >>>> '+ access_token);
   		HttpRequest req = new HttpRequest();
   		req.setMethod('GET');	// Http method of get is used here.
   		// setEndPoint url parameters are passed 
   		req.setEndpoint('https://www.googleapis.com/drive/v3/files?corpora=user,allTeamDrives&includeTeamDriveItems=true&supportsTeamDrives=true');
   		// to pass access token.
   		System.debug('AccessToken in disp is ' + access_token);
   		req.setHeader('Authorization', 'Bearer ' + access_token);
   		req.setTimeout(60*1000);

   		Http h = new Http();
   		String resp;
   		HttpResponse res = h.send(req);
   		System.debug('Send request is ' + res);
   		resp = res.getBody();	// JSON string values are returned here.
   		Map<String,object> m = (Map<String, Object>)Json.deserializeuntyped(resp);
   		System.debug(m.size());
   		String str = (String)m.get('files.Name');
   		//files = str.split(',');
   		//System.debug('?????? '+files[0]);
   		System.debug(resp);
   		return str;
   	}
}

Can anyone please explain this statement :
global class ContactBatch implements Database.Batchable<sObject>{
}

As far as I know Database is a class in apex and batchable is an interface, So why can't we write as: 
global class ContactBatch implements Batchable{
}

Also, explain the syntax for <sObject> here
I am trying to change the "status" field(custom) of the contact object by using a batch. If I update the fields in the execute method then it gets updated but if I try to update it in the finish method then my list is empty. I am not getting this!
 
global class BatchNSchedulable implements Database.Batchable<sObject>{
	global list<contact> con=new list<contact>();
	String query = 'SELECT id,name,status__c FROM contact WHERE CreatedDate= Yesterday';
	global Database.QueryLocator start(Database.BatchableContext bc){
		System.debug('In the start');
		 return (Database.getQueryLocator(query));
	}
	global void execute(Database.BatchableContext bc,list<sObject> li){
		System.debug('In the execute');
		con = (list<contact>)li;
		System.debug(con.size());	
		for(contact ct:con){
			ct.put('status__c','None');
		}
		System.debug('con in execute is '+con);
	}
	global void finish(Database.BatchableContext bc){
		System.debug('con is '+con);
		update con;
		System.debug('In the finish');
	}

}

 
<apex:actionFunction action="{!docReady}" name="funAtLast" reRender="form,alpha,table,button"/>
When I call funAtLast() function defined in my script on my VisualForce page then which one will execute first, docReady() of controller or the funAtLast() method of script?
I have values of my CSV stored in a string variable named 'csv'. Now i want to download the content of this variable with click of button('submit') on page but i don't want to redirect to another page.The best is by using java script.PS: the variable is stored in my component it is not a page.
Controller code:
public class PaginationForComponent {
    public PaginationForComponent(){
    allContactList = new list<wrapper>();
    myOrder = 'desc';
    sortField='name';
    PageNumber = 1;
    alphabet = 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','Others','All'};
    RecordsPerPageslist = 10;
    System.debug('constructor called');
    csv='';
  }
  Boolean lstNamePresent=false;
  public String objName{get;set;}
  public String fieldNames{get;set;}
  list<sObject> con = new list<sObject>();
  public String alphaSearchConct{get;set;}
  public string msg {get;set;}
  public Map<id,Boolean> m = new Map<id,boolean>(); 
  list<sObject> sortedList;
  public String myOrder{get;set;}                 // Ascending or Descending order of sorting
  public String sortField{get;set;}               // Field by which sorting should be done
  public boolean selectAll{get;set;}
  public list<String> alphabet{get;set;}
  public list<sObject> cont;
  public list<wrapper> allContactList{get;set;}
  public list<wrapper> ct = new list<wrapper>();
  public list<String> query;
  public String csv{get;set;}
 
  public ApexPages.StandardSetController stdSetController{            //Instantiating a standard set controller
    get{
        if(stdSetController==null){
            //con = Database.query('SELECT '+ fieldNames+' FROM '+ objName );//del it from here update con from script n return allContactList by filling it from there only
            System.debug('con in ssc is : ' + con);
            stdSetController = new ApexPages.StandardSetController(con);
        }
        stdSetController.setPageSize(RecordsPerPageslist);        //Limiting Number of records to be displayed per page 
        System.debug('stdSetController called and fieldNames are : ' + allContactList);
        return stdSetController;   
    }
    set;
  }
  public void SelectedListContacts(){         // Select contacts and save them in a map  
    for(wrapper wc:allContactList){
        m.put(wc.con.id,wc.isSelected);
        if(wc.isSelected==false){
            selectAll=false;
         }
    }
  }
  public void SelectedAllContacts(){          //To select all contacts in a page
    System.debug(selectAll);
    allContactList.clear();
    for(sObject c:(list<sObject>)stdSetController.getRecords()){
        allContactList.add(new wrapper(c));
    }
    if(selectAll==true){
        for(wrapper wc:allContactList){
            m.put(wc.con.id,wc.isSelected=true);
    }
   }
    else{
      for(wrapper wc:allContactList)
          m.put(wc.con.id,wc.isSelected=false);
   }
  }
  public String[] getqueryList(){
    query = fieldNames.split(',');
    for(String s:query){
      if(s=='lastname'){
        lstNamePresent=true;
      }
  }

}
  public list<wrapper> getWrapperContacts(){      //List of wrapper class to display in table
    return allContactList;
  }

  public Integer stdSize(){
    Integer i = stdSetController.getRecords().size();
    return i;
  }

  public void docReady(){
    con = Database.query('SELECT '+ fieldNames+' FROM '+ objName );
    System.debug('docReady con is ' + con);
    for(sObject c:(list<sObject>)stdSetController.getRecords())
          allContactList.add(new wrapper(c));
    System.debug('docReady allContactList is ' + allContactList);
  }

public void submit() {
    Set<id> ids = new set<id>();
    for(id i:m.keySet()){
        if(m.get(i)==true){ 
        ids.add(i);
        }
    }
    String queryStr = 'SELECT ' + fieldNames + ' FROM ' + objName + ' WHERE id IN :ids';
    sObject[] c = Database.query(queryStr);
    String temp = '';
    for(Integer i=0;i<c.size();i++){
    for(String s: query){
       temp = String.valueOf((c[i].get(s)));
       // System.debug('before escape csv temp is ' + temp);
        if(temp!=null){
            temp = temp.escapeCsv();}
       // System.debug('temp after escapeCsv() is ' + temp);
        csv += temp;
       // System.debug('str is '+str);
        csv += ', ';
    }
  }
}
// To convert to CSV file
 
public String getgenerateCSV() {
  System.debug('csv is :' + csv);
  return csv;
}
/*public String[] getqueries(){
  System.debug(csvQuery);
  return csvQuery;
}*/
  public class wrapper{
    public boolean isSelected{get;set;}  
    public sObject con{get;set;}  
    public   wrapper(sObject con){
            //System.debug('constructor of wrapper class called ');
            isSelected = false;
            this.con = con;
        }
  }
}
Component code:
<apex:component controller="PaginationForComponent" allowDml="true">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
    </script>
    <script>
    	function SuccessFailure(msg) {
        	if(msg == '') {
            	window.top.location.reload()
            } else {
            	alert(msg);
            }
        }
        function cannotFind(msg){
            if(msg!=null)
                alert(msg);
        }
        $(document).ready(function(){
            funAtLast();
        });
    </script>
    <apex:attribute name="objectName" description="The object's name" type="String" required="true" assignTo="{!objName}"/>
    <apex:attribute name="fieldName" description="Fields to be displayed" type="String" required="true" assignTo="{!fieldNames}"/>
    <apex:outputPanel id="form">
        <apex:actionFunction action="{!docReady}" name="funAtLast" reRender="form,alpha,table,button"/>
        <style>
    .bPageBlock .pbBody .dataCol {
        border:0px;
    }
    .bPageBlock .pbBody .labelCol { 
        border:0px;
    }
	</style>
       <!-- <apex:commandButton value="Process" reRender="form,alpha,table,button"/>-->
        <apex:outputPanel rendered="{!allContactList.size!=0}" id="page">
            <!-- For alphabetic search-->
                <div align="right" >
                        <apex:repeat value="{!alphabet}" var="alph" >
                            <apex:commandLink value="{!alph}  " action="{!alphaSearch}" oncomplete="cannotFind('{!msg}');" reRender="table,button" id="cs" > &ensp;
                                <style type="text/css">
                                    #cs:hover{
                                        background-color: #b3ffff;
                                    }
                                </style>
                                <apex:param name="a" value="{!alph}" assignTo="{!alphaSearchConct}"/>
                            </apex:commandLink>
                        </apex:repeat>
                </div>
            <apex:pageBlock id="table">
                <!-- To delete selected records-->
                <apex:commandButton action="{!DelSelected}" value="Delete Selected" oncomplete="SuccessFailure('{!msg}');"/>
                <!-- Button for csv download -->
                <apex:commandButton action="{!submit}" value="Download CSV" reRender="none"/>
                <apex:pageMessages rendered="true" id="Msg"/>
                <apex:PageBlockTable value="{!WrapperContacts}" var="contacts">
                    <!-- To Edit and Delete a record -->
                   <apex:column headerValue="Action">
                        <apex:outputLink value="{!URLFOR($Action[objectName].Edit,contacts.con.id)}">
                            Edit |
                        </apex:outputLink>
                        <apex:outputLink value="{!URLFOR($Action[objectName].Delete,contacts.con.id)}"> 
                            Del |
                        </apex:outputLink>
                    </apex:column>
                    <apex:column >
                    <apex:facet name="header">
                            <apex:inputCheckbox value="{!selectAll}">  
                                <apex:actionSupport event="onclick" action="{!SelectedAllContacts}" reRender="table"/>
                                </apex:inputCheckbox>  
                            </apex:facet>
                        <apex:inputCheckbox value="{!contacts.isSelected}">
                            <apex:actionSupport event="onclick" action="{!SelectedListContacts}" reRender="none" />
                        </apex:inputCheckbox> 
                    </apex:column>
                    <apex:repeat value="{!queryList}" var="fldNames">
                        <apex:column >
                            <apex:facet name="header">
                                <apex:commandLink value="{!fldNames}" action="{!toggleSort}" reRender="table">
                                    <apex:param name="sortField" value="{!fldNames}" assignTo="{!sortField}" />
                                    <apex:param name="myOrder" value="{!IF(myOrder == 'DESC', 'ASC','DESC')}" assignTo="{!myOrder}" />
                                </apex:commandLink>
                            </apex:facet>
                            {!contacts.con[fldNames]}
                        </apex:column>
                    </apex:repeat>
                </apex:PageBlockTable>
            </apex:pageBlock>
            <apex:outputPanel id="button"> 
                <div align = "center" >
                    <!-- To return to first page of records-->
                    <apex:commandButton action="{!first}" value="<<" title="First Page" disabled="{!!HasPrevious}" reRender="table,button"/>
                    <!-- To return to Previous page of records-->
                    <apex:commandButton action="{!previous}" value="Previous" disabled="{!!HasPrevious}" reRender="table,button"/>
                    <!-- To return to next page of records-->
                    <apex:commandButton action="{!next}" value="Next >" disabled = "{!!HasNext}" reRender="table,button"/>
                    <!-- To return to last page of records-->
                    <apex:commandButton action="{!last}" value=">>" title="Last Page" disabled="{!!HasNext}" reRender="table,button"/>
                    <!-- InputText to display current page and to navigate to any page number, At righmost side of page-->
                    <span style="float:right">
                        <apex:outputLabel value="Page ">
                        </apex:outputLabel>
                         <!-- To navigate to the page--> 
                        <apex:InputText value="{!PageNumber}" maxLength="4" size="1">
                        <apex:actionSupport event="onchange" action="{!NavigateByText}"  reRender="table,button"/>
                        </apex:InputText>
                         <!-- The above action support is not working-->         
                        <apex:outputLabel value=" of {!TotalPages}">
                        </apex:outputLabel>
                    </span>
                    <!-- To display a list for number of records to be selected per page-->
                    <span style = "float:left">
                        <apex:SelectList value="{!RecordsPerPageslist}" size="1" >
                            <apex:selectOptions value="{!RecordsPerPageOptionList}">    
                            </apex:selectOptions>
                            <apex:actionSupport event="onchange" action="{!ChangeNumberOfRecordsPerPage}" reRender="table,button"/>
                        </apex:SelectList>
                    </span>
                </div>
            </apex:outputPanel>    
        </apex:outputPanel> 
    </apex:outputPanel>
</apex:component>

I have tried to provide only the relevant code, if something irrelevant is present then please ignore that and the values are being inserted in csv variable
 
id i = 0037F00000M6MCHQA3;
String fieldNames='name,id';
String objName = 'contact';
String queryStr = 'SELECT ' + fieldNames + ' FROM ' + objName + ' WHERE id IN :(\'i\')';
System.debug(queryStr);

 
I try to pass on a list to a new visualForce page and then display that list as a table to download as a csv file. But I am getting blank csv file. As soon as i redirect to my new page the list gets empty even though "setRedirect=false". Following is my code:
Controller code:
public class PaginationForComponent {
  public PaginationForComponent(){
    allContactList = new list<wrapper>();
    myOrder = 'desc';
    sortField='name';
    PageNumber = 1;
    alphabet = 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','Others','All'};
    RecordsPerPageslist = 10;
    System.debug('constructor called');
  }
  Boolean lstNamePresent=false;
  public String objName{get;set;}
  public String fieldNames{get;set;}
  list<sObject> con = new list<sObject>();
  public String alphaSearchConct{get;set;}
  public string msg {get;set;}
  public Map<id,Boolean> m = new Map<id,boolean>(); 
  list<sObject> sortedList;
  public String myOrder{get;set;}                 // Ascending or Descending order of sorting
  public String sortField{get;set;}               // Field by which sorting should be done
  public boolean selectAll{get;set;}
  public list<String> alphabet{get;set;}
  public list<sObject> cont;
  public list<wrapper> allContactList{get;set;}
  public list<wrapper> ct = new list<wrapper>();
  public list<wrapper> csvList = new list<wrapper>();
  public list<String> query = new list<String>();
  public list<String> csvQuery;
public Pagereference submit() {
    csvList = new list<wrapper>();
    csvQuery = new list<String>();
    try {
    for (id i: m.keySet()) {
      System.debug('id is '+i);
      if (m.get(i) == true) {
        sObject c = Database.query('SELECT ' + fieldNames + ' FROM ' + objName + ' WHERE id= :i');
        ct.add(new wrapper(c));
        System.debug('ct is '+ ct);
      }
     }
    } 
    catch (System.QueryException e) {
     System.debug('Error while generating csv file ' + e);
    }
    csvList.addAll(ct);
    csvQuery.addAll(query);
    System.debug('csv list earlier ' + csvList);
    Pagereference pgReference = Page.ConvertToCSVController;
    PgReference.setRedirect(false);
    return pgReference;
    }
public list < wrapper > getgenerateCSV() {
    System.debug('csv list is :' + csvList);
    return csvList;
  }
  public String[] getqueries(){
    return csvQuery;
  }
    public class wrapper{
      public boolean isSelected{get;set;}  
      public sObject con{get;set;}  
      public   wrapper(sObject con){
              //System.debug('constructor of wrapper class called ');
              isSelected = false;
              this.con = con;
          }
    }
  }

My  page code(on which it is redirected)
<apex:page controller="PaginationForComponent" contentType="application/vnd.ms-excel#contacts.xls" readOnly="True">
<apex:form id="form">
    <apex:pageBlock >
        <apex:pageBlockTable value="{!generateCSV}" var="csv">
            <apex:repeat value="{!queries}" var="fldNames">
                <apex:column value="{!csv.con[fldNames]}"/> 
            </apex:repeat>
        </apex:pageBlockTable> 
    </apex:pageBlock>
</apex:form>
</apex:page>

 
My vf code is :
<apex:page sidebar="false" controller="t1">
	<apex:form >
	<apex:pageBlock >
		Select Object Name &ensp;&nbsp;
		<apex:SelectList value="{!ObjList}" size="1">
          <apex:selectOptions value="{!objectList}">    
           </apex:selectOptions>
          <!-- <apex:actionSupport event="onchange" action="{!ChangeNumberOfRecordsPerPage}" reRender="table,button"/>-->
        </apex:SelectList>
        <apex:panelBar >
        	<apex:panelBarItem label="Field Values"/>
        	<apex:SelectList value="{!fldList}" multiselect="true">
        		<apex:selectOptions value="{!fieldList}">
        	</apex:selectOptions>
        </apex:SelectList>
    </apex:panelBar>
	</apex:pageBlock>
	</apex:form>
  <!--  <c:Dynamic_pagination objectName="contact" fieldName="Name,Account.name,Title">
    </c:Dynamic_pagination>
-->
</apex:page>

Controller code is:
public class t1 {

    public String ObjList{get;set;}
    public String fldList{get;set;}
	public list < SelectOption > getobjectList() { 
        list < SelectOption > options = new list < SelectOption > ();
        for(Schema.SObjectType item : ProcessInstance.TargetObjectId.getDescribe().getReferenceTo()){
            String name = item.getDescribe().getName();
            if(!item.getDescribe().CustomSetting && item.getDescribe().isAccessible() && !name.containsignorecase('orgDeleteRequest') && !name.containsignorecase('Solution') 
                && !name.containsignorecase('StreamingChannel') ){
                options.add(new SelectOption(item.getDescribe().getName(), item.getDescribe().getLabel()));
            }
            options.sort();
        }
        return options;
    }
    public list <SelectOption> getfieldList(){
        list<SelectOption> options = new list<SelectOption>();
        Schema.DescribeSObjectResult[] descResult = Schema.describeSObjects(new String[]{ObjList});
        Map <String,Schema.SObjectField> fldMap = descResult[0].fields.getmap();
        for(String K:fldMap.KeySet()){
            options.add(new SelectOption(K,K));
        }
        options.sort();
        return options;
        //System.debug(Schema.sObjectType.Account.fields.getmap());
    }
}

Complete error that I am getting is: ​Unable to Access Page
The value of the "entityName" parameter contains a character that is not allowed or the value exceeds the maximum allowed length. Remove the character from the parameter value or reduce the value length and resubmit.
Can anyone please explain why am I getting this error and how to resolve it?
i encountered the following 
Schema.sObjectType.Account.fields.getmap()

Here what is getMap() method? In which class this method is defined, and what does it do? Also if you can give me more details about this method like can this method be over loaded,what is the return type of this etc etc
I want my outputPanel with id = form  to be rendred only if the condition is true,In the debug log i checked my condition is getting true but still i cannot see my output panel.Following is my code:
<apex:component controller="PaginationForComponent" >
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
    </script>
    <script>
    	function SuccessFailure(msg) {
        	if(msg == '') {
            	window.top.location.reload()
            } else {
            	alert(msg);
            }
        }
        $(document).ready(function(){
            funAtLast();
            alert('document.ready called');
        });
    </script>
    <apex:attribute name="objectName" description="The object's name" type="String" required="true" assignTo="{!objName}"/>
    <apex:attribute name="fieldName" description="Fields to be displayed" type="String" required="true" assignTo="{!fieldNames}"/>
    <apex:form >
        <apex:actionFunction action="{!docReady}" name="funAtLast" reRender="none"/>
        <apex:commandButton value="Process" reRender="form,alpha,table,button"/>
    
    <apex:outputPanel id="form" rendered="{!allContactList.size!=0}">
        <!-- For alphabetic search-->
        <apex:pageBlock id="alpha">
            <div align="right">
                <apex:panelGrid >
                    <apex:repeat value="{!alphabet}" var="alph">
                        <apex:commandLink value="{!alph} | " action="{!alphaSearch}" reRender="table,button">
                            <apex:param name="a" value="{!alph}" assignTo="{!alphaSearchConct}"/>
                        </apex:commandLink>
                    </apex:repeat>
                </apex:panelGrid>
            </div>
        
        </apex:outputPanel>    
    </apex:outputPanel>    
    </apex:form >
</apex:component>

 
I have a wrapper class that i want to display on a visualforce page using repeat tag. Following is my code 
public class PaginationForComponent {
    public String objName{get;set;}
	public String[] fieldNames{get;set;}
	list<sObject> con = new list<sObject>();

	
	public PaginationForComponent(){
		RecordsPerPageslist = 10;
	}

	public String query;
	public String alphaSearchConct{get;set;}
	public string msg {get;set;}
	public Map<id,Boolean> m = new Map<id,boolean>(); 
	list<sObject> sortedList;
	public String myOrder{get;set;}                 // Ascending or Descending order of sorting
	public String sortField{get;set;}               // Field by which sorting should be done
	public boolean selectAll{get;set;}
	public list<String> alphabet{get;set;}
	public list<sObject> cont;
	public list<wrapper> allContactList = new list<wrapper>();
	public void fieldvalues(){
		query = fieldNames[0] + ' , ';
		for(Integer i=1;i<fieldNames.size();i++){
			query = query + fieldNames[i] + ' , ';
		}
		query='SELECT ' + query + ' FROM ' + 'objName';
	}
	public Integer RecordsPerPageslist{ 
        get;
        set{                                                          //To select number of records per page
            if(value!=null){
                this.RecordsPerPagesList=value;
                System.debug('RecordsPerPageList called');
            }
        }       
    }  
    public ApexPages.StandardSetController stdSetController{            //Instantiating a standard set controller
          get{
              if(stdSetController==null){
                    con = Database.query(query);
                    System.debug('con in ssc is : ' + con);
                   stdSetController = new ApexPages.StandardSetController(con);
              }
                stdSetController.setPageSize(RecordsPerPageslist);        //Limiting Number of records to be displayed per page 
                  System.debug('stdSetController called ');
              return stdSetController;   
          }
          set;
      }
    public list<wrapper> getWrapperContacts(){      //List of wrapper class to display in table
       for(sObject c:(list<sObject>)stdSetController.getRecords()){
       		allContactList.add(new wrapper(c));
       }
        return allContactList;
    }

    public class wrapper{
	  public boolean isSelected{get;set;}  
	  public sObject con{get;set;}  
	  public   wrapper(sObject con){
	          System.debug('constructor of wrapper class called ');
	          isSelected = false;
	          this.con = con;
	          }
	          
	      }
}
 
<apex:component controller="PaginationForComponent" >
    <apex:attribute name="objectName" description="The object's name" type="String" required="true" assignTo="{!objName}"/>
    <apex:attribute name="fieldName" description="Fields to be displayed" type="String[]" required="true" assignTo="{!fieldNames}"/>
    <apex:pageBlock >
        <apex:repeat value="{!getWrapperContacts}" var="repeat">
            <apex:outputText value="{!repeat}">
            
            </apex:outputText>
            
        </apex:repeat>
    
    </apex:pageBlock>
</apex:component>

 
There is a function in my controller class (getConstructor()) that i want to use after my page has been loaded. For this i am using a jquery function 
$(document).ready()

No, i want to call this document.ready function inside a actionFunction, so that the jquery function gets executed but i don't know how to do that
public class PaginationForComponent {
    public String objName{get;set;}
	public String fieldNames{get;set;}
public void getConstructor(){
        System.debug('Field values are '+ fieldNames);
		con = Database.query('SELECT '+ fieldNames +' FROM '+ objName);
        System.debug('Field values are '+ fieldNames);
        System.debug(con);
        myOrder = 'desc';
        sortField='name';
        PageNumber = 1;
        RecordsPerPageslist=10;
        alphabet = 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','Others','All'};
        allContactList = new list<wrapper>();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c));
	}
public ApexPages.StandardSetController stdSetController{            //Instantiating a standard set controller
	        get{
	            if(stdSetController==null){
	                 stdSetController = new ApexPages.StandardSetController(con);
	            }
	              stdSetController.setPageSize(RecordsPerPageslist);        //Limiting Number of records to be displayed per page 
	                System.debug('stdSetController called ');
	            return stdSetController;   
	        }
	        set;
	    }public Integer TotalPages{                                            // Total number of pages as per user selection of Records per page
	        get{
	             System.debug('TotalPages called'); 
	            if(stdSetController.getResultSize() <=10)
	                   this.TotalPages=1;
	              if(Math.Mod(stdSetController.getResultSize() ,stdSetController.getPageSize()) == 0)
	                  this.TotalPages =(stdSetController.getResultSize()/stdSetController.getPageSize());
	              else
	                this.TotalPages = (stdSetController.getResultSize()/stdSetController.getPageSize())+1;
	              //System.Debug(this.TotalPages);
	                return totalpages;
	        }
	        set;
	    }
	public Integer RecordsPerPageslist{ 
        get;
        set{                                                          //To select number of records per page
            if(value!=null){
                this.RecordsPerPagesList=value;
                System.debug('RecordsPerPageList called');
            }
        }       
    }    
}
for the component:
<apex:component controller="PaginationForComponent" >
    
    <apex:attribute name="objectName" description="The object's name" type="String" required="true" assignTo="{!objName}"/>
    <apex:attribute name="fieldName" description="Fields to be displayed" type="String" required="true" assignTo="{!fieldNames}"/>
    {!objName}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script>
    <script>
    	function SuccessFailure(msg) {
        	if(msg == '') {
            	window.top.location.reload()
            } else {
            	alert(msg);
            }
        }
    $(document).ready(function(){
        construct();
        });
    </script>
    <apex:form > 
        <apex:actionFunction name="construct" action="{!getConstructor}"/>
.........


 
I have created a visualforce component and would like to use $Action.object name.action name($Action.Contact.Del) within it but i am getting the above error. Following is my controller and component code:
Component code
<apex:component controller ="PaginationForComponent">
    <apex:attribute name= "objectName" description = "The object's name" type = "String" required = "true" assignTo="{!objName}"/>
    <apex:attribute name= "fieldName" description = "Fields to be displayed" type = "String" required ="true" assignTo="{!fieldNames}"/>
<apex:outputLink value="{!URLFOR($Action."{!objName}".Edit,contacts.con.id)}"> 
                        Edit |
                    </apex:outputlink>
                    <apex:outputLink value="{!URLFOR($Action."{!objName}".Delete,contacts.con.id)}"> 
                        Del |
                    </apex:outputlink>

Controller code:
public class PaginationForComponent {
public String objName{get;set;}
	public String fieldNames{get;set;}
}

Ps: Only relevant code is provided here​
String objName = 'Contact';
string alphaSearchConct = 'A';
String fieldNames = 'name,id';
list<sObject> ct = Database.query('SELECT '+ fieldNames +'FROM '+ objName +'WHERE lastname Like:'+alphaSearchConct +'%');

 
In th following code the action support for my input text field is not working as it should work(Line number 69-70 in vf code).I want to navigate to the page number entered by the user.Following is my controller and VF code:
Code for controller
public class ContactListViewController {
    public ContactlistViewController(){
        system.debug('constructor first called');
        RecordsPerPageslist=10;
        allContactList = new list<wrapper>();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c));
        System.debug('constructor called');
    }
    Map<id,Boolean> m = new Map<id,boolean>();  	 // To store boolean values of checkboxes corrosponding to every contact id
    list<contact> con = [SELECT Name,id,Account.name,Title,Phone,Email FROM Contact];
    public list<wrapper> allContactList;			//Wrapper class object
    
    public list<wrapper> getWrapperContacts(){  	//List of wrapper class to display in table
        return allContactList;
    }
    
    public void getSelectedListContacts(){  		// Select contacts and save them in a map
        for(wrapper wc:allContactList){
            m.put(wc.con.id,wc.isSelected);
        }
        
        System.debug('getSelectedListContacts = '+m);
        
    }
    public void getSelectedAllContacts(){			//To select all contacts in a page
        for(wrapper wc:allContactList){
            m.put(wc.con.id,wc.isSelected=true);
        }
    }
    public void next(){
        System.debug('next');
		allContactList.clear();        
        this.stdSetController.next();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
        }
    }
    public void previous(){
		allContactList.clear();        
        this.stdSetController.previous();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
    }
    }
    public void last(){
        allContactList.clear();        
        this.stdSetController.last();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
    }
    }
    public void first(){
        allContactList.clear();        
        this.stdSetController.first();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
    }
    }
    public boolean getHasNext(){
        return stdSetController.getHasNext();
    }
    public boolean getHasPrevious(){
        return stdSetController.getHasPrevious();
    }
    public list<String> alphabet{
        get{															//To display a list of alphabets on vf page 
            alphabet = 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','Others','All'};
       		return alphabet;	 
                }
        set;
    }
    public String alphaSearchConct{get;set;}							// To get commandlink parameter for alphabet selected
    public Pagereference getalphaSearch(){								//To update contact list as per the alphabet selected by the user
        allContactList.clear();
        if (alphaSearchConct=='All'){
            con = [SELECT name,Account.name,Title,Phone,Email FROM contact];
        }
        else{
            	con = [SELECT name,Account.name,Title,Phone,Email FROM contact WHERE lastName Like:alphaSearchConct+'%'];
        }
        ApexPages.StandardSetController ssc = new ApexPages.StandardSetController(con);
        stdSetController= ssc;
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c));
        system.debug('alphaSearchconct called');
        return null;
    }      
    public Integer PageNumber{
        get{                                                            //To get current page number
  		    System.debug('get of pageNumber called '+ PageNumber);
            this.PageNumber=stdSetController.getPageNumber();   
            return this.PageNumber;
        }
        set{  
            System.debug('set of pageNumber called');
           	this.pageNumber=value;         
    }
        }
    
    public PageReference NavigateByText(){
        
        System.debug('getNavigateByText '+ stdSetController.getPageNumber());
        allContactList.clear();
        this.stdSetController.setPageNumber(PageNumber);
            for(contact c:(list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c));
            //System.debug(stdSetController.getRecords());
           for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
               System.debug(wc.isSelected);
               System.debug('pageNumber called');
               
    }
        return null;
    }
    public Integer TotalPages{                                            // Total number of pages as per user selection of Records per page
        get{
              if(stdSetController.getResultSize() <=10)
                   this.TotalPages=1;
              if(Math.Mod(stdSetController.getResultSize() ,stdSetController.getPageSize()) == 0)
                  this.TotalPages =(stdSetController.getResultSize()/stdSetController.getPageSize());
              else
                this.TotalPages = (stdSetController.getResultSize()/stdSetController.getPageSize())+1;
              //System.Debug(this.TotalPages);
                return totalpages;
        }
        set;
    }
    public Integer MaxNumberOfRecords{                                    //Maximum number of records in a query list
        get{
             return stdSetController.getRecords().size();
        }
        set;
    }
    public list<SelectOption> getRecordsPerPageOptionList(){              //To display a drop down list on vf page  
            list<SelectOption>  options = new list<SelectOption>();
            options.add(new selectOption('10','10'));
            options.add(new selectOption('25','25'));
            options.add(new selectOption('50','50'));
            options.add(new selectOption('100','100'));
            options.add(new selectOption('200','200'));
            return options;
    }
    public Integer RecordsPerPageslist{ 
        get;
        set{                                                          //To select number of records per page
            if(value!=null){
                this.RecordsPerPagesList=value;
                System.debug('RecordsPerPageList called');
            }
        }       
    }
    public Pagereference getChangeNumberOfRecordsPerPage(){
        allContactList.clear();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
         for(wrapper wc:allContactList)
            wc.isSelected=m.get(wc.con.id);
        return null;
    } 
    public ApexPages.StandardSetController stdSetController{            //Instantiating a standard set controller
        get{
            if(stdSetController==null){
             	 stdSetController = new ApexPages.StandardSetController(con);
            }
              stdSetController.setPageSize(RecordsPerPageslist);        //Limiting Number of records to be displayed per page 
            	System.debug('stdSetController called '+ stdSetController.getPageNumber());
            return stdSetController;   
        }
        set;
    }
    public class wrapper{
      public boolean isSelected{get;set;}
      public Contact con{get;set;}
       
         wrapper(contact con){
            isSelected = false;
            this.con = con;
        }
    }
}
Code for VF page:
<apex:page controller="ContactListViewController" sidebar="false">
    <apex:form >
        <!-- For alphabetic search-->
        <div align="right">
            <apex:panelGrid >
                <apex:repeat value="{!alphabet}" var="alph">
                    <apex:commandLink value="{!alph} | " action="{!getalphaSearch}" reRender="table">
                        <apex:param name="a" value="{!alph}" assignTo="{!alphaSearchConct}"/>
                    </apex:commandLink>
                </apex:repeat>
            </apex:panelGrid>
        </div>
        <apex:PageBlock id="table">
            <apex:pageMessages />
            <apex:commandButton action="{!getSelectedAllContacts}" value="Select All" reRender="table"/>
            <apex:PageBlockTable value="{!WrapperContacts}" var="contacts" >
                <!-- To display and select Checkboxes-->
                <apex:column >
                    <apex:facet name="header">
                    	<apex:inputCheckbox value="{!contacts.isSelected}">
                        	<apex:actionSupport event="onclick" action="{!getSelectedAllContacts}" reRender="table"/>
                        </apex:inputCheckbox>	
                        </apex:facet>
                    <apex:inputCheckbox value="{!contacts.isSelected}">
                        <apex:actionSupport event="onclick" action="{!getSelectedListContacts}" reRender="table"/>
                    </apex:inputCheckbox>  
                </apex:column>
                <!-- To Edit and Delete a record -->
                <apex:column headerValue="Action">
                    <apex:outputLink value="{!URLFOR($Action.Contact.Edit,contacts.con.id)}"> 
                        Edit |
                    </apex:outputlink>
                    <apex:outputLink value="{!URLFOR($Action.Contact.Delete,contacts.con.id)}"> 
                        Del |
                    </apex:outputlink>
                </apex:column>
                <apex:column headerValue="Name">
                    <apex:outputLink value="/{!contacts.con.id}">
                        {!contacts.con.name}
                    </apex:outputLink>
                </apex:column>
                <apex:column headerValue="Account Name">
                    <apex:outputLink value="/{!contacts.con.account.id}">
                        {!contacts.con.account.name}
                    </apex:outputLink>
                </apex:column>
                <apex:column value="{!contacts.con.Title}"/>
                <apex:column value="{!contacts.con.Phone}"/>
                <apex:column value="{!contacts.con.email}"/>
                <apex:inlineEditSupport />
            </apex:PageBlockTable>
      		</apex:PageBlock> 
        <!-- below code for pagination -->
        <apex:outputPanel id="button"> 
        <div align = "center" >
            <!-- To return to first page of records-->
            <apex:commandButton action="{!first}" value="<<" title="First Page" disabled="{!!HasPrevious}" reRender="table,button"/>
            <!-- To return to Previous page of records-->
            <apex:commandButton action="{!previous}" value="Previous" disabled="{!!HasPrevious}" reRender="table,button"/>
            <!-- To return to next page of records-->
            <apex:commandButton action="{!next}" value="Next >" disabled = "{!!HasNext}" reRender="table,button"/>
            <!-- To return to last page of records-->
            <apex:commandButton action="{!last}" value=">>" title="Last Page" disabled="{!!HasNext}" reRender="table,button"/>
            <!-- InputText to display current page and to navigate to any page number, At righmost side of page-->
            <span style="float:right">
                <apex:outputLabel value="Page ">
                </apex:outputLabel>
                 <!-- To navigate to the page--> 
                <apex:InputText value="{!PageNumber}" maxLength="4" size="1"/>
                <apex:actionSupport event="onchange" action="{!NavigateByText}" reRender="table,button"/>
                <!-- The above action support is not working-->         
                <apex:outputLabel value=" of {!TotalPages}">
                </apex:outputLabel>
            </span>
            <!-- To display a list for number of records to be selected per page-->
            <span style = "float:left">
                <apex:SelectList value="{!RecordsPerPageslist}" size="1" >
                    <apex:selectOptions value="{!RecordsPerPageOptionList}">    
                    </apex:selectOptions>
                    <apex:actionSupport event="onchange" action="{!getChangeNumberOfRecordsPerPage}" reRender="table,button"/>
                </apex:SelectList>
            </span>
        </div>
    </apex:outputPanel>      
    </apex:form>
</apex:page>


 
In the followin code as soon as my page gets refreshed my record gets unchecked again,How can i avoid that?

Controller code:
public class t1 {
    list<contact> con = [SELECT Name,Account.name,Title,Phone,Email FROM Contact];
    public list<wrapper> allContactList;
    public list<contact> SelectedContact = new list<contact> ();
   
    public list<wrapper> getWrapperContacts(){  
        allContactList = new list<wrapper>();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        return allContactList;
    }

    public void getSelectedListContacts(){
        for(wrapper wc:allContactList){
            System.debug(wc.isSelected+' '+wc.con);
            if(wc.isSelected==true){
                SelectedContact.add(wc.con);
            }
        }
        System.debug(selectedContact);
    }
    public void getSelectedAllContacts(){			//To select all contacts
        for(wrapper wc:allContactList){
            SelectedContact.add(wc.con);
        	//new t1.wrapper().isSelected=true;
        }
    }
     public ApexPages.StandardSetController stdSetController{            //Instantiating a standard set controller
        get{
            if(stdSetController==null){
             	 stdSetController = new ApexPages.StandardSetController(con);
            }
              stdSetController.setPageSize(10);        //Limiting Number of records to be displayed per page 
               return stdSetController;   
        }
        set;
    }
    
    public class wrapper{
      public boolean isSelected{
          get{
              if(this.isSelected==null)
                this.isSelected = false;
            else
                this.isSelected = true;
              return isSelected;
          }
          set;
          }
      public Contact con{get;set;}
       
         wrapper(contact con){
           //isSelected = false;
            this.con = con;
        }
    }
}

VisualForce code:
<apex:page controller="t1" >
<apex:form >
<apex:pageBlock id="table">
<apex:commandButton action="{!getSelectedAllContacts}" value="Select All" reRender="table"/>
<apex:pageBlockTable value="{!WrapperContacts}" var="c">
<apex:column >
<apex:inputCheckbox value="{!c.isSelected}">
<apex:actionSupport event="onclick" action="{!getSelectedListContacts}" reRender="table"/>
</apex:inputCheckbox>
</apex:column>
<apex:column value="{!c.con.name}"/>
<apex:column value="{!c.con.title}"/>
</apex:pageBlockTable>
    <!-- To return to first page of records-->
           <apex:commandButton action="{!stdSetController.first}" value="<<" title="First Page" disabled="{!!stdSetController.HasPrevious}" reRender="table,button"/>
           <!-- To return to Previous page of records-->
           <apex:commandButton action="{!stdSetController.previous}" value="Previous" disabled="{!!stdSetController.HasPrevious}" reRender="table,button"/>
           <!-- To return to next page of records-->
           <apex:commandButton action="{!stdSetController.next}" value="Next >" disabled = "{!!stdSetController.HasNext}" reRender="table,button"/>
           <!-- To return to last page of records-->
            <apex:commandButton action="{!stdSetController.last}" value=">>" title="Last Page" disabled="{!!stdSetController.HasNext}" reRender="table,button"/>
</apex:pageBlock>
</apex:form>
</apex:page>

Here on this visualforce page i want to select number of records from the picklist given in the left bottom of the page and then display number of records as per it but, I am not able to fetch the value from picklist to my controller.Following is my visualforce and controller code:
VisualForce code:
<apex:page controller="ContactListViewController">
<apex:form >
<apex:PageBlock >
    <apex:PageBlockTable value="{!ContactList}" var="contacts">
    <apex:column headerValue="Name">
        <apex:outputLink value="/{!contacts.id}">
        {!contacts.name}
        </apex:outputLink>
    </apex:column>
    <apex:column headerValue="Account Name">
        <apex:outputLink value="/{!contacts.account.id}">
            {!contacts.account.name}
        </apex:outputLink>
    </apex:column>
    <apex:column value="{!contacts.Title}"/>
    <apex:column value="{!contacts.Phone}"/>
    <apex:column value="{!contacts.email}"/>
    <apex:inlineEditSupport />
    </apex:PageBlockTable>
    <!-- below code for pagination -->
    <div align = "center">
           <!-- To return to first page of records-->
           <apex:commandButton action="{!stdSetController.first}" value="<<" title="First Page" disabled="{!!stdSetController.HasPrevious}"/>
           <!-- To return to Previous page of records-->
           <apex:commandButton action="{!stdSetController.previous}" value="Previous" disabled="{!!stdSetController.HasPrevious}"/>
           <!-- To return to next page of records-->
           <apex:commandButton action="{!stdSetController.next}" value="Next >" disabled = "{!!stdSetController.HasNext}"/>
           <!-- To return to last page of records-->
            <apex:commandButton action="{!stdSetController.last}" value=">>" title="Last Page" disabled="{!!stdSetController.HasNext}"/>
           <!-- InputText to display current page and to navigate to any page number, At righmost side of page-->
           <span style="float:right">
                <apex:outputLabel value="Page ">
                </apex:outputLabel>
                <apex:InputText value="{!PageNumber}" maxLength="4" size="1"/>
                <!-- To navigate to the page-->
                
                <apex:outputLabel value=" of {!stdSetController.PageNumber}">
                </apex:outputLabel>
            </span>
            <!-- To display a list for number of records to be selected per page-->
            <span style = "float:left">
                <apex:SelectList value="{!RecordsPerPageslist}" size="1">
                    <apex:selectOptions value="{!RecordsPerPageOptionList}">
                    </apex:selectOptions>
                </apex:SelectList>
            </span>
            </div>

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

Controller code:
public class ContactListViewController {
    list<contact> con = [SELECT Name,Account.name,Title,Phone,Email FROM Contact];
        public ApexPages.StandardSetController stdSetController{
        get{
        stdSetController = new ApexPages.StandardSetController(con);
                return stdSetController;            
        }
        set;//what is use of this set, if we remove this then error is displayed!. 
        //The value is already set in the getter we just need to use that value not setting it
    }
    public Integer PageNumber{
        get{
            this.PageNumber=stdSetController.getPageNumber();
            return this.PageNumber;
        }
        set{
            stdSetController.setPageNumber(value);
        }
    }
    public Integer MaxNumberOfRecords{
        get{
        return stdSetController.getRecords().size();
        }
        set;
    }
    public list<SelectOption> getRecordsPerPageOptionList(){
        list<selectOption> options = new list<SelectOption>();
            options.add(new selectOption('10','10'));
            options.add(new selectOption('25','25'));
            options.add(new selectOption('50','50'));
            options.add(new selectOption('100','100'));
            options.add(new selectOption('200','200'));
            return options;
    }
    public Integer RecordsPerPageslist{
        get;set{
            if(value==null) 
                this.RecordsPerPageslist=10;
             else
                 this.RecordsPerPageslist=value;
        }    
    }
    public list<contact> getcontactList(){ 
       stdSetController.setPageSize(RecordsPerPageslist);
        return (list<contact>)stdSetController.getRecords();
    }
}

The error displayed on my page is:
Visualforce Error
Help for this Page
System.NullPointerException: Argument 1 cannot be null 
Class.ContactListViewController.getcontactList: line 41, column 1
I am iterating  a map using repeat on a vf page. I want to send the selected folder's id in the apex. I tried to use param but it is giving null values.Following is my code:
Page:
<apex:pageBlockSection id="FolderName" collapsible="true" title="Folder">
				<apex:repeat value="{!foMapNames}" var="fokey">
					<apex:commandLink value="{!foMapNames[fokey]}" action="{!folderIn}" reRender="none">
						<apex:param value="{!fokey}" assignTo="{!foId}"/>
					</apex:commandLink>
					<br/>
				</apex:repeat>
			</apex:pageBlockSection>

here fokey is null.
 
Can anyone please explain this statement :
global class ContactBatch implements Database.Batchable<sObject>{
}

As far as I know Database is a class in apex and batchable is an interface, So why can't we write as: 
global class ContactBatch implements Batchable{
}

Also, explain the syntax for <sObject> here
I am trying to change the "status" field(custom) of the contact object by using a batch. If I update the fields in the execute method then it gets updated but if I try to update it in the finish method then my list is empty. I am not getting this!
 
global class BatchNSchedulable implements Database.Batchable<sObject>{
	global list<contact> con=new list<contact>();
	String query = 'SELECT id,name,status__c FROM contact WHERE CreatedDate= Yesterday';
	global Database.QueryLocator start(Database.BatchableContext bc){
		System.debug('In the start');
		 return (Database.getQueryLocator(query));
	}
	global void execute(Database.BatchableContext bc,list<sObject> li){
		System.debug('In the execute');
		con = (list<contact>)li;
		System.debug(con.size());	
		for(contact ct:con){
			ct.put('status__c','None');
		}
		System.debug('con in execute is '+con);
	}
	global void finish(Database.BatchableContext bc){
		System.debug('con is '+con);
		update con;
		System.debug('In the finish');
	}

}

 
id i = 0037F00000M6MCHQA3;
String fieldNames='name,id';
String objName = 'contact';
String queryStr = 'SELECT ' + fieldNames + ' FROM ' + objName + ' WHERE id IN :(\'i\')';
System.debug(queryStr);

 
i encountered the following 
Schema.sObjectType.Account.fields.getmap()

Here what is getMap() method? In which class this method is defined, and what does it do? Also if you can give me more details about this method like can this method be over loaded,what is the return type of this etc etc
I have created a visualforce component and would like to use $Action.object name.action name($Action.Contact.Del) within it but i am getting the above error. Following is my controller and component code:
Component code
<apex:component controller ="PaginationForComponent">
    <apex:attribute name= "objectName" description = "The object's name" type = "String" required = "true" assignTo="{!objName}"/>
    <apex:attribute name= "fieldName" description = "Fields to be displayed" type = "String" required ="true" assignTo="{!fieldNames}"/>
<apex:outputLink value="{!URLFOR($Action."{!objName}".Edit,contacts.con.id)}"> 
                        Edit |
                    </apex:outputlink>
                    <apex:outputLink value="{!URLFOR($Action."{!objName}".Delete,contacts.con.id)}"> 
                        Del |
                    </apex:outputlink>

Controller code:
public class PaginationForComponent {
public String objName{get;set;}
	public String fieldNames{get;set;}
}

Ps: Only relevant code is provided here​
String objName = 'Contact';
string alphaSearchConct = 'A';
String fieldNames = 'name,id';
list<sObject> ct = Database.query('SELECT '+ fieldNames +'FROM '+ objName +'WHERE lastname Like:'+alphaSearchConct +'%');

 
In th following code the action support for my input text field is not working as it should work(Line number 69-70 in vf code).I want to navigate to the page number entered by the user.Following is my controller and VF code:
Code for controller
public class ContactListViewController {
    public ContactlistViewController(){
        system.debug('constructor first called');
        RecordsPerPageslist=10;
        allContactList = new list<wrapper>();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c));
        System.debug('constructor called');
    }
    Map<id,Boolean> m = new Map<id,boolean>();  	 // To store boolean values of checkboxes corrosponding to every contact id
    list<contact> con = [SELECT Name,id,Account.name,Title,Phone,Email FROM Contact];
    public list<wrapper> allContactList;			//Wrapper class object
    
    public list<wrapper> getWrapperContacts(){  	//List of wrapper class to display in table
        return allContactList;
    }
    
    public void getSelectedListContacts(){  		// Select contacts and save them in a map
        for(wrapper wc:allContactList){
            m.put(wc.con.id,wc.isSelected);
        }
        
        System.debug('getSelectedListContacts = '+m);
        
    }
    public void getSelectedAllContacts(){			//To select all contacts in a page
        for(wrapper wc:allContactList){
            m.put(wc.con.id,wc.isSelected=true);
        }
    }
    public void next(){
        System.debug('next');
		allContactList.clear();        
        this.stdSetController.next();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
        }
    }
    public void previous(){
		allContactList.clear();        
        this.stdSetController.previous();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
    }
    }
    public void last(){
        allContactList.clear();        
        this.stdSetController.last();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
    }
    }
    public void first(){
        allContactList.clear();        
        this.stdSetController.first();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
    }
    }
    public boolean getHasNext(){
        return stdSetController.getHasNext();
    }
    public boolean getHasPrevious(){
        return stdSetController.getHasPrevious();
    }
    public list<String> alphabet{
        get{															//To display a list of alphabets on vf page 
            alphabet = 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','Others','All'};
       		return alphabet;	 
                }
        set;
    }
    public String alphaSearchConct{get;set;}							// To get commandlink parameter for alphabet selected
    public Pagereference getalphaSearch(){								//To update contact list as per the alphabet selected by the user
        allContactList.clear();
        if (alphaSearchConct=='All'){
            con = [SELECT name,Account.name,Title,Phone,Email FROM contact];
        }
        else{
            	con = [SELECT name,Account.name,Title,Phone,Email FROM contact WHERE lastName Like:alphaSearchConct+'%'];
        }
        ApexPages.StandardSetController ssc = new ApexPages.StandardSetController(con);
        stdSetController= ssc;
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c));
        system.debug('alphaSearchconct called');
        return null;
    }      
    public Integer PageNumber{
        get{                                                            //To get current page number
  		    System.debug('get of pageNumber called '+ PageNumber);
            this.PageNumber=stdSetController.getPageNumber();   
            return this.PageNumber;
        }
        set{  
            System.debug('set of pageNumber called');
           	this.pageNumber=value;         
    }
        }
    
    public PageReference NavigateByText(){
        
        System.debug('getNavigateByText '+ stdSetController.getPageNumber());
        allContactList.clear();
        this.stdSetController.setPageNumber(PageNumber);
            for(contact c:(list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c));
            //System.debug(stdSetController.getRecords());
           for(wrapper wc:allContactList){
            wc.isSelected=m.get(wc.con.id);
               System.debug(wc.isSelected);
               System.debug('pageNumber called');
               
    }
        return null;
    }
    public Integer TotalPages{                                            // Total number of pages as per user selection of Records per page
        get{
              if(stdSetController.getResultSize() <=10)
                   this.TotalPages=1;
              if(Math.Mod(stdSetController.getResultSize() ,stdSetController.getPageSize()) == 0)
                  this.TotalPages =(stdSetController.getResultSize()/stdSetController.getPageSize());
              else
                this.TotalPages = (stdSetController.getResultSize()/stdSetController.getPageSize())+1;
              //System.Debug(this.TotalPages);
                return totalpages;
        }
        set;
    }
    public Integer MaxNumberOfRecords{                                    //Maximum number of records in a query list
        get{
             return stdSetController.getRecords().size();
        }
        set;
    }
    public list<SelectOption> getRecordsPerPageOptionList(){              //To display a drop down list on vf page  
            list<SelectOption>  options = new list<SelectOption>();
            options.add(new selectOption('10','10'));
            options.add(new selectOption('25','25'));
            options.add(new selectOption('50','50'));
            options.add(new selectOption('100','100'));
            options.add(new selectOption('200','200'));
            return options;
    }
    public Integer RecordsPerPageslist{ 
        get;
        set{                                                          //To select number of records per page
            if(value!=null){
                this.RecordsPerPagesList=value;
                System.debug('RecordsPerPageList called');
            }
        }       
    }
    public Pagereference getChangeNumberOfRecordsPerPage(){
        allContactList.clear();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
         for(wrapper wc:allContactList)
            wc.isSelected=m.get(wc.con.id);
        return null;
    } 
    public ApexPages.StandardSetController stdSetController{            //Instantiating a standard set controller
        get{
            if(stdSetController==null){
             	 stdSetController = new ApexPages.StandardSetController(con);
            }
              stdSetController.setPageSize(RecordsPerPageslist);        //Limiting Number of records to be displayed per page 
            	System.debug('stdSetController called '+ stdSetController.getPageNumber());
            return stdSetController;   
        }
        set;
    }
    public class wrapper{
      public boolean isSelected{get;set;}
      public Contact con{get;set;}
       
         wrapper(contact con){
            isSelected = false;
            this.con = con;
        }
    }
}
Code for VF page:
<apex:page controller="ContactListViewController" sidebar="false">
    <apex:form >
        <!-- For alphabetic search-->
        <div align="right">
            <apex:panelGrid >
                <apex:repeat value="{!alphabet}" var="alph">
                    <apex:commandLink value="{!alph} | " action="{!getalphaSearch}" reRender="table">
                        <apex:param name="a" value="{!alph}" assignTo="{!alphaSearchConct}"/>
                    </apex:commandLink>
                </apex:repeat>
            </apex:panelGrid>
        </div>
        <apex:PageBlock id="table">
            <apex:pageMessages />
            <apex:commandButton action="{!getSelectedAllContacts}" value="Select All" reRender="table"/>
            <apex:PageBlockTable value="{!WrapperContacts}" var="contacts" >
                <!-- To display and select Checkboxes-->
                <apex:column >
                    <apex:facet name="header">
                    	<apex:inputCheckbox value="{!contacts.isSelected}">
                        	<apex:actionSupport event="onclick" action="{!getSelectedAllContacts}" reRender="table"/>
                        </apex:inputCheckbox>	
                        </apex:facet>
                    <apex:inputCheckbox value="{!contacts.isSelected}">
                        <apex:actionSupport event="onclick" action="{!getSelectedListContacts}" reRender="table"/>
                    </apex:inputCheckbox>  
                </apex:column>
                <!-- To Edit and Delete a record -->
                <apex:column headerValue="Action">
                    <apex:outputLink value="{!URLFOR($Action.Contact.Edit,contacts.con.id)}"> 
                        Edit |
                    </apex:outputlink>
                    <apex:outputLink value="{!URLFOR($Action.Contact.Delete,contacts.con.id)}"> 
                        Del |
                    </apex:outputlink>
                </apex:column>
                <apex:column headerValue="Name">
                    <apex:outputLink value="/{!contacts.con.id}">
                        {!contacts.con.name}
                    </apex:outputLink>
                </apex:column>
                <apex:column headerValue="Account Name">
                    <apex:outputLink value="/{!contacts.con.account.id}">
                        {!contacts.con.account.name}
                    </apex:outputLink>
                </apex:column>
                <apex:column value="{!contacts.con.Title}"/>
                <apex:column value="{!contacts.con.Phone}"/>
                <apex:column value="{!contacts.con.email}"/>
                <apex:inlineEditSupport />
            </apex:PageBlockTable>
      		</apex:PageBlock> 
        <!-- below code for pagination -->
        <apex:outputPanel id="button"> 
        <div align = "center" >
            <!-- To return to first page of records-->
            <apex:commandButton action="{!first}" value="<<" title="First Page" disabled="{!!HasPrevious}" reRender="table,button"/>
            <!-- To return to Previous page of records-->
            <apex:commandButton action="{!previous}" value="Previous" disabled="{!!HasPrevious}" reRender="table,button"/>
            <!-- To return to next page of records-->
            <apex:commandButton action="{!next}" value="Next >" disabled = "{!!HasNext}" reRender="table,button"/>
            <!-- To return to last page of records-->
            <apex:commandButton action="{!last}" value=">>" title="Last Page" disabled="{!!HasNext}" reRender="table,button"/>
            <!-- InputText to display current page and to navigate to any page number, At righmost side of page-->
            <span style="float:right">
                <apex:outputLabel value="Page ">
                </apex:outputLabel>
                 <!-- To navigate to the page--> 
                <apex:InputText value="{!PageNumber}" maxLength="4" size="1"/>
                <apex:actionSupport event="onchange" action="{!NavigateByText}" reRender="table,button"/>
                <!-- The above action support is not working-->         
                <apex:outputLabel value=" of {!TotalPages}">
                </apex:outputLabel>
            </span>
            <!-- To display a list for number of records to be selected per page-->
            <span style = "float:left">
                <apex:SelectList value="{!RecordsPerPageslist}" size="1" >
                    <apex:selectOptions value="{!RecordsPerPageOptionList}">    
                    </apex:selectOptions>
                    <apex:actionSupport event="onchange" action="{!getChangeNumberOfRecordsPerPage}" reRender="table,button"/>
                </apex:SelectList>
            </span>
        </div>
    </apex:outputPanel>      
    </apex:form>
</apex:page>


 
In the followin code as soon as my page gets refreshed my record gets unchecked again,How can i avoid that?

Controller code:
public class t1 {
    list<contact> con = [SELECT Name,Account.name,Title,Phone,Email FROM Contact];
    public list<wrapper> allContactList;
    public list<contact> SelectedContact = new list<contact> ();
   
    public list<wrapper> getWrapperContacts(){  
        allContactList = new list<wrapper>();
        for(contact c: (list<contact>)stdSetController.getRecords())
                allContactList.add(new wrapper(c)); 
        return allContactList;
    }

    public void getSelectedListContacts(){
        for(wrapper wc:allContactList){
            System.debug(wc.isSelected+' '+wc.con);
            if(wc.isSelected==true){
                SelectedContact.add(wc.con);
            }
        }
        System.debug(selectedContact);
    }
    public void getSelectedAllContacts(){			//To select all contacts
        for(wrapper wc:allContactList){
            SelectedContact.add(wc.con);
        	//new t1.wrapper().isSelected=true;
        }
    }
     public ApexPages.StandardSetController stdSetController{            //Instantiating a standard set controller
        get{
            if(stdSetController==null){
             	 stdSetController = new ApexPages.StandardSetController(con);
            }
              stdSetController.setPageSize(10);        //Limiting Number of records to be displayed per page 
               return stdSetController;   
        }
        set;
    }
    
    public class wrapper{
      public boolean isSelected{
          get{
              if(this.isSelected==null)
                this.isSelected = false;
            else
                this.isSelected = true;
              return isSelected;
          }
          set;
          }
      public Contact con{get;set;}
       
         wrapper(contact con){
           //isSelected = false;
            this.con = con;
        }
    }
}

VisualForce code:
<apex:page controller="t1" >
<apex:form >
<apex:pageBlock id="table">
<apex:commandButton action="{!getSelectedAllContacts}" value="Select All" reRender="table"/>
<apex:pageBlockTable value="{!WrapperContacts}" var="c">
<apex:column >
<apex:inputCheckbox value="{!c.isSelected}">
<apex:actionSupport event="onclick" action="{!getSelectedListContacts}" reRender="table"/>
</apex:inputCheckbox>
</apex:column>
<apex:column value="{!c.con.name}"/>
<apex:column value="{!c.con.title}"/>
</apex:pageBlockTable>
    <!-- To return to first page of records-->
           <apex:commandButton action="{!stdSetController.first}" value="<<" title="First Page" disabled="{!!stdSetController.HasPrevious}" reRender="table,button"/>
           <!-- To return to Previous page of records-->
           <apex:commandButton action="{!stdSetController.previous}" value="Previous" disabled="{!!stdSetController.HasPrevious}" reRender="table,button"/>
           <!-- To return to next page of records-->
           <apex:commandButton action="{!stdSetController.next}" value="Next >" disabled = "{!!stdSetController.HasNext}" reRender="table,button"/>
           <!-- To return to last page of records-->
            <apex:commandButton action="{!stdSetController.last}" value=">>" title="Last Page" disabled="{!!stdSetController.HasNext}" reRender="table,button"/>
</apex:pageBlock>
</apex:form>
</apex:page>

Here on this visualforce page i want to select number of records from the picklist given in the left bottom of the page and then display number of records as per it but, I am not able to fetch the value from picklist to my controller.Following is my visualforce and controller code:
VisualForce code:
<apex:page controller="ContactListViewController">
<apex:form >
<apex:PageBlock >
    <apex:PageBlockTable value="{!ContactList}" var="contacts">
    <apex:column headerValue="Name">
        <apex:outputLink value="/{!contacts.id}">
        {!contacts.name}
        </apex:outputLink>
    </apex:column>
    <apex:column headerValue="Account Name">
        <apex:outputLink value="/{!contacts.account.id}">
            {!contacts.account.name}
        </apex:outputLink>
    </apex:column>
    <apex:column value="{!contacts.Title}"/>
    <apex:column value="{!contacts.Phone}"/>
    <apex:column value="{!contacts.email}"/>
    <apex:inlineEditSupport />
    </apex:PageBlockTable>
    <!-- below code for pagination -->
    <div align = "center">
           <!-- To return to first page of records-->
           <apex:commandButton action="{!stdSetController.first}" value="<<" title="First Page" disabled="{!!stdSetController.HasPrevious}"/>
           <!-- To return to Previous page of records-->
           <apex:commandButton action="{!stdSetController.previous}" value="Previous" disabled="{!!stdSetController.HasPrevious}"/>
           <!-- To return to next page of records-->
           <apex:commandButton action="{!stdSetController.next}" value="Next >" disabled = "{!!stdSetController.HasNext}"/>
           <!-- To return to last page of records-->
            <apex:commandButton action="{!stdSetController.last}" value=">>" title="Last Page" disabled="{!!stdSetController.HasNext}"/>
           <!-- InputText to display current page and to navigate to any page number, At righmost side of page-->
           <span style="float:right">
                <apex:outputLabel value="Page ">
                </apex:outputLabel>
                <apex:InputText value="{!PageNumber}" maxLength="4" size="1"/>
                <!-- To navigate to the page-->
                
                <apex:outputLabel value=" of {!stdSetController.PageNumber}">
                </apex:outputLabel>
            </span>
            <!-- To display a list for number of records to be selected per page-->
            <span style = "float:left">
                <apex:SelectList value="{!RecordsPerPageslist}" size="1">
                    <apex:selectOptions value="{!RecordsPerPageOptionList}">
                    </apex:selectOptions>
                </apex:SelectList>
            </span>
            </div>

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

Controller code:
public class ContactListViewController {
    list<contact> con = [SELECT Name,Account.name,Title,Phone,Email FROM Contact];
        public ApexPages.StandardSetController stdSetController{
        get{
        stdSetController = new ApexPages.StandardSetController(con);
                return stdSetController;            
        }
        set;//what is use of this set, if we remove this then error is displayed!. 
        //The value is already set in the getter we just need to use that value not setting it
    }
    public Integer PageNumber{
        get{
            this.PageNumber=stdSetController.getPageNumber();
            return this.PageNumber;
        }
        set{
            stdSetController.setPageNumber(value);
        }
    }
    public Integer MaxNumberOfRecords{
        get{
        return stdSetController.getRecords().size();
        }
        set;
    }
    public list<SelectOption> getRecordsPerPageOptionList(){
        list<selectOption> options = new list<SelectOption>();
            options.add(new selectOption('10','10'));
            options.add(new selectOption('25','25'));
            options.add(new selectOption('50','50'));
            options.add(new selectOption('100','100'));
            options.add(new selectOption('200','200'));
            return options;
    }
    public Integer RecordsPerPageslist{
        get;set{
            if(value==null) 
                this.RecordsPerPageslist=10;
             else
                 this.RecordsPerPageslist=value;
        }    
    }
    public list<contact> getcontactList(){ 
       stdSetController.setPageSize(RecordsPerPageslist);
        return (list<contact>)stdSetController.getRecords();
    }
}

The error displayed on my page is:
Visualforce Error
Help for this Page
System.NullPointerException: Argument 1 cannot be null 
Class.ContactListViewController.getcontactList: line 41, column 1
 query = 'Select ' + CorrespondingFields + ' from ' + AllObjectsList;

Here,  object and fields of that object both are dynamic.
pls help how to display records in table on visualforce page.
Hi,
What is Schema.sObjectType in this satatement ?
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();

I am unable to know exactly..
Thanks in Advance,
Anji
I was solving this challenge and my VF code is:

<apex:page standardController="Account" recordSetVar="Accounts" >
    <apex:pageblock>
        <apex:repeat var="a" value="{!Accounts}" rendered="true"  id="account_list">
            <li>
                <apex:outputLink value="https://ap1.salesforce.com/{!a.ID}" >
                    <apex:outputText value="{!a.Name}"/>
                </apex:outputLink>
            </li>
        </apex:repeat>
    </apex:pageblock>
</apex:page>

I am getting the list of accounts as required and on clicking on any of the accouts, it redirects to that accounts detail page.
Still I am getting following error from trailhead:

"The page does not bind to the record ID value (in order to link to the record detail page)"
Hello developer heroes!

I'm working through the Apex modules on Trailhead and can't seem to get past this one: https://developer.salesforce.com/en/trailhead/force_com_programmatic_beginner/apex_triggers/apex_triggers_bulk.

Hopefully this doesn't read like a 'please complete the course for me' kinda post, but I have written a trigger that I believe meets the criteria but it isn't passing the check, so I wanted to seek the guidance of the experts.

The challenge is to do this:

Create an Apex trigger for Opportunity that adds a task to any opportunity set to 'Closed Won'.

To complete this challenge, you need to add a trigger for Opportunity. The trigger will add a task to any opportunity inserted or updated with the stage of 'Closed Won'. The task's subject must be 'Follow Up Test Task'.The Apex trigger must be called 'ClosedOpportunityTrigger'

- With 'ClosedOpportunityTrigger' active, if an opportunity is inserted or updated with a stage of 'Closed Won', it will have a task created with the subject 'Follow Up Test Task'.
- To associate the task with the opportunity, fill the 'WhatId' field with the opportunity ID.
- This challenge specifically tests 200 records in one operation.


And here is the trigger I have come up with, which compiles OK and stands up to a manual (though admittedly unbulkified) test:
trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {

    List<Task> taskList = new List<Task>();
    
    for (Opportunity opp : [SELECT Id, StageName FROM Opportunity WHERE StageName = 'Closed Won' AND Id IN :Trigger.new]){
                    
            taskList.add(new Task(Subject = 'Follow Up Test Task',
                                  WhatId = opp.Id));
       
    }

    if(taskList.size()>0){
        
        insert taskList;
        
    }
    
}
I have tried replacing the SOQL with a straightforward 'for (Opportunity opp : Trigger.new)' and having the taskList.add inside an IF that checks for Closed Won - no luck. I also thought about checking to see if the stage was being changed to Closed Won, rather than the trigger firing on every edit, but I don't think this is what the module is asking for.

Where do you think I'm going wrong?

Huge thanks in advance!