Cannot seem to remove an object item from an arraylist - java

I am not able to remove an item from a arraylist.
What i tried is pasted below. Cannot seem to figure out what is wrong in below code.
The xhtml is
<p:dataTable id="emaildt" styleClass="hide-column-names"
style="width:70%" rowIndexVar="rowIndex"
value="#{myBean.emailAddressList}" var="email">
<p:column style="width:15%">
<p:inputText id="email" value="#{email.email}"
validatorMessage="Invalid email" onblur="TrimString(this)">
<f:validateRegex
pattern="^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+#((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$" />
<p:ajax event="blur"
global="false" listener="#{myBean.checkEmailExist(email)}" />
</p:inputText>
</p:column>
<p:column style="width:13%">
<p:spacer width="10" rendered="#{myBean.emailAddressList.size()>'1'}"/>
<p:commandLink id="delete" immediate="true"
actionListener="#{myBean.removeEmailFromList}"
update="emaildt" process="emaildt"
rendered="#{myBean.emailAddressList.size()>'1' && false}">
<h:graphicImage value="../images/button_remove.gif" />
<f:param name="rowToRemove" value="#{rowIndex}" />
</p:commandLink>
<p:spacer width="5" rendered="#{rowIndex == myBean.emailAddressList.size()-1}"/>
<p:commandLink id="addemailbtn" immediate="true"
actionListener="#{myBean.addEmail}"
style="float:right;" update="emaildt" process="#this emaildt"
rendered="#{rowIndex == myBean.emailAddressList.size()-1}">
<h:graphicImage value="../images/addbutton.jpg" />
</p:commandLink>
</p:column>
</p:dataTable>
Create a model class EmailAddressModel with string email and its getters and setters.
MyBean code is
List<emailAddressList> emailAddressList; //make its getters and setters
#PostConstruct
public void fillPage() {
emailAddressList = new ArrayList<EmailAddressModel>();
emailAddressList.add(new EmailAddressModel());
}
public void addEmail() {
try
{
EmailAddressModel emailAddress = new EmailAddressModel();
emailAddressList.add(emailAddress);
}
catch(IndexOutOfBoundsException I) {
log.warn("FL Warning", I);
}
}
public void removeEmailFromList() {
String rowIndex = null;
try {
rowIndex = FacesContext.getCurrentInstance().getExternalContext()
.getRequestParameterMap().get("rowToRemove");
int index = Integer.parseInt(rowIndex);
emailAddressList.remove(index);
} catch (Exception e) {
log.warn("FL Warning", e);
}
}
Issue is -> after we add and enter the values to first and second remove, click on delete of first row, then the second row gets deleted. On debugging, the first row is gets removed in backend arraylist but in front end, the second row gets deleted.
Hope that the above information is helpful.

Check the value of what's passed to rowIndex, as Boris the Spider mentioned, Java is zero indexed.
It's likely you're returning a rowIndex of 1, when the first item is indexed at 0.
To test, In your try-catch block you could use:
int index = Integer.parseInt(rowIndex) - 1;

Got the solution added atrribute resetValues="true" to p:commandLink.
Thank you all helping me..:)

Related

'Show All' button for Primefaces DataTable

