Unable to bind Component attribute with controller - salesforce

I am trying to develop a visualforce custom component which takes an attribute from a visual force page. I need to access that attribute in controller's Constructor so that i can brings some records from database and i need to display those records in the Component. But problem is that i am not getting Attribute value in Controller.
See the below code to understand the problem clearly..
Controller :
public with sharing class AdditionalQuestionController {
public String CRFType {get;set;}
public AdditionalQuestionController () {
system.debug('CRFType : '+CRFType);
List<AdditoinalQuestion__c> lstAddQues = [Select AddQues__c from AdditoinalQuestion__c wehre CRFType = :CRFType];
system.debug('lstAddQue : '+lstAddQue);
}
}
Component :
<apex:component controller="AdditionalQuestionController" allowDML="true">
<apex:attribute name="CRFType" description="This is CRF Type." type="String" required="true" assignTo="{!CRFType}" />
<apex:repeat value="{!lstAddQue}" var="que">
{!que}<br />
</apex:repeat>
</apex:component>
VisualForce page :
<apex:page >
<c:AdditionalQuestionComponent CRFType="STE" />
</apex:page>
Thanks,
Vivek

I believe the issue here is that you're expecting the member variable to have a value inside the constructor — the snag is that the instance of the class is being constructed! It doesn't exist yet and so there is no way that a non-static member variable could be given a value prior.
Instead of doing the query in your constructor, specify your own getter for lstAddQue and do the query in there when you need the data. Of course, you may want to cache the value so that the query is not run every time, but from the looks of things that won't be relevant here.

Setter methods on the attributes in a VF component appear to be called after the constructor has returned, unfortunately. Here's an alternative solution for your controller that uses a getter method to populate your list (which would be called after your CRFType member variable has been set):
public with sharing class AdditionalQuestionController {
public String CRFType {set;}
public AdditionalQuestionController () {
system.debug('CRFType : '+CRFType); // this will be null in the constructor
}
public List<AdditoinalQuestion__c> getLstAddQue() {
system.debug('CRFType : '+CRFType); // this will now be set
List<AdditoinalQuestion__c> lstAddQues = [Select AddQues__c from AdditoinalQuestion__c wehre CRFType = :CRFType];
system.debug('lstAddQue : '+lstAddQue);
return lstAddQue;
}
}

Related

Display value as returned from controller method

Beginner in Salesforce so please bear with me.
I have created a lightning component and I would like to display on a page a value as returned by a component controller.
public class My_Controller {
#AuraEnabled
public static Decimal getRate(String currFrom, String currTo) {
Decimal value = 1.067773;
return value;
}
}
<aura:component controller="My_Controller">
<lightning:input type="string" name="res" aura:id="res" value= "
{!c.My_Controller.getRate('A', 'B')}" label="Result"/>
But it could not be so simple :) as I get: "Failed to save Rate.cmp: unexpected token: '(' at column 46 of expression: c.My_Controller.getRate('A', 'B'): Source"
What is the proper way to call the method?
You cannot call an Apex server controller method directly from Lightning clientside markup.
Instead, you'd need to declare an <aura:attribute> in your component markup and bind the value to that attribute.
<aura:attribute name="rate" type="String" />
<lightning:input type="string" name="res" aura:id="res" value="{! v.rate }" label="Result"/>
Then, your JavaScript client-side controller needs to make a server-side call, asynchronously, to get the value from Apex. Finally, the Lightning JavaScript callback from that async method would populate the return value into the <aura:attribute>, and the framework's data binding infrastructure will take care of updating the <lightning:input>.
It sounds complex, but it's mostly boilerplate code. The documentation linked above includes detailed examples.
public class My_Controller {
#AuraEnabled
public static Decimal getRate(String currFrom, String currTo) {
Decimal value = 1.067773;
return value;
}
}
<aura:component controller="My_Controller">
<aura:attribute name = "value" type= "Decimal"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<lightning:input type="string" name="res" aura:id="res" value= "
{!v.value}" label="Result"/>
<aura:component>
add a new method in controller.js:-
({
doInit : function(component, event, helper) {
var action = component.get("c.getRate");
action.setParams({
"currFrom": 'Test',
"currTo" : 'Test'
});
action.setCallback( this, function(actionResult) {
var state = actionResult.getState();
component.set('v.spinner',false);
if (state === "SUCCESS"){
var result = actionResult.getReturnValue();
component.set("v.value",result);
}
});
$A.enqueueAction(action);
}
})

