Access values from dynamic input text generated from ui:repeat JSF - list

<p:outputPanel id="panel">
<ui:repeat value="#{dataController.display()}"
var="item" rendered="#{Bean.showtable}">
<b:row>
<b:column col-md="5">
<h:outputText value="#{item.name}" style="font-family: verdana;font-size:16px;margin-bottom:15px;"></h:outputText>
</b:column>
<b:column col-md="7">
<h:inputText style="width:200px;height:30px;margin-bottom:15px;"
autocomplete="off"></h:inputText>
</b:column>
</b:row>
</ui:repeat>
In the above code, I have used ui:repeat for displaying the names of the items in a list in output text alongwith the input text for entering the values of the items.
The input text depends on the values in the list i.e dynamically generated.
I need to access the values from the input text and add them to List.
Can anyone please suggest me an approach to access the values from input text to bean/list despite using ui:repeat once to display the input text?
I have tried to create an empty list and again using ui:repeat only for input text.. tried to access values from input text.But ui:repeat doesnot work again.. as it was already used once for displaying.
I am new to JSF.Any help would be appreciated.Thankyou.

Don't use empty list. Initialize it with null or empty values.
Let's say we have inputs as your list, your bean should look like this.
#Named
#ViewScoped
public class DataController implements Serializable {
private List<String> inputs;
// getters and setters
#PostConstruct
public void init() {
inputs = new ArrayList<String>();
}
public List<Bean> getDisplay() {
List<Bean> display = new ArrayList<Bean>();
// add values to display
for (int i = inputs.size(); i < display.size(); i++) {
inputs.add("");
}
return display;
}
// for testing inputs
public void testInputs() {
for (String input : inputs) {
System.out.println(">>>>>" + input);
}
}
}
xhtml
<ui:repeat value="#{dataController.display()}" varStatus="idx" ...>
...
<h:inputText value="#{dataController.inputs[idx.index]}" style="width:200px;height:30px;margin-bottom:15px;" autocomplete="off"></h:inputText>
...
</ui:repeat>
<p:commandButton value="Test Inputs" action="#{dataController.testInputs}" update="#form" />
Hope this helps.

Related

Aspose words API - mail merge functionality - can the "merged" text be richtext (with styles/images/bullets/tables)?

