Duplicating row dynamically in h:dataTable - jsf

I have a data table
<h:dataTable value="#{vendor.vh.currentVendorVO.vfms}" var="row">
In VendorVO
private VFM[] vfms;
public VFM[] getVfms() {
return vfms;
}
public void setVfms(VFM[] vfms) {
this.vfms = vfms;
}
In VFM
private String orderTypeId;
private String fulfillTypeId;
private int orderSeq;
private String lastUpdated;
private String lastUpdatedBy;
private boolean lastItem;
private String action = "none";
I would like to duplicate the <h:dataTable> row when a button is clicked.
How can I achieve this?

Use a dynamically expansible ArrayList instead of a fixed size array [].
private List<VFM> vfms; // +getter (setter is unnecessary)
Then, it's just a matter of letting the button invoke add() method on it with new VFM instance.
<h:commandButton value="Add" action="#{bean.addVfm}" />
public void addVfm() {
vfms.add(new VFM());
}
If you intend to have this button on every row which copies a new VFM instance, then just pass it along and add a copy constructor.
<h:commandButton value="Copy" action="#{bean.copyVfm(row)}" />
public void copyVfm(VFM vfm) {
vfms.add(new VFM(vfm));
}
public VFM(VFM vfm) {
orderTypeId = vfm.orderTypeId;
fulfillTypeId = vfm.fulfillTypeId;
orderSeq = vfm.orderSeq;
lastUpdated = vfm.lastUpdated;
lastUpdatedBy = vfm.lastUpdatedBy;
lastItem = vfm.lastItem;
action = vfm.action;
}

Related

How to get the values from multiple dynaforms?

I have been following this tutorial
http://www.primefaces.org/showcase-ext/sections/dynaform/basicUsage.jsf
I have been able to create tree Dynaform objects and send it to the page. But I am having a hard time obtaining the values that the user entered once they clicked submit. I want to be able to get these values in the backbean.
Here is submit button
<p:commandButton value="Submit" action="#{dynaFormController.submitForm}"
process="dynaForm" update=":mainForm:dynaFormGroup :mainForm:inputValues"
oncomplete="handleComplete(xhr, status, args)"/>
<p:commandButton type="reset" value="Reset" style="margin-left: 5px;"/>
I know the submit calls this function
<h:outputScript id="dynaFormScript" target="body">
/* <![CDATA[ */
function handleComplete(xhr, status, args) {
if(args && args.isValid) {
PF('inputValuesWidget').show();
} else {
PF('inputValuesWidget').hide();
}
}
/* ]]> */
</h:outputScript>
Then in the bean we have:
public String submitForm() {
FacesMessage.Severity sev = FacesContext.getCurrentInstance().getMaximumSeverity();
boolean hasErrors = (sev != null && (FacesMessage.SEVERITY_ERROR.compareTo(sev) >= 0));
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.addCallbackParam("isValid", !hasErrors);
return null;
}
How would I be able to get either the fields values from the submitted form?
I have 3 dynaforms that I would like to submit them and be able to get the values in the back bean. Can anyone explain? I tried looking up some tutorials but I didn't find any explaining this.
Thanks.
It's the same as plain JSF.
You need a variable in your bean, its getters and setters.
Then, you compare it to the DynaFormControl.
#ManagedBean
#SessionScoped
public class DynaFormController implements Serializable {
private static final long serialVersionUID = 1L;
private DynaFormModel model;
private BookProperty bookProperty;
public String getBookProperty() {
return bookProperty;
}
public void setBookProperty(BookProperty bookProperty) {
this.bookProperty = bookProperty;
}
public String submitForm() {
//your code
List<DynaFormControl> controls = model.getControls();
for (DynaFormControl control : controls) {
if(control.getData() instanceof BookProperty) {
BookProperty bp = (BookProperty) c.getData();
//use the object
}
}
return null;
}
}

How to pause a Java "for" loop in order to expect a "p:commandbutton" click event ton be triggered in order to continue with the loop?