ADF input text enable when check box is checked

i am New to ADF, i want display/enable the input text box when checkbox is checked and i should disable when it is unchecked below is the check box ADF code,
ADF Code:
<af:selectBooleanCheckbox label="Apply WITSML Filter" id="sbc11"
autoSubmit="true" contentStyle="margin-left:10px;" valueChangeListener="#{pageFlowScope.welljobs_bean.applyWITSMLFilterIndicator}"/>
Bean:
private transient RichSelectBooleanCheckbox applyWITSMLFilterIndicator;
public void setapplyWITSMLFilterIndicator(RichSelectBooleanCheckbox applyWITSMLFilterIndicator) {
this.applyWITSMLFilterIndicator= applyWITSMLFilterIndicator;
}
public RichSelectBooleanCheckbox getapplyWITSMLFilterIndicator() {
return applyWITSMLFilterIndicator;
}
The input text i want to show:
<af:inputText id="it140" autoComplete="off"
binding="#{pageFlowScope.welljobs_bean.applyWITSMLFilterIndicator.curvesFilter}"
dimensionsFrom="content" editable="inherit" rendered="true"/>
Bean:
private transient RichInputText curvesFilter;
public void setCurvesFilter(RichInputText curvesFilter) {
this.curvesFilter = curvesFilter;
}
public RichInputText getCurvesFilter() {
return curvesFilter;
}
Can anybody please help?
it is also giving me javax.faces.FacesException: javax.el.PropertyNotFoundException: The class 'java.lang.String' does not have the property 'curvesFilter'. Exception
You can do this with EL Expression, partial trigger/autosubmit and ValueChangeEvent.
You want to save the boolean value of the checkedbox inside your bean so you can render or disable the inputText when this value change inside your valueChangeEventListener.
You then want to refresh the inputText so it will display it's new render/disable value by adding the following property to the inputText parent :
partialTriggers="sbc11"
partialTriggers refresh the whole content of a container when an action occur on the element id you give him.
Assuming you want to disable/enable the inputText :
Bean :
public boolean checkboxIsChecked = false; //or private with getter and setter
public void checkBoxValueChange(ValueChangeEvent ve){
this.checkboxIsChecked = ve.getNewValue();
}
Jsf :
<af:selectBooleanCheckbox label="Apply WITSML Filter" id="sbc11"
autoSubmit="true" contentStyle="margin-left:10px;" valueChangeListener="#
{pageFlowScope.welljobs_bean.checkBoxValueChange}"/>
...
<af:inputText id="it140" autoComplete="off"
binding="#{pageFlowScope.welljobs_bean.applyWITSMLFilterIndicator.curvesFilter}"
dimensionsFrom="content" disabled="#{pageFlowScope.welljobs_bean.checkboxIsChecked}"/>
don't forget to add the partialTriggers="CHECKBOXID" to the inputText parent container
For official example see documentation : https://docs.oracle.com/cd/E16764_01/web.1111/b31973/af_lifecycle.htm#CIAHCFJF

How can I pass variables state from one page to another, if both pages use the same controller, but the second page uses a controller extension?

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>

apex:commandButton can't return nothing?

