You need to sign in to do that
Don't have an account?
How to create Apex controls dynamically using Apex class.
Hi,
I have a VF page in which i have Apex input text controls and a command Button control.
I am able to fill the Text boxes using the properties created in the controller.
My requirement here is when clicked on the command button in the Vf page i want to dynamically add a input text to the VF page.
Can we do it using Apex code??.
I have been looking around for adding controls in VF page using Apex code. I went through the developers guide and cook book for reference even then i failed to get the result.
Do any one have an idea about adding apex controls dynamically??
Please help me out...This might be a very silly question to ask but i am not able to resolve this problem from days.
Thanks in Advance,
pspl
If the data type is known, you can dynamically create a list (up to 1000 fields), by using a wrapper class, an array, and a apex: dataTable or apex: repeat section. Here's a simple example:
Controller:
public class pageController { public class text { public String Value { get; set; } } private List<text> textValues; public void setTextValues(List<text> items) { textValues = items; } public List<text> getTextValues() { if(textValues==null) { textValues = new List<text>(); textValues.add(new text()); } return textValues; } public void addItem() { textValues.add(new text()); } }
Page:
<apex:page controller="pageController"> Field List: <apex:form> <apex:dataTable columns="1" value="{!textValues}" var="item"> <apex:column> <apex:inputText value="{!item.value}" /> </apex:column> </apex:dataTable><br /> <apex:commandButton action="{!addItem}" value="Add Row"/> </apex:form> </apex:page>
Since you're using a wrapper class, you could create a dynamic list of fields of any arbitrary type using "render" to display the appropriate type of field, and then modify your logic so that the correct value. My example here doesn't include picklists, but I do show how to switch between a text, textarea, and checkbox, and add and remove rows arbitrarily.
Controller:
public class pageController { public class customField { public String fieldType { get; set; } public String flagForDeletion { get; set; } private String Value; public String getTextValue() { return value; } public String getCheckValue() { return value; } public String getTextAreaValue() { return value; } public void setTextValue(String s) { value = s; } public void setCheckValue(String s) { value = s; } public void setTextAreaValue(String s) { value = s; } public Boolean getIsText() { return fieldType == 'text'; } public Boolean getIsCheck() { return fieldType == 'check'; } public Boolean getIsTextArea() { return fieldType == 'area'; } public List<SelectOption> getDataTypeList() { List<SelectOption> dataTypes = new List<SelectOption>(); dataTypes.add(new SelectOption('text','Text Field')); dataTypes.add(new SelectOption('check','Checkbox')); dataTypes.add(new SelectOption('area','Text Area')); return dataTypes; } } public List<customField> fieldList { get; set; } public pageController() { fieldList = new List<customField>(); } public void addRow() { customField cf = new customField(); cf.fieldType = 'text'; cf.flagForDeletion = 'false'; cf.setTextValue(''); fieldList.add(cf); } public void delRows() { for(Integer i = fieldList.size()-1; i>=0; i--) { if(fieldList[i].FlagForDeletion == 'true') { fieldList.remove(i); } } } }
Page:
<apex:page controller="pageController"> Field List: <apex:form id="theForm"> <apex:dataTable columns="1" value="{!fieldList}" var="field"> <apex:column> <apex:inputCheckbox value="{!field.flagfordeletion}" /> <apex:selectList value="{!field.fieldtype}" size="1"> <apex:selectOptions value="{!field.datatypelist}" /> <apex:actionSupport event="onchange" reRender="theForm"/> </apex:selectList> <apex:inputText value="{!field.textvalue}" rendered="{!field.istext}" /> <apex:inputTextarea value="{!field.textareavalue}" rendered="{!field.istextarea}" /> <apex:inputCheckbox value="{!field.checkvalue}" rendered="{!field.ischeck}" /> </apex:column> </apex:dataTable><br /> <apex:commandButton action="{!addrow}" value="Add Row"/> <apex:commandButton action="{!delRows}" value="Delete Selected Rows"/> </apex:form> </apex:page>
All Answers
I don't think you can dynamically create controls, but you can programmatically hide and display controls using the render attribute. Your control button could set an apex property to true and the VF control can use it as
render="{!displayMyControl}"
Thanks for your quick reply clark.
I exactly dont know the count of the Input controls in vf page , this count can be any number based on requirement so in this case ur solution fails it would be better if i can create controls dynamically.
is there any soln for this...
Hi,
As far as I am aware, there is no way to create dynamic controls, but something like this may do the trick for you:
This is the VisualForce page:
<apex:page controller="aaPage78">
<apex:form>
<apex:outputPanel id="out">
<table border="1">
<apex:repeat value="{!Lists}" var="l">
<tr>
<td>
<apex:selectList value="{!l.countries}" multiselect="true">
<apex:selectOptions value="{!l.items}"/>
</apex:selectList><p/>
</td>
<td>
<apex:actionstatus id="status" startText="testing...">
<apex:facet name="stop">
<apex:outputPanel>
<p>You have selected:</p>
<apex:dataList value="{!l.countries}" var="c">{!c}</apex:dataList>
</apex:outputPanel>
</apex:facet>
</apex:actionstatus>
</td>
</tr>
</apex:repeat>
</table>
</apex:outputPanel>
<apex:commandButton value="Test" action="{!test}" status="status"/>
</apex:form>
</apex:page>
And this is the Controller:
public class aaPage78 {
public List<selectList> lists {get; set;}
public aaPage78() {
lists = new List<selectList>();
for (Integer i = 0; i < 5; i++) {
lists.add(new selectList(i));
}
}
public PageReference test() {
return null;
}
public class selectList {
Integer intValue;
String[] countries = new String[]{};
public selectList(Integer intValue) {
this.intValue = intValue;
}
public List<SelectOption> getItems() {
List<SelectOption> options = new List<SelectOption>();
options.add(new SelectOption('Value:' + intValue + ' - US','Label:' + intValue + ' - US'));
options.add(new SelectOption('Value:' + intValue + ' - CANADA','Label:' + intValue + ' - Canada'));
options.add(new SelectOption('Value:' + intValue + ' - MEXICO','Label:' + intValue + ' - Mexico'));
return options;
}
public String[] getCountries() {
return countries;
}
public void setCountries(String[] countries) {
this.countries = countries;
}
}
}
In here I am creating 5 listboxes, but you can easily get the idea.
One thing to know, is that creating "custom" code is harder than "regular" code
If the data type is known, you can dynamically create a list (up to 1000 fields), by using a wrapper class, an array, and a apex: dataTable or apex: repeat section. Here's a simple example:
Controller:
public class pageController { public class text { public String Value { get; set; } } private List<text> textValues; public void setTextValues(List<text> items) { textValues = items; } public List<text> getTextValues() { if(textValues==null) { textValues = new List<text>(); textValues.add(new text()); } return textValues; } public void addItem() { textValues.add(new text()); } }
Page:
<apex:page controller="pageController"> Field List: <apex:form> <apex:dataTable columns="1" value="{!textValues}" var="item"> <apex:column> <apex:inputText value="{!item.value}" /> </apex:column> </apex:dataTable><br /> <apex:commandButton action="{!addItem}" value="Add Row"/> </apex:form> </apex:page>
Since you're using a wrapper class, you could create a dynamic list of fields of any arbitrary type using "render" to display the appropriate type of field, and then modify your logic so that the correct value. My example here doesn't include picklists, but I do show how to switch between a text, textarea, and checkbox, and add and remove rows arbitrarily.
Controller:
public class pageController { public class customField { public String fieldType { get; set; } public String flagForDeletion { get; set; } private String Value; public String getTextValue() { return value; } public String getCheckValue() { return value; } public String getTextAreaValue() { return value; } public void setTextValue(String s) { value = s; } public void setCheckValue(String s) { value = s; } public void setTextAreaValue(String s) { value = s; } public Boolean getIsText() { return fieldType == 'text'; } public Boolean getIsCheck() { return fieldType == 'check'; } public Boolean getIsTextArea() { return fieldType == 'area'; } public List<SelectOption> getDataTypeList() { List<SelectOption> dataTypes = new List<SelectOption>(); dataTypes.add(new SelectOption('text','Text Field')); dataTypes.add(new SelectOption('check','Checkbox')); dataTypes.add(new SelectOption('area','Text Area')); return dataTypes; } } public List<customField> fieldList { get; set; } public pageController() { fieldList = new List<customField>(); } public void addRow() { customField cf = new customField(); cf.fieldType = 'text'; cf.flagForDeletion = 'false'; cf.setTextValue(''); fieldList.add(cf); } public void delRows() { for(Integer i = fieldList.size()-1; i>=0; i--) { if(fieldList[i].FlagForDeletion == 'true') { fieldList.remove(i); } } } }
Page:
<apex:page controller="pageController"> Field List: <apex:form id="theForm"> <apex:dataTable columns="1" value="{!fieldList}" var="field"> <apex:column> <apex:inputCheckbox value="{!field.flagfordeletion}" /> <apex:selectList value="{!field.fieldtype}" size="1"> <apex:selectOptions value="{!field.datatypelist}" /> <apex:actionSupport event="onchange" reRender="theForm"/> </apex:selectList> <apex:inputText value="{!field.textvalue}" rendered="{!field.istext}" /> <apex:inputTextarea value="{!field.textareavalue}" rendered="{!field.istextarea}" /> <apex:inputCheckbox value="{!field.checkvalue}" rendered="{!field.ischeck}" /> </apex:column> </apex:dataTable><br /> <apex:commandButton action="{!addrow}" value="Add Row"/> <apex:commandButton action="{!delRows}" value="Delete Selected Rows"/> </apex:form> </apex:page>
Hi there,
It is very interesting thing , but do you know how to save all the records in this page.
If you have any idae then please post.
Thanks
@bcg:
Looking at this example, I realize it's not necessarily the best I could have come up with. However, all that is really needed is to loop through the fieldList list and perform some action on the results. Regrettably, the prior code lacks an ID value or Name to work with, so it becomes cumbersome. However, if you added the ability to track the field name, and changed Value to a public-access variable, you would do the following:
Please let me know if you need further clarification.
Thanks!
How can we post back data from dynamically created textboxes. Like if we have created 4 textboxes then how do we post back data from those textboxes to controller we we are not certain about no of textboxes.
If you used my previous example, they'd be bound to the collection of data. The text boxes are just UI elements, but they are bound to real values. Make sure that the "value" attribute is a formula (e.g. {!object.fieldname} ) and not just a copy of the text (e.g. component.value = object.fieldname ).
Have you taken a look at "Dynamic Visualforce Components"? There is a much easier way to do this now. Check it out:
Dynamic Visualforce Components