I have a list of books List<Book>, which I retrieve from my database.
Imagine that the Book class looks like this:
public class Book {
private String title;
private int pages;
// CONSTRUCTORS
public Book() {
}
public Book(String title, int pages) {
this.title = title;
this.pages = pages;
}
// GETTERS & SETTERS
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
}
In my service bookService I write a method in which I loop through the List
List<Book> bookList;
and I check whether the number of pages is has a number or it is "0" zero. In case the value is "0" zero, I want to show a form/dialog asking the user to define the number of pages.
For that reason I have built a form in my XHTML, which looks like this:
<h:form id="BookPagesPromptForm">
<p:dialog header="Define number of pages"
widgetVar="BookPagesPromptDialogWidget" dynamic="true" modal="true"
resizable="false" width="300px" height="150px" position="center,top"
showHeader="true">
<div>Title : #{bookService.getTitle()}</div><br />
<div>Pages <p:inputText value="#{bookService.newPagesValue}" /></div><br />
<div><p:commandButton id="savePagesCommandButton" value="Save Pages Value" onclick="#{bookService.closeBookPagesForm()}" /></div>
</p:dialog>
</h:form>
In my service I have the following method which I use to loop through my booList:
public class BookService {
// ...
// ... Code ...
// ...
private List<Book> bookList;
private IBookDAO bookDao;
// ...
// ... More Code ...
// ...
public void updateRecordsWithZeroPages() {
for (Book bk : bookList) {
if (bk.getPages() == 0) {
RequestContext context = RequestContext.getCurrentInstance();
context.execute("PF('BookPagesPromptDialogWidget').show();");
// Here I need to wait for user's input and as soon as the user
// clicks
// the "savePagesCommandButton" I want to update the record in
// my
// database.
bookDao.update(bk);
}
}
}
public void closeBookPagesForm() {
RequestContext context = RequestContext.getCurrentInstance();
context.execute("PF('BookPagesPromptDialogWidget').hide();");
}
}
In my flow book-flow.xml I have defined my service (partial code):
<view-state id="bookList">
<var name="bookService" class="com.stavros.BookService" />
</view-state>
The proble is that in my loop it does not stop when in the first record which has "0" zero pages, but it goes through all records and stops only when the loop is finished. As a consequence the form appears and asks the user about the last value from the loop.
In case you know how to make a "pause" in the loop and continue the loop only when the user click on the the "savePagesCommandButton" on the UI, please let me know.

Need to pass the current tab name to the backing managed bean from dynamically generated tab

I am using primefaces. And my requirement is to have number of tabs which will be generated based on a list specified in the backing bean. Now the second criteria is that if the tab changes the content under that tab should also changes. So I kept the onChange event and tried to get the value through event.getTab().getTitle(), but it is returning null to the backing bean.
<p:tabView id="tabView" binding="#{dndProductsView.tabView}">
<p:ajax event="tabChange" listener="#{dndProductsView.onTabChange}"/>
</p:tabView>
Managed Bean required codes are as :-
#PostConstruct
public void init() {
user = SessionBean.getUserName();
categorylist = categoryLogics.findAllOrderedByCategoryName();
productList = productLogics.findAllOrderedByProductName();
droppedProducts = new ArrayList<Product>();
}
private TabView tabView;
#Inject
private FacesContext facesContext;
public void setTabView(TabView tabView) {
this.tabView = tabView;
}
public TabView getTabView() {
tabView = new TabView();
for (Category c : categorylist) {
Tab t = new Tab();
t.setTitle(c.getCategoryName());
tabView.getChildren().add(t);
}
return tabView;
}
public void onTabChange(TabChangeEvent event) {
String titleName = event.getTab().getTitle();
System.out.println("" + titleName);
}
The tab is getting generated properly and when the tab changes, the onTabChange() method is called but event.getTab().getTitle() returns null.
Integer index=(Integer)tabview.getActiveIndex();
It is not a name but it is index of activ tab witch in this case is the one you are interested in.
Index starts from 0 being the first tab :)

JSF links in table not updating, sorting not swapping