I have:
<apex:commandButton action="{!whatever}" value="myButton" reRender="sectionX" />
And
public String whatever(){
return 'ok';
}
It doesn't work (returns 401 Unauthorized), but if I write:
public void whatever(){
// some code
}
works fine.
The question is: how can I return something (a JSON or a Page) to this call?
Thanks
CommandButtons are used to execute some code on the server and they return a PageReference, not a string/json value.
<apex:commandButton action="{!whatever}" value="myButton" reRender="sectionX" />
So the method whatever should do the work and then assign the result to a public property on the controller so the page can display the result.
The rerender attribute says to reload the data in the outputpanel sectionX. SectionX needs to enclose the results you want to display from the commandbutton action.
public class myController {
public string Result {get;set;}
public PageReference whatever() {
// do your work here
Result = DateTime.Now();
return null;
}
}
Visualforce
<apex:outputpanel id="sectionX">{!Result}</apex:outputpanel>
Every time you click myButton command button the outputpanel will display a new datetime string.
An afterthought: If you want to put a string result/JSON into a javascript method, you can do something like the following.
<script>
function processJSON(val) {
var res = JSON.parse(val);
// do your work here
}
</script>
<apex:outputpanel id="sectionX">
<script>
processJSON("{!Result}");
</script>
</apex:outputpanel>
In your example commandbutton code you used rerender so you dont need to return a non null PageReference. If, on the other hand, you want to go to another page when you click the commandbutton, you would not set the rerender attribute and you would need to return a non-null PageReference,
ie
public PageReference whatever() {
return Page.MyVisualforcePage;
}
Not realy. Look here
As for me, I used method which returns PageReference variable.
Better to do like this:
public PageReference whatever(){
PageReference pageRef = null; // null won't refresh page at all if I'm not mistaken
// some cool logic goes here
if(toNavigate) {
pageRef = new PageReference('here is some URL to which user must be navigated');
} else if(toRefreshCurrent) {
pageRef = ApexPages.currentPage();
}
return pageRef;
}
About returning page - look here.

How can I link labels in a SelectCheckBoxes component in Visualforce?

I have an <apex:SelectCheckBoxes> component in my Visualforce page, which gets its select options from an Apex method. I want to have a label with a link appearing next to each checkbox. How can I achieve this? Please help.
One way to accomplish this is by using apex:inputCheckbox controls individually, rather than relying on selectCheckboxes to do all the rendering for you. It's hard to get more specific in a suggestion because the question can be answered in many ways.
If, for example, you need these checkboxes to appear in a list alongside SObject instances, create a wrapper class. If they are essentially a-la-carte, you can create a class that contains a Boolean and create a list of instances of this class. Then create a dataTable, pageBlockTable, etc., and in one of the columns you include the checkbox component. Or simply use apex:repeat if you don't want any of the other table formatting.
Here's the repeat example from the VF guide:
<!-- Page: -->
<apex:page controller="repeatCon" id="thePage">
<apex:repeat value="{!strings}" var="string" id="theRepeat">
<apex:outputText value="{!string}" id="theValue"/><br/>
</apex:repeat>
</apex:page>
/*** Controller: ***/
public class repeatCon
{
public String[] getStrings()
{
return new String[]{'ONE','TWO','THREE'};
}
}
Replacing outputText with inputCheckbox and a String array with Boolean. Then simply start with an apex:outputLink and follow it with the checkbox.
EDIT -
Here's an example of using a class to get the job you want done.
Apex:
public class Example
{
public List<CheckboxClass> theCheckboxes {get; private set;} // Reference THIS array
public Example()
{
theCheckboxes = new List<CheckboxClass>();
theCheckboxes.add(new Checkbox(true));
theCheckboxes.add(new Checkbox(false));
theCheckboxes.add(new Checkbox(true));
theCheckboxes.add(new Checkbox(false));
}
public class CheckboxClass
{
public Boolean theCheckbox {get; private set;}
public CheckboxClass(Boolean b)
{
this.theCheckbox = b;
}
}
}
Visualforce:
<apex:form>
<apex:pageBlock>
<apex:pageBlockTable value="{!theCheckboxes}" var="item">
<apex:column headerValue="The Checkboxes">
<apex:inputCheckbox value="{!item.theCheckbox}">
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
I haven't tested this, but this is the idea I believe you're looking for.

Resources