Looking for word api which can perform mail merge type of functionality with richtext. Basically, text will be richtext/formatted text with fonts styles and WILL have
a) images
b) bullets
c) tables
Overall purpose: Create a word template with bookmarks. Get get data from DB(for those fields) and insert. Data will be html text/richtext. Autogenerate word document. python or .net api will be preferred.
Can Aspose.words work with richtext as described above? Any other recommendations for excellent word APIs?
Yes, you can achieve this using Aspose.Words. You can use IFieldMergingCallback to insert formatted text upon mail merge. For example, see the following link
https://apireference.aspose.com/words/net/aspose.words.mailmerging/ifieldmergingcallback
In case of reach text (if you mean RTF or MarkDown formats) you first need to read this content into a separate instance of Document and then use DocumentBuilder.InsertDocument method
https://apireference.aspose.com/words/net/aspose.words/documentbuilder/methods/insertdocument
The following code example shows how to use InsertHtml method in IFieldMergingCallback
[Test]
public void Test001()
{
Document doc = new Document(#"C:\Temp\in.docx");
doc.MailMerge.FieldMergingCallback = new HandleMergeFieldInsertHtml();
const string html = #"<h1>Hello world!</h1>";
doc.MailMerge.Execute(new string[] { "myField" }, new object[] { html });
doc.Save(#"C:\Temp\out.docx");
}
private class HandleMergeFieldInsertHtml : IFieldMergingCallback
{
void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
{
FieldMergeField field = args.Field;
// Insert the text for this merge field as HTML data, using DocumentBuilder
DocumentBuilder builder = new DocumentBuilder(args.Document);
builder.MoveToMergeField(args.DocumentFieldName);
builder.Write(field.TextBefore ?? "");
builder.InsertHtml((string)args.FieldValue);
// The HTML text itself should not be inserted
// We have already inserted it as an HTML
args.Text = "";
}
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
{
// Do nothing
}
}
If you would like manually format the text, then you can use DocumentBuilder appropriate properties.
[Test]
public void Test001()
{
Document doc = new Document(#"C:\Temp\in.docx");
doc.MailMerge.FieldMergingCallback = new HandleMergeFieldInsertText();
const string text = #"Hello world!";
doc.MailMerge.Execute(new string[] { "myField" }, new object[] { text });
doc.Save(#"C:\Temp\out.docx");
}
private class HandleMergeFieldInsertText : IFieldMergingCallback
{
void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
{
FieldMergeField field = args.Field;
DocumentBuilder builder = new DocumentBuilder(args.Document);
builder.MoveToMergeField(args.DocumentFieldName);
// Apply style or other formatting.
builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;
builder.Write(field.TextBefore ?? "");
builder.Write((string)args.FieldValue);
// The text itself should not be inserted
// We have already inserted it using DocumentBuilder.
args.Text = "";
}
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
{
// Do nothing
}
}
Hope this helps.
Disclosure: I work at Aspose.Words team.

How can I create an .arff file from .txt?

Is there any simple way to do that? I'm not in Java and I'm new in Python so I would need another way(s). Thanks in advance!
Do you perhaps mean a csv file that ends in .txt? If the data inside the file looks like this:
1,434,2236,5,569,some,value,other,value
4,347,2351,1,232,different,value,than,those
Then it has comma separated values (csv) and Weka has classes and functions which convert a csv file into an arff: http://weka.wikispaces.com/Converting+CSV+to+ARFF You can use these from the command line, like this:
java weka.core.converters.CSVLoader filename.csv > filename.arff
Otherwise, #D3mon-1stVFW 's comment links to great documentation from weka about turning text files (things like blog posts or books or essays) into the arff format. http://weka.wikispaces.com/ARFF+files+from+Text+Collections and this can also be called from the command line, like this:
java weka.core.converters.TextDirectoryLoader /directory/with/your/text/files > output.arff
Missing -dir argument specifier:
java weka.core.converters.TextDirectoryLoader -dir /directory/with/your/text/files > output.arff
This solution assumes you have your data in .csv format - see kaz's solution.
One simple way to do this is in version 3.6.11 (I'm on a mac) is to open up the Explorer and then in the Preprocess tab select "Open file...", just as you would when you want to open a .arff file. Then where it asks for the File Format at the bottom of the dialog box, change it to .csv. You can now load CSV files straight into Weka. If the first line of your CSV file is a header line, these names will be used as the attribute names.
On the right-hand side of the Preprocesses tabs is a "Save..." button. You can click on that and save your data as a .arff file.
This is a bit long-winded to explain, but takes only a few moments to perform and is very intuitive.
package WekaDemo;
public class Txt2Arff {
static ArrayList inList=new ArrayList();
static String colNames[];
static String colTypes[];
static String indata[][];
static ArrayList clsList=new ArrayList();
static ArrayList disCls=new ArrayList();
static String res="";
public String genTrain()
{File fe=new File("input2.txt");
FileInputStream fis=new FileInputStream(fe);
byte bt[]=new byte[fis.available()];
fis.read(bt);
fis.close();
String st=new String(bt);
String s1[]=st.trim().split("\n");
String col[]=s1[0].trim().split("\t");
colNames=col;
colTypes=s1[1].trim().split("\t");
for(int i=2;i<s1.length;i++)
{
inList.add(s1[i]);
}
ArrayList at1=new ArrayList();
for(int i=0;i<inList.size();i++)
{
String g1=inList.get(i).toString();
if(!g1.contains("?"))
{
at1.add(g1);
res=res+g1+"\n";
}
}
indata=new String[at1.size()][colNames.length-1]; // remove cls
for(int i=0;i<at1.size();i++)
{
String s2[]=at1.get(i).toString().trim().split("\t");
for(int j=0;j<s2.length-1;j++)
{
indata[i][j]=s2[j].trim();
}
if(!disCls.contains(s2[s2.length-1].trim()))
disCls.add(s2[s2.length-1].trim());
clsList.add(s2[s2.length-1]);
}
String ar="#relation tra\n";
try
{
for(int i=0;i<colNames.length-1;i++) // all columName which you have split
//and store in Colname
{
//where yor attitude in nominal or you can say character value
if(colTypes[i].equals("con"))
ar=ar+"#attribute "+colNames[i].trim().replace(" ","_")+" real\n";
else
{
ArrayList at1=new ArrayList();
for(int j=0;j<indata.length;j++) //your all numeric data
{
if(!at1.contains(indata[j][i].trim()))
at1.add(indata[j][i].trim());
}
String sg1="{";
for(int j=0;j<at1.size();j++)
{
sg1=sg1+at1.get(j).toString().trim()+",";
}
sg1=sg1.substring(0,sg1.lastIndexOf(","));
sg1=sg1+"}";
ar=ar+"#attribute "+colNames[i].trim().replace(" ", "_")+" "+sg1+"\n";
}
}
//end of attribute
// now adding a class Attribute
ArrayList dis=new ArrayList();
String c1="";
for(int i=0;i<clsList.size();i++)
{
String g=clsList.get(i).toString().trim();
if(!dis.contains(g))
{
dis.add(g);
c1=c1+g+",";
}
}
c1=c1.substring(0, c1.lastIndexOf(","));
ar=ar+"#attribute class {"+c1+"}\n"; //attribute name
//adding class attribute is done
//now data
ar=ar+"#data\n";
for(int i=0;i<indata.length;i++)
{
String g1="";
for(int j=0;j<indata[0].length;j++)
{
g1=g1+indata[i][j]+",";
}
g1=g1+clsList.get(i);
ar=ar+g1+"\n";
}
}
catch(Exception e)
{
e.printStackTrace();
}
return ar;
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Txt2Arff T2A=new Txt2Arff();
String ar1=T2A.genTrain();
File fe1=new File("tr.arff");
FileOutputStream fos1=new FileOutputStream(fe1);
fos1.write(ar1.getBytes());
fos1.close();
}}

a list of list value populated in struts2 iterator

For my case, it is a little bit trickier. I just have another list in person object, it is called state. like below:
public class People {
private int id;
private String name;
private List<State> states;
// Plus setters/getters
}
public class State {
private int id;
private String stateAbbr;
private String stateName;
public State (String stateAbbr, String stateName) {
this.stateAbbr = stateAbbr;
this.stateName = stateName;
}
// Plus setters/getters
}
Action class:
public class PersonAction extends ActionSupport {
private List<People> peopleList;
public List<People> getPeopleList() {
return peopleList;
}
public void setPeopleList(List<People> peopleList) {
this.peopleList = peopleList;
}
//Initial Load method
#Override
public String execute() {
peopleList = new ArrayList<People>();
int alpha = 65;
for(int i = 0; i < 3 ; i++) {
People people = new People();
people.setId(i);
people.setName(String.valueOf((char)alpha++));
peopleList.add(people);
}
for (People people : peopleList){
State state = new State("BC", "BritishColumbia");
List<State> states = new ArrayList<State>();
states.add(state);
state = new State("AC", "AppleColumbia");
states.add(state);
people.setStates(states);
}
return SUCCESS;
}
//Function that handles the form submit
public String updatePerson() {
for(People people : peopleList) {
System.out.println(people.getId() + ":" + people.getName());
}
return SUCCESS;
}
}
JSP page
<s:form action="doUpdate">
<s:iterator value="peopleList" status="stat" var="people">
<s:textfield value="%{#people.name}"
name="peopleList[%{#stat.index}].name" />
<s:iterator value="states" status="stateStatus" var="personState">
<s:textfield value="%{#personState.stateAbbr}"
name="peopleList[%{#stat.index}].states[%{#stateStatus.index}].stateAbbr" label="Abbr State" />
<br />
</s:iterator>
</s:iterator>
<s:submit value="Submit" />
</s:form>
When I submit this page, I got states is [null] in person, why?
Answer for the new question:
If your State class doesn't have a default constructor, S2/OGNL will not be able to instantiate an empty version of the class.
Provide a default (no-argument) constructor, and the person's states list will be populated.
(Too bad both answers can't be accepted ;)
The state property is a property of a specific person. In this case, you need to "connect" the state to persons[%{#stat.index}], so:
<s:textfield ...
name="persons[%{#stat.index}].states[%{#stateStatus.index}]" .../>
The iterator status variable has an index property that avoids the math you're doing on the IteratorStatus (docs) instance:
<s:textfield ... name="persons[%{#stat.index}].name" />
Also, depending on which version of S2 you're using, you may not need the # character.

Render a HtmlSelectOneMenu with only one entry as readonly inputfield in jsf?

Well we're trying to render a shitload of lists. Some of them have only one entry and we want them to appear as read only input fields (so users don't get fooled and it's easier to read).
But it seems kinda hard to access the inner selectitems size from outside.
I had my go with overwriting the htmlselectonemenu tag... Is there a different nicer way? Even possible to access it on tag level?
/**
* In case there is only one or less elements in the select list -> set readonly(true)
*/
public class HtmlSelectOneMenuModf extends HtmlSelectOneMenu {
#Override
public boolean isReadonly() {
for (Iterator iterator = getChildren().iterator(); iterator.hasNext();) {
Object obj = iterator.next();
if ( obj instanceof UISelectItems) {
UISelectItemsi = (UISelectItems) obj;
if(i.getSelectItems().size() <=1)
super.setReadonly(true);
}
}
return super.isReadonly();
}
}
We're chilling on JSF 1.2 btw...
Use JSTL fn:length().
<%#taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<h:selectOneMenu value="#{bean.item}" readonly="#{fn:length(bean.items) le 1}">
<f:selectItems value="#{bean.items}" />
</h:selectOneMenu>

Why does my XML ASP.NET web service return results which repeats itself?

I have written an ASP.NET web service.
It looks like this:
WebServices.logic pLogic = new WebServices.logic();
WebServices.manager[] pManager = new PowerManager[1];
pManager[0] = new PowerManager();
pManager[0].CustomerId = "sjsjshd";
pManager[0].state = pLogic.getState("sasj");
return pManager[0];
The pManager class looks like this:
public string _CustomerId;
public int PowerStatus;
public List<ArrayList> _Power;
public string CustomerId
{
get
{
return _CustomerId;
}
set
{
_CustomerId = value;
}
}
public List<ArrayList> Power
{
get
{
return _Power;
}
set
{
_Power = value;
}
}
When I run it, I get a repetition of the results, like so:
<p>
<_CustomerId>sjsjshd</_CustomerId>
<pStatus>0</PowerStatus>
−
<_p>
−
<ArrayOfAnyType>
<anyType xsi:type="xsd:int">1</anyType>
</ArrayOfAnyType>
<ArrayOfAnyType/>
</_p>
<CustomerId>sjsjshd</CustomerId>
−
<p>
−
<ArrayOfAnyType>
<anyType xsi:type="xsd:int">1</anyType>
</ArrayOfAnyType>
<ArrayOfAnyType/>
</p>
</pManager>
However, there is no duplicate values stored (Eg. I store client name in a collection, but only once - count of 1). There are no duplicates stored when I call getState(). This method returns a collection and it contains one value, but the results in XML has a repetition of this.
How comes the results appear to repeat themselves? When running the system, I only get one error.
Thanks
OK, looks like your XML serialization is giving you all the public members of your PowerManager class. Based on the naming convention of starting with an underscore, those members should be private, like this:
private string _CustomerId;
private List<ArrayList> _Power;
You also state "When running the system, I only get one error." What error are you getting?