I have a table displayed. When the user clicks on the headers i want the table to reorganise itself, sorted according to the selected header. Clicking on the same header again, swaps the order of sorting
Within the table, there are several commandLinks.
Now, the problems are as follows
the first update to the sorting order happens, but clicking on the header again will not swap the order.
When the table is refreshed, the links have their value changed, but the link still maps to the object that was previously there
Code:
Table:
<h:form title="table">
<h:dataTable value="#{employee.employeeList}" var="a"
styleClass="order-table" headerClass="order-table-header"
rowClasses="order-table-odd-row,order-table-even-row"
style="width:100%">
<h:column>
<f:facet name="header"><h:commandLink value="Number" action="#{employee.sortByNumber()}" /></f:facet>
<h:commandLink value="#{a.number}" action="#{employee.setEmp(a)}" />
</h:column>
...
...
...
</h:dataTable>
</h:form>
Employee Bean:
public String filter = ""; //has getters and setters
public String order = ""; //has getters and setters
public static final String ORDER_ASCENDING = "asc";
public static final String ORDER_DESCENDING = "desc";
public static final String FILTER_NUMBER = "number";
public void sortByNumber(){
if(filter.equals(FILTER_NUMBER)){
swapOrder();
}else{
filter = FILTER_NUMBER;
order = ORDER_ASCENDING;
}
refreshPage();
}
public void swapOrder(){
if(order.equals(ORDER_ASCENDING)){
order = ORDER_DESCENDING;
}else{
order = ORDER_ASCENDING;
}
}
public void refreshPage(){
FacesContext context = FacesContext.getCurrentInstance();
String viewId = context.getViewRoot().getViewId();
ViewHandler handler = context.getApplication().getViewHandler();
UIViewRoot root = handler.createView(context, viewId);
root.setViewId(viewId);
context.setViewRoot(root);
}
public String setEmp(Employee employee) {
this.employee = employee;
return "details"; //redirects to the details page where the employee set in the previous line is used
}

Dynamic action construction

I have a basic JSF question. I have a loop where I am trying to create mutile command link depending on the list value. and that command link will call the corresponding action from the list filed.
Basically I have this bean:
public class FavoriteTasks implements Serializable {
private static final long serialVersionUID = -8702569738872927728L;
private String key;
private String action;
private String widget;
private String name;
public FavoriteTasks(String key, String action, String widget, String name) {
super();
this.key = key;
this.action = action;
this.widget = widget;
}
And then populating it using properties file:
private void setUpFavTasks(UserUIPreferencesVO uiPref) {
List<String> fTaskList = uiPref.getFavoriteTasks();
favTasks =new ArrayList<FavoriteTasks>();
for(String var:fTaskList){
FavoriteTasks ft = new FavoriteTasks(var,
ConfigurationData.getValue(var+".action"),
ConfigurationData.getValue(var+".widget"),
ConfigurationData.getValue(var+".name"));
favTasks.add(ft);
}
}
Now the issue is the action is not understanding that it needs to get the value first and read that and then make the method call depending on the value.
<ui:repeat value="#{userSessionBean.favTasks}" var="favTasks" >
<li><ice:commandLink styleClass="shortcut-menu" action="#{favTasks.action}">
<f:param name="filterByContentWidget" value="#{favTasks.widget}" />
<f:param name="filterByContentGroup" value="#{favTasks.key}" />
<f:param name="menuName" value="#{favTasks.name}" />
<h:outputText value="#{msgs[favTasks.key]}" />
</ice:commandLink>
</li>
</ui:repeat>
action is trying to get favTasks.action and failing as there are no such method. it needs to read the value stored in favTasks.action and then go to the method that value is saying... for example if the favTasks.action = catalogHandler.showCatalog. it needs to invoke catalogHandler.showCatalog not favTasks.action
The action attribute is used to indicate the next view when you click the commandLink. It is a method expression that returns a String.
For example:
public String method() {
//do something
return "success";
}
and in your commandLink as
<ice:commandLink value="Submit" action="#{bean.method}" />
when clicked will take you to success.xhtml
Also you need to declare public setters/getters you just can't get/set any private variables that you have in your code:
private String key;
private String widget;
private String name;

Resources