I would like to have a 'Show All' button for a primefaces datatable, however, I'm experiencing some trouble. Here's some test code that demostrates the problem:
Test.xhtml:
...
<h:form>
<p:selectBooleanCheckbox value="#{testBean.showAll}" itemLabel="Show All">
<p:ajax update="#form"/>
</p:selectBooleanCheckbox>
<p:panel id="test">
<p:dataTable id="values" var="value" value="#{testBean.fullList}" filteredValue="#{testBean.filteredList}" paginatorAlwaysVisible="false"
paginator="#{!testBean.showAll}" rows="#{!testBean.showAll ? 2 : null }" widgetVar="valuesTable"
emptyMessage="No records found.">
<p:column id="enum" sortBy="#{value.toString()}" filterBy="#{value.toString()}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Enum" />
</f:facet>
<h:outputText value ="#{value.toString()}"/>
</p:column>
<p:column id="name" sortBy="#{value.name}" filterBy="#{value.name}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{value.name}" />
</p:column>
</p:dataTable>
</p:panel>
</h:form>
...
And here's TestBean.java:
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
#Named(value = "testBean")
#SessionScoped
public class TestBean implements Serializable {
public static enum Value {
ONE, TWO, THREE;
public String getName() {
return name().toLowerCase();
}
#Override
public String toString() {
return this.name();
}
}
/**
* Creates a new instance of TestBean
*/
public TestBean() {
}
private boolean showAll = false;
private List<Value> fullList = Arrays.asList(Value.values());
private List<Value> filteredList;
public boolean isShowAll() {
return showAll;
}
public void setShowAll(boolean showAll) {
this.showAll = showAll;
}
public List<Value> getFullList() {
return fullList;
}
public void setFullList(List<Value> fullList) {
this.fullList = fullList;
}
public List<Value> getFilteredList() {
return filteredList;
}
public void setFilteredList(List<Value> filteredList) {
this.filteredList = filteredList;
}
}
If I don't change tabs, the page works as expected: toggling the 'Show All' button updates the table to show all 3 values, or only two. However, if show all is not checked (only 2 rows are showing), and I click to the 2nd page of the table to view the third record, and then click 'Show All', the table does not update properly. It removes the paginator from the top of the table (as expected), but still only shows the 3rd record. And if I then uncheck show all and navigate back to the first page of the datatable, it is now broken too.
I've tried changing the ajax update statement to the id of the table, but that didn't change the results.
Am I doing something wrong? Thanks in advance.
You have to programmatically set the values you need directly on the DataTable component (I used explicit first and rows bean properties just for more readability):
<h:form>
<p:selectBooleanCheckbox value="#{testBean.showAll}" itemLabel="Show All">
<p:ajax update="#form" />
</p:selectBooleanCheckbox>
<p:panel id="test">
<p:dataTable id="values" var="value" value="#{testBean.fullList}"
filteredValue="#{testBean.filteredList}" paginatorAlwaysVisible="false"
paginator="#{!testBean.showAll}" first="#{testBean.first}" rows="#{testBean.rows}"
widgetVar="valuesTable" emptyMessage="No records found.">
<p:column id="enum" sortBy="#{value.toString()}" filterBy="#{value.toString()}"
filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Enum" />
</f:facet>
<h:outputText value="#{value.toString()}" />
</p:column>
<p:column id="name" sortBy="#{value.name}" filterBy="#{value.name}"
filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{value.name}" />
</p:column>
</p:dataTable>
</p:panel>
</h:form>
and
#Named
#ViewScoped
public class TestBean implements Serializable
{
private static final long serialVersionUID = 1L;
public static enum Value
{
ONE, TWO, THREE;
public String getName()
{
return name().toLowerCase();
}
#Override
public String toString()
{
return name();
}
}
private boolean showAll = false;
private int first = 0;
private int rows = 2;
private List<Value> fullList = Arrays.asList(Value.values());
private List<Value> filteredList;
public boolean isShowAll()
{
return showAll;
}
public void setShowAll(boolean showAll)
{
this.showAll = showAll;
first = 0;
rows = showAll ? 0 : 2;
filteredList = null;
// get the FacesContext instance
FacesContext context = FacesContext.getCurrentInstance();
// get the current component (p:selectBooleanCheckbox)
UIComponent component = UIComponent.getCurrentComponent(context);
// find DataTable within the same NamingContainer
DataTable table = (DataTable) component.findComponent("values");
// reset first row index
table.setFirst(first);
// reset last row index
table.setRows(rows);
// reset filterd value
table.setFilteredValue(null);
}
// all other getters/setters
}
Tested on Wildfly 10.0.0.Final with JSF 2.3.0-m06 (Mojarra) and PrimeFaces 6.0.2
I had the same problem, was resolved by this steps:
Adding styleClass="all-paginator" to datatable
<p:dataTable id="values" var="value" value="#{testBean.fullList}"
filteredValue="#{testBean.filteredList}" styleClass="all-paginator"..>
Add a getter of number of all records in the controller (TestBean.java) like:
public int getRecordNumber() {
if(CollectionUtils.isEmpty(fullList)){
return 0;
}
return fullList.size();
}
Add the property of the recordNumber at the end of the datatable attribute "rowsPerPageTemplate"
<p:dataTable id="values" var="value" value="#{testBean.fullList}" filteredValue="#{testBean.filteredList}"
styleClass="all-paginator" rowsPerPageTemplate="20,30,40,50,#{testBean.recordNumber}"..>

