Adressing array index in iBATIS 2 - ibatis

It's possibile to adress an array by index in a sqlmap?
What I want is:
class A {
String[] foo = {"",""};
}
<resultMap id="someResultMap" class="A">
<result property="foo[0]" column="COLUMN_Y" />
<result property="foo[1]" column="COLUMN_X" />
</resultMap>
If I try I get:
There is no WRITEABLE property named 'foo[0]' in class 'A'

It's not possible to set value to an array by index in a sqlmap becuase iBatis uses setter to write the value. You should have setter for your property to use it in the sql map.
I would suggest to create property in your class for coulumnX and columnY. If you still want array to be used in the class, you can do some work around in your class like below.
class A {
String[] foo = {"",""};
String col1;
String col2;
//have getter and setter for col1 and col2
getFoo(){
foo[1] = getCol1();
foo[2] = getCol2();
return foo;
}
}
<resultMap id="someResultMap" class="A">
<result property="col1" column="COLUMN_Y" />
<result property="col2" column="COLUMN_X" />
</resultMap>

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);
}
})

Dynamic checkbox from list with Thymeleaf

I try to save the values from dynamically created checkboxes:
<div>
<ul>
<li th:each="item, stat : *{users}">
<input type="checkbox" th:field="*{users[__${stat.index}__]}" th:value="${item}" />
<label th:text="${item}"></label>
</li>
</ul>
</div>
The controller provides the String items as follwing:
public List<String> getUsers() {
return users;
}
And the setter for the Strings is:
public void setUsers(final String[] users) {
for (final String string : users) {
System.out.println(string);
}
}
The values are correct shown in the html page. But when i click save button, and the setter is called, the values are empty. What can i do, where is the problem?
Any help would appreciate.
Please check out section about handlin multi-value checkboxes in Tutorial: Thymeleaf + Spring.
You should provide some model attribute (of type List<String>) containing all users possible to select. Let's call it selectableUsers.
Then it can collaborate with your form-backing bean (that one containing users) in a following manner:
<div>
<ul>
<li th:each="item : ${selectableUsers}">
<input type="checkbox" th:field="*{users}" th:value="${item}" />
<label th:for="${#ids.prev('users')}" th:text="${item}"></label>
</li>
</ul>
</div>
Note I think that getter and setter for a field should handle the same type, but they don't (getter returns List<String> however setter consumes String[])
What you are trying to do looks logical, but it does not work that way.
If you did not get it resolved you can do this instead:
In relevant method of your controller you can add list of titles for your checkboxes:
List<String> allUsers = Arrays.asList("abc","xyz"); // OR generate list dynamically
model.addAttribute("selectableUsers", allUsers);
Or add it to ModelAndView if that is what you are using.
Change your html to what was suggested by #Jakub Ch.
Change your getter and setter methods as follows:
private String users;
...
public String getUsers() {
return this.users;
}
public void setUsers(String users) {
this.users = users;
}
Then 'users' field will contain comma separated String values or their id numbers ( depending on how you set it up) indicating selected checkboxes. Then you can convert String values to array using code like below or if id numbers are stored get String values from your ArrayList.
public List<String> getStrings() {
return Arrays.asList(strings.split(","));
}
Hope it helps.

Setting values to each comboBox item

populate combobox code:
ComboBox getCategoryComboBox = new ComboBox();
searchOptionForm.add(getCategoryComboBox);
getCategoryComboBox.setUIID("TextField");
getCategoryComboBox.addItem("Choose Category");
for (Map<String, Object> entry : alacc.responseCategory) {
String categoryName = (String) entry.get("name");
String categoryId = (String) entry.get("id");//how to set this to combobox item
getCategoryComboBox.addItem(categoryName);
}
categoryId is taken from for loop above, how to set it in each combobox items? I need to get the categoryId of each selected combobox item, how can i get this?
You have several ways to do this.
One way is to just do:
getCategoryComboBox.addItem(entry);
Which would provide you the full entry on getSelectedItem() effectively solving that problem.
To make the name render properly though you would need to do this:
cb.setRenderer(new DefaultListCellRenderer<Object>() {
public Component getCellRendererComponent(Component list, Object model, Object value, int index, boolean isSelected) {
if(value instanceof Map) {
value = ((Map)value).get("name");
}
return super.getCellRendererComponent(list, model, value, index, isSelected);
}
});
Notice you will also need to define the theme constant otherPopupRendererBool to false for this to work properly.

Create UI components on page load

I am currently working on oracle adf task flows and regions and I want to create and update some UI components on page load and for this I am using method call activity as default.The problem is that I am getting null values following is my code in the bean that executes on the method call.
package view;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import oracle.adf.view.rich.component.rich.output.RichOutputText;
public class testBean {
public testBean() {
}
public String testMethod() {
// Add event code here...
FacesContext facesContext = FacesContext.getCurrentInstance();
UIViewRoot root = facesContext.getViewRoot();
RichOutputText text = ( RichOutputText )root.findComponent( "r1:ot1" );
text.setValue( "Adding text on run time" );
return "product";
}
}
The set value method returning me null may be it is because the fragment product.jsff which is the view activity is not initiated and the output text with ot1 returning null.
The better approach to achieve the setting of value is to have a property in your bean say: textValue and then bind the value attribute of your ot1 with the property of the bean.
class TestBean{
private String textValue;
public String testMethod() {
textValue = "Adding text on run time";
}
public String getTextValue(){
return textValue;
}
}
Your JSPX would be:
<af:outputText id="ot1" value=#{beanName.textValue}" />

Unable to bind Component attribute with controller

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;
}
}

Resources