Ok so the title is confusing and the question will likely be too as Im new to this whole VF/Apex thing and dont know proper terminology.
The idea is when the user selects one of the options ("other") then the controller will concatenate the value of the textbox (!otherString) into the custom object.
The issuse is I want the input textbox to go below the select menu but if I put it below the menu the user input is no longer readable.
This works:
<apex:inputText value="{!otherString}" id="otherText" />
<apex:selectCheckboxes layout="PageDirection" value="{!other}" id="standardMap" required="true">
<apex:selectOptions value="{!shareTypes}" />
</apex:selectCheckboxes>
Output: "Other: Model" ("Model" being whatever the user typed)
This doesnt work:
<apex:selectCheckboxes layout="PageDirection" value="{!other}" id="standardMap" required="true">
<apex:selectOptions value="{!shareTypes}" />
</apex:selectCheckboxes>
<apex:inputText value="{!otherString}" id="otherText" />
Output: "Other: null" (null being because it couldnt read the textbox)
Relevant Controller Code:
List<String> other = new List<String>{};
public String otherString{get;set;}
public List<String> getOther() {
return other;
}
public void setOther(List<String> other) {
Set<String> mySet = new Set<String>();
mySet.addAll(other);
if (mySet.Contains('Other'))
{
String result = String.join(other, ', ' );
control.Share_Types__c = result + ': ' +otherString;
}
else
{
String result = String.join(other, ', ' );
control.Share_Types__c = result;
}
}
but if I put it below the menu the user input is no longer readable
Your code kind of relies on the order in which getter and setter methods will execute (if you'll enable debug logging or fire up developer console you'll see that the order of get/set statements kind of matches the order in which expressions appear on the page... but there's a chance you'll see something firing more than once!).
Salesforce recommends not relying on the order in which get/set fire and your application shouldn't care if setOther is called once or 10 times (so you shouldn't have complex queries as side-effects in setters for example).
I assume you already have some action method (something that's bound to apex:commandButton or apex:commandLink) - you should move this logic from the setter to that method instead. Do you have our own method or are you using StandardController's {!save} for example?
Some further reading:
https://www.salesforce.com/us/developer/docs/pages/Content/pages_controller_methods.htm (check the warnings with red exclamation marks)
https://salesforce.stackexchange.com/questions/9167/getter-setter-confused (a shameless plug :P)
http://www.tehnrd.com/getter-method-order-and-visualforce-pages/
Edit - you've mentioned you're looking into some submitting without user having to click any button. Check if something like this is close to what you need.
public class Checkboxes{
public List<SelectOption> options {get;private set;}
public List<String> selected {get;set;}
public Boolean otherSelected {get; private set;}
public String otherOption {get;set;}
public transient String output {get; private set;}
public Checkboxes(){
options = new List<SelectOption>{
new SelectOption('Apex', 'Apex'),
new SelectOption('JavaScript', 'JavaScript'),
new SelectOption('Visualforce', 'Visualforce'),
new SelectOption('Other', 'Other')
};
selected = new List<String>();
otherSelected = false;
}
public void skillsChanged(){
try{
Set<String> temp = new Set<String>();
temp.addAll(selected);
otherSelected = temp.contains('Other');
if(otherSelected){
output = 'Other : ' + (String.isBlank(otherOption) ? '<not specified>' : otherOption);
} else {
output = String.join(selected, ', ');
}
System.debug(output);
} catch(Exception e){
ApexPages.addMessages(e);
}
}
}
<apex:page controller="Checkboxes" tabStyle="Account">
<apex:pageMessages />
<apex:form>
<apex:pageblock id="block">
<apex:pageBlockButtons location="top">
<apex:actionStatus id="status">
<apex:facet name="start"><img src="/img/loading.gif" alt="Loading" title="Loading"/></apex:facet>
</apex:actionStatus>
</apex:pageBlockButtons>
<apex:pageBlockSection title="input" columns="1">
<apex:selectCheckboxes label="Your skills" value="{!selected}" required="true">
<apex:selectOptions value="{!options}" />
<apex:actionSupport action="{!skillsChanged}" event="onchange" status="status" rerender="messages, block"/>
</apex:selectCheckboxes>
<apex:inputText label="Please Specify" value="{!otherOption}" rendered="{!otherSelected}">
<apex:actionSupport action="{!skillsChanged}" event="onchange" status="status" rerender="messages, text"/>
</apex:inputText>
</apex:pageBlockSection>
<apex:pageBlockSection title="output">
<apex:outputText value="{!output}" id="text"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
Related
So I have this in the page:
< apex:commandButton id="songdbabc" value="Synch from song db" action="{!sendingSign}" />
and this in the controller:
public PageReference sendingSign(){
System.debug(' message ');
return null;
}
But everytime I press the button there isn`t any message in the "Log" I mean the action is not executed , any idea?
Do you have another variable or function with same name? I mean public String sendingSign {get; set;} or maybe public String getSendingSign()? These would "shadow" your action function. Do you have more than 1 controller extension in <apex:page> tag? they'd be checked for matching function names from right to left (so if you have few classes maybe it's calling the match from a class you're not looking at)
Open up your browser's JS console / network panel, see if there's any traffic recorded at all when you click the button...
Try changing your sendingSign method to :
public void sendingSign(){
System.debug(' message ');
}
And recheck your log.
EDIT: Fixed! Removed "Static" variables from my extension; all bad behavior cleared right up.
Original:
I had to build a stackoverflow account just so I could vent a little here. I'm facing the same issue, and found that it will only skip my action if I include a picklist on the same page. I've never had this issue.
this page runs the action, but doesn't include the picklist I want:
<apex:page standardController="Checklist_Template_Item__c" recordSetVar="Checklist_Template_Items__r" extensions="ChecklistTemplateItemMassApply">
<apex:form >
<apex:pageBlock >
<apex:commandButton action="{!myCustomAction}" value="Append/Remove" />
<apex:commandButton action="{!cancel}" value="Cancel"/>
<apex:variable value="{!appendValue}" var="appendValue"/>
<apex:variable value="{!selection}" var="selection"/>
<apex:pageBlockSection >
Include your selected items for select machine models.
<apex:inputText value="{!appendValue}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
this page completely skips the action, but includes my picklist:
<apex:page standardController="Checklist_Template_Item__c" recordSetVar="Checklist_Template_Items__r" extensions="ChecklistTemplateItemMassApply">
<apex:form >
<apex:pageBlock >
<apex:commandButton action="{!myCustomAction}" value="Append/Remove" />
<apex:commandButton action="{!cancel}" value="Cancel"/>
<apex:variable value="{!appendValue}" var="appendValue"/>
<apex:variable value="{!selection}" var="selection"/>
<apex:pageBlockSection >
Include your selected items on certain machine models.
<apex:inputText value="{!appendValue}"/>
<apex:pageBlockSectionItem >
<apex:outputText value="Why tho"/>
<apex:selectList size="1" value="{!selection}" required="true">
<apex:selectOptions value="{!applyRemove}"/>
</apex:selectList>
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
having either a page constructor or not, action doesn't run when the picklist is included:
extension v1:
public without sharing class ChecklistTemplateItemMassApply{
public static String appendValue{get;set;}
public static String selection{get;set;}
public static List<SelectOption> applyRemove{get;set;}
ApexPages.StandardSetController setCon;
public ChecklistTemplateItemMassApply(ApexPages.StandardSetController myController){
setCon = myController;
List<String> addList = new List<String>{'Applies_To__c'};
setCon.addFields(addList);
system.debug('addList = '+addList);
applyRemove = new List<SelectOption>();
applyRemove.add(new SelectOption('','--None--'));
applyRemove.add(new SelectOption('Include','Include'));
applyRemove.add(new SelectOption('Remove','Remove'));
}
public ApexPages.pageReference myCustomAction(){
system.debug('hey');
PageReference returnPage = new PageReference(ApexPages.currentPage().getParameters().get('retURL'));
system.debug('returnPage = '+returnPage);
return returnPage;
}
}
extension V2:
public without sharing class ChecklistTemplateItemMassApply{
public static String appendValue{get;set;}
public static String selection{get;set;}
public static List<SelectOption> applyRemove{get;set;}
ApexPages.StandardSetController setCon;
public ChecklistTemplateItemMassApply(ApexPages.StandardSetController myController){
setCon = myController;
List<String> addList = new List<String>{'Applies_To__c'};
setCon.addFields(addList);
system.debug('addList = '+addList);
applyRemove = new List<SelectOption>();
applyRemove.add(new SelectOption('','--None--'));
applyRemove.add(new SelectOption('Include','Include'));
applyRemove.add(new SelectOption('Remove','Remove'));
}
public void ApexPages.pageReference myCustomAction(){
system.debug('hey');
}
}
I'm racking my brain over this. Its a simple on change function which should fire but when I test in my org, I never get the debug "here" despite getting the rest in my class. I've looked over dozens of different google results and the code is identical. Does anyone know if SF is just broken?
public class testController {
public static String testNewString {get;set;}
public testController(){}
public static Boolean isAccountAvailable()
{
System.debug('here');
List<Account> tempList = ([SELECT Id
FROM Account
WHERE Name = :testNewString]);
if(tempList.size() != 0)
{
return true;
}
else
{
return false;
}
}
}
<apex:page controller="testController" docType="html-5.0">
<apex:form id="form1">
<apex:inputText value="{!testNewString }" html-placeholder="New Sales Order #">
<apex:actionSupport event="onChange" action="{!isAccountAvailable}" rerender="form1" />
</apex:inputText>
</apex:form>
</apex:page>
For whoever is looking for an answer, the fix for this code snippet is subtle. Make sure the function returns a page reference. Making fields global might help make it visible to VF.
public class TestController {
public String testNewString {get;set;}
public testController(){}
public PageReference isAccountAvailable()
{
System.debug('here');
List<Account> tempList = ([SELECT Id
FROM Account
WHERE Name = :testNewString]);
if(tempList.size() != 0)
{
System.debug('true');
}
else
{
System.debug('false');
}
return null;
}
}
<apex:page controller="TestController" docType="html-5.0">
<apex:form id="form1">
<apex:inputText value="{!testNewString}" html-placeholder="New Sales Order #">
<apex:actionSupport event="onchange" action="{!isAccountAvailable}" rerender="form1" />
</apex:inputText>
</apex:form>
</apex:page>
I have the following Visualforce page, and apex class as controller.
I would like to pass valus in the input text boxes contain th ids inputText1 and InputText2 to the same variable in the following apex class.
Everytime, the inputText1 and inputText2 in the apex class is null, and I don't know why!
Iv'e bin sitting on it all day long, and I couldn't figgure out why it happens!
Please help me with that, because I'm feeling hopeless with that.
<apex:page controller="LoginPages" rendered="true" showHeader="false" sidebar="false" standardStylesheets="true">
<apex:Pagemessages id="msg"/>
<apex:pageMessages ></apex:pageMessages>
<apex:pageBlock >
<apex:form >
<p><b>Login Page</b><br /></p>
<apex:panelGrid columns="2" style="margin-top:1em;">
<p><b>UserName</b><br />
<apex:inputtext required="true" id="inputText1" value="{!inputText1}"/>
</p>
<p><b>Password</b><br />
<apex:inputtext id="inputText2" value="{!inputText2}"/>
</p>
<apex:commandButton action="{!loginUser}" value="login" id="login" immediate="true"/>
</apex:panelGrid>
</apex:form>
</apex:pageBlock>
</apex:page>
public class LoginPages{
public String inputText1;
public String inputText2;
public String getInputText1(){
return inputText1;
}
public void setInputText1(String str1){
inputText1 = str1;
}
public String getInputText2(){
return inputText2;
}
public void setInputText2(String str2){
inputText1 = str2;
}
public PageReference registerUser() {
PageReference newPage = new PageReference('/apex/newPage');
newPage.setRedirect(true);
return newPage;
}
public void loginUser() {
ApexPages.Message mymsg = new ApexPages.Message(ApexPAges.Severity.INFO, 'sdsdf' + inputText1);
apexpages.addMessage(mymsg);
// PageReference newPage = new PageReference('/apex/login');
System.debug('sdfsdf' + inputText1);
List<User__c> users = [Select Name, Password__c from User__c Where Name = :inputText1];
if (users.size() > 0){
for (User__c user : users){
if (user.Password__c == inputText2){
//newPage.setAnchor('/apex/catalog');
//newPage.setRedirect(true);
}
}
}
//return newPage;
}
}
Remove immediate="true". "Immediate" results in no data being passed from the form to the server.
Also - you could write your variables bit simpler and then you won't need the explicit getXYZ/setXYZ methods:
public String inputText1 {get;set;}
Right now it seems that anything with the <apex:selectCheckboxes> wont work (regardless of version since I did try bumping it back on both the page and controller). See blog entry for full debugging steps:http://salesforcegirl.blogspot.hu/2013/05/bug-with.html
when trying to use a repeat to populate the Lists via maps it fails as well for both <apex:selectCheckboxes> and <apex:selectList>. But if you do it the long way, you can get <apex:selectList> to work at the very least, however not the <apex:selectCheckboxes> (which is what i need).
Here is the code:
public class sfg_testBugWithActionButton {
public String fGrade {get; set;}
public List<SelectOption> soGrade {get; set;}
public String resultString {get; set;}
public sfg_testBugWithActionButton() {
createfilterMap();
resultString = 'on Load of page';
}
public PageReference preformAction() {
system.debug('Grade: ' + fGrade);//this wont be hit unless you use selectList
resultString = 'button action preformed';
return null;
}
private void createfilterMap() {
soGrade = new List<SelectOption>();
soGrade.add(new SelectOption('A', 'A'));
soGrade.add(new SelectOption('B', 'B'));
soGrade.add(new SelectOption('C', 'C'));
}
}
Page:
<apex:page showHeader="true" sidebar="true" controller="sfg_testBugWithActionButton">
<apex:form>
<apex:outputpanel id="mainWrap">
<h2>Grade</h2>
<apex:selectCheckboxes value="{!fGrade}" layout="pageDirection">
<apex:selectOptions value="{!soGrade}" />
</apex:selectCheckboxes>
<apex:commandButton action="{!preformAction}" rerender="renderWrap" value="Submit Action" />
<br />
<apex:outputpanel id="renderWrap">
{!resultString}
</apex:outputpanel>
</apex:outputpanel>
</apex:form>
</apex:page>
<apex:selectCheckboxes> hold multiple values so its value needs to be an array of strings:
public List<String> fGrade {get; set;}
Then you just need to initialize it in the constructor, and the example in the question works:
this.fGrade = new List<String>();
I have a dynamic picklist field that contains all the apex classes name that are in my org. There is a "Show" button on the page as well. Now if a user selects a value from this picklist and clicks on Show button, the apex code of that class should get displayed below.
Pls suggest how can I implement it in my VF page.
Thanks!
<apex:form >
<apex:selectList value="{!selectedClass}" size="5">
<apex:selectOptions value="{!ClassList}" ></apex:selectOptions>
</apex:selectList>
<apex:pageBlock >
<apex:commandButton action="{!show}" value="Show" id="Button"/>
<apex:pageBlockSection title="My Current Class">
You could query the body field of the ApexClass object for what you're looking for:
public class SomeController {
private List<ApexClass> allApexClasses;
public String selectedClass {public get; public set;}
public String apexCodeOutput {public get; private set;}
public SomeController() {
// only select classes that aren't part of a managed package, since you won't be able to view the body
allApexClasses = [select id, name, body from ApexClass where lengthwithoutcomments <> -1 order by name asc];
}
public List<SelectOption> getClassList() {
List<SelectOption> opts = new List<SelectOption> opts;
for ( ApexClass ac : allApexClasses )
opts.add(new SelectOption(ac.Id, ac.Name));
return opts;
}
public PageReference show() {
if ( selectedClass != null ) {
Id classId = (Id) selectedClass;
for ( ApexClass ac : allApexClasses ) {
if ( classId == ac.Id ) {
apexCodeOutput = ac.body;
break;
}
}
}
return null;
}
}
And then in your VF page, just rerender the output code when clicking the button. You'll want to use a <pre> tag around the code to preserve spacing so the code is readable.
<apex:form>
<apex:selectList value="{!selectedClass}" size="5">
<apex:selectOptions value="{!ClassList}" ></apex:selectOptions>
</apex:selectList>
<apex:pageBlock >
<apex:commandButton action="{!show}" value="Show" rerender="apexoutput" id="Button"/>
<apex:pageBlockSection title="My Current Class">
<apex:outputPanel id="apexoutput">
<pre>{!apexcodeoutput}</pre>
</apex:outputPanel>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>