Adding one or more outputText to existing page dynamically

I have a need to continuously update a page with new data produced by managedbeans. Managedbean creates a new List of values for every few minutes and UI must create a OutputText for each of the value in the newly created List by managedbean. Catch is, the UI should retain the outputTexts and add new one's for every request, it should not refresh/remove old outputTexts.
My code is like below - updates the same outputText fields for each ajax call, which I need to change like mentioned above.
<c:forEach var="data" items="#{myBean.dataList}">
<p:fieldset legend="#{data}" toggleable="true" toggleSpeed="500">
<h:panelGrid columns="2" cellpadding="5" border="0">
<p:scrollPanel style="height:300px">
<p:poll interval="2" listener="#{myBean.getDataList}" update="field1 field2"/>
<h:outputText value="#{data.field1}" id="field1"/>
<h:outputText value="#{data.field2}" id="field2"/>
</p:scrollPanel>
</h:panelGrid>
</p:fieldset>
</c:forEach>
so for each ajax call, there may be few data items produced by managedbeans and for each of those item there should be a new outputText field.
You can use datalist for <h:outputText value="#{data.field1}" id="field1"/>
Make a list and use them as outputtext, yes you need some css formatting because datalist used default css. sample code
<p:poll interval="3" listener="#{yourbean.yourmethod}" update="<updatecomponet>" />
<p:dataList value="#{yourbean.tempList}" var="s" id="updatecomponet">
<p:outputLabel value="#{s}"></p:outputLabel>
</p:dataList>
Note: You need to add value in list when poll call listener. it is working in my project, let me know for anything else. Hope this will help.
Maybe not the perfect solution, but you can use a DataTable with lazy loading, the poll component can update the datatable page and you don't need to update a huge amount of components.
Edit:
xhtml
<p:dataTable var="v"
value="#{myBean.getLazyList}"
scrollRows="1"
liveScroll="true"
rows="20"
scrollHeight="300"
lazy="true"
scrollable="true"
id="tsUpdates">
<p:column>
<h:outputText value="#{v.fields1}" />
</p:column>
</p:dataTable>
Bean
public class Bean {
private LazyDataModel<MyClass> lazyList;
#Named("myBean")
#ViewScoped
#PostConstruct
public void init() {
lazyList = new LazyMyClassModel(); //where myList is your data source
}
//getters and setters
}
LazyModel
public class LazyMyClassModel extends LazyDataModel<MyClass>{
private Integer findAllCount;
public LazyMyClassModel(){
}
#Override
public List<MyClass> load(int first, int pageSize, String sortField, SortOrder sortOrder,Map<String, String> filters){
List<MyClass> myList = //your live source of data
List<MyClass> data = new ArrayList<MyClass>();
data = getSubList(MyList, first, pageSize)
if (findAllCount == null) {
findAllCount = myList.size
this.setRowCount(findAllCount);
}
return data
}
public List<MyClass> getSubList(List<MyClass> list, int fromIndex, int toIndex) {
int size = list.size();
if (fromIndex >= size || toIndex <= 0 || fromIndex >= toIndex) {
return Collections.emptyList();
}
fromIndex = Math.max(0, fromIndex);
toIndex = Math.min(size, toIndex);
return list.subList(fromIndex, toIndex);
}
}

JF2 Dynamic form element doesn't remember input and page refreshes every time I add element

