Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xpages more fields (unlimited) at the click of a button

Tags:

xpages

I would like to start with x no. of fields (in my app I have a pair of textual data field and numeric data field) on a xpage application (say 10 pairs) and then when the user clicks on "more field", I want more pairs to appear dynamically without a full refresh on the page, but would like unlimited no. of fields (as long as the page doesn't crash) and then I would like to submit the form and the data for all those fields. What's the best way to implement this?

like image 940
pipalia Avatar asked Mar 15 '12 12:03

pipalia


3 Answers

Usually, fields are bound to a document data source using dot notation:

<inputText value="#{contact.firstName}" />

However, array notation is also supported:

<inputText value="#{contact['firstName']}" />

Because the field name in this latter syntax is being treated as a string, not as an implicit property of the bean, it can be dynamically computed. What I've found to be the easiest way to define these dynamic fields is to create a custom control for each of the basic types of fields, and define each as accepting the data source and the field name. So the field itself then ends up with a syntax similar to the following:

<inputText value="#{compositeData.dataSource[compositeData.fieldName]}" />

By using that syntax, a calculation of any complexity can be used to determine what field name to pass to the custom control. In the scenario you're attempting to accomplish, specifying an indexVar on the repeat control that surrounds the field pair would allow you to designate a field suffix for each... perhaps something like the following:

<xp:repeat indexVar="fieldSuffix" value="#{viewScope.rowCount}">
 <xp:div>
  <xc:dynamicInputText dataSource="#{contact}" fieldName="fullName_#{fieldSuffix}" />
  <xc:dynamicInputNumber dataSource="#{contact}" fieldName="phoneNumber_#{fieldSuffix}" />
 </xp:div>
</xp:repeat>

With this approach, you would end up with fields named "fullName_0", "fullName_1", etc., up to the limit specified in the viewScope. Typically, the only complication is ensuring that when an existing document is opened, the viewScope variable is set back to the correct limit. Another approach to that, of course, is actually saving the limit as another item on the document and binding the repeat value to it instead.

like image 162
Tim Tripcony Avatar answered Oct 15 '22 16:10

Tim Tripcony


You also can have a look at the exercise 23 "Tablewalker". It doesn't do multiple fields but does Multi-value fields which might be better in terms of processing and storage (you can do an @Elements to find out how many are there in a document). The exercise is here: http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Tutorial-Introduction-to-XPages-Exercise-23 While the button only adds one row at a time, it is easy to adjust.

like image 20
stwissel Avatar answered Oct 15 '22 16:10

stwissel


What you could do is have a Bean with 2 String values Label and Data and a managed bean that has a ArrayList of that object so inside of your repeat control you bind the repeat to the ArrayList and then bind your xp:inputText to rowData.Data and your xp:label to rowData.Label then when you want to add another 5 rows you just add However many more objects into the ArrayList then refresh your page, your data will still live in your arraylist and you will have 5 new Empty objects where you can add data.

public class Data {

private String label;
private String data;

public Data() {

}
//getters and setters

}

public class ManagedBean {

private ArrayList<Data> datalist;  // add a managed property for this one so It will create a new one when needed.

// getters and setters

public addFiveMoreObjects() {
   Data newItem;
   for (int i=0; i<5; i++) {
       newItem = new Data();
       datalist.add(newItem);
   }
}

}

<xp:repeat value="#{managedBean.datalist}" var="rowData">
<xp:text value="#{rowData.label}" />
<xp:inputText value="#{rowData.data} />
</xp:repeat>

<xp:button value="Add 5 More"> // call #{managedBean.addFiveMoreObjects}
like image 3
Toby Samples Avatar answered Oct 15 '22 18:10

Toby Samples