I have a VisualForce for create Cases, this VisualForce is going to be embedded on a Site, so the VisualForce it is built on HTML and inside the HTML I put the following :
<apex:page applyHtmlTag="false" showHeader="false" sidebar="false" docType="" Controller="MyController">
<html>
<body>
<!--
HTML PAGE
-->
<div id="FileUpload" class="row">
<apex:form enctype="multipart/form-data" id="FileUploadForm">
<apex:pageMessages id="TheMessage" />
<apex:pageBlock>
<apex:pageBlockSection showHeader="false" columns="2" id="block1">
<apex:pageBlockSectionItem >
<apex:outputLabel value="File" for="file"/>
<apex:inputFile value="{!document.body}" filename="{!strFileName}" id="file"/>
</apex:pageBlockSectionItem>
<apex:commandButton action="{!cargarArchivo}" value="Cargar Archivo" reRender="TheMessage"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</div>
</body>
</html>
</apex:page>
And the Controller is:
public String strFileName {get; set;}
public Document document {
get {
if (document == null)
document = new Document();
return document;
}
set;
}
public void cargarArchivo() {
document.AuthorId = UserInfo.getUserId();
document.FolderId = '00l29000000L2uH';
document.name = strFileName;
document.description = strFileName;
document.keywords = strFileName;
try {
insert document;
} catch (Exception e) {
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error cargando el archivo, por favor intente nuevamente'));
return;
} finally {
document.body = null; // clears the viewstate
document = new Document();
}
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Archivo cargado con éxito.'));
}
Up to here everything works very well, but when y add the reRender to the commandButton, like this:
<apex:commandButton action="{!cargarArchivo}" value="Cargar Archivo" reRender="TheMessage"/>
I get the following error:
3_3_3.Finalorg.ajax4jsf.javascript.AjaxScript:178
Uncaught TypeError: actionUrl.indexOf is not a function
at A4J.Query.getActionUrl (3_3_3.Finalorg.ajax4jsf.javascript.AjaxScript:178)
at A4J.AJAX.XMLHttpRequest.send (3_3_3.Finalorg.ajax4jsf.javascript.AjaxScript:67)
at Object.A4J.AJAX.SubmitQuery (3_3_3.Finalorg.ajax4jsf.javascript.AjaxScript:125)
at Object.A4J.AJAX.Submit (3_3_3.Finalorg.ajax4jsf.javascript.AjaxScript:126)
at HTMLInputElement.onclick (RF2_CrearCasoWeb_pag?negocio=WEB_GIE:559)
You can either use re-render or you can use inputfile tag. They can not be used together, as the error states.
Your page messages re-rendered automatically without mentioned. So you don't worry about that.
As a best practice you can use iframe tag, which embeds an independent HTML document into the current document.
Related
Project Requirement:-create new record when candidate's PAN is not blacklisted, if it is blacklisted then show warning message on visualforce page and update new phone number in blacklisted candidate object.
Pre exquisite:- i have two object 1.Sudent_matster__c : Fields:- Name, Phone__c, PAN__c, email__c etc 2.Black_Listed_Candidate__c Fields:- Name, Phone__c, PAN__c etc
QUESTION When i enter blacklisted field PAN- FHSJF10387 then this code runs perfectly fine, but i enter another blacklisted field PAN- DKFIT8888S,CNYY78912Q, RYHJI997Q.etc. then code wont work. why? i think old value should be cleared from memory?
Visual force page IMAGE [This is visualforce page ][1] [1]: https://i.stack.imgur.com/aLzjo.png
VFP CODE
<apex:page Controller="Class_Practice">
<apex:form id="frm" html-autocomplete="off" style="border-style:solid;border-width:2px;border-color:black;background-color:lightyellow">
<H1 style="text-align:center;font-size:30px;">PAN DATA CHECK</H1>
<apex:pageBlock >
<apex:pageMessages></apex:pageMessages>
<apex:pageBlockSection title="My Content Section" columns="2">
<apex:inputField value="{!newStudent.Name}"/>
<apex:inputField value="{!newStudent.First_Name__c}"/>
<apex:inputField value="{!newStudent.Last_Name__c}"/>
<apex:inputField value="{!newStudent.Email__c}"/>
<apex:inputField value="{!newStudent.Phone__c}"/>
<apex:inputField value="{!newStudent.PAN__c}"/>
<Apex:commandButton value="Save" Action="{!MySave}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
APEX CLASS Code
public class Class_Practice
{
public Student_Master__c newStudent {get;set;}
Map<Id, string> IdAndBlackListPhoneMap = New Map<Id, string>();
public static list< Black_Listed_Candidate__c> blackList =[SELECT Name,PAN__c,Phone__c FROM Black_Listed_Candidate__c];
public Class_Practice()
{
newStudent = new Student_Master__c();
}
public pageReference MySave()
{
for(Black_Listed_Candidate__c bp:blacklist)
{
if (bp.PAN__c==newStudent.PAN__c )
{
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'PAN is Black Listed'));
bp.Phone__c = newStudent.Phone__c;
IdAndBlackListPhoneMap.put(bp.Id, bp.Phone__c);
Update blacklist;
return null;
}
else
{
insert newStudent;
PageReference pg = new PageReference('/' + newStudent.Id);
pg.setRedirect(true);
return pg;
}
}
return null;
}
}
THANK YOU
I want to add a custom VF component to display the batch job details in a pageblock table. However my component aint saving, it says: Error Error: Read only property 'c:batchDetailsComponent.BatchJobDetails'
Please help.
This is the visualforce component:
<apex:component controller="BatchOpportunityDetailsExtension">
<apex:attribute name="batchJob" type="List" assignTo="{!BatchJobDetails}" description="" />
<apex:form >
<apex:pageBlock>
<apex:pageblockTable value="{!batchJob}" var="batch">
<apex:column value="{!batch.CompletedDate}"/>
<apex:column value="{!batch.JobItemsProcessed}"/>
<apex:column value="{!batch.NumberOfErrors}"/>
</apex:pageblockTable>
</apex:pageBlock>
</apex:form>
</apex:component>
VF Page:
<apex:page standardController="Opportunity_Scheduled_Information__c"
extensions="BatchOpportunityDetailsExtension">
<c:oppScheduleComponent componentValue="{!batchJob}"/>
</apex:page>
Controller:
public class BatchOpportunityDetailsExtension {
public List<AsyncApexJob> batchJobDetails = new List<AsyncApexJob>();
public Opportunity_Scheduled_Information__c pageController {get;set;}
public BatchOpportunityDetailsExtension() {}
public BatchOpportunityDetailsExtension(ApexPages.StandardController controller) {
controller.addFields(new List<String>{'Total_Amount__c', 'Number_of_Opportunities__c'});
pageController = (Opportunity_Scheduled_Information__c)controller.getRecord();
BatchJobDetails = [ SELECT id,ApexClassID,CompletedDate,JobType,JobItemsProcessed,NumberOfErrors,MethodName,Status,ExtendedStatus,TotalJobItems FROM AsyncApexJob WHERE ApexClassId='01p7F000000bKIlQAM' LIMIT 50] ;
}
public List<AsyncApexJob> getBatchJobDetails()
{
return BatchJobDetails ;
}
}
You need to set the access for your component to global.
Like this: <apex:component access="global" controller="BatchOpportunityDetailsExtension">
I have a visualforce page that has a picklist called Topic and sometimes I will need to select one of the picklist options upon page load (meaning the Topic will be passed on from another page and will need to be selected upon loading the page for the first time). I'm not sure how to do this? I'm posting part of the Visualforce page that handles topic selection and the Controller code that below. Any help would be appreciated.Thanks.
Visualforce page:
<!---------------------------------- Select Topic ----------------------------------------------------->
<apex:pageblockSection title="Select the Topic" >
<apex:selectList value="{!topic}" size="1">
<apex:outputlabel for="Topic" value="Pick a Topic :" ></apex:outputlabel>
<apex:selectOptions id="topic" value="{!Topics}"/>
<apex:actionSupport action="{!populateParameters}" reRender="parametersSection,querySection" event="onchange"/>
</apex:selectList>
</apex:pageblockSection>
<!---------------------------------- End of Select Topic ---------------------------->
<!---------------------------------- Parameters for Topic ----------------------------------------------------->
<apex:pageblockSection id="parametersSection" title="Input Parameters">
<apex:repeat value="{!topicpParamWrapperList}" var="params">
<apex:outputPanel >
<apex:outputlabel value="{!params.parameter.Name}" ></apex:outputlabel>
<apex:inputfield value="{!params.parameter.inputValue__c}" rendered="{!params.renderAsText}">
<apex:actionsupport action="{!placeValuesInQuery}" reRender="querySection,splunUrlLink" event="onchange"/>
</apex:inputfield>
<apex:inputfield value="{!params.parameter.DateTimeValueHolder__c}" rendered="{!params.renderAsDate}">
<apex:actionsupport action="{!placeValuesInQuery}" reRender="querySection,splunUrlLink" event="onchange"/>
</apex:inputfield>
</apex:outputPanel>
</apex:repeat>
</apex:pageblockSection>
<!---------------------------------- End of Parameters for Topic ----------------------------------------------------->
Apex Controller
public List < topicpParamWrapper > topicpParamWrapperList {
get;
set;
} {
topicpParamWrapperList = new List < topicpParamWrapper >();
}
public void populateParameters()
{
if(!topicpParamWrapperList.isEmpty())
{
topicpParamWrapperList.clear();
}
if(topic!='' && topic!=Null)
{
for(Query_Parameter__c qParam :[select id, Parameters__r.Variable_Name__c, Parameters__r.Type__c,Parameters__r.Name from Query_Parameter__c where Topics__c=:topic])
{
Parameters__c param = new Parameters__c();
param.Name =qParam.Parameters__r.Name ;
param.type__c = qParam.Parameters__r.type__c;
param.Variable_Name__c=qParam.Parameters__r.Variable_Name__c;
topicpParamWrapperList.add(new topicpParamWrapper(param));
}
getQueryToRun();
}
}
public void getqueryToRun(){
if(mapTopics.containsKey(topic))
{
this.queryToRun =mapTopics.get(topic).query__c;
this.queryMain=mapTopics.get(topic).query__c;
}
}
public List < topicpParamWrapper > paramList {
get;
set;
} {
paramList = new List <topicpParamWrapper>();
}
All you really have to do is to set the topic to some initial value in the constructor (the special function that has name identical to class' name). You set it to some value and then it'll be rendered properly in visualforce (assuming same value is one of the selectable options!).
You have omitted the constructor or <apex:page> tag so we don't know how you're navigating to that page. But probably easiest for you would be to pass the topic in the URL. So if you access the page like that:
/apex/MyPage?topic=Something, something
then in the constructor you could do this:
topic = ApexPages.currentPage().getParameters().get('topic');
(the name of the URL parameter doesn't have to be same as the variable name but it makes sense to have them at least similar)
You can read more about getParameters()
If there is risk that your topic will contain &, spaces etc you probably should URLENCODE it when building the link.
I have a page that needs to pass data to another page. They both use the same controller, but the second page has its own controller extension. When the first page passes data to the second page, the second page will recall the constructor of the controller. If I remove the controller extension from the second page, data can be passed and the constructor is only called on the first page, not on the second.
How can I pass state from one page to another, if both pages use the same controller, but one page uses a controller extension?
For example, in the following code, if I enter data in the outputText for the variable t and then go to the next page, the state won't save, the constructor will be recalled, and the value for t on page 2 will be "construct". If the testExtension is removed from the second page, then everything works fine.
apex/test1
VisualForce
<apex:page controller="test">
<apex:outputText value="{!t}" />
<apex:commandButton action="/test2" value="Go to test2" />
</apex:page>
Controller
class test {
public String t {get; set;}
public test() {
t = 'construct';
}
}
apex/test2 VisaulForce
<apex:page controller="test" extension="testExtension">
<apex:outputLabel value="{!t}" />
</apex:page>
controller extension:
class testExtension {
public testExtension(test controller) {
}
}
public with sharing class Fake01_Controller {
public String fake02String {get;set;}
public PageReference fake03Submit() {
PageReference prToNavigate = null;
prToNavigate = Page.Fake_02;
return prToNavigate;
}
}
Fake 01 page:
<apex:form >
<apex:inputText value="{!fake02String}" />
<apex:commandButton action="{!fake03Submit}"
value="Navigate to Fake 02"
/>
</apex:form>
Fake 02 page:
<apex:form >
<apex:outputText value="{!fake02String}" />
</apex:form>
Please, read PageReference about setRedirect method:
If set to false, the redirect is a server-side forward that preserves
the view state if and only if the target page uses the same controller
and contains the proper subset of extensions used by the source page.
class test {
public String t {get; set;}
public test() {
t = 'construct';
}
public PageReference test2() {
return page.test2;
}
}
<apex:page controller="test">
<apex:outputText value="{!t}" />
<apex:commandButton action="{!test2)" value="Go to test2" />
</apex:page>
I have a data table which iterates through a custom object and generates checkboxes. On the second page, I want to determine which of these checkboxes have been selected.
In the VisualForce page:
Age <apex:inputText value="{!age}" id="age" />
<apex:dataTable value="{!Areas}" var="a">
<apex:column >
<apex:inputCheckbox value="{!a.name}" /> <apex:outputText value="{!a.name}" />
</apex:column>
</apex:dataTable>
In the Controller:
public String age {get; set; }
public List<Area_Of_Interest__c> getAreas() {
areas = [select id, name from Area_Of_Interest__c];
return areas;
}
On my second page, I can retrieve the value that the user put in the textbox "age" by using {!age}. How Do I retrieve which checkboxes have been checked?
Thank you.
Ok, if you want to handle it with Javascript, use Pavel's method, otherwise use the following to do it via the controller. You must create a wrapper class for whatever you wish to track. I'm not sure how it works, but somehow if you name a boolean variable "selected" in your wrapper class, it is mapped to the checkbox. Below is the code:
So in your Visual force page, do:
<apex:dataTable value="{!Foos}" var="f">
<apex:column >
<apex:outputLabel value="{!f.foo.name}" /> <apex:inputCheckbox value="{!f.selected}" />
</apex:column>
</apex:dataTable>
<apex:commandButton action="{!getPage2}" value="go"/>
In your Controller, do the following:
1) Make a Wrapper class with the boolean "selected", which somehow maps to the inputCheckbox selected:
public class wFoo {
public Foo__c foo {get; set}
public boolean selected {get; set;}
public wFoo(Foo__c foo) {
this.foo = foo;
selected = false; //If you want all checkboxes initially selected, set this to true
}
}
2) declare the list variables
public List<wFoo> foos {get; set;}
public List<Foo__c> selectedFoos {get; set;}
3) Define the accessor for the List
public List<wFoo> getFoos() {
if (foos == null) {
foos = new List<wFoo>();
for (Foo__c foo : [select id, name from Foo__c]) {
foos.add(new wFoo(foo));
}
}
return foos;
}
4) Define the method to process the selected checkboxes and place them in a List for use on another page
public void processSelectedFoos() {
selectedFoos = new List<Foo__c>();
for (wFoo foo : getFoos) {
if (foo.selected = true) {
selectedFoos.add(foo.foo); // This adds the wrapper wFoo's real Foo__c
}
}
}
5) Define the method to return the PageReference to the next page when the submit button is clicked
public PageReference getPage2() {
processSelectedFoos();
return Page.Page2;
}
In my current project I had faced with the same issue. I used apex:pageBlockTable, but I guess that you can use my code (I made some changes in my code for an object names)
<apex:pageBlockTable value="{!Areas}" var="areas">
<apex:column width="25px">
<apex:facet name="header">
<input type="checkbox" onClick="selectAll();" />
</apex:facet>
<input type="checkbox" id="{!areas.Id}" onClick="saveSelection();" />
</apex:column>
... some additional columns
</apex:pageBlockTable>
I had placed custom object ids to the input id in html, and it looks as
<input id="003R000000lCIq6IAG" onclick="saveSelection();" type="checkbox">
<input id="003R000000lCIoJIAW" onclick="saveSelection();" type="checkbox">
The saveSelection() function has written on javascript
<script>
var areaIds = [];
function saveSelection() {
var selectedIds = areaIds.join('');
$j(':checkbox').each(function(){
if (this.checked) {
if (selectedIds.indexOf(this.id) === -1) {
areaIds.push(this.id);
selectedIds = selectedIds + this.id;
}
} else {
if (selectedIds.indexOf(this.id) !== -1) {
for (i=0; i < areaIds.length; i++) {
if (areaIds[i] === this.id) {
areaIds.splice(i, 1);
selectedIds = areaIds.join('');
}
}
}
}
});
}
and for the restoring was used the following code
function restoreSelection() {
contIds = areaIds.join('');
i = 0;
$j(':checkbox').each(function(){ if(this.id !== ''){ if(contIds.indexOf(this.id) !== -1){this.checked=true;};}});
}
I use jQuery here, that means you should include the following code to your page too
<apex:includeScript id="JQuery" value="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"/>
... some code
<script>
window.$j = jQuery.noConflict();
... some code
</script>
The js is also involved from pagination buttons:
<apex:panelGrid columns="7">
<apex:commandButton status="fetchStatus" reRender="results" value="|<" action="{!first}" disabled="{!!hasPrevious}" title="First Page" onClick="saveSelection();" oncomplete=" restoreSelection()"/>
<apex:commandButton status="fetchStatus" reRender="results" value="<" action="{!previous}" disabled="{!!hasPrevious}" title="Previous Page" onClick="saveSelection();" oncomplete="restoreSelection()"/>
<apex:commandButton status="fetchStatus" reRender="results" value=">" action="{!next}" disabled="{!!hasNext}" title="Next Page" onClick="saveSelection();" oncomplete=" restoreSelection()"/>
<apex:commandButton status="fetchStatus" reRender="results" value=">|" action="{!last}" disabled="{!!hasNext}" title="Last Page" onClick="saveSelection();" oncomplete=" restoreSelection()" />
<apex:outputText >{!(pageNumber * size)+1-size}-{!IF((pageNumber * size)>noOfRecords, noOfRecords,(pageNumber * size))} of {!noOfRecords}</apex:outputText>
<apex:outputPanel style="color:#4AA02C;font-weight:bold">
<apex:actionStatus id="fetchStatus" startText="Fetching..." stopText=""/>
</apex:outputPanel>
</apex:panelGrid>
I hope this may help you.