I am trying to make a form with options to add rows. However, after I type in some input and click the add button again, the input I enter disappears. I'm not sure what is wrong with my code. In addition, when I click the add button, the page refreshes. Is there way to stop this page refresh?
Person.java
public class Person{
private List<String> guys = new ArrayList<String>();
public List<String> getGuys() {
return guys;
}
public void setGuys(List<String> guys) {
this.guys = guys;
public void addNewItem(){
guys.add("");
}
}
form.xhtml
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men">
<h:column>
<p:inputText value="#{men}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton name="submit" type="submit" value="Submit"></h:commandButton>
</h:form>
Provided that the bean is placed in the right scope for the functional requirement, the view scope, the only major mistake left is that you're expecting that the String class has some magic setter method.
It hasn't. The String class is immutable. The following will never work on a String:
<p:inputText value="#{men}" />
You have 2 options:
Create a real model class. You can find complete examples in the following answers:
How to dynamically add JSF components
Recommended JSF 2.0 CRUD frameworks
Set the value by row index instead:
<h:dataTable binding="#{table}" value="#{person.guys}">
<h:column>
<p:inputText value="#{person.guys[table.rowIndex]}" />
</h:column>
</h:dataTable>
(note: no additional bean property necessary for the table! the code is as-is)
This does basically a person.getGuys().add(table.getRowIndex(), submittedValue). I.e. the setter is invoked on the List itself, which works perfectly fine. See also the following related answers concerning ui:repeat:
Using <ui:repeat><h:inputText> on a List<String> doesn't update model values
How map multiple inputText to an array property?
You never update your list, you are just adding empty items. You should do something like this:
Person.java (viewscoped)
public class Person implements Serializable {
private List<String> guys = new ArrayList<String>();
private HtmlDataTable dtGuys;
public void addNewItem() {
guys.add("");
}
public void addToList(ValueChangeEvent e) {
guys.set(dtGuys.getRowIndex(), e.getNewValue().toString());
}
public String save() {
System.out.println("saving...");
for (String item : guys) {
System.out.println("item= " + item);
}
return null;
}
//gettes and setters
}
form.xhtml
<h:form id="frmPrincipal">
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men" binding="#{person.dtGuys}" >
<h:column>
<p:inputText value="#{men}" valueChangeListener="#{person.addToList}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton id="submit" name="submit" value="Submit" action="#{person.save}"/>
</h:form>
Using jsf 2.0.10 and primefaces 3.5
Its because you don't have an scope for that bean, so its request scoped, so when you call the action the bean is created again, you can fix this using a sessionScope or conversationScope

map for h:selectbooleancheckbox with datatable returns size of 0

I have this scenario that each row of datatable has checkbox.
if checkbox is selected you can delete multiple data and edit only one data.
I am successfully able to implement the delete but I got stuck with the edit cause checkedID will return the size of 0.
for the records I am following this example
below is my codes:
list.xhtml
<h:form>
<h:commandButton value="Edit" action="#{transportationController.prepareEdit()}"/>
<h:commandButton value="Delete" action="#{transportationController.delete()}">
<p:dataTable value="#{transportationController.items}" var="item" <p:column>
<f:facet name="header">
</f:facet>
<h:selectBooleanCheckbox value="#{transportationTypeController.checkedID[item.id]}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Remark"/>
</f:facet>
<h:outputText value="#{item.remark}"/>
</p:column>
</p:dataTable>
</h:form>
managedbean ---> transportationcontroller.java
transportationcontroller is a sessionscoped
private Map<Integer, Boolean> checkedID = new HashMap<Integer, Boolean>();
private List<Transportation> transportation = new ArrayList<Transportation>();
//setters and getters.
public List<Transportation> getCheckedTransportation() {
List<Transportation> checkedItems = new ArrayList<Transportation>();
for (Transportation trans : transportation) {
if (checkedID.get(trans.getId())) {
checkedItems.add(trans);
}
}
checkedID.clear();
return checkedItems;
}
//delete function
public String delete() {
List<Transportation> list = getCheckedTransportation();
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
ejbFacade.remove(list.get(i));
}
return "List";
} else {
FacesMessage msg = new FacesMessage("Please select data", "Please select data");
JsfUtil.getCurrent().addMessage("warning-message", msg);
return null;
}
}
//edit function
public void prepareEdit() {
List<Transportation> list = getCheckedTransportation();
if (list.size() == 1) {
current = list.get(0);
} else {
FacesMessage msg = new FacesMessage("Please select at least one data", "Please select at least one data");
JsfUtil.getCurrent().addMessage("warning-message", msg);
}
}
public Transportation getSelected() {
if (current == null) {
current = new Transportation();
selectedItemIndex = -1;
}
return current;
}
entity class ---> Transportation.java
public class Transportation implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
//etc..
}
as I debug,the Map checkedID will always has size of 0 for edit but for delete it's working fine. I've been stuck on this for this hours now but I am not able to identify the problem as why checkedID always has size of 0 which is for edit only when it's working fine for delete. anyhelp would be appreciated. Thanks.
Note: i know that primefaces p:datatable has selectionMode="multiple"
and selections but I don't to use it. I only want to use primefaces
for it's pagination.

multiple f:ajax calls in multiple h:selectOneMenu

Consider the following form:
1. User selects a value from the selectOneMenu "selectorDB"
2. Ajax call returns items for the second selectOneMenu and makes the whole "second" panelGroup rendered
3. User selects a value from the second selectOneMenu
4. Ajax call returns String which is placed inside of the inputText and panelGroup which contains that inputText rendered.
Everything works fine till im not selecting a value from the second selectOneMenu. Ajax of the fourth action is not even called. I've placed a couple of console System.outs to check if the listener is called and got nothing.
Is that possible to make something like the thing I'm attempting to do?
Thank you for any replies.
*.jsf:
<h:form>
<h:panelGroup id="first">
<h:outputLabel value="Select a database to make queries against" for="selectorDB" />
<h:selectOneMenu id="selectorDB" value="#{sparqlQuerier.chosenRing}">
<f:selectItem itemLabel="Select..." itemValue="0" />
<f:selectItems value="#{sparqlQuerier.ringTitles}" />
<f:ajax render="second third" listener="#{sparqlQuerier.firstListener}"/>
</h:selectOneMenu>
</h:panelGroup>
<br />
<h:panelGroup id="second">
<h:outputLabel rendered="#{sparqlQuerier.doRenderSecond}" value="Select a query to execute" for="selectorQuery" />
<h:selectOneMenu rendered="#{sparqlQuerier.doRenderSecond}" id="selectorQuery" value="#{sparqlQuerier.chosenQuery}">
<f:selectItem itemLabel="Select..." itemValue="0" />
<f:selectItems value="#{sparqlQuerier.queries}" />
<f:ajax render="third" listener="#{sparqlQuerier.secondListener}"/>
</h:selectOneMenu>
</h:panelGroup>
<br />
<h:panelGroup id="third">
<h:inputText rendered="#{sparqlQuerier.doRenderThird}" value="#{sparqlQuerier.queryBody}" onfocus="if (this.value == '#{sparqlQuerier.queryBody}') {this.value = '';}" onblur="if (this.value == '') {this.value ='#{sparqlQuerier.queryBody}';}" />
</h:panelGroup>
</h:form>
bean:
public void firstListener(AjaxBehaviorEvent event)
{
doRenderThird = false;
doRenderSecond = false;
if(chosenRing!=0)
{
doRenderSecond = true;
try
{
// returning rows from the database...
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
public void secondListener(AjaxBehaviorEvent event)
{
doRenderThird=false;
if(chosenQuery!=0)
{
if(chosenQuery==-1)
{
queryBody="body #1";
}
else
{
queryBody="body #2";
}
doRenderThird=true;
}
System.out.println(chosenQuery);
System.out.println(doRenderThird);
}

Categories

Resources